From 553222f3e81f18da31b2552e18dc519715198590 Mon Sep 17 00:00:00 2001 From: Don Zickus Date: Thu, 29 Mar 2012 16:11:16 -0400 Subject: x86/nmi: Add new NMI queues to deal with IO_CHK and SERR In discussions with Thomas Mingarelli about hpwdt, he explained to me some issues they were some when using their virtual NMI button to test the hpwdt driver. It turns out the virtual NMI button used on HP's machines do no send unknown NMIs but instead send IO_CHK NMIs. The way the kernel code is written, the hpwdt driver can not register itself against that type of NMI and therefore can not successfully capture system information before panic'ing. To solve this I created two new NMI queues to allow driver to register against the IO_CHK and SERR NMIs. Or in the hpwdt all three (if you include unknown NMIs too). The change is straightforward and just mimics what the unknown NMI does. Reported-and-tested-by: Thomas Mingarelli Signed-off-by: Don Zickus Cc: Peter Zijlstra Cc: Linus Torvalds Cc: Andrew Morton Link: http://lkml.kernel.org/r/1333051877-15755-3-git-send-email-dzickus@redhat.com Signed-off-by: Ingo Molnar --- drivers/watchdog/hpwdt.c | 27 ++++++++++++++++++++------- 1 file changed, 20 insertions(+), 7 deletions(-) (limited to 'drivers/watchdog/hpwdt.c') diff --git a/drivers/watchdog/hpwdt.c b/drivers/watchdog/hpwdt.c index 4000b8038cac..6e414b501d58 100644 --- a/drivers/watchdog/hpwdt.c +++ b/drivers/watchdog/hpwdt.c @@ -725,19 +725,32 @@ static int __devinit hpwdt_init_nmi_decoding(struct pci_dev *dev) * Only one function can register for NMI_UNKNOWN */ retval = register_nmi_handler(NMI_UNKNOWN, hpwdt_pretimeout, 0, "hpwdt"); - if (retval != 0) { - dev_warn(&dev->dev, - "Unable to register a die notifier (err=%d).\n", - retval); - if (cru_rom_addr) - iounmap(cru_rom_addr); - } + if (retval) + goto error; + retval = register_nmi_handler(NMI_SERR, hpwdt_pretimeout, 0, "hpwdt"); + if (retval) + goto error1; + retval = register_nmi_handler(NMI_IO_CHECK, hpwdt_pretimeout, 0, "hpwdt"); + if (retval) + goto error2; dev_info(&dev->dev, "HP Watchdog Timer Driver: NMI decoding initialized" ", allow kernel dump: %s (default = 0/OFF)\n", (allow_kdump == 0) ? "OFF" : "ON"); return 0; + +error2: + unregister_nmi_handler(NMI_SERR, "hpwdt"); +error1: + unregister_nmi_handler(NMI_UNKNOWN, "hpwdt"); +error: + dev_warn(&dev->dev, + "Unable to register a die notifier (err=%d).\n", + retval); + if (cru_rom_addr) + iounmap(cru_rom_addr); + return retval; } static void hpwdt_exit_nmi_decoding(void) -- cgit v1.2.3