diff options
author | Alexander van Heukelum <heukelum@mailshack.com> | 2008-07-01 19:29:44 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2008-07-09 01:43:28 -0400 |
commit | a8c1be9d2e78d8608892c86791837acf12da4bf6 (patch) | |
tree | 274fc038d6bff0535f8535e9b63bb7d4e10f12ed /arch/x86/kernel/traps_32.c | |
parent | e93ef949fd9a3f237aedfb8e64414b28980530b8 (diff) |
x86: initial changes to unify traps_32.c and traps_64.c
This patch does not change the generated object files.
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 | 78 |
1 files changed, 39 insertions, 39 deletions
diff --git a/arch/x86/kernel/traps_32.c b/arch/x86/kernel/traps_32.c index d7cc292691ff..92439698e489 100644 --- a/arch/x86/kernel/traps_32.c +++ b/arch/x86/kernel/traps_32.c | |||
@@ -1,5 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (C) 1991, 1992 Linus Torvalds | 2 | * Copyright (C) 1991, 1992 Linus Torvalds |
3 | * Copyright (C) 2000, 2001, 2002 Andi Kleen, SuSE Labs | ||
3 | * | 4 | * |
4 | * Pentium III FXSR, SSE support | 5 | * Pentium III FXSR, SSE support |
5 | * Gareth Hughes <gareth@valinux.com>, May 2000 | 6 | * Gareth Hughes <gareth@valinux.com>, May 2000 |
@@ -130,7 +131,8 @@ void printk_address(unsigned long address, int reliable) | |||
130 | #endif | 131 | #endif |
131 | } | 132 | } |
132 | 133 | ||
133 | static inline int valid_stack_ptr(struct thread_info *tinfo, void *p, unsigned size) | 134 | static inline int valid_stack_ptr(struct thread_info *tinfo, |
135 | void *p, unsigned int size) | ||
134 | { | 136 | { |
135 | return p > (void *)tinfo && | 137 | return p > (void *)tinfo && |
136 | p <= (void *)tinfo + THREAD_SIZE - size; | 138 | p <= (void *)tinfo + THREAD_SIZE - size; |
@@ -138,14 +140,14 @@ static inline int valid_stack_ptr(struct thread_info *tinfo, void *p, unsigned s | |||
138 | 140 | ||
139 | /* The form of the top of the frame on the stack */ | 141 | /* The form of the top of the frame on the stack */ |
140 | struct stack_frame { | 142 | struct stack_frame { |
141 | struct stack_frame *next_frame; | 143 | struct stack_frame *next_frame; |
142 | unsigned long return_address; | 144 | unsigned long return_address; |
143 | }; | 145 | }; |
144 | 146 | ||
145 | static inline unsigned long | 147 | static inline unsigned long |
146 | print_context_stack(struct thread_info *tinfo, | 148 | print_context_stack(struct thread_info *tinfo, |
147 | unsigned long *stack, unsigned long bp, | 149 | unsigned long *stack, unsigned long bp, |
148 | const struct stacktrace_ops *ops, void *data) | 150 | const struct stacktrace_ops *ops, void *data) |
149 | { | 151 | { |
150 | struct stack_frame *frame = (struct stack_frame *)bp; | 152 | struct stack_frame *frame = (struct stack_frame *)bp; |
151 | 153 | ||
@@ -167,8 +169,6 @@ print_context_stack(struct thread_info *tinfo, | |||
167 | return bp; | 169 | return bp; |
168 | } | 170 | } |
169 | 171 | ||
170 | #define MSG(msg) ops->warning(data, msg) | ||
171 | |||
172 | void dump_trace(struct task_struct *task, struct pt_regs *regs, | 172 | void dump_trace(struct task_struct *task, struct pt_regs *regs, |
173 | unsigned long *stack, unsigned long bp, | 173 | unsigned long *stack, unsigned long bp, |
174 | const struct stacktrace_ops *ops, void *data) | 174 | const struct stacktrace_ops *ops, void *data) |
@@ -178,7 +178,6 @@ void dump_trace(struct task_struct *task, struct pt_regs *regs, | |||
178 | 178 | ||
179 | if (!stack) { | 179 | if (!stack) { |
180 | unsigned long dummy; | 180 | unsigned long dummy; |
181 | |||
182 | stack = &dummy; | 181 | stack = &dummy; |
183 | if (task != current) | 182 | if (task != current) |
184 | stack = (unsigned long *)task->thread.sp; | 183 | stack = (unsigned long *)task->thread.sp; |
@@ -196,7 +195,7 @@ void dump_trace(struct task_struct *task, struct pt_regs *regs, | |||
196 | } | 195 | } |
197 | #endif | 196 | #endif |
198 | 197 | ||
199 | while (1) { | 198 | for (;;) { |
200 | struct thread_info *context; | 199 | struct thread_info *context; |
201 | 200 | ||
202 | context = (struct thread_info *) | 201 | context = (struct thread_info *) |
@@ -248,10 +247,10 @@ static void print_trace_address(void *data, unsigned long addr, int reliable) | |||
248 | } | 247 | } |
249 | 248 | ||
250 | static const struct stacktrace_ops print_trace_ops = { | 249 | static const struct stacktrace_ops print_trace_ops = { |
251 | .warning = print_trace_warning, | 250 | .warning = print_trace_warning, |
252 | .warning_symbol = print_trace_warning_symbol, | 251 | .warning_symbol = print_trace_warning_symbol, |
253 | .stack = print_trace_stack, | 252 | .stack = print_trace_stack, |
254 | .address = print_trace_address, | 253 | .address = print_trace_address, |
255 | }; | 254 | }; |
256 | 255 | ||
257 | static void | 256 | static void |
@@ -351,15 +350,14 @@ void show_registers(struct pt_regs *regs) | |||
351 | printk(KERN_EMERG "Code: "); | 350 | printk(KERN_EMERG "Code: "); |
352 | 351 | ||
353 | ip = (u8 *)regs->ip - code_prologue; | 352 | ip = (u8 *)regs->ip - code_prologue; |
354 | if (ip < (u8 *)PAGE_OFFSET || | 353 | if (ip < (u8 *)PAGE_OFFSET || probe_kernel_address(ip, c)) { |
355 | probe_kernel_address(ip, c)) { | ||
356 | /* try starting at EIP */ | 354 | /* try starting at EIP */ |
357 | ip = (u8 *)regs->ip; | 355 | ip = (u8 *)regs->ip; |
358 | code_len = code_len - code_prologue + 1; | 356 | code_len = code_len - code_prologue + 1; |
359 | } | 357 | } |
360 | for (i = 0; i < code_len; i++, ip++) { | 358 | for (i = 0; i < code_len; i++, ip++) { |
361 | if (ip < (u8 *)PAGE_OFFSET || | 359 | if (ip < (u8 *)PAGE_OFFSET || |
362 | probe_kernel_address(ip, c)) { | 360 | probe_kernel_address(ip, c)) { |
363 | printk(" Bad EIP value."); | 361 | printk(" Bad EIP value."); |
364 | break; | 362 | break; |
365 | } | 363 | } |
@@ -546,7 +544,7 @@ void do_##name(struct pt_regs *regs, long error_code) \ | |||
546 | { \ | 544 | { \ |
547 | trace_hardirqs_fixup(); \ | 545 | trace_hardirqs_fixup(); \ |
548 | if (notify_die(DIE_TRAP, str, regs, error_code, trapnr, signr) \ | 546 | if (notify_die(DIE_TRAP, str, regs, error_code, trapnr, signr) \ |
549 | == NOTIFY_STOP) \ | 547 | == NOTIFY_STOP) \ |
550 | return; \ | 548 | return; \ |
551 | do_trap(trapnr, signr, str, 0, regs, error_code, NULL); \ | 549 | do_trap(trapnr, signr, str, 0, regs, error_code, NULL); \ |
552 | } | 550 | } |
@@ -562,7 +560,7 @@ void do_##name(struct pt_regs *regs, long error_code) \ | |||
562 | info.si_code = sicode; \ | 560 | info.si_code = sicode; \ |
563 | info.si_addr = (void __user *)siaddr; \ | 561 | info.si_addr = (void __user *)siaddr; \ |
564 | if (notify_die(DIE_TRAP, str, regs, error_code, trapnr, signr) \ | 562 | if (notify_die(DIE_TRAP, str, regs, error_code, trapnr, signr) \ |
565 | == NOTIFY_STOP) \ | 563 | == NOTIFY_STOP) \ |
566 | return; \ | 564 | return; \ |
567 | do_trap(trapnr, signr, str, 0, regs, error_code, &info); \ | 565 | do_trap(trapnr, signr, str, 0, regs, error_code, &info); \ |
568 | } | 566 | } |
@@ -571,7 +569,7 @@ void do_##name(struct pt_regs *regs, long error_code) \ | |||
571 | void do_##name(struct pt_regs *regs, long error_code) \ | 569 | void do_##name(struct pt_regs *regs, long error_code) \ |
572 | { \ | 570 | { \ |
573 | if (notify_die(DIE_TRAP, str, regs, error_code, trapnr, signr) \ | 571 | if (notify_die(DIE_TRAP, str, regs, error_code, trapnr, signr) \ |
574 | == NOTIFY_STOP) \ | 572 | == NOTIFY_STOP) \ |
575 | return; \ | 573 | return; \ |
576 | do_trap(trapnr, signr, str, 1, regs, error_code, NULL); \ | 574 | do_trap(trapnr, signr, str, 1, regs, error_code, NULL); \ |
577 | } | 575 | } |
@@ -586,22 +584,22 @@ void do_##name(struct pt_regs *regs, long error_code) \ | |||
586 | info.si_addr = (void __user *)siaddr; \ | 584 | info.si_addr = (void __user *)siaddr; \ |
587 | trace_hardirqs_fixup(); \ | 585 | trace_hardirqs_fixup(); \ |
588 | if (notify_die(DIE_TRAP, str, regs, error_code, trapnr, signr) \ | 586 | if (notify_die(DIE_TRAP, str, regs, error_code, trapnr, signr) \ |
589 | == NOTIFY_STOP) \ | 587 | == NOTIFY_STOP) \ |
590 | return; \ | 588 | return; \ |
591 | do_trap(trapnr, signr, str, 1, regs, error_code, &info); \ | 589 | do_trap(trapnr, signr, str, 1, regs, error_code, &info); \ |
592 | } | 590 | } |
593 | 591 | ||
594 | DO_VM86_ERROR_INFO(0, SIGFPE, "divide error", divide_error, FPE_INTDIV, regs->ip) | 592 | DO_VM86_ERROR_INFO(0, SIGFPE, "divide error", divide_error, FPE_INTDIV, regs->ip) |
595 | #ifndef CONFIG_KPROBES | 593 | #ifndef CONFIG_KPROBES |
596 | DO_VM86_ERROR(3, SIGTRAP, "int3", int3) | 594 | DO_VM86_ERROR(3, SIGTRAP, "int3", int3) |
597 | #endif | 595 | #endif |
598 | DO_VM86_ERROR(4, SIGSEGV, "overflow", overflow) | 596 | DO_VM86_ERROR(4, SIGSEGV, "overflow", overflow) |
599 | DO_VM86_ERROR(5, SIGSEGV, "bounds", bounds) | 597 | DO_VM86_ERROR(5, SIGSEGV, "bounds", bounds) |
600 | DO_ERROR_INFO(6, SIGILL, "invalid opcode", invalid_op, ILL_ILLOPN, regs->ip, 0) | 598 | DO_ERROR_INFO(6, SIGILL, "invalid opcode", invalid_op, ILL_ILLOPN, regs->ip, 0) |
601 | DO_ERROR(9, SIGFPE, "coprocessor segment overrun", coprocessor_segment_overrun) | 599 | DO_ERROR(9, SIGFPE, "coprocessor segment overrun", coprocessor_segment_overrun) |
602 | DO_ERROR(10, SIGSEGV, "invalid TSS", invalid_TSS) | 600 | DO_ERROR(10, SIGSEGV, "invalid TSS", invalid_TSS) |
603 | DO_ERROR(11, SIGBUS, "segment not present", segment_not_present) | 601 | DO_ERROR(11, SIGBUS, "segment not present", segment_not_present) |
604 | DO_ERROR(12, SIGBUS, "stack segment", stack_segment) | 602 | DO_ERROR(12, SIGBUS, "stack segment", stack_segment) |
605 | DO_ERROR_INFO(17, SIGBUS, "alignment check", alignment_check, BUS_ADRALN, 0, 0) | 603 | DO_ERROR_INFO(17, SIGBUS, "alignment check", alignment_check, BUS_ADRALN, 0, 0) |
606 | DO_ERROR_INFO(32, SIGILL, "iret exception", iret_error, ILL_BADSTK, 0, 1) | 604 | DO_ERROR_INFO(32, SIGILL, "iret exception", iret_error, ILL_BADSTK, 0, 1) |
607 | 605 | ||
@@ -799,7 +797,7 @@ static notrace __kprobes void default_do_nmi(struct pt_regs *regs) | |||
799 | 797 | ||
800 | if (!(reason & 0xc0)) { | 798 | if (!(reason & 0xc0)) { |
801 | if (notify_die(DIE_NMI_IPI, "nmi_ipi", regs, reason, 2, SIGINT) | 799 | if (notify_die(DIE_NMI_IPI, "nmi_ipi", regs, reason, 2, SIGINT) |
802 | == NOTIFY_STOP) | 800 | == NOTIFY_STOP) |
803 | return; | 801 | return; |
804 | #ifdef CONFIG_X86_LOCAL_APIC | 802 | #ifdef CONFIG_X86_LOCAL_APIC |
805 | /* | 803 | /* |
@@ -818,6 +816,8 @@ static notrace __kprobes void default_do_nmi(struct pt_regs *regs) | |||
818 | } | 816 | } |
819 | if (notify_die(DIE_NMI, "nmi", regs, reason, 2, SIGINT) == NOTIFY_STOP) | 817 | if (notify_die(DIE_NMI, "nmi", regs, reason, 2, SIGINT) == NOTIFY_STOP) |
820 | return; | 818 | return; |
819 | |||
820 | /* AK: following checks seem to be broken on modern chipsets. FIXME */ | ||
821 | if (reason & 0x80) | 821 | if (reason & 0x80) |
822 | mem_parity_error(reason, regs); | 822 | mem_parity_error(reason, regs); |
823 | if (reason & 0x40) | 823 | if (reason & 0x40) |
@@ -915,7 +915,7 @@ void __kprobes do_debug(struct pt_regs *regs, long error_code) | |||
915 | tsk->thread.debugctlmsr = 0; | 915 | tsk->thread.debugctlmsr = 0; |
916 | 916 | ||
917 | if (notify_die(DIE_DEBUG, "debug", regs, condition, error_code, | 917 | if (notify_die(DIE_DEBUG, "debug", regs, condition, error_code, |
918 | SIGTRAP) == NOTIFY_STOP) | 918 | SIGTRAP) == NOTIFY_STOP) |
919 | return; | 919 | return; |
920 | /* It's safe to allow irq's after DR6 has been saved */ | 920 | /* It's safe to allow irq's after DR6 has been saved */ |
921 | if (regs->flags & X86_EFLAGS_IF) | 921 | if (regs->flags & X86_EFLAGS_IF) |
@@ -997,7 +997,7 @@ void math_error(void __user *ip) | |||
997 | * C1 reg you need in case of a stack fault, 0x040 is the stack | 997 | * C1 reg you need in case of a stack fault, 0x040 is the stack |
998 | * fault bit. We should only be taking one exception at a time, | 998 | * fault bit. We should only be taking one exception at a time, |
999 | * so if this combination doesn't produce any single exception, | 999 | * so if this combination doesn't produce any single exception, |
1000 | * then we have a bad program that isn't syncronizing its FPU usage | 1000 | * then we have a bad program that isn't synchronizing its FPU usage |
1001 | * and it will suffer the consequences since we won't be able to | 1001 | * and it will suffer the consequences since we won't be able to |
1002 | * fully reproduce the context of the exception | 1002 | * fully reproduce the context of the exception |
1003 | */ | 1003 | */ |
@@ -1006,7 +1006,7 @@ void math_error(void __user *ip) | |||
1006 | switch (swd & ~cwd & 0x3f) { | 1006 | switch (swd & ~cwd & 0x3f) { |
1007 | case 0x000: /* No unmasked exception */ | 1007 | case 0x000: /* No unmasked exception */ |
1008 | return; | 1008 | return; |
1009 | default: /* Multiple exceptions */ | 1009 | default: /* Multiple exceptions */ |
1010 | break; | 1010 | break; |
1011 | case 0x001: /* Invalid Op */ | 1011 | case 0x001: /* Invalid Op */ |
1012 | /* | 1012 | /* |
@@ -1198,16 +1198,16 @@ void __init trap_init(void) | |||
1198 | early_iounmap(p, 4); | 1198 | early_iounmap(p, 4); |
1199 | #endif | 1199 | #endif |
1200 | 1200 | ||
1201 | set_trap_gate(0, ÷_error); | 1201 | set_trap_gate(0, ÷_error); |
1202 | set_intr_gate(1, &debug); | 1202 | set_intr_gate(1, &debug); |
1203 | set_intr_gate(2, &nmi); | 1203 | set_intr_gate(2, &nmi); |
1204 | set_system_intr_gate(3, &int3); /* int3/4 can be called from all */ | 1204 | set_system_intr_gate(3, &int3); /* int3 can be called from all */ |
1205 | set_system_gate(4, &overflow); | 1205 | set_system_gate(4, &overflow); /* int4 can be called from all */ |
1206 | set_trap_gate(5, &bounds); | 1206 | set_trap_gate(5, &bounds); |
1207 | set_trap_gate(6, &invalid_op); | 1207 | set_trap_gate(6, &invalid_op); |
1208 | set_trap_gate(7, &device_not_available); | 1208 | set_trap_gate(7, &device_not_available); |
1209 | set_task_gate(8, GDT_ENTRY_DOUBLEFAULT_TSS); | 1209 | set_task_gate(8, GDT_ENTRY_DOUBLEFAULT_TSS); |
1210 | set_trap_gate(9, &coprocessor_segment_overrun); | 1210 | set_trap_gate(9, &coprocessor_segment_overrun); |
1211 | set_trap_gate(10, &invalid_TSS); | 1211 | set_trap_gate(10, &invalid_TSS); |
1212 | set_trap_gate(11, &segment_not_present); | 1212 | set_trap_gate(11, &segment_not_present); |
1213 | set_trap_gate(12, &stack_segment); | 1213 | set_trap_gate(12, &stack_segment); |