[PATCH] x86_64: Reduce NMI watchdog stack usage
[pandora-kernel.git] / arch / x86_64 / kernel / nmi.c
1 /*
2  *  linux/arch/x86_64/nmi.c
3  *
4  *  NMI watchdog support on APIC systems
5  *
6  *  Started by Ingo Molnar <mingo@redhat.com>
7  *
8  *  Fixes:
9  *  Mikael Pettersson   : AMD K7 support for local APIC NMI watchdog.
10  *  Mikael Pettersson   : Power Management for local APIC NMI watchdog.
11  *  Pavel Machek and
12  *  Mikael Pettersson   : PM converted to driver model. Disable/enable API.
13  */
14
15 #include <linux/config.h>
16 #include <linux/mm.h>
17 #include <linux/irq.h>
18 #include <linux/delay.h>
19 #include <linux/bootmem.h>
20 #include <linux/smp_lock.h>
21 #include <linux/interrupt.h>
22 #include <linux/mc146818rtc.h>
23 #include <linux/kernel_stat.h>
24 #include <linux/module.h>
25 #include <linux/sysdev.h>
26 #include <linux/nmi.h>
27 #include <linux/sysctl.h>
28
29 #include <asm/smp.h>
30 #include <asm/mtrr.h>
31 #include <asm/mpspec.h>
32 #include <asm/nmi.h>
33 #include <asm/msr.h>
34 #include <asm/proto.h>
35 #include <asm/kdebug.h>
36
37 /*
38  * lapic_nmi_owner tracks the ownership of the lapic NMI hardware:
39  * - it may be reserved by some other driver, or not
40  * - when not reserved by some other driver, it may be used for
41  *   the NMI watchdog, or not
42  *
43  * This is maintained separately from nmi_active because the NMI
44  * watchdog may also be driven from the I/O APIC timer.
45  */
46 static DEFINE_SPINLOCK(lapic_nmi_owner_lock);
47 static unsigned int lapic_nmi_owner;
48 #define LAPIC_NMI_WATCHDOG      (1<<0)
49 #define LAPIC_NMI_RESERVED      (1<<1)
50
51 /* nmi_active:
52  * +1: the lapic NMI watchdog is active, but can be disabled
53  *  0: the lapic NMI watchdog has not been set up, and cannot
54  *     be enabled
55  * -1: the lapic NMI watchdog is disabled, but can be enabled
56  */
57 int nmi_active;         /* oprofile uses this */
58 int panic_on_timeout;
59
60 unsigned int nmi_watchdog = NMI_DEFAULT;
61 static unsigned int nmi_hz = HZ;
62 unsigned int nmi_perfctr_msr;   /* the MSR to reset in NMI handler */
63
64 /* Note that these events don't tick when the CPU idles. This means
65    the frequency varies with CPU load. */
66
67 #define K7_EVNTSEL_ENABLE       (1 << 22)
68 #define K7_EVNTSEL_INT          (1 << 20)
69 #define K7_EVNTSEL_OS           (1 << 17)
70 #define K7_EVNTSEL_USR          (1 << 16)
71 #define K7_EVENT_CYCLES_PROCESSOR_IS_RUNNING    0x76
72 #define K7_NMI_EVENT            K7_EVENT_CYCLES_PROCESSOR_IS_RUNNING
73
74 #define P6_EVNTSEL0_ENABLE      (1 << 22)
75 #define P6_EVNTSEL_INT          (1 << 20)
76 #define P6_EVNTSEL_OS           (1 << 17)
77 #define P6_EVNTSEL_USR          (1 << 16)
78 #define P6_EVENT_CPU_CLOCKS_NOT_HALTED  0x79
79 #define P6_NMI_EVENT            P6_EVENT_CPU_CLOCKS_NOT_HALTED
80
81 /* Run after command line and cpu_init init, but before all other checks */
82 void __init nmi_watchdog_default(void)
83 {
84         if (nmi_watchdog != NMI_DEFAULT)
85                 return;
86
87         /* For some reason the IO APIC watchdog doesn't work on the AMD
88            8111 chipset. For now switch to local APIC mode using
89            perfctr0 there.  On Intel CPUs we don't have code to handle
90            the perfctr and the IO-APIC seems to work, so use that.  */
91
92         if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD) {
93                 nmi_watchdog = NMI_LOCAL_APIC; 
94                 printk(KERN_INFO 
95               "Using local APIC NMI watchdog using perfctr0\n");
96         } else {
97                 printk(KERN_INFO "Using IO APIC NMI watchdog\n");
98                 nmi_watchdog = NMI_IO_APIC;
99         }
100 }
101
102 /* Why is there no CPUID flag for this? */
103 static __init int cpu_has_lapic(void)
104 {
105         switch (boot_cpu_data.x86_vendor) { 
106         case X86_VENDOR_INTEL:
107         case X86_VENDOR_AMD: 
108                 return boot_cpu_data.x86 >= 6; 
109         /* .... add more cpus here or find a different way to figure this out. */       
110         default:
111                 return 0;
112         }       
113 }
114
115 static int __init check_nmi_watchdog (void)
116 {
117         int *counts;
118         int cpu;
119
120         if (nmi_watchdog == NMI_NONE)
121                 return 0;
122
123         if (nmi_watchdog == NMI_LOCAL_APIC && !cpu_has_lapic())  {
124                 nmi_watchdog = NMI_NONE;
125                 return -1; 
126         }       
127
128         counts = kmalloc(NR_CPUS * sizeof(int),GFP_KERNEL);
129         if (!counts) {
130                 nmi_watchdog = NMI_NONE;
131                 return 0;
132         }
133
134         printk(KERN_INFO "Testing NMI watchdog ... ");
135
136         for (cpu = 0; cpu < NR_CPUS; cpu++)
137                 counts[cpu] = cpu_pda[cpu].__nmi_count; 
138         local_irq_enable();
139         mdelay((10*1000)/nmi_hz); // wait 10 ticks
140
141         for (cpu = 0; cpu < NR_CPUS; cpu++) {
142                 if (cpu_pda[cpu].__nmi_count - counts[cpu] <= 5) {
143                         printk("CPU#%d: NMI appears to be stuck (%d)!\n", 
144                                cpu,
145                                cpu_pda[cpu].__nmi_count);
146                         nmi_active = 0;
147                         lapic_nmi_owner &= ~LAPIC_NMI_WATCHDOG;
148                         kfree(counts);
149                         return -1;
150                 }
151         }
152         printk("OK.\n");
153
154         /* now that we know it works we can reduce NMI frequency to
155            something more reasonable; makes a difference in some configs */
156         if (nmi_watchdog == NMI_LOCAL_APIC)
157                 nmi_hz = 1;
158
159         kfree(counts);
160         return 0;
161 }
162 /* Have this called later during boot so counters are updating */
163 late_initcall(check_nmi_watchdog);
164
165 int __init setup_nmi_watchdog(char *str)
166 {
167         int nmi;
168
169         if (!strncmp(str,"panic",5)) {
170                 panic_on_timeout = 1;
171                 str = strchr(str, ',');
172                 if (!str)
173                         return 1;
174                 ++str;
175         }
176
177         get_option(&str, &nmi);
178
179         if (nmi >= NMI_INVALID)
180                 return 0;
181                 nmi_watchdog = nmi;
182         return 1;
183 }
184
185 __setup("nmi_watchdog=", setup_nmi_watchdog);
186
187 static void disable_lapic_nmi_watchdog(void)
188 {
189         if (nmi_active <= 0)
190                 return;
191         switch (boot_cpu_data.x86_vendor) {
192         case X86_VENDOR_AMD:
193                 wrmsr(MSR_K7_EVNTSEL0, 0, 0);
194                 break;
195         case X86_VENDOR_INTEL:
196                 wrmsr(MSR_IA32_EVNTSEL0, 0, 0);
197                 break;
198         }
199         nmi_active = -1;
200         /* tell do_nmi() and others that we're not active any more */
201         nmi_watchdog = 0;
202 }
203
204 static void enable_lapic_nmi_watchdog(void)
205 {
206         if (nmi_active < 0) {
207                 nmi_watchdog = NMI_LOCAL_APIC;
208                 setup_apic_nmi_watchdog();
209         }
210 }
211
212 int reserve_lapic_nmi(void)
213 {
214         unsigned int old_owner;
215
216         spin_lock(&lapic_nmi_owner_lock);
217         old_owner = lapic_nmi_owner;
218         lapic_nmi_owner |= LAPIC_NMI_RESERVED;
219         spin_unlock(&lapic_nmi_owner_lock);
220         if (old_owner & LAPIC_NMI_RESERVED)
221                 return -EBUSY;
222         if (old_owner & LAPIC_NMI_WATCHDOG)
223                 disable_lapic_nmi_watchdog();
224         return 0;
225 }
226
227 void release_lapic_nmi(void)
228 {
229         unsigned int new_owner;
230
231         spin_lock(&lapic_nmi_owner_lock);
232         new_owner = lapic_nmi_owner & ~LAPIC_NMI_RESERVED;
233         lapic_nmi_owner = new_owner;
234         spin_unlock(&lapic_nmi_owner_lock);
235         if (new_owner & LAPIC_NMI_WATCHDOG)
236                 enable_lapic_nmi_watchdog();
237 }
238
239 void disable_timer_nmi_watchdog(void)
240 {
241         if ((nmi_watchdog != NMI_IO_APIC) || (nmi_active <= 0))
242                 return;
243
244         disable_irq(0);
245         unset_nmi_callback();
246         nmi_active = -1;
247         nmi_watchdog = NMI_NONE;
248 }
249
250 void enable_timer_nmi_watchdog(void)
251 {
252         if (nmi_active < 0) {
253                 nmi_watchdog = NMI_IO_APIC;
254                 touch_nmi_watchdog();
255                 nmi_active = 1;
256                 enable_irq(0);
257         }
258 }
259
260 #ifdef CONFIG_PM
261
262 static int nmi_pm_active; /* nmi_active before suspend */
263
264 static int lapic_nmi_suspend(struct sys_device *dev, pm_message_t state)
265 {
266         nmi_pm_active = nmi_active;
267         disable_lapic_nmi_watchdog();
268         return 0;
269 }
270
271 static int lapic_nmi_resume(struct sys_device *dev)
272 {
273         if (nmi_pm_active > 0)
274         enable_lapic_nmi_watchdog();
275         return 0;
276 }
277
278 static struct sysdev_class nmi_sysclass = {
279         set_kset_name("lapic_nmi"),
280         .resume         = lapic_nmi_resume,
281         .suspend        = lapic_nmi_suspend,
282 };
283
284 static struct sys_device device_lapic_nmi = {
285         .id             = 0,
286         .cls    = &nmi_sysclass,
287 };
288
289 static int __init init_lapic_nmi_sysfs(void)
290 {
291         int error;
292
293         if (nmi_active == 0 || nmi_watchdog != NMI_LOCAL_APIC)
294                 return 0;
295
296         error = sysdev_class_register(&nmi_sysclass);
297         if (!error)
298                 error = sysdev_register(&device_lapic_nmi);
299         return error;
300 }
301 /* must come after the local APIC's device_initcall() */
302 late_initcall(init_lapic_nmi_sysfs);
303
304 #endif  /* CONFIG_PM */
305
306 /*
307  * Activate the NMI watchdog via the local APIC.
308  * Original code written by Keith Owens.
309  */
310
311 static void setup_k7_watchdog(void)
312 {
313         int i;
314         unsigned int evntsel;
315
316         /* No check, so can start with slow frequency */
317         nmi_hz = 1; 
318
319         /* XXX should check these in EFER */
320
321         nmi_perfctr_msr = MSR_K7_PERFCTR0;
322
323         for(i = 0; i < 4; ++i) {
324                 /* Simulator may not support it */
325                 if (checking_wrmsrl(MSR_K7_EVNTSEL0+i, 0UL))
326                         return;
327                 wrmsrl(MSR_K7_PERFCTR0+i, 0UL);
328         }
329
330         evntsel = K7_EVNTSEL_INT
331                 | K7_EVNTSEL_OS
332                 | K7_EVNTSEL_USR
333                 | K7_NMI_EVENT;
334
335         wrmsr(MSR_K7_EVNTSEL0, evntsel, 0);
336         wrmsrl(MSR_K7_PERFCTR0, -((u64)cpu_khz*1000) / nmi_hz);
337         apic_write(APIC_LVTPC, APIC_DM_NMI);
338         evntsel |= K7_EVNTSEL_ENABLE;
339         wrmsr(MSR_K7_EVNTSEL0, evntsel, 0);
340 }
341
342 void setup_apic_nmi_watchdog(void)
343 {
344         switch (boot_cpu_data.x86_vendor) {
345         case X86_VENDOR_AMD:
346                 if (boot_cpu_data.x86 != 15)
347                         return;
348                 if (strstr(boot_cpu_data.x86_model_id, "Screwdriver"))
349                         return;
350                 setup_k7_watchdog();
351                 break;
352         default:
353                 return;
354         }
355         lapic_nmi_owner = LAPIC_NMI_WATCHDOG;
356         nmi_active = 1;
357 }
358
359 /*
360  * the best way to detect whether a CPU has a 'hard lockup' problem
361  * is to check it's local APIC timer IRQ counts. If they are not
362  * changing then that CPU has some problem.
363  *
364  * as these watchdog NMI IRQs are generated on every CPU, we only
365  * have to check the current processor.
366  *
367  * since NMIs don't listen to _any_ locks, we have to be extremely
368  * careful not to rely on unsafe variables. The printk might lock
369  * up though, so we have to break up any console locks first ...
370  * [when there will be more tty-related locks, break them up
371  *  here too!]
372  */
373
374 static unsigned int
375         last_irq_sums [NR_CPUS],
376         alert_counter [NR_CPUS];
377
378 void touch_nmi_watchdog (void)
379 {
380         int i;
381
382         /*
383          * Just reset the alert counters, (other CPUs might be
384          * spinning on locks we hold):
385          */
386         for (i = 0; i < NR_CPUS; i++)
387                 alert_counter[i] = 0;
388 }
389
390 void nmi_watchdog_tick (struct pt_regs * regs, unsigned reason)
391 {
392         int sum, cpu;
393
394         cpu = safe_smp_processor_id();
395         sum = read_pda(apic_timer_irqs);
396         if (last_irq_sums[cpu] == sum) {
397                 /*
398                  * Ayiee, looks like this CPU is stuck ...
399                  * wait a few IRQs (5 seconds) before doing the oops ...
400                  */
401                 alert_counter[cpu]++;
402                 if (alert_counter[cpu] == 5*nmi_hz) {
403                         if (notify_die(DIE_NMI, "nmi", regs, reason, 2, SIGINT)
404                                                         == NOTIFY_STOP) {
405                                 alert_counter[cpu] = 0; 
406                                 return;
407                         } 
408                         die_nmi("NMI Watchdog detected LOCKUP on CPU%d", regs);
409                 }
410         } else {
411                 last_irq_sums[cpu] = sum;
412                 alert_counter[cpu] = 0;
413         }
414         if (nmi_perfctr_msr)
415                 wrmsr(nmi_perfctr_msr, -(cpu_khz/nmi_hz*1000), -1);
416 }
417
418 static int dummy_nmi_callback(struct pt_regs * regs, int cpu)
419 {
420         return 0;
421 }
422  
423 static nmi_callback_t nmi_callback = dummy_nmi_callback;
424  
425 asmlinkage void do_nmi(struct pt_regs * regs, long error_code)
426 {
427         int cpu = safe_smp_processor_id();
428
429         nmi_enter();
430         add_pda(__nmi_count,1);
431         if (!nmi_callback(regs, cpu))
432                 default_do_nmi(regs);
433         nmi_exit();
434 }
435
436 void set_nmi_callback(nmi_callback_t callback)
437 {
438         nmi_callback = callback;
439 }
440
441 void unset_nmi_callback(void)
442 {
443         nmi_callback = dummy_nmi_callback;
444 }
445
446 #ifdef CONFIG_SYSCTL
447
448 static int unknown_nmi_panic_callback(struct pt_regs *regs, int cpu)
449 {
450         unsigned char reason = get_nmi_reason();
451         char buf[64];
452
453         if (!(reason & 0xc0)) {
454                 sprintf(buf, "NMI received for unknown reason %02x\n", reason);
455                 die_nmi(buf,regs);
456         }
457         return 0;
458 }
459
460 /*
461  * proc handler for /proc/sys/kernel/unknown_nmi_panic
462  */
463 int proc_unknown_nmi_panic(struct ctl_table *table, int write, struct file *file,
464                         void __user *buffer, size_t *length, loff_t *ppos)
465 {
466         int old_state;
467
468         old_state = unknown_nmi_panic;
469         proc_dointvec(table, write, file, buffer, length, ppos);
470         if (!!old_state == !!unknown_nmi_panic)
471                 return 0;
472
473         if (unknown_nmi_panic) {
474                 if (reserve_lapic_nmi() < 0) {
475                         unknown_nmi_panic = 0;
476                         return -EBUSY;
477                 } else {
478                         set_nmi_callback(unknown_nmi_panic_callback);
479                 }
480         } else {
481                 release_lapic_nmi();
482                 unset_nmi_callback();
483         }
484         return 0;
485 }
486
487 #endif
488
489 EXPORT_SYMBOL(nmi_active);
490 EXPORT_SYMBOL(nmi_watchdog);
491 EXPORT_SYMBOL(reserve_lapic_nmi);
492 EXPORT_SYMBOL(release_lapic_nmi);
493 EXPORT_SYMBOL(disable_timer_nmi_watchdog);
494 EXPORT_SYMBOL(enable_timer_nmi_watchdog);
495 EXPORT_SYMBOL(touch_nmi_watchdog);