Re: [PATCH 2/2] alpha: annotate hardirqs-off on IPL 7 interrupt entry

From: Magnus Lindholm

Date: Tue Aug 11 2026 - 02:33:27 EST


On Mon, Aug 10, 2026 at 10:28 PM Matt Turner <mattst88@xxxxxxxxx> wrote:
>
> do_entInt() opens with local_irq_disable(), which with
> CONFIG_TRACE_IRQFLAGS only calls trace_hardirqs_off() if interrupts were
> not already off:
>
> #define local_irq_disable() \
> do { \
> bool was_disabled = raw_irqs_disabled();\
> raw_local_irq_disable(); \
> if (!was_disabled) \
> trace_hardirqs_off(); \
> } while (0)
>
> On alpha raw_irqs_disabled() is (rdps() & 7) == IPL_MAX, i.e. IPL 7.
> PALcode raises PS.IPL to the level of the interrupt before entInt runs,
> so for an IPL 7 entry - a processor machine check (vector 0x660) or a
> system event (vector 0x680), both IPL_MCHECK == IPL_MAX - the gate is
> already true and the annotation is skipped. lockdep keeps whatever
> hardirq state the interrupted context had. If that context had
> interrupts enabled, lockdep believes they are still enabled for the
> duration of the handler, and every lockdep_assert_irqs_disabled() in the
> interrupt path fires:
>
> WARNING: kernel/context_tracking.c:346 at ct_irq_enter+0xc4/0xd0, CPU#0: swapper/0/0
> [...]
> [<fffffc0001ef74d4>] ct_irq_enter+0xc4/0xd0
> [<fffffc000105ebd0>] irq_enter+0x20/0x50
> [<fffffc000103707c>] do_entInt+0x1dc/0x2e0
> [<fffffc0001031d60>] ret_from_exception+0x0/0x10
>
> irq event stamp: 735356346
> hardirqs last enabled at (735356346): trace_hardirqs_on+0x68/0x220
> hardirqs last disabled at (735356345): do_idle+0xf0/0x270
>
> The stamps show the problem directly: the most recent event is the
> enable from the interrupted idle loop, and do_entInt() recorded no
> disable at all. ct_irq_exit() warns the same way on the way out.
>
> Ordinary device interrupts arrive at IPL 3-5 and IPIs and performance
> counter interrupts at IPL 6, so was_disabled is false for them and the
> annotation happens normally. Only the two IPL 7 vectors are affected,
> which is why this needs an environmental event to show up.
>
> Take the hardware IPL out of the decision and drive the annotation from
> lockdep's own state instead.
>
> This corrects the annotation only. An IPL 7 event can also interrupt a
> region that has legitimately disabled interrupts, where irq_enter() and
> irq_exit() are not the right primitives and NMI semantics are needed;
> that is a larger change and is left alone here.
>
> Tested on an AlphaServer ES47 (Marvel/EV7) by injecting system events
> through the system management path: fifteen injections, idle and under
> load, with no splat. The same injection on a freshly booted kernel
> without this change reproduces both warnings.
>
> Signed-off-by: Matt Turner <mattst88@xxxxxxxxx>
> ---
> arch/alpha/kernel/irq_alpha.c | 13 ++++++++++++-
> 1 file changed, 12 insertions(+), 1 deletion(-)
>
> diff --git a/arch/alpha/kernel/irq_alpha.c b/arch/alpha/kernel/irq_alpha.c
> index cb4d58079d83..014c1e98e922 100644
> --- a/arch/alpha/kernel/irq_alpha.c
> +++ b/arch/alpha/kernel/irq_alpha.c
> @@ -52,8 +52,19 @@ do_entInt(unsigned long type, unsigned long vector,
> * Note that there is no matching local_irq_enable() due to
> * severe problems with RTI at IPL0 and some MILO PALcode
> * (namely LX164).
> + *
> + * PALcode has already raised PS.IPL to the level of the interrupt
> + * being delivered. For an IPL 7 entry - a machine check or a system
> + * event - that is IPL_MAX, which is what arch_irqs_disabled() tests
> + * for, so local_irq_disable() would decide interrupts were already
> + * off and skip trace_hardirqs_off(). lockdep would then spend the
> + * whole handler believing interrupts are enabled. Drive the
> + * annotation from lockdep's own state rather than the hardware IPL.
> */
> - local_irq_disable();
> + raw_local_irq_disable();
> + if (lockdep_hardirqs_enabled())
> + trace_hardirqs_off();
> +
> old_regs = set_irq_regs(regs);
>
> switch (type) {
> --

Hi Matt,

Nice catch! On an SMP AlphaServer ES40 with GENERIC_ENTRY and lockdep enabled,
a PSU state change generates vector 0x680 and reliably triggers the
lockdep/check_flags
and ct_irq_enter warnings without this patch. With the patch applied,
repeated PSU state
changes generate the expected 0x680 reports without any lockdep warnings.

I also exercised normal IRQ traffic under load; lockdep remained enabled with no
redundant hardirq transitions or other regressions.

For verbose machine checks on tsunami I had also applies this patch:
https://lore.kernel.org/linux-alpha/20251125224352.32034-1-linmag7@xxxxxxxxx/

Reviewed-by: Magnus Lindholm <linmag7@xxxxxxxxx>
Tested-by: Magnus Lindholm <linmag7@xxxxxxxxx>

Thanks,
Magnus