diff options
Diffstat (limited to 'arch')
| -rw-r--r-- | arch/x86/ia32/ia32_signal.c | 2 | ||||
| -rw-r--r-- | arch/x86/include/asm/compat.h | 9 | ||||
| -rw-r--r-- | arch/x86/include/asm/processor.h | 2 | ||||
| -rw-r--r-- | arch/x86/include/asm/thread_info.h | 12 | ||||
| -rw-r--r-- | arch/x86/include/asm/traps.h | 25 | ||||
| -rw-r--r-- | arch/x86/kernel/dumpstack.c | 2 | ||||
| -rw-r--r-- | arch/x86/kernel/irqinit.c | 2 | ||||
| -rw-r--r-- | arch/x86/kernel/ptrace.c | 3 | ||||
| -rw-r--r-- | arch/x86/kernel/signal.c | 2 | ||||
| -rw-r--r-- | arch/x86/kernel/traps.c | 133 | ||||
| -rw-r--r-- | arch/x86/kernel/vm86_32.c | 2 | ||||
| -rw-r--r-- | arch/x86/kernel/vsyscall_64.c | 2 | ||||
| -rw-r--r-- | arch/x86/math-emu/fpu_entry.c | 5 | ||||
| -rw-r--r-- | arch/x86/mm/fault.c | 10 |
14 files changed, 124 insertions, 87 deletions
diff --git a/arch/x86/ia32/ia32_signal.c b/arch/x86/ia32/ia32_signal.c index 8ff8e7ddfc55..a69245ba27e3 100644 --- a/arch/x86/ia32/ia32_signal.c +++ b/arch/x86/ia32/ia32_signal.c | |||
| @@ -346,7 +346,7 @@ static int ia32_setup_sigcontext(struct sigcontext_ia32 __user *sc, | |||
| 346 | put_user_ex(regs->dx, &sc->dx); | 346 | put_user_ex(regs->dx, &sc->dx); |
| 347 | put_user_ex(regs->cx, &sc->cx); | 347 | put_user_ex(regs->cx, &sc->cx); |
| 348 | put_user_ex(regs->ax, &sc->ax); | 348 | put_user_ex(regs->ax, &sc->ax); |
| 349 | put_user_ex(current->thread.trap_no, &sc->trapno); | 349 | put_user_ex(current->thread.trap_nr, &sc->trapno); |
| 350 | put_user_ex(current->thread.error_code, &sc->err); | 350 | put_user_ex(current->thread.error_code, &sc->err); |
| 351 | put_user_ex(regs->ip, &sc->ip); | 351 | put_user_ex(regs->ip, &sc->ip); |
| 352 | put_user_ex(regs->cs, (unsigned int __user *)&sc->cs); | 352 | put_user_ex(regs->cs, (unsigned int __user *)&sc->cs); |
diff --git a/arch/x86/include/asm/compat.h b/arch/x86/include/asm/compat.h index 355edc091604..d6805798d6fc 100644 --- a/arch/x86/include/asm/compat.h +++ b/arch/x86/include/asm/compat.h | |||
| @@ -235,15 +235,6 @@ static inline void __user *arch_compat_alloc_user_space(long len) | |||
| 235 | return (void __user *)round_down(sp - len, 16); | 235 | return (void __user *)round_down(sp - len, 16); |
| 236 | } | 236 | } |
| 237 | 237 | ||
| 238 | static inline bool is_ia32_task(void) | ||
| 239 | { | ||
| 240 | #ifdef CONFIG_IA32_EMULATION | ||
| 241 | if (current_thread_info()->status & TS_COMPAT) | ||
| 242 | return true; | ||
| 243 | #endif | ||
| 244 | return false; | ||
| 245 | } | ||
| 246 | |||
| 247 | static inline bool is_x32_task(void) | 238 | static inline bool is_x32_task(void) |
| 248 | { | 239 | { |
| 249 | #ifdef CONFIG_X86_X32_ABI | 240 | #ifdef CONFIG_X86_X32_ABI |
diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h index f302ef6bb200..7284c9a6a0b5 100644 --- a/arch/x86/include/asm/processor.h +++ b/arch/x86/include/asm/processor.h | |||
| @@ -463,7 +463,7 @@ struct thread_struct { | |||
| 463 | unsigned long ptrace_dr7; | 463 | unsigned long ptrace_dr7; |
| 464 | /* Fault info: */ | 464 | /* Fault info: */ |
| 465 | unsigned long cr2; | 465 | unsigned long cr2; |
| 466 | unsigned long trap_no; | 466 | unsigned long trap_nr; |
| 467 | unsigned long error_code; | 467 | unsigned long error_code; |
| 468 | /* floating point and extended processor state */ | 468 | /* floating point and extended processor state */ |
| 469 | struct fpu fpu; | 469 | struct fpu fpu; |
diff --git a/arch/x86/include/asm/thread_info.h b/arch/x86/include/asm/thread_info.h index af1db7e722f4..ad6df8ccd715 100644 --- a/arch/x86/include/asm/thread_info.h +++ b/arch/x86/include/asm/thread_info.h | |||
| @@ -266,6 +266,18 @@ static inline void set_restore_sigmask(void) | |||
| 266 | ti->status |= TS_RESTORE_SIGMASK; | 266 | ti->status |= TS_RESTORE_SIGMASK; |
| 267 | set_bit(TIF_SIGPENDING, (unsigned long *)&ti->flags); | 267 | set_bit(TIF_SIGPENDING, (unsigned long *)&ti->flags); |
| 268 | } | 268 | } |
| 269 | |||
| 270 | static inline bool is_ia32_task(void) | ||
| 271 | { | ||
| 272 | #ifdef CONFIG_X86_32 | ||
| 273 | return true; | ||
| 274 | #endif | ||
| 275 | #ifdef CONFIG_IA32_EMULATION | ||
| 276 | if (current_thread_info()->status & TS_COMPAT) | ||
| 277 | return true; | ||
| 278 | #endif | ||
| 279 | return false; | ||
| 280 | } | ||
| 269 | #endif /* !__ASSEMBLY__ */ | 281 | #endif /* !__ASSEMBLY__ */ |
| 270 | 282 | ||
| 271 | #ifndef __ASSEMBLY__ | 283 | #ifndef __ASSEMBLY__ |
diff --git a/arch/x86/include/asm/traps.h b/arch/x86/include/asm/traps.h index 0012d0902c5f..88eae2aec619 100644 --- a/arch/x86/include/asm/traps.h +++ b/arch/x86/include/asm/traps.h | |||
| @@ -89,4 +89,29 @@ asmlinkage void smp_thermal_interrupt(void); | |||
| 89 | asmlinkage void mce_threshold_interrupt(void); | 89 | asmlinkage void mce_threshold_interrupt(void); |
| 90 | #endif | 90 | #endif |
| 91 | 91 | ||
| 92 | /* Interrupts/Exceptions */ | ||
| 93 | enum { | ||
| 94 | X86_TRAP_DE = 0, /* 0, Divide-by-zero */ | ||
| 95 | X86_TRAP_DB, /* 1, Debug */ | ||
| 96 | X86_TRAP_NMI, /* 2, Non-maskable Interrupt */ | ||
| 97 | X86_TRAP_BP, /* 3, Breakpoint */ | ||
| 98 | X86_TRAP_OF, /* 4, Overflow */ | ||
| 99 | X86_TRAP_BR, /* 5, Bound Range Exceeded */ | ||
| 100 | X86_TRAP_UD, /* 6, Invalid Opcode */ | ||
| 101 | X86_TRAP_NM, /* 7, Device Not Available */ | ||
| 102 | X86_TRAP_DF, /* 8, Double Fault */ | ||
| 103 | X86_TRAP_OLD_MF, /* 9, Coprocessor Segment Overrun */ | ||
| 104 | X86_TRAP_TS, /* 10, Invalid TSS */ | ||
| 105 | X86_TRAP_NP, /* 11, Segment Not Present */ | ||
| 106 | X86_TRAP_SS, /* 12, Stack Segment Fault */ | ||
| 107 | X86_TRAP_GP, /* 13, General Protection Fault */ | ||
| 108 | X86_TRAP_PF, /* 14, Page Fault */ | ||
| 109 | X86_TRAP_SPURIOUS, /* 15, Spurious Interrupt */ | ||
| 110 | X86_TRAP_MF, /* 16, x87 Floating-Point Exception */ | ||
| 111 | X86_TRAP_AC, /* 17, Alignment Check */ | ||
| 112 | X86_TRAP_MC, /* 18, Machine Check */ | ||
| 113 | X86_TRAP_XF, /* 19, SIMD Floating-Point Exception */ | ||
| 114 | X86_TRAP_IRET = 32, /* 32, IRET Exception */ | ||
| 115 | }; | ||
| 116 | |||
| 92 | #endif /* _ASM_X86_TRAPS_H */ | 117 | #endif /* _ASM_X86_TRAPS_H */ |
diff --git a/arch/x86/kernel/dumpstack.c b/arch/x86/kernel/dumpstack.c index 90bf130f09bc..1b81839b6c88 100644 --- a/arch/x86/kernel/dumpstack.c +++ b/arch/x86/kernel/dumpstack.c | |||
| @@ -268,7 +268,7 @@ int __kprobes __die(const char *str, struct pt_regs *regs, long err) | |||
| 268 | #endif | 268 | #endif |
| 269 | printk("\n"); | 269 | printk("\n"); |
| 270 | if (notify_die(DIE_OOPS, str, regs, err, | 270 | if (notify_die(DIE_OOPS, str, regs, err, |
| 271 | current->thread.trap_no, SIGSEGV) == NOTIFY_STOP) | 271 | current->thread.trap_nr, SIGSEGV) == NOTIFY_STOP) |
| 272 | return 1; | 272 | return 1; |
| 273 | 273 | ||
| 274 | show_registers(regs); | 274 | show_registers(regs); |
diff --git a/arch/x86/kernel/irqinit.c b/arch/x86/kernel/irqinit.c index 6d5fc8cfd5d6..252981afd6c4 100644 --- a/arch/x86/kernel/irqinit.c +++ b/arch/x86/kernel/irqinit.c | |||
| @@ -60,7 +60,7 @@ static irqreturn_t math_error_irq(int cpl, void *dev_id) | |||
| 60 | outb(0, 0xF0); | 60 | outb(0, 0xF0); |
| 61 | if (ignore_fpu_irq || !boot_cpu_data.hard_math) | 61 | if (ignore_fpu_irq || !boot_cpu_data.hard_math) |
| 62 | return IRQ_NONE; | 62 | return IRQ_NONE; |
| 63 | math_error(get_irq_regs(), 0, 16); | 63 | math_error(get_irq_regs(), 0, X86_TRAP_MF); |
| 64 | return IRQ_HANDLED; | 64 | return IRQ_HANDLED; |
| 65 | } | 65 | } |
| 66 | 66 | ||
diff --git a/arch/x86/kernel/ptrace.c b/arch/x86/kernel/ptrace.c index 284c35ae60e4..685845cf16e0 100644 --- a/arch/x86/kernel/ptrace.c +++ b/arch/x86/kernel/ptrace.c | |||
| @@ -33,6 +33,7 @@ | |||
| 33 | #include <asm/prctl.h> | 33 | #include <asm/prctl.h> |
| 34 | #include <asm/proto.h> | 34 | #include <asm/proto.h> |
| 35 | #include <asm/hw_breakpoint.h> | 35 | #include <asm/hw_breakpoint.h> |
| 36 | #include <asm/traps.h> | ||
| 36 | 37 | ||
| 37 | #include "tls.h" | 38 | #include "tls.h" |
| 38 | 39 | ||
| @@ -1425,7 +1426,7 @@ static void fill_sigtrap_info(struct task_struct *tsk, | |||
| 1425 | int error_code, int si_code, | 1426 | int error_code, int si_code, |
| 1426 | struct siginfo *info) | 1427 | struct siginfo *info) |
| 1427 | { | 1428 | { |
| 1428 | tsk->thread.trap_no = 1; | 1429 | tsk->thread.trap_nr = X86_TRAP_DB; |
| 1429 | tsk->thread.error_code = error_code; | 1430 | tsk->thread.error_code = error_code; |
| 1430 | 1431 | ||
| 1431 | memset(info, 0, sizeof(*info)); | 1432 | memset(info, 0, sizeof(*info)); |
diff --git a/arch/x86/kernel/signal.c b/arch/x86/kernel/signal.c index 5134e17855f0..115eac431483 100644 --- a/arch/x86/kernel/signal.c +++ b/arch/x86/kernel/signal.c | |||
| @@ -151,7 +151,7 @@ int setup_sigcontext(struct sigcontext __user *sc, void __user *fpstate, | |||
| 151 | put_user_ex(regs->r15, &sc->r15); | 151 | put_user_ex(regs->r15, &sc->r15); |
| 152 | #endif /* CONFIG_X86_64 */ | 152 | #endif /* CONFIG_X86_64 */ |
| 153 | 153 | ||
| 154 | put_user_ex(current->thread.trap_no, &sc->trapno); | 154 | put_user_ex(current->thread.trap_nr, &sc->trapno); |
| 155 | put_user_ex(current->thread.error_code, &sc->err); | 155 | put_user_ex(current->thread.error_code, &sc->err); |
| 156 | put_user_ex(regs->ip, &sc->ip); | 156 | put_user_ex(regs->ip, &sc->ip); |
| 157 | #ifdef CONFIG_X86_32 | 157 | #ifdef CONFIG_X86_32 |
diff --git a/arch/x86/kernel/traps.c b/arch/x86/kernel/traps.c index 860f126ca233..ff9281f16029 100644 --- a/arch/x86/kernel/traps.c +++ b/arch/x86/kernel/traps.c | |||
| @@ -119,7 +119,7 @@ do_trap(int trapnr, int signr, char *str, struct pt_regs *regs, | |||
| 119 | * traps 0, 1, 3, 4, and 5 should be forwarded to vm86. | 119 | * traps 0, 1, 3, 4, and 5 should be forwarded to vm86. |
| 120 | * On nmi (interrupt 2), do_trap should not be called. | 120 | * On nmi (interrupt 2), do_trap should not be called. |
| 121 | */ | 121 | */ |
| 122 | if (trapnr < 6) | 122 | if (trapnr < X86_TRAP_UD) |
| 123 | goto vm86_trap; | 123 | goto vm86_trap; |
| 124 | goto trap_signal; | 124 | goto trap_signal; |
| 125 | } | 125 | } |
| @@ -132,7 +132,7 @@ do_trap(int trapnr, int signr, char *str, struct pt_regs *regs, | |||
| 132 | trap_signal: | 132 | trap_signal: |
| 133 | #endif | 133 | #endif |
| 134 | /* | 134 | /* |
| 135 | * We want error_code and trap_no set for userspace faults and | 135 | * We want error_code and trap_nr set for userspace faults and |
| 136 | * kernelspace faults which result in die(), but not | 136 | * kernelspace faults which result in die(), but not |
| 137 | * kernelspace faults which are fixed up. die() gives the | 137 | * kernelspace faults which are fixed up. die() gives the |
| 138 | * process no chance to handle the signal and notice the | 138 | * process no chance to handle the signal and notice the |
| @@ -141,7 +141,7 @@ trap_signal: | |||
| 141 | * delivered, faults. See also do_general_protection below. | 141 | * delivered, faults. See also do_general_protection below. |
| 142 | */ | 142 | */ |
| 143 | tsk->thread.error_code = error_code; | 143 | tsk->thread.error_code = error_code; |
| 144 | tsk->thread.trap_no = trapnr; | 144 | tsk->thread.trap_nr = trapnr; |
| 145 | 145 | ||
| 146 | #ifdef CONFIG_X86_64 | 146 | #ifdef CONFIG_X86_64 |
| 147 | if (show_unhandled_signals && unhandled_signal(tsk, signr) && | 147 | if (show_unhandled_signals && unhandled_signal(tsk, signr) && |
| @@ -164,7 +164,7 @@ trap_signal: | |||
| 164 | kernel_trap: | 164 | kernel_trap: |
| 165 | if (!fixup_exception(regs)) { | 165 | if (!fixup_exception(regs)) { |
| 166 | tsk->thread.error_code = error_code; | 166 | tsk->thread.error_code = error_code; |
| 167 | tsk->thread.trap_no = trapnr; | 167 | tsk->thread.trap_nr = trapnr; |
| 168 | die(str, regs, error_code); | 168 | die(str, regs, error_code); |
| 169 | } | 169 | } |
| 170 | return; | 170 | return; |
| @@ -203,27 +203,31 @@ dotraplinkage void do_##name(struct pt_regs *regs, long error_code) \ | |||
| 203 | do_trap(trapnr, signr, str, regs, error_code, &info); \ | 203 | do_trap(trapnr, signr, str, regs, error_code, &info); \ |
| 204 | } | 204 | } |
| 205 | 205 | ||
| 206 | DO_ERROR_INFO(0, SIGFPE, "divide error", divide_error, FPE_INTDIV, regs->ip) | 206 | DO_ERROR_INFO(X86_TRAP_DE, SIGFPE, "divide error", divide_error, FPE_INTDIV, |
| 207 | DO_ERROR(4, SIGSEGV, "overflow", overflow) | 207 | regs->ip) |
| 208 | DO_ERROR(5, SIGSEGV, "bounds", bounds) | 208 | DO_ERROR(X86_TRAP_OF, SIGSEGV, "overflow", overflow) |
| 209 | DO_ERROR_INFO(6, SIGILL, "invalid opcode", invalid_op, ILL_ILLOPN, regs->ip) | 209 | DO_ERROR(X86_TRAP_BR, SIGSEGV, "bounds", bounds) |
| 210 | DO_ERROR(9, SIGFPE, "coprocessor segment overrun", coprocessor_segment_overrun) | 210 | DO_ERROR_INFO(X86_TRAP_UD, SIGILL, "invalid opcode", invalid_op, ILL_ILLOPN, |
| 211 | DO_ERROR(10, SIGSEGV, "invalid TSS", invalid_TSS) | 211 | regs->ip) |
| 212 | DO_ERROR(11, SIGBUS, "segment not present", segment_not_present) | 212 | DO_ERROR(X86_TRAP_OLD_MF, SIGFPE, "coprocessor segment overrun", |
| 213 | coprocessor_segment_overrun) | ||
| 214 | DO_ERROR(X86_TRAP_TS, SIGSEGV, "invalid TSS", invalid_TSS) | ||
| 215 | DO_ERROR(X86_TRAP_NP, SIGBUS, "segment not present", segment_not_present) | ||
| 213 | #ifdef CONFIG_X86_32 | 216 | #ifdef CONFIG_X86_32 |
| 214 | DO_ERROR(12, SIGBUS, "stack segment", stack_segment) | 217 | DO_ERROR(X86_TRAP_SS, SIGBUS, "stack segment", stack_segment) |
| 215 | #endif | 218 | #endif |
| 216 | DO_ERROR_INFO(17, SIGBUS, "alignment check", alignment_check, BUS_ADRALN, 0) | 219 | DO_ERROR_INFO(X86_TRAP_AC, SIGBUS, "alignment check", alignment_check, |
| 220 | BUS_ADRALN, 0) | ||
| 217 | 221 | ||
| 218 | #ifdef CONFIG_X86_64 | 222 | #ifdef CONFIG_X86_64 |
| 219 | /* Runs on IST stack */ | 223 | /* Runs on IST stack */ |
| 220 | dotraplinkage void do_stack_segment(struct pt_regs *regs, long error_code) | 224 | dotraplinkage void do_stack_segment(struct pt_regs *regs, long error_code) |
| 221 | { | 225 | { |
| 222 | if (notify_die(DIE_TRAP, "stack segment", regs, error_code, | 226 | if (notify_die(DIE_TRAP, "stack segment", regs, error_code, |
| 223 | 12, SIGBUS) == NOTIFY_STOP) | 227 | X86_TRAP_SS, SIGBUS) == NOTIFY_STOP) |
| 224 | return; | 228 | return; |
| 225 | preempt_conditional_sti(regs); | 229 | preempt_conditional_sti(regs); |
| 226 | do_trap(12, SIGBUS, "stack segment", regs, error_code, NULL); | 230 | do_trap(X86_TRAP_SS, SIGBUS, "stack segment", regs, error_code, NULL); |
| 227 | preempt_conditional_cli(regs); | 231 | preempt_conditional_cli(regs); |
| 228 | } | 232 | } |
| 229 | 233 | ||
| @@ -233,10 +237,10 @@ dotraplinkage void do_double_fault(struct pt_regs *regs, long error_code) | |||
| 233 | struct task_struct *tsk = current; | 237 | struct task_struct *tsk = current; |
| 234 | 238 | ||
| 235 | /* Return not checked because double check cannot be ignored */ | 239 | /* Return not checked because double check cannot be ignored */ |
| 236 | notify_die(DIE_TRAP, str, regs, error_code, 8, SIGSEGV); | 240 | notify_die(DIE_TRAP, str, regs, error_code, X86_TRAP_DF, SIGSEGV); |
| 237 | 241 | ||
| 238 | tsk->thread.error_code = error_code; | 242 | tsk->thread.error_code = error_code; |
| 239 | tsk->thread.trap_no = 8; | 243 | tsk->thread.trap_nr = X86_TRAP_DF; |
| 240 | 244 | ||
| 241 | /* | 245 | /* |
| 242 | * This is always a kernel trap and never fixable (and thus must | 246 | * This is always a kernel trap and never fixable (and thus must |
| @@ -264,7 +268,7 @@ do_general_protection(struct pt_regs *regs, long error_code) | |||
| 264 | goto gp_in_kernel; | 268 | goto gp_in_kernel; |
| 265 | 269 | ||
| 266 | tsk->thread.error_code = error_code; | 270 | tsk->thread.error_code = error_code; |
| 267 | tsk->thread.trap_no = 13; | 271 | tsk->thread.trap_nr = X86_TRAP_GP; |
| 268 | 272 | ||
| 269 | if (show_unhandled_signals && unhandled_signal(tsk, SIGSEGV) && | 273 | if (show_unhandled_signals && unhandled_signal(tsk, SIGSEGV) && |
| 270 | printk_ratelimit()) { | 274 | printk_ratelimit()) { |
| @@ -291,9 +295,9 @@ gp_in_kernel: | |||
| 291 | return; | 295 | return; |
| 292 | 296 | ||
| 293 | tsk->thread.error_code = error_code; | 297 | tsk->thread.error_code = error_code; |
| 294 | tsk->thread.trap_no = 13; | 298 | tsk->thread.trap_nr = X86_TRAP_GP; |
| 295 | if (notify_die(DIE_GPF, "general protection fault", regs, | 299 | if (notify_die(DIE_GPF, "general protection fault", regs, error_code, |
| 296 | error_code, 13, SIGSEGV) == NOTIFY_STOP) | 300 | X86_TRAP_GP, SIGSEGV) == NOTIFY_STOP) |
| 297 | return; | 301 | return; |
| 298 | die("general protection fault", regs, error_code); | 302 | die("general protection fault", regs, error_code); |
| 299 | } | 303 | } |
| @@ -302,13 +306,13 @@ gp_in_kernel: | |||
| 302 | dotraplinkage void __kprobes do_int3(struct pt_regs *regs, long error_code) | 306 | dotraplinkage void __kprobes do_int3(struct pt_regs *regs, long error_code) |
| 303 | { | 307 | { |
| 304 | #ifdef CONFIG_KGDB_LOW_LEVEL_TRAP | 308 | #ifdef CONFIG_KGDB_LOW_LEVEL_TRAP |
| 305 | if (kgdb_ll_trap(DIE_INT3, "int3", regs, error_code, 3, SIGTRAP) | 309 | if (kgdb_ll_trap(DIE_INT3, "int3", regs, error_code, X86_TRAP_BP, |
| 306 | == NOTIFY_STOP) | 310 | SIGTRAP) == NOTIFY_STOP) |
| 307 | return; | 311 | return; |
| 308 | #endif /* CONFIG_KGDB_LOW_LEVEL_TRAP */ | 312 | #endif /* CONFIG_KGDB_LOW_LEVEL_TRAP */ |
| 309 | 313 | ||
| 310 | if (notify_die(DIE_INT3, "int3", regs, error_code, 3, SIGTRAP) | 314 | if (notify_die(DIE_INT3, "int3", regs, error_code, X86_TRAP_BP, |
| 311 | == NOTIFY_STOP) | 315 | SIGTRAP) == NOTIFY_STOP) |
| 312 | return; | 316 | return; |
| 313 | 317 | ||
| 314 | /* | 318 | /* |
| @@ -317,7 +321,7 @@ dotraplinkage void __kprobes do_int3(struct pt_regs *regs, long error_code) | |||
| 317 | */ | 321 | */ |
| 318 | debug_stack_usage_inc(); | 322 | debug_stack_usage_inc(); |
| 319 | preempt_conditional_sti(regs); | 323 | preempt_conditional_sti(regs); |
| 320 | do_trap(3, SIGTRAP, "int3", regs, error_code, NULL); | 324 | do_trap(X86_TRAP_BP, SIGTRAP, "int3", regs, error_code, NULL); |
| 321 | preempt_conditional_cli(regs); | 325 | preempt_conditional_cli(regs); |
| 322 | debug_stack_usage_dec(); | 326 | debug_stack_usage_dec(); |
| 323 | } | 327 | } |
| @@ -422,8 +426,8 @@ dotraplinkage void __kprobes do_debug(struct pt_regs *regs, long error_code) | |||
| 422 | preempt_conditional_sti(regs); | 426 | preempt_conditional_sti(regs); |
| 423 | 427 | ||
| 424 | if (regs->flags & X86_VM_MASK) { | 428 | if (regs->flags & X86_VM_MASK) { |
| 425 | handle_vm86_trap((struct kernel_vm86_regs *) regs, | 429 | handle_vm86_trap((struct kernel_vm86_regs *) regs, error_code, |
| 426 | error_code, 1); | 430 | X86_TRAP_DB); |
| 427 | preempt_conditional_cli(regs); | 431 | preempt_conditional_cli(regs); |
| 428 | debug_stack_usage_dec(); | 432 | debug_stack_usage_dec(); |
| 429 | return; | 433 | return; |
| @@ -460,7 +464,8 @@ void math_error(struct pt_regs *regs, int error_code, int trapnr) | |||
| 460 | struct task_struct *task = current; | 464 | struct task_struct *task = current; |
| 461 | siginfo_t info; | 465 | siginfo_t info; |
| 462 | unsigned short err; | 466 | unsigned short err; |
| 463 | char *str = (trapnr == 16) ? "fpu exception" : "simd exception"; | 467 | char *str = (trapnr == X86_TRAP_MF) ? "fpu exception" : |
| 468 | "simd exception"; | ||
| 464 | 469 | ||
| 465 | if (notify_die(DIE_TRAP, str, regs, error_code, trapnr, SIGFPE) == NOTIFY_STOP) | 470 | if (notify_die(DIE_TRAP, str, regs, error_code, trapnr, SIGFPE) == NOTIFY_STOP) |
| 466 | return; | 471 | return; |
| @@ -470,7 +475,7 @@ void math_error(struct pt_regs *regs, int error_code, int trapnr) | |||
| 470 | { | 475 | { |
| 471 | if (!fixup_exception(regs)) { | 476 | if (!fixup_exception(regs)) { |
| 472 | task->thread.error_code = error_code; | 477 | task->thread.error_code = error_code; |
| 473 | task->thread.trap_no = trapnr; | 478 | task->thread.trap_nr = trapnr; |
| 474 | die(str, regs, error_code); | 479 | die(str, regs, error_code); |
| 475 | } | 480 | } |
| 476 | return; | 481 | return; |
| @@ -480,12 +485,12 @@ void math_error(struct pt_regs *regs, int error_code, int trapnr) | |||
| 480 | * Save the info for the exception handler and clear the error. | 485 | * Save the info for the exception handler and clear the error. |
| 481 | */ | 486 | */ |
| 482 | save_init_fpu(task); | 487 | save_init_fpu(task); |
| 483 | task->thread.trap_no = trapnr; | 488 | task->thread.trap_nr = trapnr; |
| 484 | task->thread.error_code = error_code; | 489 | task->thread.error_code = error_code; |
| 485 | info.si_signo = SIGFPE; | 490 | info.si_signo = SIGFPE; |
| 486 | info.si_errno = 0; | 491 | info.si_errno = 0; |
| 487 | info.si_addr = (void __user *)regs->ip; | 492 | info.si_addr = (void __user *)regs->ip; |
| 488 | if (trapnr == 16) { | 493 | if (trapnr == X86_TRAP_MF) { |
| 489 | unsigned short cwd, swd; | 494 | unsigned short cwd, swd; |
| 490 | /* | 495 | /* |
| 491 | * (~cwd & swd) will mask out exceptions that are not set to unmasked | 496 | * (~cwd & swd) will mask out exceptions that are not set to unmasked |
| @@ -529,10 +534,11 @@ void math_error(struct pt_regs *regs, int error_code, int trapnr) | |||
| 529 | info.si_code = FPE_FLTRES; | 534 | info.si_code = FPE_FLTRES; |
| 530 | } else { | 535 | } else { |
| 531 | /* | 536 | /* |
| 532 | * If we're using IRQ 13, or supposedly even some trap 16 | 537 | * If we're using IRQ 13, or supposedly even some trap |
| 533 | * implementations, it's possible we get a spurious trap... | 538 | * X86_TRAP_MF implementations, it's possible |
| 539 | * we get a spurious trap, which is not an error. | ||
| 534 | */ | 540 | */ |
| 535 | return; /* Spurious trap, no error */ | 541 | return; |
| 536 | } | 542 | } |
| 537 | force_sig_info(SIGFPE, &info, task); | 543 | force_sig_info(SIGFPE, &info, task); |
| 538 | } | 544 | } |
| @@ -543,13 +549,13 @@ dotraplinkage void do_coprocessor_error(struct pt_regs *regs, long error_code) | |||
| 543 | ignore_fpu_irq = 1; | 549 | ignore_fpu_irq = 1; |
| 544 | #endif | 550 | #endif |
| 545 | 551 | ||
| 546 | math_error(regs, error_code, 16); | 552 | math_error(regs, error_code, X86_TRAP_MF); |
| 547 | } | 553 | } |
| 548 | 554 | ||
| 549 | dotraplinkage void | 555 | dotraplinkage void |
| 550 | do_simd_coprocessor_error(struct pt_regs *regs, long error_code) | 556 | do_simd_coprocessor_error(struct pt_regs *regs, long error_code) |
| 551 | { | 557 | { |
| 552 | math_error(regs, error_code, 19); | 558 | math_error(regs, error_code, X86_TRAP_XF); |
| 553 | } | 559 | } |
| 554 | 560 | ||
| 555 | dotraplinkage void | 561 | dotraplinkage void |
| @@ -643,20 +649,21 @@ dotraplinkage void do_iret_error(struct pt_regs *regs, long error_code) | |||
| 643 | info.si_errno = 0; | 649 | info.si_errno = 0; |
| 644 | info.si_code = ILL_BADSTK; | 650 | info.si_code = ILL_BADSTK; |
| 645 | info.si_addr = NULL; | 651 | info.si_addr = NULL; |
| 646 | if (notify_die(DIE_TRAP, "iret exception", | 652 | if (notify_die(DIE_TRAP, "iret exception", regs, error_code, |
| 647 | regs, error_code, 32, SIGILL) == NOTIFY_STOP) | 653 | X86_TRAP_IRET, SIGILL) == NOTIFY_STOP) |
| 648 | return; | 654 | return; |
| 649 | do_trap(32, SIGILL, "iret exception", regs, error_code, &info); | 655 | do_trap(X86_TRAP_IRET, SIGILL, "iret exception", regs, error_code, |
| 656 | &info); | ||
| 650 | } | 657 | } |
| 651 | #endif | 658 | #endif |
| 652 | 659 | ||
| 653 | /* Set of traps needed for early debugging. */ | 660 | /* Set of traps needed for early debugging. */ |
| 654 | void __init early_trap_init(void) | 661 | void __init early_trap_init(void) |
| 655 | { | 662 | { |
| 656 | set_intr_gate_ist(1, &debug, DEBUG_STACK); | 663 | set_intr_gate_ist(X86_TRAP_DB, &debug, DEBUG_STACK); |
| 657 | /* int3 can be called from all */ | 664 | /* int3 can be called from all */ |
| 658 | set_system_intr_gate_ist(3, &int3, DEBUG_STACK); | 665 | set_system_intr_gate_ist(X86_TRAP_BP, &int3, DEBUG_STACK); |
| 659 | set_intr_gate(14, &page_fault); | 666 | set_intr_gate(X86_TRAP_PF, &page_fault); |
| 660 | load_idt(&idt_descr); | 667 | load_idt(&idt_descr); |
| 661 | } | 668 | } |
| 662 | 669 | ||
| @@ -672,30 +679,30 @@ void __init trap_init(void) | |||
| 672 | early_iounmap(p, 4); | 679 | early_iounmap(p, 4); |
| 673 | #endif | 680 | #endif |
| 674 | 681 | ||
| 675 | set_intr_gate(0, ÷_error); | 682 | set_intr_gate(X86_TRAP_DE, ÷_error); |
| 676 | set_intr_gate_ist(2, &nmi, NMI_STACK); | 683 | set_intr_gate_ist(X86_TRAP_NMI, &nmi, NMI_STACK); |
| 677 | /* int4 can be called from all */ | 684 | /* int4 can be called from all */ |
| 678 | set_system_intr_gate(4, &overflow); | 685 | set_system_intr_gate(X86_TRAP_OF, &overflow); |
| 679 | set_intr_gate(5, &bounds); | 686 | set_intr_gate(X86_TRAP_BR, &bounds); |
| 680 | set_intr_gate(6, &invalid_op); | 687 | set_intr_gate(X86_TRAP_UD, &invalid_op); |
| 681 | set_intr_gate(7, &device_not_available); | 688 | set_intr_gate(X86_TRAP_NM, &device_not_available); |
| 682 | #ifdef CONFIG_X86_32 | 689 | #ifdef CONFIG_X86_32 |
| 683 | set_task_gate(8, GDT_ENTRY_DOUBLEFAULT_TSS); | 690 | set_task_gate(X86_TRAP_DF, GDT_ENTRY_DOUBLEFAULT_TSS); |
| 684 | #else | 691 | #else |
| 685 | set_intr_gate_ist(8, &double_fault, DOUBLEFAULT_STACK); | 692 | set_intr_gate_ist(X86_TRAP_DF, &double_fault, DOUBLEFAULT_STACK); |
| 686 | #endif | 693 | #endif |
| 687 | set_intr_gate(9, &coprocessor_segment_overrun); | 694 | set_intr_gate(X86_TRAP_OLD_MF, &coprocessor_segment_overrun); |
| 688 | set_intr_gate(10, &invalid_TSS); | 695 | set_intr_gate(X86_TRAP_TS, &invalid_TSS); |
| 689 | set_intr_gate(11, &segment_not_present); | 696 | set_intr_gate(X86_TRAP_NP, &segment_not_present); |
| 690 | set_intr_gate_ist(12, &stack_segment, STACKFAULT_STACK); | 697 | set_intr_gate_ist(X86_TRAP_SS, &stack_segment, STACKFAULT_STACK); |
| 691 | set_intr_gate(13, &general_protection); | 698 | set_intr_gate(X86_TRAP_GP, &general_protection); |
| 692 | set_intr_gate(15, &spurious_interrupt_bug); | 699 | set_intr_gate(X86_TRAP_SPURIOUS, &spurious_interrupt_bug); |
| 693 | set_intr_gate(16, &coprocessor_error); | 700 | set_intr_gate(X86_TRAP_MF, &coprocessor_error); |
| 694 | set_intr_gate(17, &alignment_check); | 701 | set_intr_gate(X86_TRAP_AC, &alignment_check); |
| 695 | #ifdef CONFIG_X86_MCE | 702 | #ifdef CONFIG_X86_MCE |
| 696 | set_intr_gate_ist(18, &machine_check, MCE_STACK); | 703 | set_intr_gate_ist(X86_TRAP_MC, &machine_check, MCE_STACK); |
| 697 | #endif | 704 | #endif |
| 698 | set_intr_gate(19, &simd_coprocessor_error); | 705 | set_intr_gate(X86_TRAP_XF, &simd_coprocessor_error); |
| 699 | 706 | ||
| 700 | /* Reserve all the builtin and the syscall vector: */ | 707 | /* Reserve all the builtin and the syscall vector: */ |
| 701 | for (i = 0; i < FIRST_EXTERNAL_VECTOR; i++) | 708 | for (i = 0; i < FIRST_EXTERNAL_VECTOR; i++) |
| @@ -720,7 +727,7 @@ void __init trap_init(void) | |||
| 720 | 727 | ||
| 721 | #ifdef CONFIG_X86_64 | 728 | #ifdef CONFIG_X86_64 |
| 722 | memcpy(&nmi_idt_table, &idt_table, IDT_ENTRIES * 16); | 729 | memcpy(&nmi_idt_table, &idt_table, IDT_ENTRIES * 16); |
| 723 | set_nmi_gate(1, &debug); | 730 | set_nmi_gate(X86_TRAP_DB, &debug); |
| 724 | set_nmi_gate(3, &int3); | 731 | set_nmi_gate(X86_TRAP_BP, &int3); |
| 725 | #endif | 732 | #endif |
| 726 | } | 733 | } |
diff --git a/arch/x86/kernel/vm86_32.c b/arch/x86/kernel/vm86_32.c index 328cb37bb827..255f58ae71e8 100644 --- a/arch/x86/kernel/vm86_32.c +++ b/arch/x86/kernel/vm86_32.c | |||
| @@ -569,7 +569,7 @@ int handle_vm86_trap(struct kernel_vm86_regs *regs, long error_code, int trapno) | |||
| 569 | } | 569 | } |
| 570 | if (trapno != 1) | 570 | if (trapno != 1) |
| 571 | return 1; /* we let this handle by the calling routine */ | 571 | return 1; /* we let this handle by the calling routine */ |
| 572 | current->thread.trap_no = trapno; | 572 | current->thread.trap_nr = trapno; |
| 573 | current->thread.error_code = error_code; | 573 | current->thread.error_code = error_code; |
| 574 | force_sig(SIGTRAP, current); | 574 | force_sig(SIGTRAP, current); |
| 575 | return 0; | 575 | return 0; |
diff --git a/arch/x86/kernel/vsyscall_64.c b/arch/x86/kernel/vsyscall_64.c index d5c69860b524..f386dc49f988 100644 --- a/arch/x86/kernel/vsyscall_64.c +++ b/arch/x86/kernel/vsyscall_64.c | |||
| @@ -152,7 +152,7 @@ static bool write_ok_or_segv(unsigned long ptr, size_t size) | |||
| 152 | 152 | ||
| 153 | thread->error_code = 6; /* user fault, no page, write */ | 153 | thread->error_code = 6; /* user fault, no page, write */ |
| 154 | thread->cr2 = ptr; | 154 | thread->cr2 = ptr; |
| 155 | thread->trap_no = 14; | 155 | thread->trap_nr = X86_TRAP_PF; |
| 156 | 156 | ||
| 157 | memset(&info, 0, sizeof(info)); | 157 | memset(&info, 0, sizeof(info)); |
| 158 | info.si_signo = SIGSEGV; | 158 | info.si_signo = SIGSEGV; |
diff --git a/arch/x86/math-emu/fpu_entry.c b/arch/x86/math-emu/fpu_entry.c index 7718541541d4..9b868124128d 100644 --- a/arch/x86/math-emu/fpu_entry.c +++ b/arch/x86/math-emu/fpu_entry.c | |||
| @@ -28,6 +28,7 @@ | |||
| 28 | #include <linux/regset.h> | 28 | #include <linux/regset.h> |
| 29 | 29 | ||
| 30 | #include <asm/uaccess.h> | 30 | #include <asm/uaccess.h> |
| 31 | #include <asm/traps.h> | ||
| 31 | #include <asm/desc.h> | 32 | #include <asm/desc.h> |
| 32 | #include <asm/user.h> | 33 | #include <asm/user.h> |
| 33 | #include <asm/i387.h> | 34 | #include <asm/i387.h> |
| @@ -269,7 +270,7 @@ void math_emulate(struct math_emu_info *info) | |||
| 269 | FPU_EIP = FPU_ORIG_EIP; /* Point to current FPU instruction. */ | 270 | FPU_EIP = FPU_ORIG_EIP; /* Point to current FPU instruction. */ |
| 270 | 271 | ||
| 271 | RE_ENTRANT_CHECK_OFF; | 272 | RE_ENTRANT_CHECK_OFF; |
| 272 | current->thread.trap_no = 16; | 273 | current->thread.trap_nr = X86_TRAP_MF; |
| 273 | current->thread.error_code = 0; | 274 | current->thread.error_code = 0; |
| 274 | send_sig(SIGFPE, current, 1); | 275 | send_sig(SIGFPE, current, 1); |
| 275 | return; | 276 | return; |
| @@ -662,7 +663,7 @@ static int valid_prefix(u_char *Byte, u_char __user **fpu_eip, | |||
| 662 | void math_abort(struct math_emu_info *info, unsigned int signal) | 663 | void math_abort(struct math_emu_info *info, unsigned int signal) |
| 663 | { | 664 | { |
| 664 | FPU_EIP = FPU_ORIG_EIP; | 665 | FPU_EIP = FPU_ORIG_EIP; |
| 665 | current->thread.trap_no = 16; | 666 | current->thread.trap_nr = X86_TRAP_MF; |
| 666 | current->thread.error_code = 0; | 667 | current->thread.error_code = 0; |
| 667 | send_sig(signal, current, 1); | 668 | send_sig(signal, current, 1); |
| 668 | RE_ENTRANT_CHECK_OFF; | 669 | RE_ENTRANT_CHECK_OFF; |
diff --git a/arch/x86/mm/fault.c b/arch/x86/mm/fault.c index f0b4caf85c1a..3ecfd1aaf214 100644 --- a/arch/x86/mm/fault.c +++ b/arch/x86/mm/fault.c | |||
| @@ -615,7 +615,7 @@ pgtable_bad(struct pt_regs *regs, unsigned long error_code, | |||
| 615 | dump_pagetable(address); | 615 | dump_pagetable(address); |
| 616 | 616 | ||
| 617 | tsk->thread.cr2 = address; | 617 | tsk->thread.cr2 = address; |
| 618 | tsk->thread.trap_no = 14; | 618 | tsk->thread.trap_nr = X86_TRAP_PF; |
| 619 | tsk->thread.error_code = error_code; | 619 | tsk->thread.error_code = error_code; |
| 620 | 620 | ||
| 621 | if (__die("Bad pagetable", regs, error_code)) | 621 | if (__die("Bad pagetable", regs, error_code)) |
| @@ -636,7 +636,7 @@ no_context(struct pt_regs *regs, unsigned long error_code, | |||
| 636 | /* Are we prepared to handle this kernel fault? */ | 636 | /* Are we prepared to handle this kernel fault? */ |
| 637 | if (fixup_exception(regs)) { | 637 | if (fixup_exception(regs)) { |
| 638 | if (current_thread_info()->sig_on_uaccess_error && signal) { | 638 | if (current_thread_info()->sig_on_uaccess_error && signal) { |
| 639 | tsk->thread.trap_no = 14; | 639 | tsk->thread.trap_nr = X86_TRAP_PF; |
| 640 | tsk->thread.error_code = error_code | PF_USER; | 640 | tsk->thread.error_code = error_code | PF_USER; |
| 641 | tsk->thread.cr2 = address; | 641 | tsk->thread.cr2 = address; |
| 642 | 642 | ||
| @@ -676,7 +676,7 @@ no_context(struct pt_regs *regs, unsigned long error_code, | |||
| 676 | printk(KERN_EMERG "Thread overran stack, or stack corrupted\n"); | 676 | printk(KERN_EMERG "Thread overran stack, or stack corrupted\n"); |
| 677 | 677 | ||
| 678 | tsk->thread.cr2 = address; | 678 | tsk->thread.cr2 = address; |
| 679 | tsk->thread.trap_no = 14; | 679 | tsk->thread.trap_nr = X86_TRAP_PF; |
| 680 | tsk->thread.error_code = error_code; | 680 | tsk->thread.error_code = error_code; |
| 681 | 681 | ||
| 682 | sig = SIGKILL; | 682 | sig = SIGKILL; |
| @@ -754,7 +754,7 @@ __bad_area_nosemaphore(struct pt_regs *regs, unsigned long error_code, | |||
| 754 | /* Kernel addresses are always protection faults: */ | 754 | /* Kernel addresses are always protection faults: */ |
| 755 | tsk->thread.cr2 = address; | 755 | tsk->thread.cr2 = address; |
| 756 | tsk->thread.error_code = error_code | (address >= TASK_SIZE); | 756 | tsk->thread.error_code = error_code | (address >= TASK_SIZE); |
| 757 | tsk->thread.trap_no = 14; | 757 | tsk->thread.trap_nr = X86_TRAP_PF; |
| 758 | 758 | ||
| 759 | force_sig_info_fault(SIGSEGV, si_code, address, tsk, 0); | 759 | force_sig_info_fault(SIGSEGV, si_code, address, tsk, 0); |
| 760 | 760 | ||
| @@ -838,7 +838,7 @@ do_sigbus(struct pt_regs *regs, unsigned long error_code, unsigned long address, | |||
| 838 | 838 | ||
| 839 | tsk->thread.cr2 = address; | 839 | tsk->thread.cr2 = address; |
| 840 | tsk->thread.error_code = error_code; | 840 | tsk->thread.error_code = error_code; |
| 841 | tsk->thread.trap_no = 14; | 841 | tsk->thread.trap_nr = X86_TRAP_PF; |
| 842 | 842 | ||
| 843 | #ifdef CONFIG_MEMORY_FAILURE | 843 | #ifdef CONFIG_MEMORY_FAILURE |
| 844 | if (fault & (VM_FAULT_HWPOISON|VM_FAULT_HWPOISON_LARGE)) { | 844 | if (fault & (VM_FAULT_HWPOISON|VM_FAULT_HWPOISON_LARGE)) { |
