aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kernel/traps_32.c
diff options
context:
space:
mode:
authorAlexander van Heukelum <heukelum@mailshack.com>2008-07-01 19:29:44 -0400
committerIngo Molnar <mingo@elte.hu>2008-07-09 01:43:28 -0400
commita8c1be9d2e78d8608892c86791837acf12da4bf6 (patch)
tree274fc038d6bff0535f8535e9b63bb7d4e10f12ed /arch/x86/kernel/traps_32.c
parente93ef949fd9a3f237aedfb8e64414b28980530b8 (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.c78
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
133static inline int valid_stack_ptr(struct thread_info *tinfo, void *p, unsigned size) 134static 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 */
140struct stack_frame { 142struct 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
145static inline unsigned long 147static inline unsigned long
146print_context_stack(struct thread_info *tinfo, 148print_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
172void dump_trace(struct task_struct *task, struct pt_regs *regs, 172void 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
250static const struct stacktrace_ops print_trace_ops = { 249static 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
257static void 256static 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) \
571void do_##name(struct pt_regs *regs, long error_code) \ 569void 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
594DO_VM86_ERROR_INFO(0, SIGFPE, "divide error", divide_error, FPE_INTDIV, regs->ip) 592DO_VM86_ERROR_INFO(0, SIGFPE, "divide error", divide_error, FPE_INTDIV, regs->ip)
595#ifndef CONFIG_KPROBES 593#ifndef CONFIG_KPROBES
596DO_VM86_ERROR(3, SIGTRAP, "int3", int3) 594DO_VM86_ERROR(3, SIGTRAP, "int3", int3)
597#endif 595#endif
598DO_VM86_ERROR(4, SIGSEGV, "overflow", overflow) 596DO_VM86_ERROR(4, SIGSEGV, "overflow", overflow)
599DO_VM86_ERROR(5, SIGSEGV, "bounds", bounds) 597DO_VM86_ERROR(5, SIGSEGV, "bounds", bounds)
600DO_ERROR_INFO(6, SIGILL, "invalid opcode", invalid_op, ILL_ILLOPN, regs->ip, 0) 598DO_ERROR_INFO(6, SIGILL, "invalid opcode", invalid_op, ILL_ILLOPN, regs->ip, 0)
601DO_ERROR(9, SIGFPE, "coprocessor segment overrun", coprocessor_segment_overrun) 599DO_ERROR(9, SIGFPE, "coprocessor segment overrun", coprocessor_segment_overrun)
602DO_ERROR(10, SIGSEGV, "invalid TSS", invalid_TSS) 600DO_ERROR(10, SIGSEGV, "invalid TSS", invalid_TSS)
603DO_ERROR(11, SIGBUS, "segment not present", segment_not_present) 601DO_ERROR(11, SIGBUS, "segment not present", segment_not_present)
604DO_ERROR(12, SIGBUS, "stack segment", stack_segment) 602DO_ERROR(12, SIGBUS, "stack segment", stack_segment)
605DO_ERROR_INFO(17, SIGBUS, "alignment check", alignment_check, BUS_ADRALN, 0, 0) 603DO_ERROR_INFO(17, SIGBUS, "alignment check", alignment_check, BUS_ADRALN, 0, 0)
606DO_ERROR_INFO(32, SIGILL, "iret exception", iret_error, ILL_BADSTK, 0, 1) 604DO_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, &divide_error); 1201 set_trap_gate(0, &divide_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);