aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlexander van Heukelum <heukelum@fastmail.fm>2008-09-30 12:41:36 -0400
committerIngo Molnar <mingo@elte.hu>2008-10-13 04:33:20 -0400
commite407d62088b7f61f38e1086062650c75a4f2757a (patch)
treeb0b5b666361c305f93bdf0e439d69acf7ee2f0e0
parentae82157b3d8bb4902f76b56c7450a945288786ac (diff)
x86, traps: introduce dotraplinkage
Mark the exception handlers with "dotraplinkage" to hide the calling convention differences between i386 and x86_64. Signed-off-by: Alexander van Heukelum <heukelum@fastmail.fm> Signed-off-by: Ingo Molnar <mingo@elte.hu>
-rw-r--r--arch/x86/kernel/entry_64.S2
-rw-r--r--arch/x86/kernel/traps_32.c28
-rw-r--r--arch/x86/kernel/traps_64.c31
-rw-r--r--include/asm-x86/traps.h73
4 files changed, 72 insertions, 62 deletions
diff --git a/arch/x86/kernel/entry_64.S b/arch/x86/kernel/entry_64.S
index 977c8ea66028..1db6ce4314e1 100644
--- a/arch/x86/kernel/entry_64.S
+++ b/arch/x86/kernel/entry_64.S
@@ -1243,7 +1243,7 @@ ENTRY(simd_coprocessor_error)
1243END(simd_coprocessor_error) 1243END(simd_coprocessor_error)
1244 1244
1245ENTRY(device_not_available) 1245ENTRY(device_not_available)
1246 zeroentry math_state_restore 1246 zeroentry do_device_not_available
1247END(device_not_available) 1247END(device_not_available)
1248 1248
1249 /* runs on exception stack */ 1249 /* runs on exception stack */
diff --git a/arch/x86/kernel/traps_32.c b/arch/x86/kernel/traps_32.c
index 0206c915748c..7eb1203c909d 100644
--- a/arch/x86/kernel/traps_32.c
+++ b/arch/x86/kernel/traps_32.c
@@ -190,7 +190,7 @@ vm86_trap:
190} 190}
191 191
192#define DO_ERROR(trapnr, signr, str, name) \ 192#define DO_ERROR(trapnr, signr, str, name) \
193void do_##name(struct pt_regs *regs, long error_code) \ 193dotraplinkage void do_##name(struct pt_regs *regs, long error_code) \
194{ \ 194{ \
195 if (notify_die(DIE_TRAP, str, regs, error_code, trapnr, signr) \ 195 if (notify_die(DIE_TRAP, str, regs, error_code, trapnr, signr) \
196 == NOTIFY_STOP) \ 196 == NOTIFY_STOP) \
@@ -200,7 +200,7 @@ void do_##name(struct pt_regs *regs, long error_code) \
200} 200}
201 201
202#define DO_ERROR_INFO(trapnr, signr, str, name, sicode, siaddr) \ 202#define DO_ERROR_INFO(trapnr, signr, str, name, sicode, siaddr) \
203void do_##name(struct pt_regs *regs, long error_code) \ 203dotraplinkage void do_##name(struct pt_regs *regs, long error_code) \
204{ \ 204{ \
205 siginfo_t info; \ 205 siginfo_t info; \
206 info.si_signo = signr; \ 206 info.si_signo = signr; \
@@ -224,7 +224,7 @@ DO_ERROR(11, SIGBUS, "segment not present", segment_not_present)
224DO_ERROR(12, SIGBUS, "stack segment", stack_segment) 224DO_ERROR(12, SIGBUS, "stack segment", stack_segment)
225DO_ERROR_INFO(17, SIGBUS, "alignment check", alignment_check, BUS_ADRALN, 0) 225DO_ERROR_INFO(17, SIGBUS, "alignment check", alignment_check, BUS_ADRALN, 0)
226 226
227void __kprobes 227dotraplinkage void __kprobes
228do_general_protection(struct pt_regs *regs, long error_code) 228do_general_protection(struct pt_regs *regs, long error_code)
229{ 229{
230 struct task_struct *tsk; 230 struct task_struct *tsk;
@@ -428,7 +428,8 @@ static notrace __kprobes void default_do_nmi(struct pt_regs *regs)
428 reassert_nmi(); 428 reassert_nmi();
429} 429}
430 430
431notrace __kprobes void do_nmi(struct pt_regs *regs, long error_code) 431dotraplinkage notrace __kprobes void
432do_nmi(struct pt_regs *regs, long error_code)
432{ 433{
433 int cpu; 434 int cpu;
434 435
@@ -456,7 +457,7 @@ void restart_nmi(void)
456 acpi_nmi_enable(); 457 acpi_nmi_enable();
457} 458}
458 459
459void __kprobes do_int3(struct pt_regs *regs, long error_code) 460dotraplinkage void __kprobes do_int3(struct pt_regs *regs, long error_code)
460{ 461{
461#ifdef CONFIG_KPROBES 462#ifdef CONFIG_KPROBES
462 if (notify_die(DIE_INT3, "int3", regs, error_code, 3, SIGTRAP) 463 if (notify_die(DIE_INT3, "int3", regs, error_code, 3, SIGTRAP)
@@ -494,7 +495,7 @@ void __kprobes do_int3(struct pt_regs *regs, long error_code)
494 * find every occurrence of the TF bit that could be saved away even 495 * find every occurrence of the TF bit that could be saved away even
495 * by user code) 496 * by user code)
496 */ 497 */
497void __kprobes do_debug(struct pt_regs *regs, long error_code) 498dotraplinkage void __kprobes do_debug(struct pt_regs *regs, long error_code)
498{ 499{
499 struct task_struct *tsk = current; 500 struct task_struct *tsk = current;
500 unsigned int condition; 501 unsigned int condition;
@@ -627,7 +628,7 @@ void math_error(void __user *ip)
627 force_sig_info(SIGFPE, &info, task); 628 force_sig_info(SIGFPE, &info, task);
628} 629}
629 630
630void do_coprocessor_error(struct pt_regs *regs, long error_code) 631dotraplinkage void do_coprocessor_error(struct pt_regs *regs, long error_code)
631{ 632{
632 conditional_sti(regs); 633 conditional_sti(regs);
633 ignore_fpu_irq = 1; 634 ignore_fpu_irq = 1;
@@ -682,7 +683,8 @@ static void simd_math_error(void __user *ip)
682 force_sig_info(SIGFPE, &info, task); 683 force_sig_info(SIGFPE, &info, task);
683} 684}
684 685
685void do_simd_coprocessor_error(struct pt_regs *regs, long error_code) 686dotraplinkage void
687do_simd_coprocessor_error(struct pt_regs *regs, long error_code)
686{ 688{
687 conditional_sti(regs); 689 conditional_sti(regs);
688 690
@@ -706,7 +708,8 @@ void do_simd_coprocessor_error(struct pt_regs *regs, long error_code)
706 force_sig(SIGSEGV, current); 708 force_sig(SIGSEGV, current);
707} 709}
708 710
709void do_spurious_interrupt_bug(struct pt_regs *regs, long error_code) 711dotraplinkage void
712do_spurious_interrupt_bug(struct pt_regs *regs, long error_code)
710{ 713{
711 conditional_sti(regs); 714 conditional_sti(regs);
712#if 0 715#if 0
@@ -784,7 +787,8 @@ asmlinkage void math_emulate(long arg)
784 787
785#endif /* CONFIG_MATH_EMULATION */ 788#endif /* CONFIG_MATH_EMULATION */
786 789
787void __kprobes do_device_not_available(struct pt_regs *regs, long error) 790dotraplinkage void __kprobes
791do_device_not_available(struct pt_regs *regs, long error)
788{ 792{
789 if (read_cr0() & X86_CR0_EM) { 793 if (read_cr0() & X86_CR0_EM) {
790 conditional_sti(regs); 794 conditional_sti(regs);
@@ -796,14 +800,14 @@ void __kprobes do_device_not_available(struct pt_regs *regs, long error)
796} 800}
797 801
798#ifdef CONFIG_X86_MCE 802#ifdef CONFIG_X86_MCE
799void __kprobes do_machine_check(struct pt_regs *regs, long error) 803dotraplinkage void __kprobes do_machine_check(struct pt_regs *regs, long error)
800{ 804{
801 conditional_sti(regs); 805 conditional_sti(regs);
802 machine_check_vector(regs, error); 806 machine_check_vector(regs, error);
803} 807}
804#endif 808#endif
805 809
806void do_iret_error(struct pt_regs *regs, long error_code) 810dotraplinkage void do_iret_error(struct pt_regs *regs, long error_code)
807{ 811{
808 siginfo_t info; 812 siginfo_t info;
809 local_irq_enable(); 813 local_irq_enable();
diff --git a/arch/x86/kernel/traps_64.c b/arch/x86/kernel/traps_64.c
index b295ebf0cb3f..be73323ca952 100644
--- a/arch/x86/kernel/traps_64.c
+++ b/arch/x86/kernel/traps_64.c
@@ -125,7 +125,7 @@ kernel_trap:
125} 125}
126 126
127#define DO_ERROR(trapnr, signr, str, name) \ 127#define DO_ERROR(trapnr, signr, str, name) \
128asmlinkage void do_##name(struct pt_regs *regs, long error_code) \ 128dotraplinkage void do_##name(struct pt_regs *regs, long error_code) \
129{ \ 129{ \
130 if (notify_die(DIE_TRAP, str, regs, error_code, trapnr, signr) \ 130 if (notify_die(DIE_TRAP, str, regs, error_code, trapnr, signr) \
131 == NOTIFY_STOP) \ 131 == NOTIFY_STOP) \
@@ -135,7 +135,7 @@ asmlinkage void do_##name(struct pt_regs *regs, long error_code) \
135} 135}
136 136
137#define DO_ERROR_INFO(trapnr, signr, str, name, sicode, siaddr) \ 137#define DO_ERROR_INFO(trapnr, signr, str, name, sicode, siaddr) \
138asmlinkage void do_##name(struct pt_regs *regs, long error_code) \ 138dotraplinkage void do_##name(struct pt_regs *regs, long error_code) \
139{ \ 139{ \
140 siginfo_t info; \ 140 siginfo_t info; \
141 info.si_signo = signr; \ 141 info.si_signo = signr; \
@@ -159,7 +159,7 @@ DO_ERROR(11, SIGBUS, "segment not present", segment_not_present)
159DO_ERROR_INFO(17, SIGBUS, "alignment check", alignment_check, BUS_ADRALN, 0) 159DO_ERROR_INFO(17, SIGBUS, "alignment check", alignment_check, BUS_ADRALN, 0)
160 160
161/* Runs on IST stack */ 161/* Runs on IST stack */
162asmlinkage void do_stack_segment(struct pt_regs *regs, long error_code) 162dotraplinkage void do_stack_segment(struct pt_regs *regs, long error_code)
163{ 163{
164 if (notify_die(DIE_TRAP, "stack segment", regs, error_code, 164 if (notify_die(DIE_TRAP, "stack segment", regs, error_code,
165 12, SIGBUS) == NOTIFY_STOP) 165 12, SIGBUS) == NOTIFY_STOP)
@@ -169,7 +169,7 @@ asmlinkage void do_stack_segment(struct pt_regs *regs, long error_code)
169 preempt_conditional_cli(regs); 169 preempt_conditional_cli(regs);
170} 170}
171 171
172asmlinkage void do_double_fault(struct pt_regs *regs, long error_code) 172dotraplinkage void do_double_fault(struct pt_regs *regs, long error_code)
173{ 173{
174 static const char str[] = "double fault"; 174 static const char str[] = "double fault";
175 struct task_struct *tsk = current; 175 struct task_struct *tsk = current;
@@ -186,7 +186,7 @@ asmlinkage void do_double_fault(struct pt_regs *regs, long error_code)
186 die(str, regs, error_code); 186 die(str, regs, error_code);
187} 187}
188 188
189asmlinkage void __kprobes 189dotraplinkage void __kprobes
190do_general_protection(struct pt_regs *regs, long error_code) 190do_general_protection(struct pt_regs *regs, long error_code)
191{ 191{
192 struct task_struct *tsk; 192 struct task_struct *tsk;
@@ -317,7 +317,7 @@ asmlinkage notrace __kprobes void default_do_nmi(struct pt_regs *regs)
317 io_check_error(reason, regs); 317 io_check_error(reason, regs);
318} 318}
319 319
320asmlinkage notrace __kprobes void 320dotraplinkage notrace __kprobes void
321do_nmi(struct pt_regs *regs, long error_code) 321do_nmi(struct pt_regs *regs, long error_code)
322{ 322{
323 nmi_enter(); 323 nmi_enter();
@@ -343,7 +343,7 @@ void restart_nmi(void)
343} 343}
344 344
345/* runs on IST stack. */ 345/* runs on IST stack. */
346asmlinkage void __kprobes do_int3(struct pt_regs *regs, long error_code) 346dotraplinkage void __kprobes do_int3(struct pt_regs *regs, long error_code)
347{ 347{
348 if (notify_die(DIE_INT3, "int3", regs, error_code, 3, SIGTRAP) 348 if (notify_die(DIE_INT3, "int3", regs, error_code, 3, SIGTRAP)
349 == NOTIFY_STOP) 349 == NOTIFY_STOP)
@@ -376,8 +376,7 @@ asmlinkage __kprobes struct pt_regs *sync_regs(struct pt_regs *eregs)
376} 376}
377 377
378/* runs on IST stack. */ 378/* runs on IST stack. */
379asmlinkage void __kprobes do_debug(struct pt_regs *regs, 379dotraplinkage void __kprobes do_debug(struct pt_regs *regs, long error_code)
380 unsigned long error_code)
381{ 380{
382 struct task_struct *tsk = current; 381 struct task_struct *tsk = current;
383 unsigned long condition; 382 unsigned long condition;
@@ -510,7 +509,7 @@ void math_error(void __user *ip)
510 force_sig_info(SIGFPE, &info, task); 509 force_sig_info(SIGFPE, &info, task);
511} 510}
512 511
513asmlinkage void do_coprocessor_error(struct pt_regs *regs, long error_code) 512dotraplinkage void do_coprocessor_error(struct pt_regs *regs, long error_code)
514{ 513{
515 conditional_sti(regs); 514 conditional_sti(regs);
516 if (!user_mode(regs) && 515 if (!user_mode(regs) &&
@@ -572,7 +571,8 @@ static void simd_math_error(void __user *ip)
572 force_sig_info(SIGFPE, &info, task); 571 force_sig_info(SIGFPE, &info, task);
573} 572}
574 573
575asmlinkage void do_simd_coprocessor_error(struct pt_regs *regs, long error_code) 574dotraplinkage void
575do_simd_coprocessor_error(struct pt_regs *regs, long error_code)
576{ 576{
577 conditional_sti(regs); 577 conditional_sti(regs);
578 if (!user_mode(regs) && 578 if (!user_mode(regs) &&
@@ -581,7 +581,8 @@ asmlinkage void do_simd_coprocessor_error(struct pt_regs *regs, long error_code)
581 simd_math_error((void __user *)regs->ip); 581 simd_math_error((void __user *)regs->ip);
582} 582}
583 583
584asmlinkage void do_spurious_interrupt_bug(struct pt_regs *regs, long error_code) 584dotraplinkage void
585do_spurious_interrupt_bug(struct pt_regs *regs, long error_code)
585{ 586{
586} 587}
587 588
@@ -633,6 +634,12 @@ asmlinkage void math_state_restore(void)
633} 634}
634EXPORT_SYMBOL_GPL(math_state_restore); 635EXPORT_SYMBOL_GPL(math_state_restore);
635 636
637dotraplinkage void __kprobes
638do_device_not_available(struct pt_regs *regs, long error)
639{
640 math_state_restore();
641}
642
636void __init trap_init(void) 643void __init trap_init(void)
637{ 644{
638 set_intr_gate(0, &divide_error); 645 set_intr_gate(0, &divide_error);
diff --git a/include/asm-x86/traps.h b/include/asm-x86/traps.h
index c82c39c7b5ea..6c3dc2c65751 100644
--- a/include/asm-x86/traps.h
+++ b/include/asm-x86/traps.h
@@ -3,7 +3,12 @@
3 3
4#include <asm/debugreg.h> 4#include <asm/debugreg.h>
5 5
6/* Common in X86_32 and X86_64 */ 6#ifdef CONFIG_X86_32
7#define dotraplinkage
8#else
9#define dotraplinkage asmlinkage
10#endif
11
7asmlinkage void divide_error(void); 12asmlinkage void divide_error(void);
8asmlinkage void debug(void); 13asmlinkage void debug(void);
9asmlinkage void nmi(void); 14asmlinkage void nmi(void);
@@ -12,31 +17,47 @@ asmlinkage void overflow(void);
12asmlinkage void bounds(void); 17asmlinkage void bounds(void);
13asmlinkage void invalid_op(void); 18asmlinkage void invalid_op(void);
14asmlinkage void device_not_available(void); 19asmlinkage void device_not_available(void);
20#ifdef CONFIG_X86_64
21asmlinkage void double_fault(void);
22#endif
15asmlinkage void coprocessor_segment_overrun(void); 23asmlinkage void coprocessor_segment_overrun(void);
16asmlinkage void invalid_TSS(void); 24asmlinkage void invalid_TSS(void);
17asmlinkage void segment_not_present(void); 25asmlinkage void segment_not_present(void);
18asmlinkage void stack_segment(void); 26asmlinkage void stack_segment(void);
19asmlinkage void general_protection(void); 27asmlinkage void general_protection(void);
20asmlinkage void page_fault(void); 28asmlinkage void page_fault(void);
29asmlinkage void spurious_interrupt_bug(void);
21asmlinkage void coprocessor_error(void); 30asmlinkage void coprocessor_error(void);
22asmlinkage void simd_coprocessor_error(void);
23asmlinkage void alignment_check(void); 31asmlinkage void alignment_check(void);
24asmlinkage void spurious_interrupt_bug(void);
25#ifdef CONFIG_X86_MCE 32#ifdef CONFIG_X86_MCE
26asmlinkage void machine_check(void); 33asmlinkage void machine_check(void);
27#endif /* CONFIG_X86_MCE */ 34#endif /* CONFIG_X86_MCE */
35asmlinkage void simd_coprocessor_error(void);
28 36
29void do_divide_error(struct pt_regs *, long); 37dotraplinkage void do_divide_error(struct pt_regs *, long);
30void do_overflow(struct pt_regs *, long); 38dotraplinkage void do_debug(struct pt_regs *, long);
31void do_bounds(struct pt_regs *, long); 39dotraplinkage void do_nmi(struct pt_regs *, long);
32void do_coprocessor_segment_overrun(struct pt_regs *, long); 40dotraplinkage void do_int3(struct pt_regs *, long);
33void do_invalid_TSS(struct pt_regs *, long); 41dotraplinkage void do_overflow(struct pt_regs *, long);
34void do_segment_not_present(struct pt_regs *, long); 42dotraplinkage void do_bounds(struct pt_regs *, long);
35void do_stack_segment(struct pt_regs *, long); 43dotraplinkage void do_invalid_op(struct pt_regs *, long);
36void do_alignment_check(struct pt_regs *, long); 44dotraplinkage void do_device_not_available(struct pt_regs *, long);
37void do_invalid_op(struct pt_regs *, long); 45dotraplinkage void do_coprocessor_segment_overrun(struct pt_regs *, long);
38void do_general_protection(struct pt_regs *, long); 46dotraplinkage void do_invalid_TSS(struct pt_regs *, long);
39void do_nmi(struct pt_regs *, long); 47dotraplinkage void do_segment_not_present(struct pt_regs *, long);
48dotraplinkage void do_stack_segment(struct pt_regs *, long);
49dotraplinkage void do_general_protection(struct pt_regs *, long);
50dotraplinkage void do_page_fault(struct pt_regs *, unsigned long);
51dotraplinkage void do_spurious_interrupt_bug(struct pt_regs *, long);
52dotraplinkage void do_coprocessor_error(struct pt_regs *, long);
53dotraplinkage void do_alignment_check(struct pt_regs *, long);
54#ifdef CONFIG_X86_MCE
55dotraplinkage void do_machine_check(struct pt_regs *, long);
56#endif
57dotraplinkage void do_simd_coprocessor_error(struct pt_regs *, long);
58#ifdef CONFIG_X86_32
59dotraplinkage void do_iret_error(struct pt_regs *, long);
60#endif
40 61
41static inline int get_si_code(unsigned long condition) 62static inline int get_si_code(unsigned long condition)
42{ 63{
@@ -52,31 +73,9 @@ extern int panic_on_unrecovered_nmi;
52extern int kstack_depth_to_print; 73extern int kstack_depth_to_print;
53 74
54#ifdef CONFIG_X86_32 75#ifdef CONFIG_X86_32
55
56void do_iret_error(struct pt_regs *, long);
57void do_int3(struct pt_regs *, long);
58void do_debug(struct pt_regs *, long);
59void math_error(void __user *); 76void math_error(void __user *);
60void do_coprocessor_error(struct pt_regs *, long);
61void do_simd_coprocessor_error(struct pt_regs *, long);
62void do_spurious_interrupt_bug(struct pt_regs *, long);
63unsigned long patch_espfix_desc(unsigned long, unsigned long); 77unsigned long patch_espfix_desc(unsigned long, unsigned long);
64asmlinkage void math_emulate(long); 78asmlinkage void math_emulate(long);
79#endif
65 80
66void do_page_fault(struct pt_regs *regs, unsigned long error_code);
67
68#else /* CONFIG_X86_32 */
69
70asmlinkage void double_fault(void);
71
72asmlinkage void do_int3(struct pt_regs *, long);
73asmlinkage void do_stack_segment(struct pt_regs *, long);
74asmlinkage void do_debug(struct pt_regs *, unsigned long);
75asmlinkage void do_coprocessor_error(struct pt_regs *, long);
76asmlinkage void do_simd_coprocessor_error(struct pt_regs *, long);
77asmlinkage void do_spurious_interrupt_bug(struct pt_regs *, long);
78
79asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long error_code);
80
81#endif /* CONFIG_X86_32 */
82#endif /* ASM_X86__TRAPS_H */ 81#endif /* ASM_X86__TRAPS_H */