aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
Diffstat (limited to 'arch')
-rw-r--r--arch/x86/kernel/traps_32.c66
1 files changed, 15 insertions, 51 deletions
diff --git a/arch/x86/kernel/traps_32.c b/arch/x86/kernel/traps_32.c
index 1bd7960b1357..8fa8485b49ce 100644
--- a/arch/x86/kernel/traps_32.c
+++ b/arch/x86/kernel/traps_32.c
@@ -530,56 +530,6 @@ vm86_trap:
530 return; 530 return;
531} 531}
532 532
533#define DO_TRAP(trapnr, signr, str, name) \
534void do_##name(struct pt_regs *regs, long error_code) \
535{ \
536 trace_hardirqs_fixup(); \
537 if (notify_die(DIE_TRAP, str, regs, error_code, trapnr, signr) \
538 == NOTIFY_STOP) \
539 return; \
540 do_trap(trapnr, signr, str, 0, regs, error_code, NULL); \
541}
542
543#define DO_TRAP_INFO(trapnr, signr, str, name, sicode, siaddr, irq) \
544void do_##name(struct pt_regs *regs, long error_code) \
545{ \
546 siginfo_t info; \
547 if (irq) \
548 local_irq_enable(); \
549 info.si_signo = signr; \
550 info.si_errno = 0; \
551 info.si_code = sicode; \
552 info.si_addr = (void __user *)siaddr; \
553 if (notify_die(DIE_TRAP, str, regs, error_code, trapnr, signr) \
554 == NOTIFY_STOP) \
555 return; \
556 do_trap(trapnr, signr, str, 0, regs, error_code, &info); \
557}
558
559#define DO_VM86_TRAP(trapnr, signr, str, name) \
560void do_##name(struct pt_regs *regs, long error_code) \
561{ \
562 if (notify_die(DIE_TRAP, str, regs, error_code, trapnr, signr) \
563 == NOTIFY_STOP) \
564 return; \
565 do_trap(trapnr, signr, str, 1, regs, error_code, NULL); \
566}
567
568#define DO_VM86_TRAP_INFO(trapnr, signr, str, name, sicode, siaddr) \
569void do_##name(struct pt_regs *regs, long error_code) \
570{ \
571 siginfo_t info; \
572 info.si_signo = signr; \
573 info.si_errno = 0; \
574 info.si_code = sicode; \
575 info.si_addr = (void __user *)siaddr; \
576 trace_hardirqs_fixup(); \
577 if (notify_die(DIE_TRAP, str, regs, error_code, trapnr, signr) \
578 == NOTIFY_STOP) \
579 return; \
580 do_trap(trapnr, signr, str, 1, regs, error_code, &info); \
581}
582
583#define DO_ERROR(trapnr, signr, str, name) \ 533#define DO_ERROR(trapnr, signr, str, name) \
584void do_##name(struct pt_regs *regs, long error_code) \ 534void do_##name(struct pt_regs *regs, long error_code) \
585{ \ 535{ \
@@ -643,7 +593,6 @@ DO_ERROR(10, SIGSEGV, "invalid TSS", invalid_TSS)
643DO_ERROR(11, SIGBUS, "segment not present", segment_not_present) 593DO_ERROR(11, SIGBUS, "segment not present", segment_not_present)
644DO_ERROR(12, SIGBUS, "stack segment", stack_segment) 594DO_ERROR(12, SIGBUS, "stack segment", stack_segment)
645DO_ERROR_INFO(17, SIGBUS, "alignment check", alignment_check, BUS_ADRALN, 0, 0) 595DO_ERROR_INFO(17, SIGBUS, "alignment check", alignment_check, BUS_ADRALN, 0, 0)
646DO_TRAP_INFO(32, SIGILL, "iret exception", iret_error, ILL_BADSTK, 0, 1)
647 596
648void __kprobes 597void __kprobes
649do_general_protection(struct pt_regs *regs, long error_code) 598do_general_protection(struct pt_regs *regs, long error_code)
@@ -1263,6 +1212,21 @@ void __kprobes do_machine_check(struct pt_regs *regs, long error)
1263} 1212}
1264#endif 1213#endif
1265 1214
1215void do_iret_error(struct pt_regs *regs, long error_code)
1216{
1217 siginfo_t info;
1218 local_irq_enable();
1219
1220 info.si_signo = SIGILL;
1221 info.si_errno = 0;
1222 info.si_code = ILL_BADSTK;
1223 info.si_addr = 0;
1224 if (notify_die(DIE_TRAP, "iret exception",
1225 regs, error_code, 32, SIGILL) == NOTIFY_STOP)
1226 return;
1227 do_trap(32, SIGILL, "iret exception", 0, regs, error_code, &info);
1228}
1229
1266void __init trap_init(void) 1230void __init trap_init(void)
1267{ 1231{
1268 int i; 1232 int i;