CVE-2026-46156
Description
In the Linux kernel, the following vulnerability has been resolved:
LoongArch: Fix potential ADE in loongson_gpu_fixup_dma_hang()
The switch case in loongson_gpu_fixup_dma_hang() may not DC2 or DC3, and readl(crtc_reg) will access with random address, because the "device" is from "base+PCI_DEVICE_ID", "base" is from "pdev->devfn+1". This is wrong when my platform inserts a discrete GPU:
lspci -tv -[0000:00]-+-00.0 Loongson Technology LLC Hyper Transport Bridge Controller ... +-06.0 Loongson Technology LLC LG100 GPU +-06.2 Loongson Technology LLC Device 7a37 ...
Add a default switch case to fix the panic as below:
Kernel ade access[#1]: CPU: 0 PID: 1 Comm: swapper/0 Not tainted 6.6.136-loong64-desktop-hwe+ #4 pc 90000000017e5534 ra 90000000017e54c0 tp 90000001002f8000 sp 90000001002fb6c0 a0 80000efe00003100 a1 0000000000003100 a2 0000000000000000 a3 0000000000000002 a4 90000001002fb6b4 a5 900000087cdb58fd a6 90000000027af000 a7 0000000000000001 t0 00000000000085b9 t1 000000000000ffff t2 0000000000000000 t3 0000000000000000 t4 fffffffffffffffd t5 00000000fffb6d9c t6 0000000000083b00 t7 00000000000070c0 t8 900000087cdb4d94 u0 900000087cdb58fd s9 90000001002fb826 s0 90000000031c12c8 s1 7fffffffffffff00 s2 90000000031c12d0 s3 0000000000002710 s4 0000000000000000 s5 0000000000000000 s6 9000000100053000 s7 7fffffffffffff00 s8 90000000030d4000 ra: 90000000017e54c0 loongson_gpu_fixup_dma_hang+0x40/0x210 ERA: 90000000017e5534 loongson_gpu_fixup_dma_hang+0xb4/0x210 CRMD: 000000b0 (PLV0 -IE -DA +PG DACF=CC DACM=CC -WE) PRMD: 00000004 (PPLV0 +PIE -PWE) EUEN: 00000000 (-FPE -SXE -ASXE -BTE) ECFG: 00071c1d (LIE=0,2-4,10-12 VS=7) ESTAT: 00480000 [ADEM] (IS= ECode=8 EsubCode=1) BADV: 7fffffffffffff00 PRID: 0014d000 (Loongson-64bit, Loongson-3A6000-HV) Modules linked in: Process swapper/0 (pid: 1, threadinfo=(____ptrval____), task=(____ptrval____)) Stack : 0000000000000006 90000001002fb778 90000001002fb704 0000000000000007 0000000016a65700 90000000017e5690 000000000000ffff ffffffffffffffff 900000000209f7c0 9000000100053000 900000000209f7a8 9000000000eebc08 0000000000000000 0000000000000000 0000000000000006 90000001002fb778 90000001000530b8 90000000027af000 0000000000000000 9000000100054000 9000000100053000 9000000000ebb70c 9000000100004c00 9000000004000001 90000001002fb7e4 bae765461f31cb12 0000000000000000 0000000000000000 0000000000000006 90000000027af000 0000000000000030 90000000027af000 900000087cd6f800 9000000100053000 0000000000000000 9000000000ebc560 7a2500147cdaf720 bae765461f31cb12 0000000000000001 0000000000000030 ... Call Trace: [<90000000017e5534>] loongson_gpu_fixup_dma_hang+0xb4/0x210 [<9000000000eebc08>] pci_fixup_device+0x108/0x280 [<9000000000ebb70c>] pci_setup_device+0x24c/0x690 [<9000000000ebc560>] pci_scan_single_device+0xe0/0x140 [<9000000000ebc684>] pci_scan_slot+0xc4/0x280 [<9000000000ebdd00>] pci_scan_child_bus_extend+0x60/0x3f0 [<9000000000f5bc94>] acpi_pci_root_create+0x2b4/0x420 [<90000000017e5e74>] pci_acpi_scan_root+0x2d4/0x440 [<9000000000f5b02c>] acpi_pci_root_add+0x21c/0x3a0 [<9000000000f4ee54>] acpi_bus_attach+0x1a4/0x3c0 [<90000000010e200c>] device_for_each_child+0x6c/0xe0 [<9000000000f4bbf4>] acpi_dev_for_each_child+0x44/0x70 [<9000000000f4ef40>] acpi_bus_attach+0x290/0x3c0 [<90000000010e200c>] device_for_each_child+0x6c/0xe0 [<9000000000f4bbf4>] acpi_dev_for_each_child+0x44/0x70 [<9000000000f4ef40>] acpi_bus_attach+0x290/0x3c0 [<9000000000f5211c>] acpi_bus_scan+0x6c/0x280 [<900000000189c028>] acpi_scan_init+0x194/0x310 [<900000000189bc6c>] acpi_init+0xcc/0x140 [<9000000000220cdc>] do_one_initcall+0x4c/0x310 [<90000000018618fc>] kernel_init_freeable+0x258/0x2d4 [<900000000184326c>] kernel_init+0x28/0x13c [<9000000000222008>] ret_from_kernel_thread+0xc/0xa4
AI Insight
LLM-synthesized narrative grounded in this CVE's description and references.
A missing default case in LoongArch GPU DMA hang fixup causes kernel panic on systems with non-DC2/DC3 GPUs.
Vulnerability
In the Linux kernel for the LoongArch architecture, the function loongson_gpu_fixup_dma_hang() contains a switch statement that only handles device IDs corresponding to DC2 or DC3 GPUs. When a system includes a discrete GPU with a different device ID (e.g., a Loongson Technology LLC Device 7a37), the code falls through without a default case and attempts to read from an invalid memory address derived from base + PCI_DEVICE_ID, where base is computed from pdev->devfn + 1. This results in an Address Error Exception (ADE) and a kernel panic. The bug is present in kernel versions prior to the fix commit [1].
Exploitation
An attacker does not need any special privileges or network access; the vulnerability is triggered automatically during kernel initialization (the swapper/0 process) on affected hardware configurations. The system must have a LoongArch CPU and a discrete GPU that is not a DC2 or DC3 device. No user interaction is required beyond booting the system. The crash occurs early in the boot process, as shown by the kernel oops trace [1].
Impact
Successful exploitation results in a kernel panic (ADE) that halts the system, causing a denial of service. There is no indication of privilege escalation, information disclosure, or arbitrary code execution. The impact is limited to system unavailability on affected hardware.
Mitigation
The fix is provided in commit 8dfa2f8780e486d05b9a0ffce70b8f5fbd62053e in the Linux kernel stable tree [1]. This commit adds a default case to the switch statement to handle unexpected device IDs gracefully. Users should update their kernel to a version containing this commit. No workaround is available in the references.
AI Insight generated on May 28, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.
Affected products
2Patches
1081fef1c27843LoongArch: Fix potential ADE in loongson_gpu_fixup_dma_hang()
1 file changed · +3 −1
arch/loongarch/pci/pci.c+3 −1 modifieddiff --git a/arch/loongarch/pci/pci.c b/arch/loongarch/pci/pci.c index d233ea2218fe0a..f33c7ea1443d94 100644 --- a/arch/loongarch/pci/pci.c +++ b/arch/loongarch/pci/pci.c @@ -132,6 +132,9 @@ static void loongson_gpu_fixup_dma_hang(struct pci_dev *pdev, bool on) crtc_reg = regbase; crtc_offset = 0x400; break; + default: + iounmap(regbase); + return; } for (i = 0; i < CRTC_NUM_MAX; i++, crtc_reg += crtc_offset) { -- cgit 1.3-korg
8dfa2f8780e4LoongArch: Fix potential ADE in loongson_gpu_fixup_dma_hang()
1 file changed · +3 −1
arch/loongarch/pci/pci.c+3 −1 modifieddiff --git a/arch/loongarch/pci/pci.c b/arch/loongarch/pci/pci.c index d233ea2218fe0a..f33c7ea1443d94 100644 --- a/arch/loongarch/pci/pci.c +++ b/arch/loongarch/pci/pci.c @@ -132,6 +132,9 @@ static void loongson_gpu_fixup_dma_hang(struct pci_dev *pdev, bool on) crtc_reg = regbase; crtc_offset = 0x400; break; + default: + iounmap(regbase); + return; } for (i = 0; i < CRTC_NUM_MAX; i++, crtc_reg += crtc_offset) { -- cgit 1.3-korg
07d190e4ec68LoongArch: Fix potential ADE in loongson_gpu_fixup_dma_hang()
1 file changed · +3 −1
arch/loongarch/pci/pci.c+3 −1 modifieddiff --git a/arch/loongarch/pci/pci.c b/arch/loongarch/pci/pci.c index 70485b167cfab5..a25307d6aee818 100644 --- a/arch/loongarch/pci/pci.c +++ b/arch/loongarch/pci/pci.c @@ -133,6 +133,9 @@ static void loongson_gpu_fixup_dma_hang(struct pci_dev *pdev, bool on) crtc_reg = regbase; crtc_offset = 0x400; break; + default: + iounmap(regbase); + return; } for (i = 0; i < CRTC_NUM_MAX; i++, crtc_reg += crtc_offset) { -- cgit 1.3-korg
2cb19b06c099LoongArch: Fix potential ADE in loongson_gpu_fixup_dma_hang()
1 file changed · +3 −1
arch/loongarch/pci/pci.c+3 −1 modifieddiff --git a/arch/loongarch/pci/pci.c b/arch/loongarch/pci/pci.c index 70485b167cfab5..a25307d6aee818 100644 --- a/arch/loongarch/pci/pci.c +++ b/arch/loongarch/pci/pci.c @@ -133,6 +133,9 @@ static void loongson_gpu_fixup_dma_hang(struct pci_dev *pdev, bool on) crtc_reg = regbase; crtc_offset = 0x400; break; + default: + iounmap(regbase); + return; } for (i = 0; i < CRTC_NUM_MAX; i++, crtc_reg += crtc_offset) { -- cgit 1.3-korg
9e1aed63a555LoongArch: Fix potential ADE in loongson_gpu_fixup_dma_hang()
1 file changed · +3 −1
arch/loongarch/pci/pci.c+3 −1 modifieddiff --git a/arch/loongarch/pci/pci.c b/arch/loongarch/pci/pci.c index d233ea2218fe0a..f33c7ea1443d94 100644 --- a/arch/loongarch/pci/pci.c +++ b/arch/loongarch/pci/pci.c @@ -132,6 +132,9 @@ static void loongson_gpu_fixup_dma_hang(struct pci_dev *pdev, bool on) crtc_reg = regbase; crtc_offset = 0x400; break; + default: + iounmap(regbase); + return; } for (i = 0; i < CRTC_NUM_MAX; i++, crtc_reg += crtc_offset) { -- cgit 1.3-korg
9e1aed63a555LoongArch: Fix potential ADE in loongson_gpu_fixup_dma_hang()
1 file changed · +3 −1
arch/loongarch/pci/pci.c+3 −1 modifieddiff --git a/arch/loongarch/pci/pci.c b/arch/loongarch/pci/pci.c index d233ea2218fe0a..f33c7ea1443d94 100644 --- a/arch/loongarch/pci/pci.c +++ b/arch/loongarch/pci/pci.c @@ -132,6 +132,9 @@ static void loongson_gpu_fixup_dma_hang(struct pci_dev *pdev, bool on) crtc_reg = regbase; crtc_offset = 0x400; break; + default: + iounmap(regbase); + return; } for (i = 0; i < CRTC_NUM_MAX; i++, crtc_reg += crtc_offset) { -- cgit 1.3-korg
8dfa2f8780e4LoongArch: Fix potential ADE in loongson_gpu_fixup_dma_hang()
1 file changed · +3 −1
arch/loongarch/pci/pci.c+3 −1 modifieddiff --git a/arch/loongarch/pci/pci.c b/arch/loongarch/pci/pci.c index d233ea2218fe0a..f33c7ea1443d94 100644 --- a/arch/loongarch/pci/pci.c +++ b/arch/loongarch/pci/pci.c @@ -132,6 +132,9 @@ static void loongson_gpu_fixup_dma_hang(struct pci_dev *pdev, bool on) crtc_reg = regbase; crtc_offset = 0x400; break; + default: + iounmap(regbase); + return; } for (i = 0; i < CRTC_NUM_MAX; i++, crtc_reg += crtc_offset) { -- cgit 1.3-korg
81fef1c27843LoongArch: Fix potential ADE in loongson_gpu_fixup_dma_hang()
1 file changed · +3 −1
arch/loongarch/pci/pci.c+3 −1 modifieddiff --git a/arch/loongarch/pci/pci.c b/arch/loongarch/pci/pci.c index d233ea2218fe0a..f33c7ea1443d94 100644 --- a/arch/loongarch/pci/pci.c +++ b/arch/loongarch/pci/pci.c @@ -132,6 +132,9 @@ static void loongson_gpu_fixup_dma_hang(struct pci_dev *pdev, bool on) crtc_reg = regbase; crtc_offset = 0x400; break; + default: + iounmap(regbase); + return; } for (i = 0; i < CRTC_NUM_MAX; i++, crtc_reg += crtc_offset) { -- cgit 1.3-korg
2cb19b06c099LoongArch: Fix potential ADE in loongson_gpu_fixup_dma_hang()
1 file changed · +3 −1
arch/loongarch/pci/pci.c+3 −1 modifieddiff --git a/arch/loongarch/pci/pci.c b/arch/loongarch/pci/pci.c index 70485b167cfab5..a25307d6aee818 100644 --- a/arch/loongarch/pci/pci.c +++ b/arch/loongarch/pci/pci.c @@ -133,6 +133,9 @@ static void loongson_gpu_fixup_dma_hang(struct pci_dev *pdev, bool on) crtc_reg = regbase; crtc_offset = 0x400; break; + default: + iounmap(regbase); + return; } for (i = 0; i < CRTC_NUM_MAX; i++, crtc_reg += crtc_offset) { -- cgit 1.3-korg
07d190e4ec68LoongArch: Fix potential ADE in loongson_gpu_fixup_dma_hang()
1 file changed · +3 −1
arch/loongarch/pci/pci.c+3 −1 modifieddiff --git a/arch/loongarch/pci/pci.c b/arch/loongarch/pci/pci.c index 70485b167cfab5..a25307d6aee818 100644 --- a/arch/loongarch/pci/pci.c +++ b/arch/loongarch/pci/pci.c @@ -133,6 +133,9 @@ static void loongson_gpu_fixup_dma_hang(struct pci_dev *pdev, bool on) crtc_reg = regbase; crtc_offset = 0x400; break; + default: + iounmap(regbase); + return; } for (i = 0; i < CRTC_NUM_MAX; i++, crtc_reg += crtc_offset) { -- cgit 1.3-korg
Vulnerability mechanics
Root cause
"Missing default case in switch statement allows uninitialized/invalid MMIO address to be passed to readl(), causing an Address Detection Exception (ADE)."
Attack vector
The vulnerability is triggered during PCI device enumeration at boot time. The function loongson_gpu_fixup_dma_hang() in arch/loongarch/pci/pci.c computes a register address from the PCI device's devfn field; when a discrete GPU (or any non-DC2/DC3 device) is present, the switch case matches none of the expected values and falls through without setting crtc_reg. The subsequent readl(crtc_reg) then dereferences a random/stale address, causing an ADE (Address Detection Exception) kernel panic [patch_id=2898218]. No special privileges or network access are required — the bug triggers automatically during normal system boot on affected LoongArch platforms with certain PCI topologies.
Affected code
The vulnerable function is loongson_gpu_fixup_dma_hang() in arch/loongarch/pci/pci.c [patch_id=2898218]. The switch statement that checks the PCI device ID for DC2 or DC3 lacked a default case, so when neither matched, crtc_reg remained uninitialized and was passed to readl().
What the fix does
The patch adds a default case to the switch statement in loongson_gpu_fixup_dma_hang() that calls iounmap(regbase) and returns early [patch_id=2898218]. This ensures that when the PCI device is neither DC2 nor DC3 (i.e., the device is not an integrated Loongson GPU that needs the DMA hang workaround), the function safely unmaps the MMIO region and exits without attempting to read from an invalid register address. The fix closes the gap that previously allowed an uninitialized crtc_reg to reach readl().
Preconditions
- configSystem must be running a LoongArch kernel with the loongson_gpu_fixup_dma_hang() fixup function
- inputPCI topology must include a device that is not a DC2 or DC3 GPU (e.g., a discrete GPU or other non-GPU device at the expected devfn offset)
- networkVulnerability triggers automatically during PCI enumeration at boot, no attacker interaction needed
Generated on May 28, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
5- git.kernel.org/stable/c/07d190e4ec689d6478f7f5e36099fb9bf457e7c5nvd
- git.kernel.org/stable/c/2cb19b06c09983727573bbe7d7430cbad480a714nvd
- git.kernel.org/stable/c/81fef1c278436e6bd68ee4ca05a0acb96e256561nvd
- git.kernel.org/stable/c/8dfa2f8780e486d05b9a0ffce70b8f5fbd62053envd
- git.kernel.org/stable/c/9e1aed63a5552958ef2a9bfd699a3f990e52a77fnvd
News mentions
0No linked articles in our index yet.