blob: 0fc4997fb14330d94d429d769867902102c37fe4 [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/*
2 * linux/arch/i386/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 * Mikael Pettersson : Pentium 4 support for local APIC NMI watchdog.
12 * Pavel Machek and
13 * Mikael Pettersson : PM converted to driver model. Disable/enable API.
14 */
15
16#include <linux/config.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070017#include <linux/delay.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070018#include <linux/interrupt.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070019#include <linux/module.h>
20#include <linux/nmi.h>
21#include <linux/sysdev.h>
22#include <linux/sysctl.h>
Don Zickus3e4ff112006-06-26 13:57:01 +020023#include <linux/percpu.h>
Andi Kleen1de84972006-09-26 10:52:27 +020024#include <linux/dmi.h>
Fernando Luis Vázquez Cao06039752006-09-26 10:52:36 +020025#include <linux/kprobes.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070026
27#include <asm/smp.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070028#include <asm/nmi.h>
Don Zickusb7471c62006-09-26 10:52:26 +020029#include <asm/kdebug.h>
Venkatesh Pallipadi248dcb22006-09-26 10:52:27 +020030#include <asm/intel_arch_perfmon.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070031
32#include "mach_traps.h"
33
Andi Kleen29cbc782006-09-30 01:47:55 +020034int unknown_nmi_panic;
35int nmi_watchdog_enabled;
36
Don Zickus828f0af2006-09-26 10:52:26 +020037/* perfctr_nmi_owner tracks the ownership of the perfctr registers:
38 * evtsel_nmi_owner tracks the ownership of the event selection
39 * - different performance counters/ event selection may be reserved for
40 * different subsystems this reservation system just tries to coordinate
41 * things a little
42 */
43static DEFINE_PER_CPU(unsigned long, perfctr_nmi_owner);
44static DEFINE_PER_CPU(unsigned long, evntsel_nmi_owner[3]);
45
46/* this number is calculated from Intel's MSR_P4_CRU_ESCR5 register and it's
47 * offset from MSR_P4_BSU_ESCR0. It will be the max for all platforms (for now)
48 */
49#define NMI_MAX_COUNTER_BITS 66
50
Linus Torvalds1da177e2005-04-16 15:20:36 -070051/* nmi_active:
Don Zickusb7471c62006-09-26 10:52:26 +020052 * >0: the lapic NMI watchdog is active, but can be disabled
53 * <0: the lapic NMI watchdog has not been set up, and cannot
Linus Torvalds1da177e2005-04-16 15:20:36 -070054 * be enabled
Don Zickusb7471c62006-09-26 10:52:26 +020055 * 0: the lapic NMI watchdog is disabled, but can be enabled
Linus Torvalds1da177e2005-04-16 15:20:36 -070056 */
Don Zickusb7471c62006-09-26 10:52:26 +020057atomic_t nmi_active = ATOMIC_INIT(0); /* oprofile uses this */
Linus Torvalds1da177e2005-04-16 15:20:36 -070058
Don Zickusb7471c62006-09-26 10:52:26 +020059unsigned int nmi_watchdog = NMI_DEFAULT;
60static unsigned int nmi_hz = HZ;
Linus Torvalds1da177e2005-04-16 15:20:36 -070061
Don Zickusb7471c62006-09-26 10:52:26 +020062struct nmi_watchdog_ctlblk {
63 int enabled;
64 u64 check_bit;
65 unsigned int cccr_msr;
66 unsigned int perfctr_msr; /* the MSR to reset in NMI handler */
67 unsigned int evntsel_msr; /* the MSR to select the events to handle */
68};
69static DEFINE_PER_CPU(struct nmi_watchdog_ctlblk, nmi_watchdog_ctlblk);
Linus Torvalds1da177e2005-04-16 15:20:36 -070070
Don Zickusb7471c62006-09-26 10:52:26 +020071/* local prototypes */
Don Zickusb7471c62006-09-26 10:52:26 +020072static int unknown_nmi_panic_callback(struct pt_regs *regs, int cpu);
73
74extern void show_registers(struct pt_regs *regs);
75extern int unknown_nmi_panic;
Linus Torvalds1da177e2005-04-16 15:20:36 -070076
Don Zickus828f0af2006-09-26 10:52:26 +020077/* converts an msr to an appropriate reservation bit */
78static inline unsigned int nmi_perfctr_msr_to_bit(unsigned int msr)
79{
80 /* returns the bit offset of the performance counter register */
81 switch (boot_cpu_data.x86_vendor) {
82 case X86_VENDOR_AMD:
83 return (msr - MSR_K7_PERFCTR0);
84 case X86_VENDOR_INTEL:
Venkatesh Pallipadi248dcb22006-09-26 10:52:27 +020085 if (cpu_has(&boot_cpu_data, X86_FEATURE_ARCH_PERFMON))
86 return (msr - MSR_ARCH_PERFMON_PERFCTR0);
87
Don Zickus828f0af2006-09-26 10:52:26 +020088 switch (boot_cpu_data.x86) {
89 case 6:
90 return (msr - MSR_P6_PERFCTR0);
91 case 15:
92 return (msr - MSR_P4_BPU_PERFCTR0);
93 }
94 }
95 return 0;
96}
97
98/* converts an msr to an appropriate reservation bit */
99static inline unsigned int nmi_evntsel_msr_to_bit(unsigned int msr)
100{
101 /* returns the bit offset of the event selection register */
102 switch (boot_cpu_data.x86_vendor) {
103 case X86_VENDOR_AMD:
104 return (msr - MSR_K7_EVNTSEL0);
105 case X86_VENDOR_INTEL:
Venkatesh Pallipadi248dcb22006-09-26 10:52:27 +0200106 if (cpu_has(&boot_cpu_data, X86_FEATURE_ARCH_PERFMON))
107 return (msr - MSR_ARCH_PERFMON_EVENTSEL0);
108
Don Zickus828f0af2006-09-26 10:52:26 +0200109 switch (boot_cpu_data.x86) {
110 case 6:
111 return (msr - MSR_P6_EVNTSEL0);
112 case 15:
113 return (msr - MSR_P4_BSU_ESCR0);
114 }
115 }
116 return 0;
117}
118
119/* checks for a bit availability (hack for oprofile) */
120int avail_to_resrv_perfctr_nmi_bit(unsigned int counter)
121{
122 BUG_ON(counter > NMI_MAX_COUNTER_BITS);
123
124 return (!test_bit(counter, &__get_cpu_var(perfctr_nmi_owner)));
125}
126
127/* checks the an msr for availability */
128int avail_to_resrv_perfctr_nmi(unsigned int msr)
129{
130 unsigned int counter;
131
132 counter = nmi_perfctr_msr_to_bit(msr);
133 BUG_ON(counter > NMI_MAX_COUNTER_BITS);
134
135 return (!test_bit(counter, &__get_cpu_var(perfctr_nmi_owner)));
136}
137
138int reserve_perfctr_nmi(unsigned int msr)
139{
140 unsigned int counter;
141
142 counter = nmi_perfctr_msr_to_bit(msr);
143 BUG_ON(counter > NMI_MAX_COUNTER_BITS);
144
145 if (!test_and_set_bit(counter, &__get_cpu_var(perfctr_nmi_owner)))
146 return 1;
147 return 0;
148}
149
150void release_perfctr_nmi(unsigned int msr)
151{
152 unsigned int counter;
153
154 counter = nmi_perfctr_msr_to_bit(msr);
155 BUG_ON(counter > NMI_MAX_COUNTER_BITS);
156
157 clear_bit(counter, &__get_cpu_var(perfctr_nmi_owner));
158}
159
160int reserve_evntsel_nmi(unsigned int msr)
161{
162 unsigned int counter;
163
164 counter = nmi_evntsel_msr_to_bit(msr);
165 BUG_ON(counter > NMI_MAX_COUNTER_BITS);
166
167 if (!test_and_set_bit(counter, &__get_cpu_var(evntsel_nmi_owner)[0]))
168 return 1;
169 return 0;
170}
171
172void release_evntsel_nmi(unsigned int msr)
173{
174 unsigned int counter;
175
176 counter = nmi_evntsel_msr_to_bit(msr);
177 BUG_ON(counter > NMI_MAX_COUNTER_BITS);
178
179 clear_bit(counter, &__get_cpu_var(evntsel_nmi_owner)[0]);
180}
181
Don Zickusb7471c62006-09-26 10:52:26 +0200182static __cpuinit inline int nmi_known_cpu(void)
183{
184 switch (boot_cpu_data.x86_vendor) {
185 case X86_VENDOR_AMD:
186 return ((boot_cpu_data.x86 == 15) || (boot_cpu_data.x86 == 6));
187 case X86_VENDOR_INTEL:
Venkatesh Pallipadi248dcb22006-09-26 10:52:27 +0200188 if (cpu_has(&boot_cpu_data, X86_FEATURE_ARCH_PERFMON))
189 return 1;
190 else
191 return ((boot_cpu_data.x86 == 15) || (boot_cpu_data.x86 == 6));
Don Zickusb7471c62006-09-26 10:52:26 +0200192 }
193 return 0;
194}
195
Eric W. Biederman29b70082005-10-30 14:59:40 -0800196#ifdef CONFIG_SMP
197/* The performance counters used by NMI_LOCAL_APIC don't trigger when
198 * the CPU is idle. To make sure the NMI watchdog really ticks on all
199 * CPUs during the test make them busy.
200 */
201static __init void nmi_cpu_busy(void *data)
202{
203 volatile int *endflag = data;
Ingo Molnar366c7f52006-07-03 00:25:25 -0700204 local_irq_enable_in_hardirq();
Eric W. Biederman29b70082005-10-30 14:59:40 -0800205 /* Intentionally don't use cpu_relax here. This is
206 to make sure that the performance counter really ticks,
207 even if there is a simulator or similar that catches the
208 pause instruction. On a real HT machine this is fine because
209 all other CPUs are busy with "useless" delay loops and don't
210 care if they get somewhat less cycles. */
211 while (*endflag == 0)
212 barrier();
213}
214#endif
215
Jack F Vogel67701ae2005-05-01 08:58:48 -0700216static int __init check_nmi_watchdog(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700217{
Eric W. Biederman29b70082005-10-30 14:59:40 -0800218 volatile int endflag = 0;
219 unsigned int *prev_nmi_count;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700220 int cpu;
221
Andi Kleen1de84972006-09-26 10:52:27 +0200222 /* Enable NMI watchdog for newer systems.
223 Actually it should be safe for most systems before 2004 too except
224 for some IBM systems that corrupt registers when NMI happens
225 during SMM. Unfortunately we don't have more exact information
226 on these and use this coarse check. */
227 if (nmi_watchdog == NMI_DEFAULT && dmi_get_year(DMI_BIOS_DATE) >= 2004)
228 nmi_watchdog = NMI_LOCAL_APIC;
229
Don Zickusb7471c62006-09-26 10:52:26 +0200230 if ((nmi_watchdog == NMI_NONE) || (nmi_watchdog == NMI_DEFAULT))
231 return 0;
232
233 if (!atomic_read(&nmi_active))
Jack F Vogel67701ae2005-05-01 08:58:48 -0700234 return 0;
235
Eric W. Biederman29b70082005-10-30 14:59:40 -0800236 prev_nmi_count = kmalloc(NR_CPUS * sizeof(int), GFP_KERNEL);
237 if (!prev_nmi_count)
238 return -1;
239
Jack F Vogel67701ae2005-05-01 08:58:48 -0700240 printk(KERN_INFO "Testing NMI watchdog ... ");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700241
Eric W. Biederman29b70082005-10-30 14:59:40 -0800242 if (nmi_watchdog == NMI_LOCAL_APIC)
243 smp_call_function(nmi_cpu_busy, (void *)&endflag, 0, 0);
244
KAMEZAWA Hiroyukic8912592006-03-28 01:56:39 -0800245 for_each_possible_cpu(cpu)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700246 prev_nmi_count[cpu] = per_cpu(irq_stat, cpu).__nmi_count;
247 local_irq_enable();
248 mdelay((10*1000)/nmi_hz); // wait 10 ticks
249
KAMEZAWA Hiroyukic8912592006-03-28 01:56:39 -0800250 for_each_possible_cpu(cpu) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700251#ifdef CONFIG_SMP
252 /* Check cpu_callin_map here because that is set
253 after the timer is started. */
254 if (!cpu_isset(cpu, cpu_callin_map))
255 continue;
256#endif
Don Zickusb7471c62006-09-26 10:52:26 +0200257 if (!per_cpu(nmi_watchdog_ctlblk, cpu).enabled)
258 continue;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700259 if (nmi_count(cpu) - prev_nmi_count[cpu] <= 5) {
Eric W. Biederman29b70082005-10-30 14:59:40 -0800260 printk("CPU#%d: NMI appears to be stuck (%d->%d)!\n",
261 cpu,
262 prev_nmi_count[cpu],
263 nmi_count(cpu));
Don Zickusb7471c62006-09-26 10:52:26 +0200264 per_cpu(nmi_watchdog_ctlblk, cpu).enabled = 0;
265 atomic_dec(&nmi_active);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700266 }
267 }
Don Zickusb7471c62006-09-26 10:52:26 +0200268 if (!atomic_read(&nmi_active)) {
269 kfree(prev_nmi_count);
270 atomic_set(&nmi_active, -1);
271 return -1;
272 }
Eric W. Biederman29b70082005-10-30 14:59:40 -0800273 endflag = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700274 printk("OK.\n");
275
276 /* now that we know it works we can reduce NMI frequency to
277 something more reasonable; makes a difference in some configs */
Venkatesh Pallipadi248dcb22006-09-26 10:52:27 +0200278 if (nmi_watchdog == NMI_LOCAL_APIC) {
279 struct nmi_watchdog_ctlblk *wd = &__get_cpu_var(nmi_watchdog_ctlblk);
280
Linus Torvalds1da177e2005-04-16 15:20:36 -0700281 nmi_hz = 1;
Venkatesh Pallipadi248dcb22006-09-26 10:52:27 +0200282 /*
283 * On Intel CPUs with ARCH_PERFMON only 32 bits in the counter
284 * are writable, with higher bits sign extending from bit 31.
285 * So, we can only program the counter with 31 bit values and
286 * 32nd bit should be 1, for 33.. to be 1.
287 * Find the appropriate nmi_hz
288 */
289 if (wd->perfctr_msr == MSR_ARCH_PERFMON_PERFCTR0 &&
290 ((u64)cpu_khz * 1000) > 0x7fffffffULL) {
291 u64 count = (u64)cpu_khz * 1000;
292 do_div(count, 0x7fffffffUL);
293 nmi_hz = count + 1;
294 }
295 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700296
Eric W. Biederman29b70082005-10-30 14:59:40 -0800297 kfree(prev_nmi_count);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700298 return 0;
299}
Jack F Vogel67701ae2005-05-01 08:58:48 -0700300/* This needs to happen later in boot so counters are working */
301late_initcall(check_nmi_watchdog);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700302
303static int __init setup_nmi_watchdog(char *str)
304{
305 int nmi;
306
307 get_option(&str, &nmi);
308
Don Zickusb7471c62006-09-26 10:52:26 +0200309 if ((nmi >= NMI_INVALID) || (nmi < NMI_NONE))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700310 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700311 /*
312 * If any other x86 CPU has a local APIC, then
313 * please test the NMI stuff there and send me the
314 * missing bits. Right now Intel P6/P4 and AMD K7 only.
315 */
Don Zickusb7471c62006-09-26 10:52:26 +0200316 if ((nmi == NMI_LOCAL_APIC) && (nmi_known_cpu() == 0))
317 return 0; /* no lapic support */
318 nmi_watchdog = nmi;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700319 return 1;
320}
321
322__setup("nmi_watchdog=", setup_nmi_watchdog);
323
324static void disable_lapic_nmi_watchdog(void)
325{
Don Zickusb7471c62006-09-26 10:52:26 +0200326 BUG_ON(nmi_watchdog != NMI_LOCAL_APIC);
327
328 if (atomic_read(&nmi_active) <= 0)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700329 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700330
Don Zickusb7471c62006-09-26 10:52:26 +0200331 on_each_cpu(stop_apic_nmi_watchdog, NULL, 0, 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700332
Don Zickusb7471c62006-09-26 10:52:26 +0200333 BUG_ON(atomic_read(&nmi_active) != 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700334}
335
336static void enable_lapic_nmi_watchdog(void)
337{
Don Zickusb7471c62006-09-26 10:52:26 +0200338 BUG_ON(nmi_watchdog != NMI_LOCAL_APIC);
339
340 /* are we already enabled */
341 if (atomic_read(&nmi_active) != 0)
342 return;
343
344 /* are we lapic aware */
345 if (nmi_known_cpu() <= 0)
346 return;
347
348 on_each_cpu(setup_apic_nmi_watchdog, NULL, 0, 1);
349 touch_nmi_watchdog();
Linus Torvalds1da177e2005-04-16 15:20:36 -0700350}
351
Linus Torvalds1da177e2005-04-16 15:20:36 -0700352void disable_timer_nmi_watchdog(void)
353{
Don Zickusb7471c62006-09-26 10:52:26 +0200354 BUG_ON(nmi_watchdog != NMI_IO_APIC);
355
356 if (atomic_read(&nmi_active) <= 0)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700357 return;
358
Don Zickusb7471c62006-09-26 10:52:26 +0200359 disable_irq(0);
360 on_each_cpu(stop_apic_nmi_watchdog, NULL, 0, 1);
361
362 BUG_ON(atomic_read(&nmi_active) != 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700363}
364
365void enable_timer_nmi_watchdog(void)
366{
Don Zickusb7471c62006-09-26 10:52:26 +0200367 BUG_ON(nmi_watchdog != NMI_IO_APIC);
368
369 if (atomic_read(&nmi_active) == 0) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700370 touch_nmi_watchdog();
Don Zickusb7471c62006-09-26 10:52:26 +0200371 on_each_cpu(setup_apic_nmi_watchdog, NULL, 0, 1);
372 enable_irq(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700373 }
374}
375
376#ifdef CONFIG_PM
377
378static int nmi_pm_active; /* nmi_active before suspend */
379
Pavel Machek438510f2005-04-16 15:25:24 -0700380static int lapic_nmi_suspend(struct sys_device *dev, pm_message_t state)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700381{
Shaohua Li4038f902006-09-26 10:52:27 +0200382 /* only CPU0 goes here, other CPUs should be offline */
Don Zickusb7471c62006-09-26 10:52:26 +0200383 nmi_pm_active = atomic_read(&nmi_active);
Shaohua Li4038f902006-09-26 10:52:27 +0200384 stop_apic_nmi_watchdog(NULL);
385 BUG_ON(atomic_read(&nmi_active) != 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700386 return 0;
387}
388
389static int lapic_nmi_resume(struct sys_device *dev)
390{
Shaohua Li4038f902006-09-26 10:52:27 +0200391 /* only CPU0 goes here, other CPUs should be offline */
392 if (nmi_pm_active > 0) {
393 setup_apic_nmi_watchdog(NULL);
394 touch_nmi_watchdog();
395 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700396 return 0;
397}
398
399
400static struct sysdev_class nmi_sysclass = {
401 set_kset_name("lapic_nmi"),
402 .resume = lapic_nmi_resume,
403 .suspend = lapic_nmi_suspend,
404};
405
406static struct sys_device device_lapic_nmi = {
407 .id = 0,
408 .cls = &nmi_sysclass,
409};
410
411static int __init init_lapic_nmi_sysfs(void)
412{
413 int error;
414
Don Zickusb7471c62006-09-26 10:52:26 +0200415 /* should really be a BUG_ON but b/c this is an
416 * init call, it just doesn't work. -dcz
417 */
418 if (nmi_watchdog != NMI_LOCAL_APIC)
419 return 0;
420
421 if ( atomic_read(&nmi_active) < 0 )
Linus Torvalds1da177e2005-04-16 15:20:36 -0700422 return 0;
423
424 error = sysdev_class_register(&nmi_sysclass);
425 if (!error)
426 error = sysdev_register(&device_lapic_nmi);
427 return error;
428}
429/* must come after the local APIC's device_initcall() */
430late_initcall(init_lapic_nmi_sysfs);
431
432#endif /* CONFIG_PM */
433
434/*
435 * Activate the NMI watchdog via the local APIC.
436 * Original code written by Keith Owens.
437 */
438
Don Zickusb7471c62006-09-26 10:52:26 +0200439static void write_watchdog_counter(unsigned int perfctr_msr, const char *descr)
Jan Beulich7fbb4f62005-06-23 00:08:23 -0700440{
441 u64 count = (u64)cpu_khz * 1000;
442
443 do_div(count, nmi_hz);
444 if(descr)
445 Dprintk("setting %s to -0x%08Lx\n", descr, count);
Don Zickusb7471c62006-09-26 10:52:26 +0200446 wrmsrl(perfctr_msr, 0 - count);
Jan Beulich7fbb4f62005-06-23 00:08:23 -0700447}
448
Don Zickusb7471c62006-09-26 10:52:26 +0200449/* Note that these events don't tick when the CPU idles. This means
450 the frequency varies with CPU load. */
451
452#define K7_EVNTSEL_ENABLE (1 << 22)
453#define K7_EVNTSEL_INT (1 << 20)
454#define K7_EVNTSEL_OS (1 << 17)
455#define K7_EVNTSEL_USR (1 << 16)
456#define K7_EVENT_CYCLES_PROCESSOR_IS_RUNNING 0x76
457#define K7_NMI_EVENT K7_EVENT_CYCLES_PROCESSOR_IS_RUNNING
458
Don Zickus828f0af2006-09-26 10:52:26 +0200459static int setup_k7_watchdog(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700460{
Don Zickusb7471c62006-09-26 10:52:26 +0200461 unsigned int perfctr_msr, evntsel_msr;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700462 unsigned int evntsel;
Don Zickusb7471c62006-09-26 10:52:26 +0200463 struct nmi_watchdog_ctlblk *wd = &__get_cpu_var(nmi_watchdog_ctlblk);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700464
Don Zickusb7471c62006-09-26 10:52:26 +0200465 perfctr_msr = MSR_K7_PERFCTR0;
466 evntsel_msr = MSR_K7_EVNTSEL0;
467 if (!reserve_perfctr_nmi(perfctr_msr))
Don Zickus828f0af2006-09-26 10:52:26 +0200468 goto fail;
469
Don Zickusb7471c62006-09-26 10:52:26 +0200470 if (!reserve_evntsel_nmi(evntsel_msr))
Don Zickus828f0af2006-09-26 10:52:26 +0200471 goto fail1;
472
Don Zickusb7471c62006-09-26 10:52:26 +0200473 wrmsrl(perfctr_msr, 0UL);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700474
475 evntsel = K7_EVNTSEL_INT
476 | K7_EVNTSEL_OS
477 | K7_EVNTSEL_USR
478 | K7_NMI_EVENT;
479
Don Zickusb7471c62006-09-26 10:52:26 +0200480 /* setup the timer */
481 wrmsr(evntsel_msr, evntsel, 0);
482 write_watchdog_counter(perfctr_msr, "K7_PERFCTR0");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700483 apic_write(APIC_LVTPC, APIC_DM_NMI);
484 evntsel |= K7_EVNTSEL_ENABLE;
Don Zickusb7471c62006-09-26 10:52:26 +0200485 wrmsr(evntsel_msr, evntsel, 0);
486
487 wd->perfctr_msr = perfctr_msr;
488 wd->evntsel_msr = evntsel_msr;
489 wd->cccr_msr = 0; //unused
490 wd->check_bit = 1ULL<<63;
Don Zickus828f0af2006-09-26 10:52:26 +0200491 return 1;
492fail1:
Don Zickusb7471c62006-09-26 10:52:26 +0200493 release_perfctr_nmi(perfctr_msr);
Don Zickus828f0af2006-09-26 10:52:26 +0200494fail:
495 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700496}
497
Don Zickusb7471c62006-09-26 10:52:26 +0200498static void stop_k7_watchdog(void)
499{
500 struct nmi_watchdog_ctlblk *wd = &__get_cpu_var(nmi_watchdog_ctlblk);
501
502 wrmsr(wd->evntsel_msr, 0, 0);
503
504 release_evntsel_nmi(wd->evntsel_msr);
505 release_perfctr_nmi(wd->perfctr_msr);
506}
507
508#define P6_EVNTSEL0_ENABLE (1 << 22)
509#define P6_EVNTSEL_INT (1 << 20)
510#define P6_EVNTSEL_OS (1 << 17)
511#define P6_EVNTSEL_USR (1 << 16)
512#define P6_EVENT_CPU_CLOCKS_NOT_HALTED 0x79
513#define P6_NMI_EVENT P6_EVENT_CPU_CLOCKS_NOT_HALTED
514
Don Zickus828f0af2006-09-26 10:52:26 +0200515static int setup_p6_watchdog(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700516{
Don Zickusb7471c62006-09-26 10:52:26 +0200517 unsigned int perfctr_msr, evntsel_msr;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700518 unsigned int evntsel;
Don Zickusb7471c62006-09-26 10:52:26 +0200519 struct nmi_watchdog_ctlblk *wd = &__get_cpu_var(nmi_watchdog_ctlblk);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700520
Don Zickusb7471c62006-09-26 10:52:26 +0200521 perfctr_msr = MSR_P6_PERFCTR0;
522 evntsel_msr = MSR_P6_EVNTSEL0;
523 if (!reserve_perfctr_nmi(perfctr_msr))
Don Zickus828f0af2006-09-26 10:52:26 +0200524 goto fail;
525
Don Zickusb7471c62006-09-26 10:52:26 +0200526 if (!reserve_evntsel_nmi(evntsel_msr))
Don Zickus828f0af2006-09-26 10:52:26 +0200527 goto fail1;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700528
Don Zickusb7471c62006-09-26 10:52:26 +0200529 wrmsrl(perfctr_msr, 0UL);
530
Linus Torvalds1da177e2005-04-16 15:20:36 -0700531 evntsel = P6_EVNTSEL_INT
532 | P6_EVNTSEL_OS
533 | P6_EVNTSEL_USR
534 | P6_NMI_EVENT;
535
Don Zickusb7471c62006-09-26 10:52:26 +0200536 /* setup the timer */
537 wrmsr(evntsel_msr, evntsel, 0);
538 write_watchdog_counter(perfctr_msr, "P6_PERFCTR0");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700539 apic_write(APIC_LVTPC, APIC_DM_NMI);
540 evntsel |= P6_EVNTSEL0_ENABLE;
Don Zickusb7471c62006-09-26 10:52:26 +0200541 wrmsr(evntsel_msr, evntsel, 0);
542
543 wd->perfctr_msr = perfctr_msr;
544 wd->evntsel_msr = evntsel_msr;
545 wd->cccr_msr = 0; //unused
546 wd->check_bit = 1ULL<<39;
Don Zickus828f0af2006-09-26 10:52:26 +0200547 return 1;
548fail1:
Don Zickusb7471c62006-09-26 10:52:26 +0200549 release_perfctr_nmi(perfctr_msr);
Don Zickus828f0af2006-09-26 10:52:26 +0200550fail:
551 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700552}
553
Don Zickusb7471c62006-09-26 10:52:26 +0200554static void stop_p6_watchdog(void)
555{
556 struct nmi_watchdog_ctlblk *wd = &__get_cpu_var(nmi_watchdog_ctlblk);
557
558 wrmsr(wd->evntsel_msr, 0, 0);
559
560 release_evntsel_nmi(wd->evntsel_msr);
561 release_perfctr_nmi(wd->perfctr_msr);
562}
563
564/* Note that these events don't tick when the CPU idles. This means
565 the frequency varies with CPU load. */
566
567#define MSR_P4_MISC_ENABLE_PERF_AVAIL (1<<7)
568#define P4_ESCR_EVENT_SELECT(N) ((N)<<25)
569#define P4_ESCR_OS (1<<3)
570#define P4_ESCR_USR (1<<2)
571#define P4_CCCR_OVF_PMI0 (1<<26)
572#define P4_CCCR_OVF_PMI1 (1<<27)
573#define P4_CCCR_THRESHOLD(N) ((N)<<20)
574#define P4_CCCR_COMPLEMENT (1<<19)
575#define P4_CCCR_COMPARE (1<<18)
576#define P4_CCCR_REQUIRED (3<<16)
577#define P4_CCCR_ESCR_SELECT(N) ((N)<<13)
578#define P4_CCCR_ENABLE (1<<12)
579#define P4_CCCR_OVF (1<<31)
580/* Set up IQ_COUNTER0 to behave like a clock, by having IQ_CCCR0 filter
581 CRU_ESCR0 (with any non-null event selector) through a complemented
582 max threshold. [IA32-Vol3, Section 14.9.9] */
583
Linus Torvalds1da177e2005-04-16 15:20:36 -0700584static int setup_p4_watchdog(void)
585{
Don Zickusb7471c62006-09-26 10:52:26 +0200586 unsigned int perfctr_msr, evntsel_msr, cccr_msr;
587 unsigned int evntsel, cccr_val;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700588 unsigned int misc_enable, dummy;
Don Zickusb7471c62006-09-26 10:52:26 +0200589 unsigned int ht_num;
590 struct nmi_watchdog_ctlblk *wd = &__get_cpu_var(nmi_watchdog_ctlblk);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700591
Don Zickusb7471c62006-09-26 10:52:26 +0200592 rdmsr(MSR_IA32_MISC_ENABLE, misc_enable, dummy);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700593 if (!(misc_enable & MSR_P4_MISC_ENABLE_PERF_AVAIL))
594 return 0;
595
Linus Torvalds1da177e2005-04-16 15:20:36 -0700596#ifdef CONFIG_SMP
Don Zickusb7471c62006-09-26 10:52:26 +0200597 /* detect which hyperthread we are on */
598 if (smp_num_siblings == 2) {
599 unsigned int ebx, apicid;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700600
Don Zickusb7471c62006-09-26 10:52:26 +0200601 ebx = cpuid_ebx(1);
602 apicid = (ebx >> 24) & 0xff;
603 ht_num = apicid & 1;
604 } else
605#endif
606 ht_num = 0;
607
608 /* performance counters are shared resources
609 * assign each hyperthread its own set
610 * (re-use the ESCR0 register, seems safe
611 * and keeps the cccr_val the same)
612 */
613 if (!ht_num) {
614 /* logical cpu 0 */
615 perfctr_msr = MSR_P4_IQ_PERFCTR0;
616 evntsel_msr = MSR_P4_CRU_ESCR0;
617 cccr_msr = MSR_P4_IQ_CCCR0;
618 cccr_val = P4_CCCR_OVF_PMI0 | P4_CCCR_ESCR_SELECT(4);
619 } else {
620 /* logical cpu 1 */
621 perfctr_msr = MSR_P4_IQ_PERFCTR1;
622 evntsel_msr = MSR_P4_CRU_ESCR0;
623 cccr_msr = MSR_P4_IQ_CCCR1;
624 cccr_val = P4_CCCR_OVF_PMI1 | P4_CCCR_ESCR_SELECT(4);
625 }
626
627 if (!reserve_perfctr_nmi(perfctr_msr))
Don Zickus828f0af2006-09-26 10:52:26 +0200628 goto fail;
629
Don Zickusb7471c62006-09-26 10:52:26 +0200630 if (!reserve_evntsel_nmi(evntsel_msr))
Don Zickus828f0af2006-09-26 10:52:26 +0200631 goto fail1;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700632
Don Zickusb7471c62006-09-26 10:52:26 +0200633 evntsel = P4_ESCR_EVENT_SELECT(0x3F)
634 | P4_ESCR_OS
635 | P4_ESCR_USR;
636
637 cccr_val |= P4_CCCR_THRESHOLD(15)
638 | P4_CCCR_COMPLEMENT
639 | P4_CCCR_COMPARE
640 | P4_CCCR_REQUIRED;
641
642 wrmsr(evntsel_msr, evntsel, 0);
643 wrmsr(cccr_msr, cccr_val, 0);
644 write_watchdog_counter(perfctr_msr, "P4_IQ_COUNTER0");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700645 apic_write(APIC_LVTPC, APIC_DM_NMI);
Don Zickusb7471c62006-09-26 10:52:26 +0200646 cccr_val |= P4_CCCR_ENABLE;
647 wrmsr(cccr_msr, cccr_val, 0);
648 wd->perfctr_msr = perfctr_msr;
649 wd->evntsel_msr = evntsel_msr;
650 wd->cccr_msr = cccr_msr;
651 wd->check_bit = 1ULL<<39;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700652 return 1;
Don Zickus828f0af2006-09-26 10:52:26 +0200653fail1:
Don Zickusb7471c62006-09-26 10:52:26 +0200654 release_perfctr_nmi(perfctr_msr);
Don Zickus828f0af2006-09-26 10:52:26 +0200655fail:
656 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700657}
658
Don Zickusb7471c62006-09-26 10:52:26 +0200659static void stop_p4_watchdog(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700660{
Don Zickusb7471c62006-09-26 10:52:26 +0200661 struct nmi_watchdog_ctlblk *wd = &__get_cpu_var(nmi_watchdog_ctlblk);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700662
Don Zickusb7471c62006-09-26 10:52:26 +0200663 wrmsr(wd->cccr_msr, 0, 0);
664 wrmsr(wd->evntsel_msr, 0, 0);
665
666 release_evntsel_nmi(wd->evntsel_msr);
667 release_perfctr_nmi(wd->perfctr_msr);
668}
669
Venkatesh Pallipadi248dcb22006-09-26 10:52:27 +0200670#define ARCH_PERFMON_NMI_EVENT_SEL ARCH_PERFMON_UNHALTED_CORE_CYCLES_SEL
671#define ARCH_PERFMON_NMI_EVENT_UMASK ARCH_PERFMON_UNHALTED_CORE_CYCLES_UMASK
672
673static int setup_intel_arch_watchdog(void)
674{
675 unsigned int ebx;
676 union cpuid10_eax eax;
677 unsigned int unused;
678 unsigned int perfctr_msr, evntsel_msr;
679 unsigned int evntsel;
680 struct nmi_watchdog_ctlblk *wd = &__get_cpu_var(nmi_watchdog_ctlblk);
681
682 /*
683 * Check whether the Architectural PerfMon supports
684 * Unhalted Core Cycles Event or not.
685 * NOTE: Corresponding bit = 0 in ebx indicates event present.
686 */
687 cpuid(10, &(eax.full), &ebx, &unused, &unused);
688 if ((eax.split.mask_length < (ARCH_PERFMON_UNHALTED_CORE_CYCLES_INDEX+1)) ||
689 (ebx & ARCH_PERFMON_UNHALTED_CORE_CYCLES_PRESENT))
690 goto fail;
691
692 perfctr_msr = MSR_ARCH_PERFMON_PERFCTR0;
693 evntsel_msr = MSR_ARCH_PERFMON_EVENTSEL0;
694
695 if (!reserve_perfctr_nmi(perfctr_msr))
696 goto fail;
697
698 if (!reserve_evntsel_nmi(evntsel_msr))
699 goto fail1;
700
701 wrmsrl(perfctr_msr, 0UL);
702
703 evntsel = ARCH_PERFMON_EVENTSEL_INT
704 | ARCH_PERFMON_EVENTSEL_OS
705 | ARCH_PERFMON_EVENTSEL_USR
706 | ARCH_PERFMON_NMI_EVENT_SEL
707 | ARCH_PERFMON_NMI_EVENT_UMASK;
708
709 /* setup the timer */
710 wrmsr(evntsel_msr, evntsel, 0);
711 write_watchdog_counter(perfctr_msr, "INTEL_ARCH_PERFCTR0");
712 apic_write(APIC_LVTPC, APIC_DM_NMI);
713 evntsel |= ARCH_PERFMON_EVENTSEL0_ENABLE;
714 wrmsr(evntsel_msr, evntsel, 0);
715
716 wd->perfctr_msr = perfctr_msr;
717 wd->evntsel_msr = evntsel_msr;
718 wd->cccr_msr = 0; //unused
719 wd->check_bit = 1ULL << (eax.split.bit_width - 1);
720 return 1;
721fail1:
722 release_perfctr_nmi(perfctr_msr);
723fail:
724 return 0;
725}
726
727static void stop_intel_arch_watchdog(void)
728{
729 unsigned int ebx;
730 union cpuid10_eax eax;
731 unsigned int unused;
732 struct nmi_watchdog_ctlblk *wd = &__get_cpu_var(nmi_watchdog_ctlblk);
733
734 /*
735 * Check whether the Architectural PerfMon supports
736 * Unhalted Core Cycles Event or not.
737 * NOTE: Corresponding bit = 0 in ebx indicates event present.
738 */
739 cpuid(10, &(eax.full), &ebx, &unused, &unused);
740 if ((eax.split.mask_length < (ARCH_PERFMON_UNHALTED_CORE_CYCLES_INDEX+1)) ||
741 (ebx & ARCH_PERFMON_UNHALTED_CORE_CYCLES_PRESENT))
742 return;
743
744 wrmsr(wd->evntsel_msr, 0, 0);
745 release_evntsel_nmi(wd->evntsel_msr);
746 release_perfctr_nmi(wd->perfctr_msr);
747}
748
Don Zickusb7471c62006-09-26 10:52:26 +0200749void setup_apic_nmi_watchdog (void *unused)
750{
Shaohua Li4038f902006-09-26 10:52:27 +0200751 struct nmi_watchdog_ctlblk *wd = &__get_cpu_var(nmi_watchdog_ctlblk);
752
Don Zickusb7471c62006-09-26 10:52:26 +0200753 /* only support LOCAL and IO APICs for now */
754 if ((nmi_watchdog != NMI_LOCAL_APIC) &&
755 (nmi_watchdog != NMI_IO_APIC))
756 return;
757
Shaohua Li4038f902006-09-26 10:52:27 +0200758 if (wd->enabled == 1)
759 return;
760
761 /* cheap hack to support suspend/resume */
762 /* if cpu0 is not active neither should the other cpus */
763 if ((smp_processor_id() != 0) && (atomic_read(&nmi_active) <= 0))
764 return;
765
Don Zickusb7471c62006-09-26 10:52:26 +0200766 if (nmi_watchdog == NMI_LOCAL_APIC) {
767 switch (boot_cpu_data.x86_vendor) {
768 case X86_VENDOR_AMD:
769 if (boot_cpu_data.x86 != 6 && boot_cpu_data.x86 != 15)
770 return;
771 if (!setup_k7_watchdog())
Don Zickus828f0af2006-09-26 10:52:26 +0200772 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700773 break;
Don Zickusb7471c62006-09-26 10:52:26 +0200774 case X86_VENDOR_INTEL:
Venkatesh Pallipadi248dcb22006-09-26 10:52:27 +0200775 if (cpu_has(&boot_cpu_data, X86_FEATURE_ARCH_PERFMON)) {
776 if (!setup_intel_arch_watchdog())
777 return;
778 break;
779 }
Don Zickusb7471c62006-09-26 10:52:26 +0200780 switch (boot_cpu_data.x86) {
781 case 6:
782 if (boot_cpu_data.x86_model > 0xd)
783 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700784
Don Zickusb7471c62006-09-26 10:52:26 +0200785 if (!setup_p6_watchdog())
786 return;
787 break;
788 case 15:
789 if (boot_cpu_data.x86_model > 0x4)
790 return;
791
792 if (!setup_p4_watchdog())
793 return;
794 break;
795 default:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700796 return;
Don Zickusb7471c62006-09-26 10:52:26 +0200797 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700798 break;
799 default:
800 return;
801 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700802 }
Shaohua Li4038f902006-09-26 10:52:27 +0200803 wd->enabled = 1;
Don Zickusb7471c62006-09-26 10:52:26 +0200804 atomic_inc(&nmi_active);
805}
806
Shaohua Li4038f902006-09-26 10:52:27 +0200807void stop_apic_nmi_watchdog(void *unused)
Don Zickusb7471c62006-09-26 10:52:26 +0200808{
Shaohua Li4038f902006-09-26 10:52:27 +0200809 struct nmi_watchdog_ctlblk *wd = &__get_cpu_var(nmi_watchdog_ctlblk);
810
Don Zickusb7471c62006-09-26 10:52:26 +0200811 /* only support LOCAL and IO APICs for now */
812 if ((nmi_watchdog != NMI_LOCAL_APIC) &&
813 (nmi_watchdog != NMI_IO_APIC))
814 return;
815
Shaohua Li4038f902006-09-26 10:52:27 +0200816 if (wd->enabled == 0)
817 return;
818
Don Zickusb7471c62006-09-26 10:52:26 +0200819 if (nmi_watchdog == NMI_LOCAL_APIC) {
820 switch (boot_cpu_data.x86_vendor) {
821 case X86_VENDOR_AMD:
822 stop_k7_watchdog();
823 break;
824 case X86_VENDOR_INTEL:
Venkatesh Pallipadi248dcb22006-09-26 10:52:27 +0200825 if (cpu_has(&boot_cpu_data, X86_FEATURE_ARCH_PERFMON)) {
826 stop_intel_arch_watchdog();
827 break;
828 }
Don Zickusb7471c62006-09-26 10:52:26 +0200829 switch (boot_cpu_data.x86) {
830 case 6:
831 if (boot_cpu_data.x86_model > 0xd)
832 break;
833 stop_p6_watchdog();
834 break;
835 case 15:
836 if (boot_cpu_data.x86_model > 0x4)
837 break;
838 stop_p4_watchdog();
839 break;
840 }
841 break;
842 default:
843 return;
844 }
845 }
Shaohua Li4038f902006-09-26 10:52:27 +0200846 wd->enabled = 0;
Don Zickusb7471c62006-09-26 10:52:26 +0200847 atomic_dec(&nmi_active);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700848}
849
850/*
851 * the best way to detect whether a CPU has a 'hard lockup' problem
852 * is to check it's local APIC timer IRQ counts. If they are not
853 * changing then that CPU has some problem.
854 *
855 * as these watchdog NMI IRQs are generated on every CPU, we only
856 * have to check the current processor.
857 *
858 * since NMIs don't listen to _any_ locks, we have to be extremely
859 * careful not to rely on unsafe variables. The printk might lock
860 * up though, so we have to break up any console locks first ...
861 * [when there will be more tty-related locks, break them up
862 * here too!]
863 */
864
865static unsigned int
866 last_irq_sums [NR_CPUS],
867 alert_counter [NR_CPUS];
868
869void touch_nmi_watchdog (void)
870{
871 int i;
872
873 /*
874 * Just reset the alert counters, (other CPUs might be
875 * spinning on locks we hold):
876 */
KAMEZAWA Hiroyukic8912592006-03-28 01:56:39 -0800877 for_each_possible_cpu(i)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700878 alert_counter[i] = 0;
Ingo Molnar8446f1d2005-09-06 15:16:27 -0700879
880 /*
881 * Tickle the softlockup detector too:
882 */
883 touch_softlockup_watchdog();
Linus Torvalds1da177e2005-04-16 15:20:36 -0700884}
Michal Schmidt1e862402006-07-30 03:03:29 -0700885EXPORT_SYMBOL(touch_nmi_watchdog);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700886
887extern void die_nmi(struct pt_regs *, const char *msg);
888
Fernando Luis Vázquez Cao06039752006-09-26 10:52:36 +0200889__kprobes int nmi_watchdog_tick(struct pt_regs * regs, unsigned reason)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700890{
891
892 /*
893 * Since current_thread_info()-> is always on the stack, and we
894 * always switch the stack NMI-atomically, it's safe to use
895 * smp_processor_id().
896 */
Jesper Juhlb791cce2006-03-28 01:56:52 -0800897 unsigned int sum;
Don Zickusb7471c62006-09-26 10:52:26 +0200898 int touched = 0;
Jesper Juhlb791cce2006-03-28 01:56:52 -0800899 int cpu = smp_processor_id();
Don Zickusb7471c62006-09-26 10:52:26 +0200900 struct nmi_watchdog_ctlblk *wd = &__get_cpu_var(nmi_watchdog_ctlblk);
901 u64 dummy;
Don Zickus3adbbcce2006-09-26 10:52:26 +0200902 int rc=0;
Don Zickusb7471c62006-09-26 10:52:26 +0200903
904 /* check for other users first */
905 if (notify_die(DIE_NMI, "nmi", regs, reason, 2, SIGINT)
906 == NOTIFY_STOP) {
Don Zickus3adbbcce2006-09-26 10:52:26 +0200907 rc = 1;
Don Zickusb7471c62006-09-26 10:52:26 +0200908 touched = 1;
909 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700910
911 sum = per_cpu(irq_stat, cpu).apic_timer_irqs;
912
Don Zickusb7471c62006-09-26 10:52:26 +0200913 /* if the apic timer isn't firing, this cpu isn't doing much */
914 if (!touched && last_irq_sums[cpu] == sum) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700915 /*
916 * Ayiee, looks like this CPU is stuck ...
917 * wait a few IRQs (5 seconds) before doing the oops ...
918 */
919 alert_counter[cpu]++;
920 if (alert_counter[cpu] == 5*nmi_hz)
George Anzinger748f2ed2005-09-03 15:56:48 -0700921 /*
922 * die_nmi will return ONLY if NOTIFY_STOP happens..
923 */
Ingo Molnar91368d72006-03-23 03:00:54 -0800924 die_nmi(regs, "BUG: NMI Watchdog detected LOCKUP");
GOTO Masanorib884e252006-03-07 21:55:29 -0800925 } else {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700926 last_irq_sums[cpu] = sum;
927 alert_counter[cpu] = 0;
928 }
Don Zickusb7471c62006-09-26 10:52:26 +0200929 /* see if the nmi watchdog went off */
930 if (wd->enabled) {
931 if (nmi_watchdog == NMI_LOCAL_APIC) {
932 rdmsrl(wd->perfctr_msr, dummy);
933 if (dummy & wd->check_bit){
934 /* this wasn't a watchdog timer interrupt */
935 goto done;
936 }
937
938 /* only Intel P4 uses the cccr msr */
939 if (wd->cccr_msr != 0) {
940 /*
941 * P4 quirks:
942 * - An overflown perfctr will assert its interrupt
943 * until the OVF flag in its CCCR is cleared.
944 * - LVTPC is masked on interrupt and must be
945 * unmasked by the LVTPC handler.
946 */
947 rdmsrl(wd->cccr_msr, dummy);
948 dummy &= ~P4_CCCR_OVF;
949 wrmsrl(wd->cccr_msr, dummy);
950 apic_write(APIC_LVTPC, APIC_DM_NMI);
951 }
Venkatesh Pallipadi248dcb22006-09-26 10:52:27 +0200952 else if (wd->perfctr_msr == MSR_P6_PERFCTR0 ||
953 wd->perfctr_msr == MSR_ARCH_PERFMON_PERFCTR0) {
954 /* P6 based Pentium M need to re-unmask
Don Zickusb7471c62006-09-26 10:52:26 +0200955 * the apic vector but it doesn't hurt
Venkatesh Pallipadi248dcb22006-09-26 10:52:27 +0200956 * other P6 variant.
957 * ArchPerfom/Core Duo also needs this */
Don Zickusb7471c62006-09-26 10:52:26 +0200958 apic_write(APIC_LVTPC, APIC_DM_NMI);
959 }
960 /* start the cycle over again */
961 write_watchdog_counter(wd->perfctr_msr, NULL);
Don Zickus3adbbcce2006-09-26 10:52:26 +0200962 rc = 1;
963 } else if (nmi_watchdog == NMI_IO_APIC) {
964 /* don't know how to accurately check for this.
965 * just assume it was a watchdog timer interrupt
966 * This matches the old behaviour.
967 */
968 rc = 1;
Fernando Luis Vázquez Cao06039752006-09-26 10:52:36 +0200969 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700970 }
Don Zickusb7471c62006-09-26 10:52:26 +0200971done:
Don Zickus3adbbcce2006-09-26 10:52:26 +0200972 return rc;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700973}
974
Don Zickus2fbe7b22006-09-26 10:52:27 +0200975int do_nmi_callback(struct pt_regs * regs, int cpu)
976{
977#ifdef CONFIG_SYSCTL
978 if (unknown_nmi_panic)
979 return unknown_nmi_panic_callback(regs, cpu);
980#endif
981 return 0;
982}
983
Linus Torvalds1da177e2005-04-16 15:20:36 -0700984#ifdef CONFIG_SYSCTL
985
986static int unknown_nmi_panic_callback(struct pt_regs *regs, int cpu)
987{
988 unsigned char reason = get_nmi_reason();
989 char buf[64];
990
Don Zickus2fbe7b22006-09-26 10:52:27 +0200991 sprintf(buf, "NMI received for unknown reason %02x\n", reason);
992 die_nmi(regs, buf);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700993 return 0;
994}
995
Don Zickus407984f2006-09-26 10:52:27 +0200996/*
Don Zickuse33e89a2006-09-26 10:52:27 +0200997 * proc handler for /proc/sys/kernel/nmi
Don Zickus407984f2006-09-26 10:52:27 +0200998 */
999int proc_nmi_enabled(struct ctl_table *table, int write, struct file *file,
1000 void __user *buffer, size_t *length, loff_t *ppos)
1001{
1002 int old_state;
1003
1004 nmi_watchdog_enabled = (atomic_read(&nmi_active) > 0) ? 1 : 0;
1005 old_state = nmi_watchdog_enabled;
1006 proc_dointvec(table, write, file, buffer, length, ppos);
1007 if (!!old_state == !!nmi_watchdog_enabled)
1008 return 0;
1009
1010 if (atomic_read(&nmi_active) < 0) {
Don Zickuse33e89a2006-09-26 10:52:27 +02001011 printk( KERN_WARNING "NMI watchdog is permanently disabled\n");
1012 return -EIO;
Don Zickus407984f2006-09-26 10:52:27 +02001013 }
1014
1015 if (nmi_watchdog == NMI_DEFAULT) {
1016 if (nmi_known_cpu() > 0)
1017 nmi_watchdog = NMI_LOCAL_APIC;
1018 else
1019 nmi_watchdog = NMI_IO_APIC;
1020 }
1021
Don Zickuse33e89a2006-09-26 10:52:27 +02001022 if (nmi_watchdog == NMI_LOCAL_APIC) {
Don Zickus407984f2006-09-26 10:52:27 +02001023 if (nmi_watchdog_enabled)
1024 enable_lapic_nmi_watchdog();
1025 else
1026 disable_lapic_nmi_watchdog();
Don Zickus407984f2006-09-26 10:52:27 +02001027 } else {
1028 printk( KERN_WARNING
1029 "NMI watchdog doesn't know what hardware to touch\n");
1030 return -EIO;
1031 }
1032 return 0;
1033}
1034
Linus Torvalds1da177e2005-04-16 15:20:36 -07001035#endif
1036
1037EXPORT_SYMBOL(nmi_active);
1038EXPORT_SYMBOL(nmi_watchdog);
Don Zickus828f0af2006-09-26 10:52:26 +02001039EXPORT_SYMBOL(avail_to_resrv_perfctr_nmi);
1040EXPORT_SYMBOL(avail_to_resrv_perfctr_nmi_bit);
1041EXPORT_SYMBOL(reserve_perfctr_nmi);
1042EXPORT_SYMBOL(release_perfctr_nmi);
1043EXPORT_SYMBOL(reserve_evntsel_nmi);
1044EXPORT_SYMBOL(release_evntsel_nmi);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001045EXPORT_SYMBOL(disable_timer_nmi_watchdog);
1046EXPORT_SYMBOL(enable_timer_nmi_watchdog);