From: Aristeu Rozanski <aris@redhat.com> Date: Tue, 25 Nov 2008 10:33:30 -0500 Subject: [x86] nmi_watchdog: call do_nmi_callback from traps-xen Message-id: 20081125153329.GF33010@redhat.com O-Subject: Re: [RHEL5.3 PATCH] nmi_watchdog: call do_nmi_callback() from traps-xen Bugzilla: 471111 RH-Acked-by: Chris Lalancette <clalance@redhat.com> RH-Acked-by: Prarit Bhargava <prarit@redhat.com> RH-Acked-by: Bill Burns <bburns@redhat.com> RH-Acked-by: Dave Anderson <anderson@redhat.com> https://bugzilla.redhat.com/show_bug.cgi?id=471111 The NMI watchdog backport work is not complete because traps-xen.c wasn't updated and the result is that the unknown_nmi_panic won't work on xen kernels, affecting NEC machines with NMI buttons. It's upstream, just compare with traps.c, since upstream traps-xen.c doesn't exist upstream. diff --git a/arch/i386/kernel/traps-xen.c b/arch/i386/kernel/traps-xen.c index 3e4e34a..3613af6 100644 --- a/arch/i386/kernel/traps-xen.c +++ b/arch/i386/kernel/traps-xen.c @@ -788,26 +788,27 @@ void die_nmi (struct pt_regs *regs, const char *msg) static void default_do_nmi(struct pt_regs * regs) { unsigned char reason = 0; + int cpu; + + cpu = smp_processor_id(); /* Only the BSP gets external NMIs from the system. */ - if (!smp_processor_id()) + if (!cpu) reason = get_nmi_reason(); if (!(reason & 0xc0)) { if (notify_die(DIE_NMI_IPI, "nmi_ipi", regs, reason, 2, SIGINT) == NOTIFY_STOP) return; -#ifdef CONFIG_X86_LOCAL_APIC /* * Ok, so this is none of the documented NMI sources, * so it must be the NMI watchdog. */ - if (nmi_watchdog) { - nmi_watchdog_tick(regs); + if (nmi_watchdog_tick(regs)) return; - } -#endif - unknown_nmi_error(reason, regs); + + if (!do_nmi_callback(regs, cpu)) + unknown_nmi_error(reason, regs); return; } if (notify_die(DIE_NMI, "nmi", regs, reason, 2, SIGINT) == NOTIFY_STOP) diff --git a/arch/x86_64/kernel/traps-xen.c b/arch/x86_64/kernel/traps-xen.c index 9357d42..696603b 100644 --- a/arch/x86_64/kernel/traps-xen.c +++ b/arch/x86_64/kernel/traps-xen.c @@ -787,17 +787,15 @@ asmlinkage __kprobes void default_do_nmi(struct pt_regs *regs) if (notify_die(DIE_NMI_IPI, "nmi_ipi", regs, reason, 2, SIGINT) == NOTIFY_STOP) return; -#ifdef CONFIG_X86_LOCAL_APIC /* * Ok, so this is none of the documented NMI sources, * so it must be the NMI watchdog. */ - if (nmi_watchdog > 0) { - nmi_watchdog_tick(regs,reason); + if (nmi_watchdog_tick(regs, reason)) return; - } -#endif - unknown_nmi_error(reason, regs); + + if (!do_nmi_callback2(regs, cpu)) + unknown_nmi_error(reason, regs); return; } if (notify_die(DIE_NMI, "nmi", regs, reason, 2, SIGINT) == NOTIFY_STOP) diff --git a/include/asm-x86_64/mach-xen/asm/nmi.h b/include/asm-x86_64/mach-xen/asm/nmi.h index 3c75095..cc2b01b 100644 --- a/include/asm-x86_64/mach-xen/asm/nmi.h +++ b/include/asm-x86_64/mach-xen/asm/nmi.h @@ -87,6 +87,7 @@ extern void release_lapic_nmi(void); extern void disable_timer_nmi_watchdog(void); extern void enable_timer_nmi_watchdog(void); extern int nmi_watchdog_tick (struct pt_regs * regs, unsigned reason); +extern int do_nmi_callback2(struct pt_regs *regs, int cpu); extern void nmi_watchdog_default(void); extern int setup_nmi_watchdog(char *);