{"api_version":"1","generated_at":"2026-09-25T22:32:52+00:00","cve":"CVE-2026-98106","urls":{"html":"https://cve.report/CVE-2026-98106","api":"https://cve.report/api/cve/CVE-2026-98106.json","docs":"https://cve.report/api","cve_org":"https://www.cve.org/CVERecord?id=CVE-2026-98106","nvd":"https://nvd.nist.gov/vuln/detail/CVE-2026-98106"},"summary":{"title":"drm/pagemap: Prevent double migration of device pages","description":"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---","state":"PUBLISHED","assigner":"Linux","published_at":"2026-09-25 11:17:41","updated_at":"2026-09-25 11:17:41"},"problem_types":[],"metrics":[],"references":[{"url":"https://git.kernel.org/stable/c/c4126f1db36e6b2e1c79b0e30a8a2de91c568f4c","name":"https://git.kernel.org/stable/c/c4126f1db36e6b2e1c79b0e30a8a2de91c568f4c","refsource":"416baaa9-dc9f-4396-8d5f-8c081fb06d67","tags":[],"title":"","mime":"","httpstatus":"","archivestatus":"0"},{"url":"https://git.kernel.org/stable/c/62451f540c46bf5c51143a1c8681b472608bd54d","name":"https://git.kernel.org/stable/c/62451f540c46bf5c51143a1c8681b472608bd54d","refsource":"416baaa9-dc9f-4396-8d5f-8c081fb06d67","tags":[],"title":"","mime":"","httpstatus":"","archivestatus":"0"},{"url":"https://www.cve.org/CVERecord?id=CVE-2026-98106","name":"CVE Program record","refsource":"CVE.ORG","tags":["canonical"]},{"url":"https://nvd.nist.gov/vuln/detail/CVE-2026-98106","name":"NVD vulnerability detail","refsource":"NVD","tags":["canonical","analysis"]}],"affected":[{"source":"CNA","vendor":"Linux","product":"Linux","version":"affected 99624bdff8670795b678eafa6509aaad3a5c0175 62451f540c46bf5c51143a1c8681b472608bd54d git","platforms":[]},{"source":"CNA","vendor":"Linux","product":"Linux","version":"affected 99624bdff8670795b678eafa6509aaad3a5c0175 c4126f1db36e6b2e1c79b0e30a8a2de91c568f4c git","platforms":[]},{"source":"CNA","vendor":"Linux","product":"Linux","version":"affected 6.15","platforms":[]},{"source":"CNA","vendor":"Linux","product":"Linux","version":"unaffected 6.15 semver","platforms":[]},{"source":"CNA","vendor":"Linux","product":"Linux","version":"unaffected 7.2.7 7.2.* semver","platforms":[]},{"source":"CNA","vendor":"Linux","product":"Linux","version":"unaffected 7.3-rc2 * original_commit_for_fix","platforms":[]}],"timeline":[],"solutions":[],"workarounds":[],"exploits":[],"credits":[],"nvd_cpes":[],"vendor_comments":[],"enrichments":{"kev":null,"epss":null,"legacy_qids":[]},"source_records":{"cve_program":{"containers":{"cna":{"affected":[{"defaultStatus":"unaffected","product":"Linux","programFiles":["drivers/gpu/drm/drm_pagemap.c","include/drm/drm_pagemap.h"],"repo":"https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git","vendor":"Linux","versions":[{"lessThan":"62451f540c46bf5c51143a1c8681b472608bd54d","status":"affected","version":"99624bdff8670795b678eafa6509aaad3a5c0175","versionType":"git"},{"lessThan":"c4126f1db36e6b2e1c79b0e30a8a2de91c568f4c","status":"affected","version":"99624bdff8670795b678eafa6509aaad3a5c0175","versionType":"git"}]},{"defaultStatus":"affected","product":"Linux","programFiles":["drivers/gpu/drm/drm_pagemap.c","include/drm/drm_pagemap.h"],"repo":"https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git","vendor":"Linux","versions":[{"status":"affected","version":"6.15"},{"lessThan":"6.15","status":"unaffected","version":"0","versionType":"semver"},{"lessThanOrEqual":"7.2.*","status":"unaffected","version":"7.2.7","versionType":"semver"},{"lessThanOrEqual":"*","status":"unaffected","version":"7.3-rc2","versionType":"original_commit_for_fix"}]}],"cpeApplicability":[{"nodes":[{"cpeMatch":[{"criteria":"cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:*","versionEndExcluding":"7.2.7","versionStartIncluding":"6.15","vulnerable":true},{"criteria":"cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:*","versionEndExcluding":"7.3-rc2","versionStartIncluding":"6.15","vulnerable":true}],"negate":false,"operator":"OR"}]}],"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---"}],"providerMetadata":{"dateUpdated":"2026-09-25T10:35:55.743Z","orgId":"416baaa9-dc9f-4396-8d5f-8c081fb06d67","shortName":"Linux"},"references":[{"url":"https://git.kernel.org/stable/c/62451f540c46bf5c51143a1c8681b472608bd54d"},{"url":"https://git.kernel.org/stable/c/c4126f1db36e6b2e1c79b0e30a8a2de91c568f4c"}],"title":"drm/pagemap: Prevent double migration of device pages","x_generator":{"engine":"bippy-1.2.0"}}},"cveMetadata":{"assignerOrgId":"416baaa9-dc9f-4396-8d5f-8c081fb06d67","assignerShortName":"Linux","cveId":"CVE-2026-98106","datePublished":"2026-09-25T10:35:55.743Z","dateReserved":"2026-09-25T10:25:14.316Z","dateUpdated":"2026-09-25T10:35:55.743Z","state":"PUBLISHED"},"dataType":"CVE_RECORD","dataVersion":"5.2"},"nvd":{"publishedDate":"2026-09-25 11:17:41","lastModifiedDate":"2026-09-25 11:17:41","problem_types":[],"metrics":[],"configurations":[]},"legacy_mitre":{"record":{"CveYear":"2026","CveId":"98106","Ordinal":"1","Title":"drm/pagemap: Prevent double migration of device pages","CVE":"CVE-2026-98106","Year":"2026"},"notes":[{"CveYear":"2026","CveId":"98106","Ordinal":"1","NoteData":"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---","Type":"Description","Title":"drm/pagemap: Prevent double migration of device pages"}]}}}