CVE-2026-98106
In the Linux kernel, the following vulnerability has been resolved:
drm/pagemap: Prevent double migration of device pages
A device-private folio migrated to system memory by a CPU fault can remain reachable through the raw-PFN eviction path until migration finalization drops the source reference.
If eviction selects the same device-private folio during this window, it can attempt to migrate the folio again. The second migration can leave an uncharged folio on an LRU list, causing folio_lruvec_lock_irqsave() to retry indefinitely and resulting in a soft lockup and RCU stall.
Mark successfully migrated device-private folios using a low bit of their zone_device_data before migration finalization. Make both CPU-fault and raw-PFN migration paths skip device-private folios carrying this flag.
Read full descriptionShow less
Mask the flag when retrieving the drm_pagemap_zdd pointer and preserve it when a device-private folio is split. Keeping the state on the physical folio also avoids depending on a virtual address that may change before a fault occurs.
v2: - Replace the retired-PFN XArray with an embedded bitmap. (Matthew Brost) - Mark every base page covered by a migrated folio so retirement remains valid if the folio is later split.
v3: - Store the migrated state in a low bit of zone_device_data instead of adding virtual-range and bitmap tracking to the ZDD. (Matthew Brost) - Mask the flag when retrieving the ZDD and preserve it when splitting a folio. - Drop the pre-existing fixes already covered by Matthew Brost's series: https://patchwork.freedesktop.org/series/171651/
v4: - Advance by the folio size only for migration entries marked with MIGRATE_PFN_COMPOUND. (Sashiko)
v5: - Simplify ZDD flag updates and folio iteration. (Matthew Brost) - Skip retired device-private folios in the CPU-fault path. (Matthew Brost) - Preserve flag bits while taking a new ZDD reference for split folios.
v6: - Restore MIGRATE_PFN_COMPOUND-aware stepping so non-compound migration entries are processed one at a time. (Sashiko) - Drop the pre-existing fixes already covered by Matthew Brost's series: https://patchwork.freedesktop.org/series/171651/
Technical details traces, logs and code from the original report
The lockup was observed as: [10109.860465] watchdog: BUG: soft lockup - CPU#9 stuck for 26s! [kworker/u65:5:6557] [10109.860524] Tainted: [S]=CPU_OUT_OF_SPEC, [O]=OOT_MODULE [10109.860524] Hardware name: ASUS System Product Name/PRIME Z790-P WIFI, BIOS 0812 02/24/2023 [10109.860525] Workqueue: xe_page_fault_work_queue xe_pagefault_queue_work [xe] [10109.860644] RIP: 0010:_raw_spin_unlock_irqrestore+0x57/0x80 [10109.860655] Call Trace: [10109.860655] <TASK> [10109.860657] folio_lruvec_lock_irqsave+0x216/0x220 [10109.860661] ? __pfx_lru_add+0x10/0x10 [10109.860665] folio_batch_move_lru+0xc8/0x450 [10109.860670] ? lock_acquire+0xc4/0x2d0 [10109.860674] ? __folio_batch_add_and_move+0x60/0x2e0 [10109.860677] ? folio_migrate_mapping+0xa6/0x110 [10109.860679] ? folio_migrate_flags+0x13b/0x1b0 [10109.860681] ? __pfx_lru_add+0x10/0x10 [10109.860683] __folio_batch_add_and_move+0xe7/0x2e0 [10109.860685] ? dma_iova_try_alloc+0xb0/0x140 [10109.860689] folio_add_lru+0x64/0x80 [10109.860691] __migrate_device_finalize+0x12c/0x270 [10109.860695] migrate_device_finalize+0x10/0x20 [10109.860698] drm_pagemap_evict_to_ram+0x185/0x370 [drm_gpusvm_helper] [10109.860704] ? drm_pagemap_evict_to_ram+0x96/0x370 [drm_gpusvm_helper] [10109.860709] xe_svm_bo_evict+0x15/0x20 [xe] [10109.860819] ? xe_svm_bo_evict+0x15/0x20 [xe] [10109.860921] xe_bo_move+0x107e/0x1570 [xe] [10109.860992] ? xe_ttm_tt_create+0x168/0x340 [xe] [10109.861059] ? __up_read+0x98/0x2b0 [10109.861061] ? lock_is_held_type+0xa3/0x130 [10109.861067] ttm_bo_handle_move_mem+0xe8/0x1e0 [ttm] [10109.861075] ttm_bo_evict+0x141/0x1c0 [ttm] [10109.861081] ttm_bo_evict_cb+0x9f/0x100 [ttm] [10109.861086] ttm_lru_walk_for_evict+0x84/0x190 [ttm] [10109.861091] ? xe_ttm_vram_mgr_new+0x258/0x3a0 [xe] [10109.861198] ttm_bo_alloc_resource+0x219/0 ---truncated---
CVSS
NVD hasn't assigned a CVSS score to this CVE (common since the April 2026 policy change).
Exploitation probability (EPSS)
- Probability of exploitation in the next 30 days: 0.15%
- Percentile among all scored CVEs: 4
- Score date: 10/5/2026
EPSS (Exploit Prediction Scoring System, FIRST) estimates how likely a vulnerability is to be exploited in the wild within 30 days. It complements CVSS (impact) and CISA KEV (confirmed exploitation).
Affected technologies (1)
⚠ AI-inferred from the description — NVD hasn't analyzed this CVE yet, these aren't verified CPEs.
References
Raw JSON (NVD)
Show
{
"id": "CVE-2026-98106",
"cveTags": [],
"metrics": {},
"affected": [
{
"source": "416baaa9-dc9f-4396-8d5f-8c081fb06d67",
"affectedData": [
{
"repo": "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git",
"vendor": "Linux",
"product": "Linux",
"versions": [
{
"status": "affected",
"version": "99624bdff8670795b678eafa6509aaad3a5c0175",
"lessThan": "62451f540c46bf5c51143a1c8681b472608bd54d",
"versionType": "git"
},
{
"status": "affected",
"version": "99624bdff8670795b678eafa6509aaad3a5c0175",
"lessThan": "c4126f1db36e6b2e1c79b0e30a8a2de91c568f4c",
"versionType": "git"
}
],
"programFiles": [
"drivers/gpu/drm/drm_pagemap.c",
"include/drm/drm_pagemap.h"
],
"defaultStatus": "unaffected"
},
{
"repo": "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git",
"vendor": "Linux",
"product": "Linux",
"versions": [
{
"status": "affected",
"version": "6.15"
},
{
"status": "unaffected",
"version": "0",
"lessThan": "6.15",
"versionType": "semver"
},
{
"status": "unaffected",
"version": "7.2.7",
"versionType": "semver",
"lessThanOrEqual": "7.2.*"
},
{
"status": "unaffected",
"version": "7.3-rc2",
"versionType": "original_commit_for_fix",
"lessThanOrEqual": "*"
}
],
"programFiles": [
"drivers/gpu/drm/drm_pagemap.c",
"include/drm/drm_pagemap.h"
],
"defaultStatus": "affected"
}
]
}
],
"published": "2026-09-25T11:17:41.110",
"references": [
{
"url": "https://git.kernel.org/stable/c/62451f540c46bf5c51143a1c8681b472608bd54d",
"source": "416baaa9-dc9f-4396-8d5f-8c081fb06d67"
},
{
"url": "https://git.kernel.org/stable/c/c4126f1db36e6b2e1c79b0e30a8a2de91c568f4c",
"source": "416baaa9-dc9f-4396-8d5f-8c081fb06d67"
}
],
"vulnStatus": "Undergoing Analysis",
"descriptions": [
{
"lang": "en",
"value": "In the Linux kernel, the following vulnerability has been resolved:\n\ndrm/pagemap: Prevent double migration of device pages\n\nA device-private folio migrated to system memory by a CPU fault can\nremain reachable through the raw-PFN eviction path until migration\nfinalization drops the source reference.\n\nIf eviction selects the same device-private folio during this window,\nit can attempt to migrate the folio again. The second migration can leave\nan uncharged folio on an LRU list, causing folio_lruvec_lock_irqsave() to\nretry indefinitely and resulting in a soft lockup and RCU stall.\n\nMark successfully migrated device-private folios using a low bit of\ntheir zone_device_data before migration finalization. Make both CPU-fault\nand raw-PFN migration paths skip device-private folios carrying this\nflag.\n\nMask the flag when retrieving the drm_pagemap_zdd pointer and preserve\nit when a device-private folio is split. Keeping the state on the physical\nfolio also avoids depending on a virtual address that may change before a\nfault occurs.\n\nv2:\n- Replace the retired-PFN XArray with an embedded bitmap. (Matthew Brost)\n- Mark every base page covered by a migrated folio so retirement remains\n valid if the folio is later split.\n\nv3:\n- Store the migrated state in a low bit of zone_device_data instead of\n adding virtual-range and bitmap tracking to the ZDD. (Matthew Brost)\n- Mask the flag when retrieving the ZDD and preserve it when splitting\n a folio.\n- Drop the pre-existing fixes already covered by Matthew Brost's series:\n https://patchwork.freedesktop.org/series/171651/\n\nv4:\n- Advance by the folio size only for migration entries marked with\n MIGRATE_PFN_COMPOUND. (Sashiko)\n\nv5:\n- Simplify ZDD flag updates and folio iteration. (Matthew Brost)\n- Skip retired device-private folios in the CPU-fault path. (Matthew Brost)\n- Preserve flag bits while taking a new ZDD reference for split folios.\n\nv6:\n- Restore MIGRATE_PFN_COMPOUND-aware stepping so non-compound migration\n entries are processed one at a time. (Sashiko)\n- Drop the pre-existing fixes already covered by Matthew Brost's series:\n https://patchwork.freedesktop.org/series/171651/\n\nThe lockup was observed as:\n[10109.860465] watchdog: BUG: soft lockup - CPU#9 stuck for 26s! [kworker/u65:5:6557]\n[10109.860524] Tainted: [S]=CPU_OUT_OF_SPEC, [O]=OOT_MODULE\n[10109.860524] Hardware name: ASUS System Product Name/PRIME Z790-P WIFI, BIOS 0812 02/24/2023\n[10109.860525] Workqueue: xe_page_fault_work_queue xe_pagefault_queue_work [xe]\n[10109.860644] RIP: 0010:_raw_spin_unlock_irqrestore+0x57/0x80\n[10109.860655] Call Trace:\n[10109.860655] <TASK>\n[10109.860657] folio_lruvec_lock_irqsave+0x216/0x220\n[10109.860661] ? __pfx_lru_add+0x10/0x10\n[10109.860665] folio_batch_move_lru+0xc8/0x450\n[10109.860670] ? lock_acquire+0xc4/0x2d0\n[10109.860674] ? __folio_batch_add_and_move+0x60/0x2e0\n[10109.860677] ? folio_migrate_mapping+0xa6/0x110\n[10109.860679] ? folio_migrate_flags+0x13b/0x1b0\n[10109.860681] ? __pfx_lru_add+0x10/0x10\n[10109.860683] __folio_batch_add_and_move+0xe7/0x2e0\n[10109.860685] ? dma_iova_try_alloc+0xb0/0x140\n[10109.860689] folio_add_lru+0x64/0x80\n[10109.860691] __migrate_device_finalize+0x12c/0x270\n[10109.860695] migrate_device_finalize+0x10/0x20\n[10109.860698] drm_pagemap_evict_to_ram+0x185/0x370 [drm_gpusvm_helper]\n[10109.860704] ? drm_pagemap_evict_to_ram+0x96/0x370 [drm_gpusvm_helper]\n[10109.860709] xe_svm_bo_evict+0x15/0x20 [xe]\n[10109.860819] ? xe_svm_bo_evict+0x15/0x20 [xe]\n[10109.860921] xe_bo_move+0x107e/0x1570 [xe]\n[10109.860992] ? xe_ttm_tt_create+0x168/0x340 [xe]\n[10109.861059] ? __up_read+0x98/0x2b0\n[10109.861061] ? lock_is_held_type+0xa3/0x130\n[10109.861067] ttm_bo_handle_move_mem+0xe8/0x1e0 [ttm]\n[10109.861075] ttm_bo_evict+0x141/0x1c0 [ttm]\n[10109.861081] ttm_bo_evict_cb+0x9f/0x100 [ttm]\n[10109.861086] ttm_lru_walk_for_evict+0x84/0x190 [ttm]\n[10109.861091] ? xe_ttm_vram_mgr_new+0x258/0x3a0 [xe]\n[10109.861198] ttm_bo_alloc_resource+0x219/0\n---truncated---"
}
],
"lastModified": "2026-09-30T14:10:59.253",
"sourceIdentifier": "416baaa9-dc9f-4396-8d5f-8c081fb06d67"
}