aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kernel/traps.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86/kernel/traps.c')
-rw-r--r--arch/x86/kernel/traps.c47
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
75DECLARE_BITMAP(used_vectors, NR_VECTORS);
76EXPORT_SYMBOL_GPL(used_vectors);
77
78asmlinkage int system_call(void); 73asmlinkage 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
87DECLARE_BITMAP(used_vectors, NR_VECTORS);
88EXPORT_SYMBOL_GPL(used_vectors);
89
92static int ignore_nmis; 90static int ignore_nmis;
93 91
94static inline void conditional_sti(struct pt_regs *regs) 92static 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 */
526asmlinkage __kprobes struct pt_regs *sync_regs(struct pt_regs *eregs) 528asmlinkage __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
942void __init trap_init(void) 945void __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 /*