diff options
author | Alexander van Heukelum <heukelum@fastmail.fm> | 2008-09-26 08:03:08 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2008-10-13 04:22:34 -0400 |
commit | 3c1326f8a6d8b9815ca88c95441330f96eef7352 (patch) | |
tree | d46c9e18d19550668d66dd065e9f187ca9a3ed57 /arch/x86/kernel/traps_32.c | |
parent | 69c89b5bf7f253756f3056e84b8603abe1c50f5b (diff) |
traps: i386: make do_trap more like x86_64
This patch hardcodes which traps should be forwarded to
handle_vm86_trap in do_trap. This allows to remove the
vm86 parameter from the i386-version of do_trap, which
makes the DO_VM86_ERROR and DO_VM86_ERROR_INFO macros
unnecessary.
x86_64 part is whitespace only.
Signed-off-by: Alexander van Heukelum <heukelum@fastmail.fm>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'arch/x86/kernel/traps_32.c')
-rw-r--r-- | arch/x86/kernel/traps_32.c | 55 |
1 files changed, 16 insertions, 39 deletions
diff --git a/arch/x86/kernel/traps_32.c b/arch/x86/kernel/traps_32.c index ab5593650899..bf4d71231d40 100644 --- a/arch/x86/kernel/traps_32.c +++ b/arch/x86/kernel/traps_32.c | |||
@@ -482,13 +482,17 @@ die_if_kernel(const char *str, struct pt_regs *regs, long err) | |||
482 | } | 482 | } |
483 | 483 | ||
484 | static void __kprobes | 484 | static void __kprobes |
485 | do_trap(int trapnr, int signr, char *str, int vm86, struct pt_regs *regs, | 485 | do_trap(int trapnr, int signr, char *str, struct pt_regs *regs, |
486 | long error_code, siginfo_t *info) | 486 | long error_code, siginfo_t *info) |
487 | { | 487 | { |
488 | struct task_struct *tsk = current; | 488 | struct task_struct *tsk = current; |
489 | 489 | ||
490 | if (regs->flags & X86_VM_MASK) { | 490 | if (regs->flags & X86_VM_MASK) { |
491 | if (vm86) | 491 | /* |
492 | * traps 0, 1, 3, 4, and 5 should be forwarded to vm86. | ||
493 | * On nmi (interrupt 2), do_trap should not be called. | ||
494 | */ | ||
495 | if (trapnr < 6) | ||
492 | goto vm86_trap; | 496 | goto vm86_trap; |
493 | goto trap_signal; | 497 | goto trap_signal; |
494 | } | 498 | } |
@@ -537,37 +541,10 @@ void do_##name(struct pt_regs *regs, long error_code) \ | |||
537 | == NOTIFY_STOP) \ | 541 | == NOTIFY_STOP) \ |
538 | return; \ | 542 | return; \ |
539 | conditional_sti(regs); \ | 543 | conditional_sti(regs); \ |
540 | do_trap(trapnr, signr, str, 0, regs, error_code, NULL); \ | 544 | do_trap(trapnr, signr, str, regs, error_code, NULL); \ |
541 | } | ||
542 | |||
543 | #define DO_ERROR_INFO(trapnr, signr, str, name, sicode, siaddr, irq) \ | ||
544 | void 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 | conditional_sti(regs); \ | ||
557 | do_trap(trapnr, signr, str, 0, regs, error_code, &info); \ | ||
558 | } | ||
559 | |||
560 | #define DO_VM86_ERROR(trapnr, signr, str, name) \ | ||
561 | void do_##name(struct pt_regs *regs, long error_code) \ | ||
562 | { \ | ||
563 | if (notify_die(DIE_TRAP, str, regs, error_code, trapnr, signr) \ | ||
564 | == NOTIFY_STOP) \ | ||
565 | return; \ | ||
566 | conditional_sti(regs); \ | ||
567 | do_trap(trapnr, signr, str, 1, regs, error_code, NULL); \ | ||
568 | } | 545 | } |
569 | 546 | ||
570 | #define DO_VM86_ERROR_INFO(trapnr, signr, str, name, sicode, siaddr) \ | 547 | #define DO_ERROR_INFO(trapnr, signr, str, name, sicode, siaddr) \ |
571 | void do_##name(struct pt_regs *regs, long error_code) \ | 548 | void do_##name(struct pt_regs *regs, long error_code) \ |
572 | { \ | 549 | { \ |
573 | siginfo_t info; \ | 550 | siginfo_t info; \ |
@@ -579,18 +556,18 @@ void do_##name(struct pt_regs *regs, long error_code) \ | |||
579 | == NOTIFY_STOP) \ | 556 | == NOTIFY_STOP) \ |
580 | return; \ | 557 | return; \ |
581 | conditional_sti(regs); \ | 558 | conditional_sti(regs); \ |
582 | do_trap(trapnr, signr, str, 1, regs, error_code, &info); \ | 559 | do_trap(trapnr, signr, str, regs, error_code, &info); \ |
583 | } | 560 | } |
584 | 561 | ||
585 | DO_VM86_ERROR_INFO(0, SIGFPE, "divide error", divide_error, FPE_INTDIV, regs->ip) | 562 | DO_ERROR_INFO(0, SIGFPE, "divide error", divide_error, FPE_INTDIV, regs->ip) |
586 | DO_VM86_ERROR(4, SIGSEGV, "overflow", overflow) | 563 | DO_ERROR(4, SIGSEGV, "overflow", overflow) |
587 | DO_VM86_ERROR(5, SIGSEGV, "bounds", bounds) | 564 | DO_ERROR(5, SIGSEGV, "bounds", bounds) |
588 | DO_ERROR_INFO(6, SIGILL, "invalid opcode", invalid_op, ILL_ILLOPN, regs->ip, 0) | 565 | DO_ERROR_INFO(6, SIGILL, "invalid opcode", invalid_op, ILL_ILLOPN, regs->ip) |
589 | DO_ERROR(9, SIGFPE, "coprocessor segment overrun", coprocessor_segment_overrun) | 566 | DO_ERROR(9, SIGFPE, "coprocessor segment overrun", coprocessor_segment_overrun) |
590 | DO_ERROR(10, SIGSEGV, "invalid TSS", invalid_TSS) | 567 | DO_ERROR(10, SIGSEGV, "invalid TSS", invalid_TSS) |
591 | DO_ERROR(11, SIGBUS, "segment not present", segment_not_present) | 568 | DO_ERROR(11, SIGBUS, "segment not present", segment_not_present) |
592 | DO_ERROR(12, SIGBUS, "stack segment", stack_segment) | 569 | DO_ERROR(12, SIGBUS, "stack segment", stack_segment) |
593 | DO_ERROR_INFO(17, SIGBUS, "alignment check", alignment_check, BUS_ADRALN, 0, 0) | 570 | DO_ERROR_INFO(17, SIGBUS, "alignment check", alignment_check, BUS_ADRALN, 0) |
594 | 571 | ||
595 | void __kprobes | 572 | void __kprobes |
596 | do_general_protection(struct pt_regs *regs, long error_code) | 573 | do_general_protection(struct pt_regs *regs, long error_code) |
@@ -868,7 +845,7 @@ void __kprobes do_int3(struct pt_regs *regs, long error_code) | |||
868 | return; | 845 | return; |
869 | #endif | 846 | #endif |
870 | 847 | ||
871 | do_trap(3, SIGTRAP, "int3", 1, regs, error_code, NULL); | 848 | do_trap(3, SIGTRAP, "int3", regs, error_code, NULL); |
872 | } | 849 | } |
873 | 850 | ||
874 | /* | 851 | /* |
@@ -1214,7 +1191,7 @@ void do_iret_error(struct pt_regs *regs, long error_code) | |||
1214 | if (notify_die(DIE_TRAP, "iret exception", | 1191 | if (notify_die(DIE_TRAP, "iret exception", |
1215 | regs, error_code, 32, SIGILL) == NOTIFY_STOP) | 1192 | regs, error_code, 32, SIGILL) == NOTIFY_STOP) |
1216 | return; | 1193 | return; |
1217 | do_trap(32, SIGILL, "iret exception", 0, regs, error_code, &info); | 1194 | do_trap(32, SIGILL, "iret exception", regs, error_code, &info); |
1218 | } | 1195 | } |
1219 | 1196 | ||
1220 | void __init trap_init(void) | 1197 | void __init trap_init(void) |