aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorDon Zickus <dzickus@redhat.com>2011-09-30 15:06:21 -0400
committerIngo Molnar <mingo@elte.hu>2011-10-10 00:56:57 -0400
commit9c48f1c629ecfa114850c03f875c6691003214de (patch)
tree5e454da487c90fc8399ce366aa2437597c9ff5e5 /drivers
parentc9126b2ee8adb9235941cedbf558d39a9e65642d (diff)
x86, nmi: Wire up NMI handlers to new routines
Just convert all the files that have an nmi handler to the new routines. Most of it is straight forward conversion. A couple of places needed some tweaking like kgdb which separates the debug notifier from the nmi handler and mce removes a call to notify_die. [Thanks to Ying for finding out the history behind that mce call https://lkml.org/lkml/2010/5/27/114 And Boris responding that he would like to remove that call because of it https://lkml.org/lkml/2011/9/21/163] The things that get converted are the registeration/unregistration routines and the nmi handler itself has its args changed along with code removal to check which list it is on (most are on one NMI list except for kgdb which has both an NMI routine and an NMI Unknown routine). Signed-off-by: Don Zickus <dzickus@redhat.com> Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl> Acked-by: Corey Minyard <minyard@acm.org> Cc: Jason Wessel <jason.wessel@windriver.com> Cc: Andi Kleen <ak@linux.intel.com> Cc: Robert Richter <robert.richter@amd.com> Cc: Huang Ying <ying.huang@intel.com> Cc: Corey Minyard <minyard@acm.org> Cc: Jack Steiner <steiner@sgi.com> Link: http://lkml.kernel.org/r/1317409584-23662-4-git-send-email-dzickus@redhat.com Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/acpi/apei/ghes.c22
-rw-r--r--drivers/char/ipmi/ipmi_watchdog.c33
-rw-r--r--drivers/watchdog/hpwdt.c24
3 files changed, 25 insertions, 54 deletions
diff --git a/drivers/acpi/apei/ghes.c b/drivers/acpi/apei/ghes.c
index 0784f99a4665..b8e08cb67a18 100644
--- a/drivers/acpi/apei/ghes.c
+++ b/drivers/acpi/apei/ghes.c
@@ -50,6 +50,7 @@
50#include <acpi/hed.h> 50#include <acpi/hed.h>
51#include <asm/mce.h> 51#include <asm/mce.h>
52#include <asm/tlbflush.h> 52#include <asm/tlbflush.h>
53#include <asm/nmi.h>
53 54
54#include "apei-internal.h" 55#include "apei-internal.h"
55 56
@@ -749,15 +750,11 @@ static void ghes_proc_in_irq(struct irq_work *irq_work)
749 } 750 }
750} 751}
751 752
752static int ghes_notify_nmi(struct notifier_block *this, 753static int ghes_notify_nmi(unsigned int cmd, struct pt_regs *regs)
753 unsigned long cmd, void *data)
754{ 754{
755 struct ghes *ghes, *ghes_global = NULL; 755 struct ghes *ghes, *ghes_global = NULL;
756 int sev, sev_global = -1; 756 int sev, sev_global = -1;
757 int ret = NOTIFY_DONE; 757 int ret = NMI_DONE;
758
759 if (cmd != DIE_NMI)
760 return ret;
761 758
762 raw_spin_lock(&ghes_nmi_lock); 759 raw_spin_lock(&ghes_nmi_lock);
763 list_for_each_entry_rcu(ghes, &ghes_nmi, list) { 760 list_for_each_entry_rcu(ghes, &ghes_nmi, list) {
@@ -770,10 +767,10 @@ static int ghes_notify_nmi(struct notifier_block *this,
770 sev_global = sev; 767 sev_global = sev;
771 ghes_global = ghes; 768 ghes_global = ghes;
772 } 769 }
773 ret = NOTIFY_STOP; 770 ret = NMI_HANDLED;
774 } 771 }
775 772
776 if (ret == NOTIFY_DONE) 773 if (ret == NMI_DONE)
777 goto out; 774 goto out;
778 775
779 if (sev_global >= GHES_SEV_PANIC) { 776 if (sev_global >= GHES_SEV_PANIC) {
@@ -825,10 +822,6 @@ static struct notifier_block ghes_notifier_sci = {
825 .notifier_call = ghes_notify_sci, 822 .notifier_call = ghes_notify_sci,
826}; 823};
827 824
828static struct notifier_block ghes_notifier_nmi = {
829 .notifier_call = ghes_notify_nmi,
830};
831
832static unsigned long ghes_esource_prealloc_size( 825static unsigned long ghes_esource_prealloc_size(
833 const struct acpi_hest_generic *generic) 826 const struct acpi_hest_generic *generic)
834{ 827{
@@ -918,7 +911,8 @@ static int __devinit ghes_probe(struct platform_device *ghes_dev)
918 ghes_estatus_pool_expand(len); 911 ghes_estatus_pool_expand(len);
919 mutex_lock(&ghes_list_mutex); 912 mutex_lock(&ghes_list_mutex);
920 if (list_empty(&ghes_nmi)) 913 if (list_empty(&ghes_nmi))
921 register_die_notifier(&ghes_notifier_nmi); 914 register_nmi_handler(NMI_LOCAL, ghes_notify_nmi, 0,
915 "ghes");
922 list_add_rcu(&ghes->list, &ghes_nmi); 916 list_add_rcu(&ghes->list, &ghes_nmi);
923 mutex_unlock(&ghes_list_mutex); 917 mutex_unlock(&ghes_list_mutex);
924 break; 918 break;
@@ -964,7 +958,7 @@ static int __devexit ghes_remove(struct platform_device *ghes_dev)
964 mutex_lock(&ghes_list_mutex); 958 mutex_lock(&ghes_list_mutex);
965 list_del_rcu(&ghes->list); 959 list_del_rcu(&ghes->list);
966 if (list_empty(&ghes_nmi)) 960 if (list_empty(&ghes_nmi))
967 unregister_die_notifier(&ghes_notifier_nmi); 961 unregister_nmi_handler(NMI_LOCAL, "ghes");
968 mutex_unlock(&ghes_list_mutex); 962 mutex_unlock(&ghes_list_mutex);
969 /* 963 /*
970 * To synchronize with NMI handler, ghes can only be 964 * To synchronize with NMI handler, ghes can only be
diff --git a/drivers/char/ipmi/ipmi_watchdog.c b/drivers/char/ipmi/ipmi_watchdog.c
index 3302586655c4..c2917ffad2c2 100644
--- a/drivers/char/ipmi/ipmi_watchdog.c
+++ b/drivers/char/ipmi/ipmi_watchdog.c
@@ -65,6 +65,7 @@
65 * mechanism for it at that time. 65 * mechanism for it at that time.
66 */ 66 */
67#include <asm/kdebug.h> 67#include <asm/kdebug.h>
68#include <asm/nmi.h>
68#define HAVE_DIE_NMI 69#define HAVE_DIE_NMI
69#endif 70#endif
70 71
@@ -1077,17 +1078,8 @@ static void ipmi_unregister_watchdog(int ipmi_intf)
1077 1078
1078#ifdef HAVE_DIE_NMI 1079#ifdef HAVE_DIE_NMI
1079static int 1080static int
1080ipmi_nmi(struct notifier_block *self, unsigned long val, void *data) 1081ipmi_nmi(unsigned int val, struct pt_regs *regs)
1081{ 1082{
1082 struct die_args *args = data;
1083
1084 if (val != DIE_NMIUNKNOWN)
1085 return NOTIFY_OK;
1086
1087 /* Hack, if it's a memory or I/O error, ignore it. */
1088 if (args->err & 0xc0)
1089 return NOTIFY_OK;
1090
1091 /* 1083 /*
1092 * If we get here, it's an NMI that's not a memory or I/O 1084 * If we get here, it's an NMI that's not a memory or I/O
1093 * error. We can't truly tell if it's from IPMI or not 1085 * error. We can't truly tell if it's from IPMI or not
@@ -1097,15 +1089,15 @@ ipmi_nmi(struct notifier_block *self, unsigned long val, void *data)
1097 1089
1098 if (testing_nmi) { 1090 if (testing_nmi) {
1099 testing_nmi = 2; 1091 testing_nmi = 2;
1100 return NOTIFY_STOP; 1092 return NMI_HANDLED;
1101 } 1093 }
1102 1094
1103 /* If we are not expecting a timeout, ignore it. */ 1095 /* If we are not expecting a timeout, ignore it. */
1104 if (ipmi_watchdog_state == WDOG_TIMEOUT_NONE) 1096 if (ipmi_watchdog_state == WDOG_TIMEOUT_NONE)
1105 return NOTIFY_OK; 1097 return NMI_DONE;
1106 1098
1107 if (preaction_val != WDOG_PRETIMEOUT_NMI) 1099 if (preaction_val != WDOG_PRETIMEOUT_NMI)
1108 return NOTIFY_OK; 1100 return NMI_DONE;
1109 1101
1110 /* 1102 /*
1111 * If no one else handled the NMI, we assume it was the IPMI 1103 * If no one else handled the NMI, we assume it was the IPMI
@@ -1120,12 +1112,8 @@ ipmi_nmi(struct notifier_block *self, unsigned long val, void *data)
1120 panic(PFX "pre-timeout"); 1112 panic(PFX "pre-timeout");
1121 } 1113 }
1122 1114
1123 return NOTIFY_STOP; 1115 return NMI_HANDLED;
1124} 1116}
1125
1126static struct notifier_block ipmi_nmi_handler = {
1127 .notifier_call = ipmi_nmi
1128};
1129#endif 1117#endif
1130 1118
1131static int wdog_reboot_handler(struct notifier_block *this, 1119static int wdog_reboot_handler(struct notifier_block *this,
@@ -1290,7 +1278,8 @@ static void check_parms(void)
1290 } 1278 }
1291 } 1279 }
1292 if (do_nmi && !nmi_handler_registered) { 1280 if (do_nmi && !nmi_handler_registered) {
1293 rv = register_die_notifier(&ipmi_nmi_handler); 1281 rv = register_nmi_handler(NMI_UNKNOWN, ipmi_nmi, 0,
1282 "ipmi");
1294 if (rv) { 1283 if (rv) {
1295 printk(KERN_WARNING PFX 1284 printk(KERN_WARNING PFX
1296 "Can't register nmi handler\n"); 1285 "Can't register nmi handler\n");
@@ -1298,7 +1287,7 @@ static void check_parms(void)
1298 } else 1287 } else
1299 nmi_handler_registered = 1; 1288 nmi_handler_registered = 1;
1300 } else if (!do_nmi && nmi_handler_registered) { 1289 } else if (!do_nmi && nmi_handler_registered) {
1301 unregister_die_notifier(&ipmi_nmi_handler); 1290 unregister_nmi_handler(NMI_UNKNOWN, "ipmi");
1302 nmi_handler_registered = 0; 1291 nmi_handler_registered = 0;
1303 } 1292 }
1304#endif 1293#endif
@@ -1336,7 +1325,7 @@ static int __init ipmi_wdog_init(void)
1336 if (rv) { 1325 if (rv) {
1337#ifdef HAVE_DIE_NMI 1326#ifdef HAVE_DIE_NMI
1338 if (nmi_handler_registered) 1327 if (nmi_handler_registered)
1339 unregister_die_notifier(&ipmi_nmi_handler); 1328 unregister_nmi_handler(NMI_UNKNOWN, "ipmi");
1340#endif 1329#endif
1341 atomic_notifier_chain_unregister(&panic_notifier_list, 1330 atomic_notifier_chain_unregister(&panic_notifier_list,
1342 &wdog_panic_notifier); 1331 &wdog_panic_notifier);
@@ -1357,7 +1346,7 @@ static void __exit ipmi_wdog_exit(void)
1357 1346
1358#ifdef HAVE_DIE_NMI 1347#ifdef HAVE_DIE_NMI
1359 if (nmi_handler_registered) 1348 if (nmi_handler_registered)
1360 unregister_die_notifier(&ipmi_nmi_handler); 1349 unregister_nmi_handler(NMI_UNKNOWN, "ipmi");
1361#endif 1350#endif
1362 1351
1363 atomic_notifier_chain_unregister(&panic_notifier_list, 1352 atomic_notifier_chain_unregister(&panic_notifier_list,
diff --git a/drivers/watchdog/hpwdt.c b/drivers/watchdog/hpwdt.c
index 809cbda03d7a..7e7feac05221 100644
--- a/drivers/watchdog/hpwdt.c
+++ b/drivers/watchdog/hpwdt.c
@@ -477,15 +477,11 @@ static int hpwdt_time_left(void)
477/* 477/*
478 * NMI Handler 478 * NMI Handler
479 */ 479 */
480static int hpwdt_pretimeout(struct notifier_block *nb, unsigned long ulReason, 480static int hpwdt_pretimeout(unsigned int ulReason, struct pt_regs *regs)
481 void *data)
482{ 481{
483 unsigned long rom_pl; 482 unsigned long rom_pl;
484 static int die_nmi_called; 483 static int die_nmi_called;
485 484
486 if (ulReason != DIE_NMIUNKNOWN)
487 goto out;
488
489 if (!hpwdt_nmi_decoding) 485 if (!hpwdt_nmi_decoding)
490 goto out; 486 goto out;
491 487
@@ -508,7 +504,7 @@ static int hpwdt_pretimeout(struct notifier_block *nb, unsigned long ulReason,
508 "Management Log for details.\n"); 504 "Management Log for details.\n");
509 505
510out: 506out:
511 return NOTIFY_OK; 507 return NMI_DONE;
512} 508}
513#endif /* CONFIG_HPWDT_NMI_DECODING */ 509#endif /* CONFIG_HPWDT_NMI_DECODING */
514 510
@@ -648,13 +644,6 @@ static struct miscdevice hpwdt_miscdev = {
648 .fops = &hpwdt_fops, 644 .fops = &hpwdt_fops,
649}; 645};
650 646
651#ifdef CONFIG_HPWDT_NMI_DECODING
652static struct notifier_block die_notifier = {
653 .notifier_call = hpwdt_pretimeout,
654 .priority = 0,
655};
656#endif /* CONFIG_HPWDT_NMI_DECODING */
657
658/* 647/*
659 * Init & Exit 648 * Init & Exit
660 */ 649 */
@@ -740,10 +729,9 @@ static int __devinit hpwdt_init_nmi_decoding(struct pci_dev *dev)
740 * die notify list to handle a critical NMI. The default is to 729 * die notify list to handle a critical NMI. The default is to
741 * be last so other users of the NMI signal can function. 730 * be last so other users of the NMI signal can function.
742 */ 731 */
743 if (priority) 732 retval = register_nmi_handler(NMI_UNKNOWN, hpwdt_pretimeout,
744 die_notifier.priority = 0x7FFFFFFF; 733 (priority) ? NMI_FLAG_FIRST : 0,
745 734 "hpwdt");
746 retval = register_die_notifier(&die_notifier);
747 if (retval != 0) { 735 if (retval != 0) {
748 dev_warn(&dev->dev, 736 dev_warn(&dev->dev,
749 "Unable to register a die notifier (err=%d).\n", 737 "Unable to register a die notifier (err=%d).\n",
@@ -763,7 +751,7 @@ static int __devinit hpwdt_init_nmi_decoding(struct pci_dev *dev)
763 751
764static void hpwdt_exit_nmi_decoding(void) 752static void hpwdt_exit_nmi_decoding(void)
765{ 753{
766 unregister_die_notifier(&die_notifier); 754 unregister_nmi_handler(NMI_UNKNOWN, "hpwdt");
767 if (cru_rom_addr) 755 if (cru_rom_addr)
768 iounmap(cru_rom_addr); 756 iounmap(cru_rom_addr);
769} 757}