aboutsummaryrefslogtreecommitdiffstats
path: root/arch/i386/kernel
diff options
context:
space:
mode:
authorDon Zickus <dzickus@redhat.com>2006-09-26 04:52:27 -0400
committerAndi Kleen <andi@basil.nowhere.org>2006-09-26 04:52:27 -0400
commit2fbe7b25c8edaf2d10e6c1a4cc9f8afe714c4764 (patch)
treee4012ae3cd4519cba1836668237f077c60fb1086 /arch/i386/kernel
parent957dc87c1bd849440f0eef27e2ade67387001e13 (diff)
[PATCH] i386/x86-64: Remove un/set_nmi_callback and reserve/release_lapic_nmi functions
Removes the un/set_nmi_callback and reserve/release_lapic_nmi functions as they are no longer needed. The various subsystems are modified to register with the die_notifier instead. Also includes compile fixes by Andrew Morton. Signed-off-by: Don Zickus <dzickus@redhat.com> Signed-off-by: Andi Kleen <ak@suse.de>
Diffstat (limited to 'arch/i386/kernel')
-rw-r--r--arch/i386/kernel/crash.c20
-rw-r--r--arch/i386/kernel/nmi.c85
-rw-r--r--arch/i386/kernel/traps.c23
3 files changed, 31 insertions, 97 deletions
diff --git a/arch/i386/kernel/crash.c b/arch/i386/kernel/crash.c
index 5b96f038367..736c76d6b31 100644
--- a/arch/i386/kernel/crash.c
+++ b/arch/i386/kernel/crash.c
@@ -22,6 +22,8 @@
22#include <asm/nmi.h> 22#include <asm/nmi.h>
23#include <asm/hw_irq.h> 23#include <asm/hw_irq.h>
24#include <asm/apic.h> 24#include <asm/apic.h>
25#include <asm/kdebug.h>
26
25#include <mach_ipi.h> 27#include <mach_ipi.h>
26 28
27 29
@@ -93,9 +95,18 @@ static void crash_save_self(struct pt_regs *regs)
93#if defined(CONFIG_SMP) && defined(CONFIG_X86_LOCAL_APIC) 95#if defined(CONFIG_SMP) && defined(CONFIG_X86_LOCAL_APIC)
94static atomic_t waiting_for_crash_ipi; 96static atomic_t waiting_for_crash_ipi;
95 97
96static int crash_nmi_callback(struct pt_regs *regs, int cpu) 98static int crash_nmi_callback(struct notifier_block *self,
99 unsigned long val, void *data)
97{ 100{
101 struct pt_regs *regs;
98 struct pt_regs fixed_regs; 102 struct pt_regs fixed_regs;
103 int cpu;
104
105 if (val != DIE_NMI)
106 return NOTIFY_OK;
107
108 regs = ((struct die_args *)data)->regs;
109 cpu = raw_smp_processor_id();
99 110
100 /* Don't do anything if this handler is invoked on crashing cpu. 111 /* Don't do anything if this handler is invoked on crashing cpu.
101 * Otherwise, system will completely hang. Crashing cpu can get 112 * Otherwise, system will completely hang. Crashing cpu can get
@@ -125,13 +136,18 @@ static void smp_send_nmi_allbutself(void)
125 send_IPI_allbutself(NMI_VECTOR); 136 send_IPI_allbutself(NMI_VECTOR);
126} 137}
127 138
139static struct notifier_block crash_nmi_nb = {
140 .notifier_call = crash_nmi_callback,
141};
142
128static void nmi_shootdown_cpus(void) 143static void nmi_shootdown_cpus(void)
129{ 144{
130 unsigned long msecs; 145 unsigned long msecs;
131 146
132 atomic_set(&waiting_for_crash_ipi, num_online_cpus() - 1); 147 atomic_set(&waiting_for_crash_ipi, num_online_cpus() - 1);
133 /* Would it be better to replace the trap vector here? */ 148 /* Would it be better to replace the trap vector here? */
134 set_nmi_callback(crash_nmi_callback); 149 if (register_die_notifier(&crash_nmi_nb))
150 return; /* return what? */
135 /* Ensure the new callback function is set before sending 151 /* Ensure the new callback function is set before sending
136 * out the NMI 152 * out the NMI
137 */ 153 */
diff --git a/arch/i386/kernel/nmi.c b/arch/i386/kernel/nmi.c
index bd96ea4f294..acd3fdea2a2 100644
--- a/arch/i386/kernel/nmi.c
+++ b/arch/i386/kernel/nmi.c
@@ -42,20 +42,6 @@ static DEFINE_PER_CPU(unsigned long, evntsel_nmi_owner[3]);
42 */ 42 */
43#define NMI_MAX_COUNTER_BITS 66 43#define NMI_MAX_COUNTER_BITS 66
44 44
45/*
46 * lapic_nmi_owner tracks the ownership of the lapic NMI hardware:
47 * - it may be reserved by some other driver, or not
48 * - when not reserved by some other driver, it may be used for
49 * the NMI watchdog, or not
50 *
51 * This is maintained separately from nmi_active because the NMI
52 * watchdog may also be driven from the I/O APIC timer.
53 */
54static DEFINE_SPINLOCK(lapic_nmi_owner_lock);
55static unsigned int lapic_nmi_owner;
56#define LAPIC_NMI_WATCHDOG (1<<0)
57#define LAPIC_NMI_RESERVED (1<<1)
58
59/* nmi_active: 45/* nmi_active:
60 * >0: the lapic NMI watchdog is active, but can be disabled 46 * >0: the lapic NMI watchdog is active, but can be disabled
61 * <0: the lapic NMI watchdog has not been set up, and cannot 47 * <0: the lapic NMI watchdog has not been set up, and cannot
@@ -325,33 +311,6 @@ static void enable_lapic_nmi_watchdog(void)
325 touch_nmi_watchdog(); 311 touch_nmi_watchdog();
326} 312}
327 313
328int reserve_lapic_nmi(void)
329{
330 unsigned int old_owner;
331
332 spin_lock(&lapic_nmi_owner_lock);
333 old_owner = lapic_nmi_owner;
334 lapic_nmi_owner |= LAPIC_NMI_RESERVED;
335 spin_unlock(&lapic_nmi_owner_lock);
336 if (old_owner & LAPIC_NMI_RESERVED)
337 return -EBUSY;
338 if (old_owner & LAPIC_NMI_WATCHDOG)
339 disable_lapic_nmi_watchdog();
340 return 0;
341}
342
343void release_lapic_nmi(void)
344{
345 unsigned int new_owner;
346
347 spin_lock(&lapic_nmi_owner_lock);
348 new_owner = lapic_nmi_owner & ~LAPIC_NMI_RESERVED;
349 lapic_nmi_owner = new_owner;
350 spin_unlock(&lapic_nmi_owner_lock);
351 if (new_owner & LAPIC_NMI_WATCHDOG)
352 enable_lapic_nmi_watchdog();
353}
354
355void disable_timer_nmi_watchdog(void) 314void disable_timer_nmi_watchdog(void)
356{ 315{
357 BUG_ON(nmi_watchdog != NMI_IO_APIC); 316 BUG_ON(nmi_watchdog != NMI_IO_APIC);
@@ -866,6 +825,15 @@ done:
866 return rc; 825 return rc;
867} 826}
868 827
828int do_nmi_callback(struct pt_regs * regs, int cpu)
829{
830#ifdef CONFIG_SYSCTL
831 if (unknown_nmi_panic)
832 return unknown_nmi_panic_callback(regs, cpu);
833#endif
834 return 0;
835}
836
869#ifdef CONFIG_SYSCTL 837#ifdef CONFIG_SYSCTL
870 838
871static int unknown_nmi_panic_callback(struct pt_regs *regs, int cpu) 839static int unknown_nmi_panic_callback(struct pt_regs *regs, int cpu)
@@ -873,37 +841,8 @@ static int unknown_nmi_panic_callback(struct pt_regs *regs, int cpu)
873 unsigned char reason = get_nmi_reason(); 841 unsigned char reason = get_nmi_reason();
874 char buf[64]; 842 char buf[64];
875 843
876 if (!(reason & 0xc0)) { 844 sprintf(buf, "NMI received for unknown reason %02x\n", reason);
877 sprintf(buf, "NMI received for unknown reason %02x\n", reason); 845 die_nmi(regs, buf);
878 die_nmi(regs, buf);
879 }
880 return 0;
881}
882
883/*
884 * proc handler for /proc/sys/kernel/unknown_nmi_panic
885 */
886int proc_unknown_nmi_panic(ctl_table *table, int write, struct file *file,
887 void __user *buffer, size_t *length, loff_t *ppos)
888{
889 int old_state;
890
891 old_state = unknown_nmi_panic;
892 proc_dointvec(table, write, file, buffer, length, ppos);
893 if (!!old_state == !!unknown_nmi_panic)
894 return 0;
895
896 if (unknown_nmi_panic) {
897 if (reserve_lapic_nmi() < 0) {
898 unknown_nmi_panic = 0;
899 return -EBUSY;
900 } else {
901 set_nmi_callback(unknown_nmi_panic_callback);
902 }
903 } else {
904 release_lapic_nmi();
905 unset_nmi_callback();
906 }
907 return 0; 846 return 0;
908} 847}
909 848
@@ -917,7 +856,5 @@ EXPORT_SYMBOL(reserve_perfctr_nmi);
917EXPORT_SYMBOL(release_perfctr_nmi); 856EXPORT_SYMBOL(release_perfctr_nmi);
918EXPORT_SYMBOL(reserve_evntsel_nmi); 857EXPORT_SYMBOL(reserve_evntsel_nmi);
919EXPORT_SYMBOL(release_evntsel_nmi); 858EXPORT_SYMBOL(release_evntsel_nmi);
920EXPORT_SYMBOL(reserve_lapic_nmi);
921EXPORT_SYMBOL(release_lapic_nmi);
922EXPORT_SYMBOL(disable_timer_nmi_watchdog); 859EXPORT_SYMBOL(disable_timer_nmi_watchdog);
923EXPORT_SYMBOL(enable_timer_nmi_watchdog); 860EXPORT_SYMBOL(enable_timer_nmi_watchdog);
diff --git a/arch/i386/kernel/traps.c b/arch/i386/kernel/traps.c
index 282f0bd40df..7db664d0b25 100644
--- a/arch/i386/kernel/traps.c
+++ b/arch/i386/kernel/traps.c
@@ -706,13 +706,6 @@ void die_nmi (struct pt_regs *regs, const char *msg)
706 do_exit(SIGSEGV); 706 do_exit(SIGSEGV);
707} 707}
708 708
709static int dummy_nmi_callback(struct pt_regs * regs, int cpu)
710{
711 return 0;
712}
713
714static nmi_callback_t nmi_callback = dummy_nmi_callback;
715
716static void default_do_nmi(struct pt_regs * regs) 709static void default_do_nmi(struct pt_regs * regs)
717{ 710{
718 unsigned char reason = 0; 711 unsigned char reason = 0;
@@ -732,9 +725,10 @@ static void default_do_nmi(struct pt_regs * regs)
732 */ 725 */
733 if (nmi_watchdog_tick(regs, reason)) 726 if (nmi_watchdog_tick(regs, reason))
734 return; 727 return;
728 if (!do_nmi_callback(regs, smp_processor_id()))
735#endif 729#endif
736 if (!rcu_dereference(nmi_callback)(regs, smp_processor_id()))
737 unknown_nmi_error(reason, regs); 730 unknown_nmi_error(reason, regs);
731
738 return; 732 return;
739 } 733 }
740 if (notify_die(DIE_NMI, "nmi", regs, reason, 2, SIGINT) == NOTIFY_STOP) 734 if (notify_die(DIE_NMI, "nmi", regs, reason, 2, SIGINT) == NOTIFY_STOP)
@@ -765,19 +759,6 @@ fastcall void do_nmi(struct pt_regs * regs, long error_code)
765 nmi_exit(); 759 nmi_exit();
766} 760}
767 761
768void set_nmi_callback(nmi_callback_t callback)
769{
770 vmalloc_sync_all();
771 rcu_assign_pointer(nmi_callback, callback);
772}
773EXPORT_SYMBOL_GPL(set_nmi_callback);
774
775void unset_nmi_callback(void)
776{
777 nmi_callback = dummy_nmi_callback;
778}
779EXPORT_SYMBOL_GPL(unset_nmi_callback);
780
781#ifdef CONFIG_KPROBES 762#ifdef CONFIG_KPROBES
782fastcall void __kprobes do_int3(struct pt_regs *regs, long error_code) 763fastcall void __kprobes do_int3(struct pt_regs *regs, long error_code)
783{ 764{