Skip to content
OpenAdvisories
Unscored CVE-2026-98395 EUVD-2026-101044GHSA-c6r3-334m-j754

powerpc/entry: Fix irq_soft_mask corruption on replayed interrupt exit

Published Oct 14, 2026 · Updated Oct 19, 2026 · Assigned by Linux

Vendor: Linux Product: Linux Package: linux Package: linux-allwinner-5.19 Package: linux-aws-5.0 Package: linux-aws-5.11 Package: linux-aws-5.13 Package: linux-aws-5.19 Package: linux-aws-5.3 Package: linux-aws-5.8 Package: linux-aws-6.14 Package: linux-aws-6.17 Package: linux-aws-6.2 Package: linux-aws-6.5 Package: linux-azure Package: linux-azure-5.11 Package: linux-azure-5.13 Package: linux-azure-5.19 Package: linux-azure-5.3 Package: linux-azure-5.8 Package: linux-azure-6.11 Package: linux-azure-6.14 Package: linux-azure-6.17 Package: linux-azure-6.2 Package: linux-azure-6.5 Package: linux-azure-edge Package: linux-azure-fde Package: linux-azure-fde-5.19 Package: linux-azure-fde-6.14 Package: linux-azure-fde-6.17 Package: linux-azure-fde-6.2 Package: linux-azure-nvidia-6.14 Package: linux-gcp Package: linux-gcp-5.11 Package: linux-gcp-5.13 Package: linux-gcp-5.19 Package: linux-gcp-5.3 Package: linux-gcp-5.8 Package: linux-gcp-6.11 Package: linux-gcp-6.14 Package: linux-gcp-6.17 Package: linux-gcp-6.2 Package: linux-gcp-6.5 Package: linux-gke Package: linux-gke-4.15 Package: linux-gke-5.15 Package: linux-gke-5.4 Package: linux-gkeop Package: linux-gkeop-5.15 Package: linux-gkeop-5.4 Package: linux-hwe Package: linux-hwe-5.11 Package: linux-hwe-5.13 Package: linux-hwe-5.19 Package: linux-hwe-5.8 Package: linux-hwe-6.11 Package: linux-hwe-6.14 Package: linux-hwe-6.2 Package: linux-hwe-6.5 Package: linux-hwe-edge Package: linux-intel-5.13 Package: linux-intel-iot-realtime Package: linux-lowlatency-hwe-5.19 Package: linux-lowlatency-hwe-6.11 Package: linux-lowlatency-hwe-6.2 Package: linux-lowlatency-hwe-6.5 Package: linux-nvidia-6.11 Package: linux-nvidia-6.17 Package: linux-nvidia-6.2 Package: linux-nvidia-6.5 Package: linux-oem Package: linux-oem-5.10 Package: linux-oem-5.13 Package: linux-oem-5.14 Package: linux-oem-5.17 Package: linux-oem-5.6 Package: linux-oem-6.0 Package: linux-oem-6.1 Package: linux-oem-6.11 Package: linux-oem-6.14 Package: linux-oem-6.5 Package: linux-oem-6.8 Package: linux-oracle-5.0 Package: linux-oracle-5.11 Package: linux-oracle-5.13 Package: linux-oracle-5.3 Package: linux-oracle-5.8 Package: linux-oracle-6.14 Package: linux-oracle-6.17 Package: linux-oracle-6.5 Package: linux-raspi-realtime Package: linux-raspi2 Package: linux-realtime Package: linux-realtime-6.14 Package: linux-realtime-6.17 Package: linux-riscv Package: linux-riscv-5.11 Package: linux-riscv-5.19 Package: linux-riscv-5.8 Package: linux-riscv-6.14 Package: linux-riscv-6.17 Package: linux-riscv-6.5 Package: linux-starfive-5.19 Package: linux-starfive-6.2 Package: linux-starfive-6.5 Package: linux-vmware Platform: Linux Ecosystem: Debian Ecosystem: Ubuntu

Description

In the Linux kernel, the following vulnerability has been resolved:

powerpc/entry: Fix irq_soft_mask corruption on replayed interrupt exit

When __replay_soft_interrupts() replays a pending interrupt (e.g.
PACA_IRQ_DEC -> timer_interrupt), it calls the handler directly with a
synthetic pt_regs. The DEFINE_INTERRUPT_HANDLER_ASYNC wrapper around
each handler calls arch_interrupt_async_exit_prepare() on the way out,
which calls arch_interrupt_exit_prepare() -> local_irq_disable() ->
arch_local_irq_disable(), which does:

irq_soft_mask_set(IRQS_DISABLED) /* 0x1 */

This unconditionally overwrites irq_soft_mask with IRQS_DISABLED (0x1),
stripping the IRQS_PMI_DISABLED (0x2) bit. The result is that
irq_soft_mask is 0x1 instead of IRQS_ALL_DISABLED (0x3) when the
handler returns to __replay_soft_interrupts().

For a normally-taken interrupt this is harmless: the next interrupt
always enters through arch_interrupt_enter_prepare() which
unconditionally sets irq_soft_mask to IRQS_ALL_DISABLED. But during
replay, next_interrupt() is called directly between replayed handlers
without going back through arch_interrupt_enter_prepare(), so the
stripped bit is never restored. next_interrupt() then fires a WARNING:

WARNING: arch/powerpc/kernel/irq_64.c:75
WARN_ON(irq_soft_mask_return() != IRQS_ALL_DISABLED)

The warning was observed early in boot on a POWER10 pseries guest
during kmem_cache_init_late(), where a spinlock release triggers
interrupt replay that processes a pending timer interrupt.

Debugger state confirming the bug:
Before timer_interrupt(&regs):
irq_soft_mask = 0x3 (IRQS_ALL_DISABLED) correct
irq_happened = 0x41 (HARD_DIS|REPLAYING) correct
After timer_interrupt(&regs) returns:
irq_soft_mask = 0x1 (IRQS_DISABLED) WRONG - PMI bit stripped
irq_happened = 0x41 unchanged

The fix is to replace local_irq_disable() with hard_irq_disable().

hard_irq_disable() is the right primitive here for two reasons:

1. On PPC64 (hw_irq.h:301) it calls irq_soft_mask_set_return(IRQS_ALL_DISABLED),
setting the soft mask to 0x3 (both IRQS_DISABLED and IRQS_PMI_DISABLED),
which preserves the PMI bit and fixes the WARNING. The additional
work it does (__hard_irq_disable(), PACA_IRQ_HARD_DIS |=) is
redundant but safe since both are already set at this point in the
exit path; the trace_hardirqs_off() inside is guarded by
if (!arch_irqs_disabled_flags(flags)) so it will not double-fire.

2. On PPC32 (hw_irq.h:467) hard_irq_disable() maps to
arch_local_irq_disable() -> __hard_irq_disable(), which clears
MSR[EE] in hardware. This is exactly correct: PPC32 has no soft-mask
PACA mechanism, so the hardware disable is the right way to satisfy
irqentry_exit()'s requirement. This also fixes a build error on PPC32
where irq_soft_mask_set() is only defined under CONFIG_PPC64:

arch/powerpc/include/asm/entry-common.h:273: error: implicit
declaration of function 'irq_soft_mask_set'

Using hard_irq_disable() requires no #ifdef and is consistent with
how the rest of the entry code (e.g. entry-common.h:463) handles the
same PPC32/PPC64 split.

Affected products

VendorProductAffectedFixed
Linux Linux 7.2 7.2.7

Fixed in Linux distributions

Distributions backport fixes, so the version that fixes this vulnerability differs per release — upgrade to at least the version shown. From the distributions' security trackers and advisories.

ReleasePackageFixed inAdvisory
Debian 14 linux 7.2.7-1 —
ReleasePackageFixed inAdvisory
Ubuntu 24.04 LTS linux-riscv +25 No fix yet —
Ubuntu 22.04 LTS linux-riscv +32 No fix yet —
Ubuntu 20.04 LTS linux-gke +28 No fix yet —
Ubuntu 18.04 LTS linux-gcp +14 No fix yet —
Ubuntu 16.04 LTS linux-hwe-edge No fix yet —
Show 1 more (older releases, extended support, other products)
ReleasePackageFixed inAdvisory
Ubuntu Pro Realtime 24.04 LTS linux-realtime-6.14 +1 No fix yet —

Advisories 1

References