diff options
Diffstat (limited to 'arch/x86/kernel/traps.c')
-rw-r--r-- | arch/x86/kernel/traps.c | 47 |
1 files changed, 26 insertions, 21 deletions
diff --git a/arch/x86/kernel/traps.c b/arch/x86/kernel/traps.c index 141907ab6e2..c9a666cdd3d 100644 --- a/arch/x86/kernel/traps.c +++ b/arch/x86/kernel/traps.c | |||
@@ -20,7 +20,6 @@ | |||
20 | #include <linux/module.h> | 20 | #include <linux/module.h> |
21 | #include <linux/ptrace.h> | 21 | #include <linux/ptrace.h> |
22 | #include <linux/string.h> | 22 | #include <linux/string.h> |
23 | #include <linux/unwind.h> | ||
24 | #include <linux/delay.h> | 23 | #include <linux/delay.h> |
25 | #include <linux/errno.h> | 24 | #include <linux/errno.h> |
26 | #include <linux/kexec.h> | 25 | #include <linux/kexec.h> |
@@ -51,7 +50,6 @@ | |||
51 | #include <asm/debugreg.h> | 50 | #include <asm/debugreg.h> |
52 | #include <asm/atomic.h> | 51 | #include <asm/atomic.h> |
53 | #include <asm/system.h> | 52 | #include <asm/system.h> |
54 | #include <asm/unwind.h> | ||
55 | #include <asm/traps.h> | 53 | #include <asm/traps.h> |
56 | #include <asm/desc.h> | 54 | #include <asm/desc.h> |
57 | #include <asm/i387.h> | 55 | #include <asm/i387.h> |
@@ -72,9 +70,6 @@ | |||
72 | 70 | ||
73 | #include "cpu/mcheck/mce.h" | 71 | #include "cpu/mcheck/mce.h" |
74 | 72 | ||
75 | DECLARE_BITMAP(used_vectors, NR_VECTORS); | ||
76 | EXPORT_SYMBOL_GPL(used_vectors); | ||
77 | |||
78 | asmlinkage int system_call(void); | 73 | asmlinkage int system_call(void); |
79 | 74 | ||
80 | /* Do we ignore FPU interrupts ? */ | 75 | /* Do we ignore FPU interrupts ? */ |
@@ -89,6 +84,9 @@ gate_desc idt_table[256] | |||
89 | __attribute__((__section__(".data.idt"))) = { { { { 0, 0 } } }, }; | 84 | __attribute__((__section__(".data.idt"))) = { { { { 0, 0 } } }, }; |
90 | #endif | 85 | #endif |
91 | 86 | ||
87 | DECLARE_BITMAP(used_vectors, NR_VECTORS); | ||
88 | EXPORT_SYMBOL_GPL(used_vectors); | ||
89 | |||
92 | static int ignore_nmis; | 90 | static int ignore_nmis; |
93 | 91 | ||
94 | static inline void conditional_sti(struct pt_regs *regs) | 92 | static inline void conditional_sti(struct pt_regs *regs) |
@@ -292,8 +290,10 @@ dotraplinkage void do_double_fault(struct pt_regs *regs, long error_code) | |||
292 | tsk->thread.error_code = error_code; | 290 | tsk->thread.error_code = error_code; |
293 | tsk->thread.trap_no = 8; | 291 | tsk->thread.trap_no = 8; |
294 | 292 | ||
295 | /* This is always a kernel trap and never fixable (and thus must | 293 | /* |
296 | never return). */ | 294 | * This is always a kernel trap and never fixable (and thus must |
295 | * never return). | ||
296 | */ | ||
297 | for (;;) | 297 | for (;;) |
298 | die(str, regs, error_code); | 298 | die(str, regs, error_code); |
299 | } | 299 | } |
@@ -520,9 +520,11 @@ dotraplinkage void __kprobes do_int3(struct pt_regs *regs, long error_code) | |||
520 | } | 520 | } |
521 | 521 | ||
522 | #ifdef CONFIG_X86_64 | 522 | #ifdef CONFIG_X86_64 |
523 | /* Help handler running on IST stack to switch back to user stack | 523 | /* |
524 | for scheduling or signal handling. The actual stack switch is done in | 524 | * Help handler running on IST stack to switch back to user stack |
525 | entry.S */ | 525 | * for scheduling or signal handling. The actual stack switch is done in |
526 | * entry.S | ||
527 | */ | ||
526 | asmlinkage __kprobes struct pt_regs *sync_regs(struct pt_regs *eregs) | 528 | asmlinkage __kprobes struct pt_regs *sync_regs(struct pt_regs *eregs) |
527 | { | 529 | { |
528 | struct pt_regs *regs = eregs; | 530 | struct pt_regs *regs = eregs; |
@@ -532,8 +534,10 @@ asmlinkage __kprobes struct pt_regs *sync_regs(struct pt_regs *eregs) | |||
532 | /* Exception from user space */ | 534 | /* Exception from user space */ |
533 | else if (user_mode(eregs)) | 535 | else if (user_mode(eregs)) |
534 | regs = task_pt_regs(current); | 536 | regs = task_pt_regs(current); |
535 | /* Exception from kernel and interrupts are enabled. Move to | 537 | /* |
536 | kernel process stack. */ | 538 | * Exception from kernel and interrupts are enabled. Move to |
539 | * kernel process stack. | ||
540 | */ | ||
537 | else if (eregs->flags & X86_EFLAGS_IF) | 541 | else if (eregs->flags & X86_EFLAGS_IF) |
538 | regs = (struct pt_regs *)(eregs->sp -= sizeof(struct pt_regs)); | 542 | regs = (struct pt_regs *)(eregs->sp -= sizeof(struct pt_regs)); |
539 | if (eregs != regs) | 543 | if (eregs != regs) |
@@ -685,12 +689,7 @@ void math_error(void __user *ip) | |||
685 | cwd = get_fpu_cwd(task); | 689 | cwd = get_fpu_cwd(task); |
686 | swd = get_fpu_swd(task); | 690 | swd = get_fpu_swd(task); |
687 | 691 | ||
688 | err = swd & ~cwd & 0x3f; | 692 | err = swd & ~cwd; |
689 | |||
690 | #ifdef CONFIG_X86_32 | ||
691 | if (!err) | ||
692 | return; | ||
693 | #endif | ||
694 | 693 | ||
695 | if (err & 0x001) { /* Invalid op */ | 694 | if (err & 0x001) { /* Invalid op */ |
696 | /* | 695 | /* |
@@ -708,7 +707,11 @@ void math_error(void __user *ip) | |||
708 | } else if (err & 0x020) { /* Precision */ | 707 | } else if (err & 0x020) { /* Precision */ |
709 | info.si_code = FPE_FLTRES; | 708 | info.si_code = FPE_FLTRES; |
710 | } else { | 709 | } else { |
711 | info.si_code = __SI_FAULT|SI_KERNEL; /* WTF? */ | 710 | /* |
711 | * If we're using IRQ 13, or supposedly even some trap 16 | ||
712 | * implementations, it's possible we get a spurious trap... | ||
713 | */ | ||
714 | return; /* Spurious trap, no error */ | ||
712 | } | 715 | } |
713 | force_sig_info(SIGFPE, &info, task); | 716 | force_sig_info(SIGFPE, &info, task); |
714 | } | 717 | } |
@@ -941,9 +944,7 @@ dotraplinkage void do_iret_error(struct pt_regs *regs, long error_code) | |||
941 | 944 | ||
942 | void __init trap_init(void) | 945 | void __init trap_init(void) |
943 | { | 946 | { |
944 | #ifdef CONFIG_X86_32 | ||
945 | int i; | 947 | int i; |
946 | #endif | ||
947 | 948 | ||
948 | #ifdef CONFIG_EISA | 949 | #ifdef CONFIG_EISA |
949 | void __iomem *p = early_ioremap(0x0FFFD9, 4); | 950 | void __iomem *p = early_ioremap(0x0FFFD9, 4); |
@@ -1000,11 +1001,15 @@ void __init trap_init(void) | |||
1000 | } | 1001 | } |
1001 | 1002 | ||
1002 | set_system_trap_gate(SYSCALL_VECTOR, &system_call); | 1003 | set_system_trap_gate(SYSCALL_VECTOR, &system_call); |
1004 | #endif | ||
1003 | 1005 | ||
1004 | /* Reserve all the builtin and the syscall vector: */ | 1006 | /* Reserve all the builtin and the syscall vector: */ |
1005 | for (i = 0; i < FIRST_EXTERNAL_VECTOR; i++) | 1007 | for (i = 0; i < FIRST_EXTERNAL_VECTOR; i++) |
1006 | set_bit(i, used_vectors); | 1008 | set_bit(i, used_vectors); |
1007 | 1009 | ||
1010 | #ifdef CONFIG_X86_64 | ||
1011 | set_bit(IA32_SYSCALL_VECTOR, used_vectors); | ||
1012 | #else | ||
1008 | set_bit(SYSCALL_VECTOR, used_vectors); | 1013 | set_bit(SYSCALL_VECTOR, used_vectors); |
1009 | #endif | 1014 | #endif |
1010 | /* | 1015 | /* |