diff options
author | Don Zickus <dzickus@redhat.com> | 2011-09-30 15:06:21 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2011-10-10 06:56:57 +0200 |
commit | 9c48f1c629ecfa114850c03f875c6691003214de (patch) | |
tree | 5e454da487c90fc8399ce366aa2437597c9ff5e5 /drivers | |
parent | c9126b2ee8adb9235941cedbf558d39a9e65642d (diff) | |
download | linux-9c48f1c629ecfa114850c03f875c6691003214de.tar.gz linux-9c48f1c629ecfa114850c03f875c6691003214de.tar.bz2 linux-9c48f1c629ecfa114850c03f875c6691003214de.zip |
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.c | 22 | ||||
-rw-r--r-- | drivers/char/ipmi/ipmi_watchdog.c | 33 | ||||
-rw-r--r-- | drivers/watchdog/hpwdt.c | 24 |
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 @@ #include <acpi/hed.h> #include <asm/mce.h> #include <asm/tlbflush.h> +#include <asm/nmi.h> #include "apei-internal.h" @@ -749,15 +750,11 @@ static void ghes_proc_in_irq(struct irq_work *irq_work) } } -static int ghes_notify_nmi(struct notifier_block *this, - unsigned long cmd, void *data) +static int ghes_notify_nmi(unsigned int cmd, struct pt_regs *regs) { struct ghes *ghes, *ghes_global = NULL; int sev, sev_global = -1; - int ret = NOTIFY_DONE; - - if (cmd != DIE_NMI) - return ret; + int ret = NMI_DONE; raw_spin_lock(&ghes_nmi_lock); list_for_each_entry_rcu(ghes, &ghes_nmi, list) { @@ -770,10 +767,10 @@ static int ghes_notify_nmi(struct notifier_block *this, sev_global = sev; ghes_global = ghes; } - ret = NOTIFY_STOP; + ret = NMI_HANDLED; } - if (ret == NOTIFY_DONE) + if (ret == NMI_DONE) goto out; if (sev_global >= GHES_SEV_PANIC) { @@ -825,10 +822,6 @@ static struct notifier_block ghes_notifier_sci = { .notifier_call = ghes_notify_sci, }; -static struct notifier_block ghes_notifier_nmi = { - .notifier_call = ghes_notify_nmi, -}; - static unsigned long ghes_esource_prealloc_size( const struct acpi_hest_generic *generic) { @@ -918,7 +911,8 @@ static int __devinit ghes_probe(struct platform_device *ghes_dev) ghes_estatus_pool_expand(len); mutex_lock(&ghes_list_mutex); if (list_empty(&ghes_nmi)) - register_die_notifier(&ghes_notifier_nmi); + register_nmi_handler(NMI_LOCAL, ghes_notify_nmi, 0, + "ghes"); list_add_rcu(&ghes->list, &ghes_nmi); mutex_unlock(&ghes_list_mutex); break; @@ -964,7 +958,7 @@ static int __devexit ghes_remove(struct platform_device *ghes_dev) mutex_lock(&ghes_list_mutex); list_del_rcu(&ghes->list); if (list_empty(&ghes_nmi)) - unregister_die_notifier(&ghes_notifier_nmi); + unregister_nmi_handler(NMI_LOCAL, "ghes"); mutex_unlock(&ghes_list_mutex); /* * 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 @@ * mechanism for it at that time. */ #include <asm/kdebug.h> +#include <asm/nmi.h> #define HAVE_DIE_NMI #endif @@ -1077,17 +1078,8 @@ static void ipmi_unregister_watchdog(int ipmi_intf) #ifdef HAVE_DIE_NMI static int -ipmi_nmi(struct notifier_block *self, unsigned long val, void *data) +ipmi_nmi(unsigned int val, struct pt_regs *regs) { - struct die_args *args = data; - - if (val != DIE_NMIUNKNOWN) - return NOTIFY_OK; - - /* Hack, if it's a memory or I/O error, ignore it. */ - if (args->err & 0xc0) - return NOTIFY_OK; - /* * If we get here, it's an NMI that's not a memory or I/O * 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) if (testing_nmi) { testing_nmi = 2; - return NOTIFY_STOP; + return NMI_HANDLED; } /* If we are not expecting a timeout, ignore it. */ if (ipmi_watchdog_state == WDOG_TIMEOUT_NONE) - return NOTIFY_OK; + return NMI_DONE; if (preaction_val != WDOG_PRETIMEOUT_NMI) - return NOTIFY_OK; + return NMI_DONE; /* * 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) panic(PFX "pre-timeout"); } - return NOTIFY_STOP; + return NMI_HANDLED; } - -static struct notifier_block ipmi_nmi_handler = { - .notifier_call = ipmi_nmi -}; #endif static int wdog_reboot_handler(struct notifier_block *this, @@ -1290,7 +1278,8 @@ static void check_parms(void) } } if (do_nmi && !nmi_handler_registered) { - rv = register_die_notifier(&ipmi_nmi_handler); + rv = register_nmi_handler(NMI_UNKNOWN, ipmi_nmi, 0, + "ipmi"); if (rv) { printk(KERN_WARNING PFX "Can't register nmi handler\n"); @@ -1298,7 +1287,7 @@ static void check_parms(void) } else nmi_handler_registered = 1; } else if (!do_nmi && nmi_handler_registered) { - unregister_die_notifier(&ipmi_nmi_handler); + unregister_nmi_handler(NMI_UNKNOWN, "ipmi"); nmi_handler_registered = 0; } #endif @@ -1336,7 +1325,7 @@ static int __init ipmi_wdog_init(void) if (rv) { #ifdef HAVE_DIE_NMI if (nmi_handler_registered) - unregister_die_notifier(&ipmi_nmi_handler); + unregister_nmi_handler(NMI_UNKNOWN, "ipmi"); #endif atomic_notifier_chain_unregister(&panic_notifier_list, &wdog_panic_notifier); @@ -1357,7 +1346,7 @@ static void __exit ipmi_wdog_exit(void) #ifdef HAVE_DIE_NMI if (nmi_handler_registered) - unregister_die_notifier(&ipmi_nmi_handler); + unregister_nmi_handler(NMI_UNKNOWN, "ipmi"); #endif 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) /* * NMI Handler */ -static int hpwdt_pretimeout(struct notifier_block *nb, unsigned long ulReason, - void *data) +static int hpwdt_pretimeout(unsigned int ulReason, struct pt_regs *regs) { unsigned long rom_pl; static int die_nmi_called; - if (ulReason != DIE_NMIUNKNOWN) - goto out; - if (!hpwdt_nmi_decoding) goto out; @@ -508,7 +504,7 @@ static int hpwdt_pretimeout(struct notifier_block *nb, unsigned long ulReason, "Management Log for details.\n"); out: - return NOTIFY_OK; + return NMI_DONE; } #endif /* CONFIG_HPWDT_NMI_DECODING */ @@ -648,13 +644,6 @@ static struct miscdevice hpwdt_miscdev = { .fops = &hpwdt_fops, }; -#ifdef CONFIG_HPWDT_NMI_DECODING -static struct notifier_block die_notifier = { - .notifier_call = hpwdt_pretimeout, - .priority = 0, -}; -#endif /* CONFIG_HPWDT_NMI_DECODING */ - /* * Init & Exit */ @@ -740,10 +729,9 @@ static int __devinit hpwdt_init_nmi_decoding(struct pci_dev *dev) * die notify list to handle a critical NMI. The default is to * be last so other users of the NMI signal can function. */ - if (priority) - die_notifier.priority = 0x7FFFFFFF; - - retval = register_die_notifier(&die_notifier); + retval = register_nmi_handler(NMI_UNKNOWN, hpwdt_pretimeout, + (priority) ? NMI_FLAG_FIRST : 0, + "hpwdt"); if (retval != 0) { dev_warn(&dev->dev, "Unable to register a die notifier (err=%d).\n", @@ -763,7 +751,7 @@ static int __devinit hpwdt_init_nmi_decoding(struct pci_dev *dev) static void hpwdt_exit_nmi_decoding(void) { - unregister_die_notifier(&die_notifier); + unregister_nmi_handler(NMI_UNKNOWN, "hpwdt"); if (cru_rom_addr) iounmap(cru_rom_addr); } |