UBUNTU-CVE-2026-89589: Medium severity ubuntu/linux-hwe-edge vulnerability
In the Linux kernel, the following vulnerability has been resolved: acpi/apei/ghes: Use rawspinlockt for CXL CPER work locks The CXL CPER work registration and unregistration helpers acquire cxlcperworklock and cxlcperproterrworklock with a spinlock guard(), which leaves local interrupts enabled. The corresponding post paths (cxlcperpostevent(), cxlcperpostproterr()) execute in hard IRQ context (they are called from the GHES error notification path) and acquire the same locks with an irqsave guard(). If a CPU is holding one of these locks via a spinlock guard() when a GHES interrupt arrives on the same CPU, the IRQ handler spins on the held lock waiting for it to release, while the lock holder is preempted by the IRQ. The result is a deadlock. Convert both locks from spinlockt to rawspinlockt and use guard() at all call sites. On PREEMPTRT kernels spinlockt is backed by rtmutex and sleeping from hard IRQ context is not permitted; rawspinlockt is safe in both contexts. Add WARNONCE to both register functions to surface double-registration bugs at runtime. Restructure both unregister functions to clear the global work pointer under the lock before calling cancelworksync(), closing the window where a CPER interrupt could schedule work on a pointer about to be freed. Add kfiforeset() after cancelworksync() so stale entries are not replayed on next module load. Both kfifos are single-consumer: only one workstruct is registered at a time, enforced by the WARNONCE guard in the register functions. kfiforeset() is safe outside the lock because cancelworksync() has already quiesced the consumer, and no new consumer can register until the current module exit completes and a fresh module init runs. Remove the redundant cancelworksync() call from cxlrasexit() and cxlpcidriverexit(). The CPER unregister functions now quiesce the work internally.
Affected Software
Remediation
Recommended actions to resolve this vulnerability, in priority order.
- Upgrade
Upgrade
ubuntu/linux-hwe-7.0to a version that resolves this vulnerability.Fixed in 7.0.0-42.42~24.04.1 - Upgrade
Upgrade
ubuntu/linux-riscv-7.0to a version that resolves this vulnerability.Fixed in 7.0.0-42.42.1~24.04.1 - Upgrade
Upgrade
ubuntu/linuxto a version that resolves this vulnerability.Fixed in 7.0.0-42.42 - Upgrade
Upgrade
ubuntu/linux-awsto a version that resolves this vulnerability.Fixed in 7.0.0-1016.17 - Upgrade
Upgrade
ubuntu/linux-gcpto a version that resolves this vulnerability.Fixed in 7.0.0-1016.18 - Upgrade
Upgrade
ubuntu/linux-ibmto a version that resolves this vulnerability.Fixed in 7.0.0-1017.17 - Upgrade
Upgrade
ubuntu/linux-oem-7.0to a version that resolves this vulnerability.Fixed in 7.0.0-1017.17 - Upgrade
Upgrade
ubuntu/linux-oracleto a version that resolves this vulnerability.Fixed in 7.0.0-1015.16 - Upgrade
Upgrade
ubuntu/linux-riscvto a version that resolves this vulnerability.Fixed in 7.0.0-42.42.1 - Configuration
Add WARN_ONCE to both register functions to detect double registration at runtime.
CXL CPER work registration functions WARN_ONCE registration guard = enabled - Configuration
Call kfifo_reset() after cancel_work_sync() so stale entries are not replayed on the next module load.
CXL CPER work queues kfifo_reset() after cancel_work_sync() = enabled - Configuration
Convert both locks from spinlock_t to raw_spinlock_t and use guard() at all call sites; acquire them with an irqsave guard() in cxl_cper_post_event() and cxl_cper_post_prot_err().
cxl_cper_work_lock and cxl_cper_prot_err_work_lock lock type and guard usage = raw_spinlock_t with guard() - Configuration
Restructure both unregister functions to clear the global work pointer while holding the lock before calling cancel_work_sync(); the unregister functions must quiesce the work internally.
CXL CPER unregister functions global work pointer teardown order = clear under lock before cancel_work_sync() - Configuration
Remove the redundant cancel_work_sync() call from cxl_ras_exit() and cxl_pci_driver_exit().
cxl_ras_exit() and cxl_pci_driver_exit() redundant cancel_work_sync() calls = removed
Event History
Frequently Asked Questions
Which Ubuntu kernel packages are in scope?
The affected software list includes ubuntu/linux-riscv, ubuntu/linux-realtime, ubuntu/linux-hwe-edge, ubuntu/linux-azure, ubuntu/linux-gcp, ubuntu/linux-azure-fde, ubuntu/linux-gke, and ubuntu/linux-aws-5.0.
What conditions lead to the deadlock?
A CPU must hold either CXL CPER work lock while a GHES error notification interrupt arrives on that same CPU and attempts to acquire the same lock. The interrupt handler then spins while the interrupted lock holder cannot resume, causing a deadlock.
Why are PREEMPT_RT kernels particularly relevant?
On PREEMPT_RT, spinlock_t is backed by an rt_mutex, and sleeping locks cannot be used from hard IRQ context. The fix uses raw_spinlock_t so the locks are safe both for normal contexts and the hard-IRQ GHES error-notification path.