]> git.proxmox.com Git - mirror_ubuntu-zesty-kernel.git/blame - arch/x86_64/kernel/nmi.c
[PATCH] x86_64: Make vsyscall.c compile without CONFIG_SYSCTL
[mirror_ubuntu-zesty-kernel.git] / arch / x86_64 / kernel / nmi.c
CommitLineData
1da177e4
LT
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 */
46static DEFINE_SPINLOCK(lapic_nmi_owner_lock);
47static 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 */
57int nmi_active; /* oprofile uses this */
58int panic_on_timeout;
59
60unsigned int nmi_watchdog = NMI_DEFAULT;
61static unsigned int nmi_hz = HZ;
62unsigned 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 */
82void __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? */
103static __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
67701ae9 115static int __init check_nmi_watchdog (void)
1da177e4 116{
ac6b931c 117 int *counts;
1da177e4
LT
118 int cpu;
119
67701ae9
JV
120 if (nmi_watchdog == NMI_NONE)
121 return 0;
122
1da177e4
LT
123 if (nmi_watchdog == NMI_LOCAL_APIC && !cpu_has_lapic()) {
124 nmi_watchdog = NMI_NONE;
125 return -1;
126 }
127
ac6b931c
AK
128 counts = kmalloc(NR_CPUS * sizeof(int),GFP_KERNEL);
129 if (!counts) {
130 nmi_watchdog = NMI_NONE;
131 return 0;
132 }
133
67701ae9 134 printk(KERN_INFO "Testing NMI watchdog ... ");
1da177e4
LT
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++) {
1da177e4
LT
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;
ac6b931c 148 kfree(counts);
1da177e4
LT
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
ac6b931c 159 kfree(counts);
1da177e4
LT
160 return 0;
161}
67701ae9
JV
162/* Have this called later during boot so counters are updating */
163late_initcall(check_nmi_watchdog);
1da177e4
LT
164
165int __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
187static 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
204static 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
212int 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
227void 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
239void 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
250void 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
262static int nmi_pm_active; /* nmi_active before suspend */
263
0b9c33a7 264static int lapic_nmi_suspend(struct sys_device *dev, pm_message_t state)
1da177e4
LT
265{
266 nmi_pm_active = nmi_active;
267 disable_lapic_nmi_watchdog();
268 return 0;
269}
270
271static 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
278static struct sysdev_class nmi_sysclass = {
279 set_kset_name("lapic_nmi"),
280 .resume = lapic_nmi_resume,
281 .suspend = lapic_nmi_suspend,
282};
283
284static struct sys_device device_lapic_nmi = {
285 .id = 0,
286 .cls = &nmi_sysclass,
287};
288
289static 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() */
302late_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
311static 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
342void setup_apic_nmi_watchdog(void)
343{
344 switch (boot_cpu_data.x86_vendor) {
345 case X86_VENDOR_AMD:
72e76be2 346 if (boot_cpu_data.x86 != 15)
1da177e4
LT
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
374static unsigned int
375 last_irq_sums [NR_CPUS],
376 alert_counter [NR_CPUS];
377
378void 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
390void 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
418static int dummy_nmi_callback(struct pt_regs * regs, int cpu)
419{
420 return 0;
421}
422
423static nmi_callback_t nmi_callback = dummy_nmi_callback;
424
425asmlinkage 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
436void set_nmi_callback(nmi_callback_t callback)
437{
438 nmi_callback = callback;
439}
440
441void unset_nmi_callback(void)
442{
443 nmi_callback = dummy_nmi_callback;
444}
445
446#ifdef CONFIG_SYSCTL
447
448static 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 */
463int 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
489EXPORT_SYMBOL(nmi_active);
490EXPORT_SYMBOL(nmi_watchdog);
491EXPORT_SYMBOL(reserve_lapic_nmi);
492EXPORT_SYMBOL(release_lapic_nmi);
493EXPORT_SYMBOL(disable_timer_nmi_watchdog);
494EXPORT_SYMBOL(enable_timer_nmi_watchdog);
495EXPORT_SYMBOL(touch_nmi_watchdog);