diff options
author | Ingo Molnar <mingo@elte.hu> | 2008-09-06 08:53:20 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2008-09-06 08:53:20 -0400 |
commit | f12e6a451aad671a724e61abce2b8b323f209355 (patch) | |
tree | e4969282d07f7682099291e59545744b3bb5dcac /arch/x86/kernel/traps_64.c | |
parent | 046fd53773cd87125f799b00422e487bf1428d38 (diff) | |
parent | dc44e65943169de2d1a1b494876f48a65a9737f1 (diff) |
Merge branch 'x86/cleanups' into x86/signal
Conflicts:
arch/x86/kernel/signal_64.c
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'arch/x86/kernel/traps_64.c')
-rw-r--r-- | arch/x86/kernel/traps_64.c | 61 |
1 files changed, 34 insertions, 27 deletions
diff --git a/arch/x86/kernel/traps_64.c b/arch/x86/kernel/traps_64.c index 38eb76156a47..56d6f1147785 100644 --- a/arch/x86/kernel/traps_64.c +++ b/arch/x86/kernel/traps_64.c | |||
@@ -32,6 +32,8 @@ | |||
32 | #include <linux/bug.h> | 32 | #include <linux/bug.h> |
33 | #include <linux/nmi.h> | 33 | #include <linux/nmi.h> |
34 | #include <linux/mm.h> | 34 | #include <linux/mm.h> |
35 | #include <linux/smp.h> | ||
36 | #include <linux/io.h> | ||
35 | 37 | ||
36 | #if defined(CONFIG_EDAC) | 38 | #if defined(CONFIG_EDAC) |
37 | #include <linux/edac.h> | 39 | #include <linux/edac.h> |
@@ -45,9 +47,6 @@ | |||
45 | #include <asm/unwind.h> | 47 | #include <asm/unwind.h> |
46 | #include <asm/desc.h> | 48 | #include <asm/desc.h> |
47 | #include <asm/i387.h> | 49 | #include <asm/i387.h> |
48 | #include <asm/nmi.h> | ||
49 | #include <asm/smp.h> | ||
50 | #include <asm/io.h> | ||
51 | #include <asm/pgalloc.h> | 50 | #include <asm/pgalloc.h> |
52 | #include <asm/proto.h> | 51 | #include <asm/proto.h> |
53 | #include <asm/pda.h> | 52 | #include <asm/pda.h> |
@@ -85,7 +84,8 @@ static inline void preempt_conditional_cli(struct pt_regs *regs) | |||
85 | 84 | ||
86 | void printk_address(unsigned long address, int reliable) | 85 | void printk_address(unsigned long address, int reliable) |
87 | { | 86 | { |
88 | printk(" [<%016lx>] %s%pS\n", address, reliable ? "": "? ", (void *) address); | 87 | printk(" [<%016lx>] %s%pS\n", |
88 | address, reliable ? "" : "? ", (void *) address); | ||
89 | } | 89 | } |
90 | 90 | ||
91 | static unsigned long *in_exception_stack(unsigned cpu, unsigned long stack, | 91 | static unsigned long *in_exception_stack(unsigned cpu, unsigned long stack, |
@@ -98,7 +98,8 @@ static unsigned long *in_exception_stack(unsigned cpu, unsigned long stack, | |||
98 | [STACKFAULT_STACK - 1] = "#SS", | 98 | [STACKFAULT_STACK - 1] = "#SS", |
99 | [MCE_STACK - 1] = "#MC", | 99 | [MCE_STACK - 1] = "#MC", |
100 | #if DEBUG_STKSZ > EXCEPTION_STKSZ | 100 | #if DEBUG_STKSZ > EXCEPTION_STKSZ |
101 | [N_EXCEPTION_STACKS ... N_EXCEPTION_STACKS + DEBUG_STKSZ / EXCEPTION_STKSZ - 2] = "#DB[?]" | 101 | [N_EXCEPTION_STACKS ... |
102 | N_EXCEPTION_STACKS + DEBUG_STKSZ / EXCEPTION_STKSZ - 2] = "#DB[?]" | ||
102 | #endif | 103 | #endif |
103 | }; | 104 | }; |
104 | unsigned k; | 105 | unsigned k; |
@@ -163,7 +164,7 @@ static unsigned long *in_exception_stack(unsigned cpu, unsigned long stack, | |||
163 | } | 164 | } |
164 | 165 | ||
165 | /* | 166 | /* |
166 | * x86-64 can have up to three kernel stacks: | 167 | * x86-64 can have up to three kernel stacks: |
167 | * process stack | 168 | * process stack |
168 | * interrupt stack | 169 | * interrupt stack |
169 | * severe exception (double fault, nmi, stack fault, debug, mce) hardware stack | 170 | * severe exception (double fault, nmi, stack fault, debug, mce) hardware stack |
@@ -219,7 +220,7 @@ void dump_trace(struct task_struct *task, struct pt_regs *regs, | |||
219 | const struct stacktrace_ops *ops, void *data) | 220 | const struct stacktrace_ops *ops, void *data) |
220 | { | 221 | { |
221 | const unsigned cpu = get_cpu(); | 222 | const unsigned cpu = get_cpu(); |
222 | unsigned long *irqstack_end = (unsigned long*)cpu_pda(cpu)->irqstackptr; | 223 | unsigned long *irqstack_end = (unsigned long *)cpu_pda(cpu)->irqstackptr; |
223 | unsigned used = 0; | 224 | unsigned used = 0; |
224 | struct thread_info *tinfo; | 225 | struct thread_info *tinfo; |
225 | 226 | ||
@@ -237,7 +238,7 @@ void dump_trace(struct task_struct *task, struct pt_regs *regs, | |||
237 | if (!bp) { | 238 | if (!bp) { |
238 | if (task == current) { | 239 | if (task == current) { |
239 | /* Grab bp right from our regs */ | 240 | /* Grab bp right from our regs */ |
240 | asm("movq %%rbp, %0" : "=r" (bp) :); | 241 | asm("movq %%rbp, %0" : "=r" (bp) : ); |
241 | } else { | 242 | } else { |
242 | /* bp is the last reg pushed by switch_to */ | 243 | /* bp is the last reg pushed by switch_to */ |
243 | bp = *(unsigned long *) task->thread.sp; | 244 | bp = *(unsigned long *) task->thread.sp; |
@@ -357,11 +358,15 @@ show_stack_log_lvl(struct task_struct *task, struct pt_regs *regs, | |||
357 | unsigned long *stack; | 358 | unsigned long *stack; |
358 | int i; | 359 | int i; |
359 | const int cpu = smp_processor_id(); | 360 | const int cpu = smp_processor_id(); |
360 | unsigned long *irqstack_end = (unsigned long *) (cpu_pda(cpu)->irqstackptr); | 361 | unsigned long *irqstack_end = |
361 | unsigned long *irqstack = (unsigned long *) (cpu_pda(cpu)->irqstackptr - IRQSTACKSIZE); | 362 | (unsigned long *) (cpu_pda(cpu)->irqstackptr); |
363 | unsigned long *irqstack = | ||
364 | (unsigned long *) (cpu_pda(cpu)->irqstackptr - IRQSTACKSIZE); | ||
362 | 365 | ||
363 | // debugging aid: "show_stack(NULL, NULL);" prints the | 366 | /* |
364 | // back trace for this cpu. | 367 | * debugging aid: "show_stack(NULL, NULL);" prints the |
368 | * back trace for this cpu. | ||
369 | */ | ||
365 | 370 | ||
366 | if (sp == NULL) { | 371 | if (sp == NULL) { |
367 | if (task) | 372 | if (task) |
@@ -404,7 +409,7 @@ void dump_stack(void) | |||
404 | 409 | ||
405 | #ifdef CONFIG_FRAME_POINTER | 410 | #ifdef CONFIG_FRAME_POINTER |
406 | if (!bp) | 411 | if (!bp) |
407 | asm("movq %%rbp, %0" : "=r" (bp):); | 412 | asm("movq %%rbp, %0" : "=r" (bp) : ); |
408 | #endif | 413 | #endif |
409 | 414 | ||
410 | printk("Pid: %d, comm: %.20s %s %s %.*s\n", | 415 | printk("Pid: %d, comm: %.20s %s %s %.*s\n", |
@@ -414,7 +419,6 @@ void dump_stack(void) | |||
414 | init_utsname()->version); | 419 | init_utsname()->version); |
415 | show_trace(NULL, NULL, &stack, bp); | 420 | show_trace(NULL, NULL, &stack, bp); |
416 | } | 421 | } |
417 | |||
418 | EXPORT_SYMBOL(dump_stack); | 422 | EXPORT_SYMBOL(dump_stack); |
419 | 423 | ||
420 | void show_registers(struct pt_regs *regs) | 424 | void show_registers(struct pt_regs *regs) |
@@ -493,7 +497,7 @@ unsigned __kprobes long oops_begin(void) | |||
493 | raw_local_irq_save(flags); | 497 | raw_local_irq_save(flags); |
494 | cpu = smp_processor_id(); | 498 | cpu = smp_processor_id(); |
495 | if (!__raw_spin_trylock(&die_lock)) { | 499 | if (!__raw_spin_trylock(&die_lock)) { |
496 | if (cpu == die_owner) | 500 | if (cpu == die_owner) |
497 | /* nested oops. should stop eventually */; | 501 | /* nested oops. should stop eventually */; |
498 | else | 502 | else |
499 | __raw_spin_lock(&die_lock); | 503 | __raw_spin_lock(&die_lock); |
@@ -638,7 +642,7 @@ kernel_trap: | |||
638 | } | 642 | } |
639 | 643 | ||
640 | #define DO_ERROR(trapnr, signr, str, name) \ | 644 | #define DO_ERROR(trapnr, signr, str, name) \ |
641 | asmlinkage void do_##name(struct pt_regs * regs, long error_code) \ | 645 | asmlinkage void do_##name(struct pt_regs *regs, long error_code) \ |
642 | { \ | 646 | { \ |
643 | if (notify_die(DIE_TRAP, str, regs, error_code, trapnr, signr) \ | 647 | if (notify_die(DIE_TRAP, str, regs, error_code, trapnr, signr) \ |
644 | == NOTIFY_STOP) \ | 648 | == NOTIFY_STOP) \ |
@@ -648,7 +652,7 @@ asmlinkage void do_##name(struct pt_regs * regs, long error_code) \ | |||
648 | } | 652 | } |
649 | 653 | ||
650 | #define DO_ERROR_INFO(trapnr, signr, str, name, sicode, siaddr) \ | 654 | #define DO_ERROR_INFO(trapnr, signr, str, name, sicode, siaddr) \ |
651 | asmlinkage void do_##name(struct pt_regs * regs, long error_code) \ | 655 | asmlinkage void do_##name(struct pt_regs *regs, long error_code) \ |
652 | { \ | 656 | { \ |
653 | siginfo_t info; \ | 657 | siginfo_t info; \ |
654 | info.si_signo = signr; \ | 658 | info.si_signo = signr; \ |
@@ -683,7 +687,7 @@ asmlinkage void do_stack_segment(struct pt_regs *regs, long error_code) | |||
683 | preempt_conditional_cli(regs); | 687 | preempt_conditional_cli(regs); |
684 | } | 688 | } |
685 | 689 | ||
686 | asmlinkage void do_double_fault(struct pt_regs * regs, long error_code) | 690 | asmlinkage void do_double_fault(struct pt_regs *regs, long error_code) |
687 | { | 691 | { |
688 | static const char str[] = "double fault"; | 692 | static const char str[] = "double fault"; |
689 | struct task_struct *tsk = current; | 693 | struct task_struct *tsk = current; |
@@ -778,9 +782,10 @@ io_check_error(unsigned char reason, struct pt_regs *regs) | |||
778 | } | 782 | } |
779 | 783 | ||
780 | static notrace __kprobes void | 784 | static notrace __kprobes void |
781 | unknown_nmi_error(unsigned char reason, struct pt_regs * regs) | 785 | unknown_nmi_error(unsigned char reason, struct pt_regs *regs) |
782 | { | 786 | { |
783 | if (notify_die(DIE_NMIUNKNOWN, "nmi", regs, reason, 2, SIGINT) == NOTIFY_STOP) | 787 | if (notify_die(DIE_NMIUNKNOWN, "nmi", regs, reason, 2, SIGINT) == |
788 | NOTIFY_STOP) | ||
784 | return; | 789 | return; |
785 | printk(KERN_EMERG "Uhhuh. NMI received for unknown reason %02x.\n", | 790 | printk(KERN_EMERG "Uhhuh. NMI received for unknown reason %02x.\n", |
786 | reason); | 791 | reason); |
@@ -882,7 +887,7 @@ asmlinkage __kprobes struct pt_regs *sync_regs(struct pt_regs *eregs) | |||
882 | else if (user_mode(eregs)) | 887 | else if (user_mode(eregs)) |
883 | regs = task_pt_regs(current); | 888 | regs = task_pt_regs(current); |
884 | /* Exception from kernel and interrupts are enabled. Move to | 889 | /* Exception from kernel and interrupts are enabled. Move to |
885 | kernel process stack. */ | 890 | kernel process stack. */ |
886 | else if (eregs->flags & X86_EFLAGS_IF) | 891 | else if (eregs->flags & X86_EFLAGS_IF) |
887 | regs = (struct pt_regs *)(eregs->sp -= sizeof(struct pt_regs)); | 892 | regs = (struct pt_regs *)(eregs->sp -= sizeof(struct pt_regs)); |
888 | if (eregs != regs) | 893 | if (eregs != regs) |
@@ -891,7 +896,7 @@ asmlinkage __kprobes struct pt_regs *sync_regs(struct pt_regs *eregs) | |||
891 | } | 896 | } |
892 | 897 | ||
893 | /* runs on IST stack. */ | 898 | /* runs on IST stack. */ |
894 | asmlinkage void __kprobes do_debug(struct pt_regs * regs, | 899 | asmlinkage void __kprobes do_debug(struct pt_regs *regs, |
895 | unsigned long error_code) | 900 | unsigned long error_code) |
896 | { | 901 | { |
897 | struct task_struct *tsk = current; | 902 | struct task_struct *tsk = current; |
@@ -1035,7 +1040,7 @@ asmlinkage void do_coprocessor_error(struct pt_regs *regs) | |||
1035 | 1040 | ||
1036 | asmlinkage void bad_intr(void) | 1041 | asmlinkage void bad_intr(void) |
1037 | { | 1042 | { |
1038 | printk("bad interrupt"); | 1043 | printk("bad interrupt"); |
1039 | } | 1044 | } |
1040 | 1045 | ||
1041 | asmlinkage void do_simd_coprocessor_error(struct pt_regs *regs) | 1046 | asmlinkage void do_simd_coprocessor_error(struct pt_regs *regs) |
@@ -1047,7 +1052,7 @@ asmlinkage void do_simd_coprocessor_error(struct pt_regs *regs) | |||
1047 | 1052 | ||
1048 | conditional_sti(regs); | 1053 | conditional_sti(regs); |
1049 | if (!user_mode(regs) && | 1054 | if (!user_mode(regs) && |
1050 | kernel_math_error(regs, "kernel simd math error", 19)) | 1055 | kernel_math_error(regs, "kernel simd math error", 19)) |
1051 | return; | 1056 | return; |
1052 | 1057 | ||
1053 | /* | 1058 | /* |
@@ -1092,7 +1097,7 @@ asmlinkage void do_simd_coprocessor_error(struct pt_regs *regs) | |||
1092 | force_sig_info(SIGFPE, &info, task); | 1097 | force_sig_info(SIGFPE, &info, task); |
1093 | } | 1098 | } |
1094 | 1099 | ||
1095 | asmlinkage void do_spurious_interrupt_bug(struct pt_regs * regs) | 1100 | asmlinkage void do_spurious_interrupt_bug(struct pt_regs *regs) |
1096 | { | 1101 | { |
1097 | } | 1102 | } |
1098 | 1103 | ||
@@ -1149,8 +1154,10 @@ void __init trap_init(void) | |||
1149 | set_intr_gate(0, ÷_error); | 1154 | set_intr_gate(0, ÷_error); |
1150 | set_intr_gate_ist(1, &debug, DEBUG_STACK); | 1155 | set_intr_gate_ist(1, &debug, DEBUG_STACK); |
1151 | set_intr_gate_ist(2, &nmi, NMI_STACK); | 1156 | set_intr_gate_ist(2, &nmi, NMI_STACK); |
1152 | set_system_gate_ist(3, &int3, DEBUG_STACK); /* int3 can be called from all */ | 1157 | /* int3 can be called from all */ |
1153 | set_system_gate(4, &overflow); /* int4 can be called from all */ | 1158 | set_system_gate_ist(3, &int3, DEBUG_STACK); |
1159 | /* int4 can be called from all */ | ||
1160 | set_system_gate(4, &overflow); | ||
1154 | set_intr_gate(5, &bounds); | 1161 | set_intr_gate(5, &bounds); |
1155 | set_intr_gate(6, &invalid_op); | 1162 | set_intr_gate(6, &invalid_op); |
1156 | set_intr_gate(7, &device_not_available); | 1163 | set_intr_gate(7, &device_not_available); |