aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorDon Zickus <dzickus@redhat.com>2012-03-29 16:11:16 -0400
committerIngo Molnar <mingo@kernel.org>2012-04-25 06:43:34 -0400
commit553222f3e81f18da31b2552e18dc519715198590 (patch)
tree53610c3d21a1b929190688c1b30687ab1af6d381 /drivers
parent09ee10143658cd021d879ead61ead72a196302b6 (diff)
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 <thomas.mingarelli@hp.com> Signed-off-by: Don Zickus <dzickus@redhat.com> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Linus Torvalds <torvalds@linux-foundation.org> Cc: Andrew Morton <akpm@linux-foundation.org> Link: http://lkml.kernel.org/r/1333051877-15755-3-git-send-email-dzickus@redhat.com Signed-off-by: Ingo Molnar <mingo@kernel.org>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/watchdog/hpwdt.c27
1 files changed, 20 insertions, 7 deletions
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)
725 * Only one function can register for NMI_UNKNOWN 725 * Only one function can register for NMI_UNKNOWN
726 */ 726 */
727 retval = register_nmi_handler(NMI_UNKNOWN, hpwdt_pretimeout, 0, "hpwdt"); 727 retval = register_nmi_handler(NMI_UNKNOWN, hpwdt_pretimeout, 0, "hpwdt");
728 if (retval != 0) { 728 if (retval)
729 dev_warn(&dev->dev, 729 goto error;
730 "Unable to register a die notifier (err=%d).\n", 730 retval = register_nmi_handler(NMI_SERR, hpwdt_pretimeout, 0, "hpwdt");
731 retval); 731 if (retval)
732 if (cru_rom_addr) 732 goto error1;
733 iounmap(cru_rom_addr); 733 retval = register_nmi_handler(NMI_IO_CHECK, hpwdt_pretimeout, 0, "hpwdt");
734 } 734 if (retval)
735 goto error2;
735 736
736 dev_info(&dev->dev, 737 dev_info(&dev->dev,
737 "HP Watchdog Timer Driver: NMI decoding initialized" 738 "HP Watchdog Timer Driver: NMI decoding initialized"
738 ", allow kernel dump: %s (default = 0/OFF)\n", 739 ", allow kernel dump: %s (default = 0/OFF)\n",
739 (allow_kdump == 0) ? "OFF" : "ON"); 740 (allow_kdump == 0) ? "OFF" : "ON");
740 return 0; 741 return 0;
742
743error2:
744 unregister_nmi_handler(NMI_SERR, "hpwdt");
745error1:
746 unregister_nmi_handler(NMI_UNKNOWN, "hpwdt");
747error:
748 dev_warn(&dev->dev,
749 "Unable to register a die notifier (err=%d).\n",
750 retval);
751 if (cru_rom_addr)
752 iounmap(cru_rom_addr);
753 return retval;
741} 754}
742 755
743static void hpwdt_exit_nmi_decoding(void) 756static void hpwdt_exit_nmi_decoding(void)