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