aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
Diffstat (limited to 'arch')
-rw-r--r--arch/x86/kernel/traps_32.c28
-rw-r--r--arch/x86/kernel/traps_64.c65
2 files changed, 58 insertions, 35 deletions
diff --git a/arch/x86/kernel/traps_32.c b/arch/x86/kernel/traps_32.c
index 01e7ca8c7661..076739863d24 100644
--- a/arch/x86/kernel/traps_32.c
+++ b/arch/x86/kernel/traps_32.c
@@ -7,13 +7,11 @@
7 */ 7 */
8 8
9/* 9/*
10 * 'Traps.c' handles hardware traps and faults after we have saved some 10 * Handle hardware traps and faults.
11 * state in 'asm.s'.
12 */ 11 */
13#include <linux/interrupt.h> 12#include <linux/interrupt.h>
14#include <linux/kallsyms.h> 13#include <linux/kallsyms.h>
15#include <linux/spinlock.h> 14#include <linux/spinlock.h>
16#include <linux/highmem.h>
17#include <linux/kprobes.h> 15#include <linux/kprobes.h>
18#include <linux/uaccess.h> 16#include <linux/uaccess.h>
19#include <linux/utsname.h> 17#include <linux/utsname.h>
@@ -32,6 +30,8 @@
32#include <linux/bug.h> 30#include <linux/bug.h>
33#include <linux/nmi.h> 31#include <linux/nmi.h>
34#include <linux/mm.h> 32#include <linux/mm.h>
33#include <linux/smp.h>
34#include <linux/io.h>
35 35
36#ifdef CONFIG_EISA 36#ifdef CONFIG_EISA
37#include <linux/ioport.h> 37#include <linux/ioport.h>
@@ -46,22 +46,26 @@
46#include <linux/edac.h> 46#include <linux/edac.h>
47#endif 47#endif
48 48
49#include <asm/processor-flags.h>
50#include <asm/arch_hooks.h>
51#include <asm/stacktrace.h> 49#include <asm/stacktrace.h>
52#include <asm/processor.h> 50#include <asm/processor.h>
51#include <asm/kmemcheck.h>
53#include <asm/debugreg.h> 52#include <asm/debugreg.h>
54#include <asm/atomic.h> 53#include <asm/atomic.h>
55#include <asm/system.h> 54#include <asm/system.h>
56#include <asm/unwind.h> 55#include <asm/unwind.h>
56#include <asm/traps.h>
57#include <asm/desc.h> 57#include <asm/desc.h>
58#include <asm/i387.h> 58#include <asm/i387.h>
59
60#include <mach_traps.h>
61
62#include <asm/processor-flags.h>
63#include <asm/arch_hooks.h>
59#include <asm/nmi.h> 64#include <asm/nmi.h>
60#include <asm/smp.h> 65#include <asm/smp.h>
61#include <asm/io.h> 66#include <asm/io.h>
62#include <asm/traps.h> 67#include <asm/traps.h>
63 68
64#include "mach_traps.h"
65#include "cpu/mcheck/mce.h" 69#include "cpu/mcheck/mce.h"
66 70
67DECLARE_BITMAP(used_vectors, NR_VECTORS); 71DECLARE_BITMAP(used_vectors, NR_VECTORS);
@@ -340,7 +344,8 @@ io_check_error(unsigned char reason, struct pt_regs *regs)
340static notrace __kprobes void 344static notrace __kprobes void
341unknown_nmi_error(unsigned char reason, struct pt_regs *regs) 345unknown_nmi_error(unsigned char reason, struct pt_regs *regs)
342{ 346{
343 if (notify_die(DIE_NMIUNKNOWN, "nmi", regs, reason, 2, SIGINT) == NOTIFY_STOP) 347 if (notify_die(DIE_NMIUNKNOWN, "nmi", regs, reason, 2, SIGINT) ==
348 NOTIFY_STOP)
344 return; 349 return;
345#ifdef CONFIG_MCA 350#ifdef CONFIG_MCA
346 /* 351 /*
@@ -446,13 +451,9 @@ static notrace __kprobes void default_do_nmi(struct pt_regs *regs)
446dotraplinkage notrace __kprobes void 451dotraplinkage notrace __kprobes void
447do_nmi(struct pt_regs *regs, long error_code) 452do_nmi(struct pt_regs *regs, long error_code)
448{ 453{
449 int cpu;
450
451 nmi_enter(); 454 nmi_enter();
452 455
453 cpu = smp_processor_id(); 456 { int cpu; cpu = smp_processor_id(); ++nmi_count(cpu); }
454
455 ++nmi_count(cpu);
456 457
457 if (!ignore_nmis) 458 if (!ignore_nmis)
458 default_do_nmi(regs); 459 default_do_nmi(regs);
@@ -472,6 +473,7 @@ void restart_nmi(void)
472 acpi_nmi_enable(); 473 acpi_nmi_enable();
473} 474}
474 475
476/* May run on IST stack. */
475dotraplinkage void __kprobes do_int3(struct pt_regs *regs, long error_code) 477dotraplinkage void __kprobes do_int3(struct pt_regs *regs, long error_code)
476{ 478{
477#ifdef CONFIG_KPROBES 479#ifdef CONFIG_KPROBES
@@ -510,6 +512,8 @@ dotraplinkage void __kprobes do_int3(struct pt_regs *regs, long error_code)
510 * about restoring all the debug state, and ptrace doesn't have to 512 * about restoring all the debug state, and ptrace doesn't have to
511 * find every occurrence of the TF bit that could be saved away even 513 * find every occurrence of the TF bit that could be saved away even
512 * by user code) 514 * by user code)
515 *
516 * May run on IST stack.
513 */ 517 */
514dotraplinkage void __kprobes do_debug(struct pt_regs *regs, long error_code) 518dotraplinkage void __kprobes do_debug(struct pt_regs *regs, long error_code)
515{ 519{
diff --git a/arch/x86/kernel/traps_64.c b/arch/x86/kernel/traps_64.c
index 71c2629997b3..22fe62a24edb 100644
--- a/arch/x86/kernel/traps_64.c
+++ b/arch/x86/kernel/traps_64.c
@@ -7,10 +7,8 @@
7 */ 7 */
8 8
9/* 9/*
10 * 'Traps.c' handles hardware traps and faults after we have saved some 10 * Handle hardware traps and faults.
11 * state in 'entry.S'.
12 */ 11 */
13#include <linux/moduleparam.h>
14#include <linux/interrupt.h> 12#include <linux/interrupt.h>
15#include <linux/kallsyms.h> 13#include <linux/kallsyms.h>
16#include <linux/spinlock.h> 14#include <linux/spinlock.h>
@@ -41,18 +39,21 @@
41 39
42#include <asm/stacktrace.h> 40#include <asm/stacktrace.h>
43#include <asm/processor.h> 41#include <asm/processor.h>
42#include <asm/kmemcheck.h>
44#include <asm/debugreg.h> 43#include <asm/debugreg.h>
45#include <asm/atomic.h> 44#include <asm/atomic.h>
46#include <asm/system.h> 45#include <asm/system.h>
47#include <asm/unwind.h> 46#include <asm/unwind.h>
47#include <asm/traps.h>
48#include <asm/desc.h> 48#include <asm/desc.h>
49#include <asm/i387.h> 49#include <asm/i387.h>
50
51#include <mach_traps.h>
52
50#include <asm/pgalloc.h> 53#include <asm/pgalloc.h>
51#include <asm/proto.h> 54#include <asm/proto.h>
52#include <asm/pda.h> 55#include <asm/pda.h>
53#include <asm/traps.h>
54 56
55#include <mach_traps.h>
56 57
57static int ignore_nmis; 58static int ignore_nmis;
58 59
@@ -73,8 +74,6 @@ static inline void preempt_conditional_cli(struct pt_regs *regs)
73{ 74{
74 if (regs->flags & X86_EFLAGS_IF) 75 if (regs->flags & X86_EFLAGS_IF)
75 local_irq_disable(); 76 local_irq_disable();
76 /* Make sure to not schedule here because we could be running
77 on an exception stack. */
78 dec_preempt_count(); 77 dec_preempt_count();
79} 78}
80 79
@@ -228,9 +227,12 @@ gp_in_kernel:
228static notrace __kprobes void 227static notrace __kprobes void
229mem_parity_error(unsigned char reason, struct pt_regs *regs) 228mem_parity_error(unsigned char reason, struct pt_regs *regs)
230{ 229{
231 printk(KERN_EMERG "Uhhuh. NMI received for unknown reason %02x.\n", 230 printk(KERN_EMERG
232 reason); 231 "Uhhuh. NMI received for unknown reason %02x on CPU %d.\n",
233 printk(KERN_EMERG "You have some hardware problem, likely on the PCI bus.\n"); 232 reason, smp_processor_id());
233
234 printk(KERN_EMERG
235 "You have some hardware problem, likely on the PCI bus.\n");
234 236
235#if defined(CONFIG_EDAC) 237#if defined(CONFIG_EDAC)
236 if (edac_handler_set()) { 238 if (edac_handler_set()) {
@@ -275,19 +277,18 @@ unknown_nmi_error(unsigned char reason, struct pt_regs *regs)
275 if (notify_die(DIE_NMIUNKNOWN, "nmi", regs, reason, 2, SIGINT) == 277 if (notify_die(DIE_NMIUNKNOWN, "nmi", regs, reason, 2, SIGINT) ==
276 NOTIFY_STOP) 278 NOTIFY_STOP)
277 return; 279 return;
278 printk(KERN_EMERG "Uhhuh. NMI received for unknown reason %02x.\n", 280 printk(KERN_EMERG
279 reason); 281 "Uhhuh. NMI received for unknown reason %02x on CPU %d.\n",
280 printk(KERN_EMERG "Do you have a strange power saving mode enabled?\n"); 282 reason, smp_processor_id());
281 283
284 printk(KERN_EMERG "Do you have a strange power saving mode enabled?\n");
282 if (panic_on_unrecovered_nmi) 285 if (panic_on_unrecovered_nmi)
283 panic("NMI: Not continuing"); 286 panic("NMI: Not continuing");
284 287
285 printk(KERN_EMERG "Dazed and confused, but trying to continue\n"); 288 printk(KERN_EMERG "Dazed and confused, but trying to continue\n");
286} 289}
287 290
288/* Runs on IST stack. This code must keep interrupts off all the time. 291static notrace __kprobes void default_do_nmi(struct pt_regs *regs)
289 Nested NMIs are prevented by the CPU. */
290asmlinkage notrace __kprobes void default_do_nmi(struct pt_regs *regs)
291{ 292{
292 unsigned char reason = 0; 293 unsigned char reason = 0;
293 int cpu; 294 int cpu;
@@ -348,7 +349,7 @@ void restart_nmi(void)
348 acpi_nmi_enable(); 349 acpi_nmi_enable();
349} 350}
350 351
351/* runs on IST stack. */ 352/* May run on IST stack. */
352dotraplinkage void __kprobes do_int3(struct pt_regs *regs, long error_code) 353dotraplinkage void __kprobes do_int3(struct pt_regs *regs, long error_code)
353{ 354{
354 if (notify_die(DIE_INT3, "int3", regs, error_code, 3, SIGTRAP) 355 if (notify_die(DIE_INT3, "int3", regs, error_code, 3, SIGTRAP)
@@ -381,7 +382,30 @@ asmlinkage __kprobes struct pt_regs *sync_regs(struct pt_regs *eregs)
381 return regs; 382 return regs;
382} 383}
383 384
384/* runs on IST stack. */ 385/*
386 * Our handling of the processor debug registers is non-trivial.
387 * We do not clear them on entry and exit from the kernel. Therefore
388 * it is possible to get a watchpoint trap here from inside the kernel.
389 * However, the code in ./ptrace.c has ensured that the user can
390 * only set watchpoints on userspace addresses. Therefore the in-kernel
391 * watchpoint trap can only occur in code which is reading/writing
392 * from user space. Such code must not hold kernel locks (since it
393 * can equally take a page fault), therefore it is safe to call
394 * force_sig_info even though that claims and releases locks.
395 *
396 * Code in ./signal.c ensures that the debug control register
397 * is restored before we deliver any signal, and therefore that
398 * user code runs with the correct debug control register even though
399 * we clear it here.
400 *
401 * Being careful here means that we don't have to be as careful in a
402 * lot of more complicated places (task switching can be a bit lazy
403 * about restoring all the debug state, and ptrace doesn't have to
404 * find every occurrence of the TF bit that could be saved away even
405 * by user code)
406 *
407 * May run on IST stack.
408 */
385dotraplinkage void __kprobes do_debug(struct pt_regs *regs, long error_code) 409dotraplinkage void __kprobes do_debug(struct pt_regs *regs, long error_code)
386{ 410{
387 struct task_struct *tsk = current; 411 struct task_struct *tsk = current;
@@ -525,11 +549,6 @@ dotraplinkage void do_coprocessor_error(struct pt_regs *regs, long error_code)
525 math_error((void __user *)regs->ip); 549 math_error((void __user *)regs->ip);
526} 550}
527 551
528asmlinkage void bad_intr(void)
529{
530 printk("bad interrupt");
531}
532
533static void simd_math_error(void __user *ip) 552static void simd_math_error(void __user *ip)
534{ 553{
535 struct task_struct *task; 554 struct task_struct *task;