aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPrasanna S.P <prasanna@in.ibm.com>2006-09-26 04:52:34 -0400
committerAndi Kleen <andi@basil.nowhere.org>2006-09-26 04:52:34 -0400
commitd28c4393a7bf558538e9def269c1caeab6ec056f (patch)
treee5319c9b9c8a75d2290f7429ec84884d7e1a91fe
parent3ca113ea74836a80645c79adba24caaa7a74120c (diff)
[PATCH] x86: error_code is not safe for kprobes
This patch moves the entry.S:error_entry to .kprobes.text section, since code marked unsafe for kprobes jumps directly to entry.S::error_entry, that must be marked unsafe as well. This patch also moves all the ".previous.text" asm directives to ".previous" for kprobes section. AK: Following a similar i386 patch from Chuck Ebbert AK: Also merged Jeremy's fix in. +From: Jeremy Fitzhardinge <jeremy@goop.org> KPROBE_ENTRY does a .section .kprobes.text, and expects its users to do a .previous at the end of the function. Unfortunately, if any code within the function switches sections, for example .fixup, then the .previous ends up putting all subsequent code into .fixup. Worse, any subsequent .fixup code gets intermingled with the code its supposed to be fixing (which is also in .fixup). It's surprising this didn't cause more havok. The fix is to use .pushsection/.popsection, so this stuff nests properly. A further cleanup would be to get rid of all .section/.previous pairs, since they're inherently fragile. +From: Chuck Ebbert <76306.1226@compuserve.com> Because code marked unsafe for kprobes jumps directly to entry.S::error_code, that must be marked unsafe as well. The easiest way to do that is to move the page fault entry point to just before error_code and let it inherit the same section. Also moved all the ".previous" asm directives for kprobes sections to column 1 and removed ".text" from them. Signed-off-by: Chuck Ebbert <76306.1226@compuserve.com> Signed-off-by: Andi Kleen <ak@suse.de>
-rw-r--r--arch/i386/kernel/entry.S25
-rw-r--r--arch/x86_64/kernel/entry.S19
-rw-r--r--include/linux/linkage.h6
3 files changed, 25 insertions, 25 deletions
diff --git a/arch/i386/kernel/entry.S b/arch/i386/kernel/entry.S
index 87f9f60b803b..ba22ec8fab54 100644
--- a/arch/i386/kernel/entry.S
+++ b/arch/i386/kernel/entry.S
@@ -591,11 +591,9 @@ ENTRY(name) \
591/* The include is where all of the SMP etc. interrupts come from */ 591/* The include is where all of the SMP etc. interrupts come from */
592#include "entry_arch.h" 592#include "entry_arch.h"
593 593
594ENTRY(divide_error) 594KPROBE_ENTRY(page_fault)
595 RING0_INT_FRAME 595 RING0_EC_FRAME
596 pushl $0 # no error code 596 pushl $do_page_fault
597 CFI_ADJUST_CFA_OFFSET 4
598 pushl $do_divide_error
599 CFI_ADJUST_CFA_OFFSET 4 597 CFI_ADJUST_CFA_OFFSET 4
600 ALIGN 598 ALIGN
601error_code: 599error_code:
@@ -645,6 +643,7 @@ error_code:
645 call *%edi 643 call *%edi
646 jmp ret_from_exception 644 jmp ret_from_exception
647 CFI_ENDPROC 645 CFI_ENDPROC
646KPROBE_END(page_fault)
648 647
649ENTRY(coprocessor_error) 648ENTRY(coprocessor_error)
650 RING0_INT_FRAME 649 RING0_INT_FRAME
@@ -720,7 +719,8 @@ debug_stack_correct:
720 call do_debug 719 call do_debug
721 jmp ret_from_exception 720 jmp ret_from_exception
722 CFI_ENDPROC 721 CFI_ENDPROC
723 .previous .text 722KPROBE_END(debug)
723
724/* 724/*
725 * NMI is doubly nasty. It can happen _while_ we're handling 725 * NMI is doubly nasty. It can happen _while_ we're handling
726 * a debug fault, and the debug fault hasn't yet been able to 726 * a debug fault, and the debug fault hasn't yet been able to
@@ -816,7 +816,7 @@ KPROBE_ENTRY(int3)
816 call do_int3 816 call do_int3
817 jmp ret_from_exception 817 jmp ret_from_exception
818 CFI_ENDPROC 818 CFI_ENDPROC
819 .previous .text 819KPROBE_END(int3)
820 820
821ENTRY(overflow) 821ENTRY(overflow)
822 RING0_INT_FRAME 822 RING0_INT_FRAME
@@ -881,7 +881,7 @@ KPROBE_ENTRY(general_protection)
881 CFI_ADJUST_CFA_OFFSET 4 881 CFI_ADJUST_CFA_OFFSET 4
882 jmp error_code 882 jmp error_code
883 CFI_ENDPROC 883 CFI_ENDPROC
884 .previous .text 884KPROBE_END(general_protection)
885 885
886ENTRY(alignment_check) 886ENTRY(alignment_check)
887 RING0_EC_FRAME 887 RING0_EC_FRAME
@@ -890,13 +890,14 @@ ENTRY(alignment_check)
890 jmp error_code 890 jmp error_code
891 CFI_ENDPROC 891 CFI_ENDPROC
892 892
893KPROBE_ENTRY(page_fault) 893ENTRY(divide_error)
894 RING0_EC_FRAME 894 RING0_INT_FRAME
895 pushl $do_page_fault 895 pushl $0 # no error code
896 CFI_ADJUST_CFA_OFFSET 4
897 pushl $do_divide_error
896 CFI_ADJUST_CFA_OFFSET 4 898 CFI_ADJUST_CFA_OFFSET 4
897 jmp error_code 899 jmp error_code
898 CFI_ENDPROC 900 CFI_ENDPROC
899 .previous .text
900 901
901#ifdef CONFIG_X86_MCE 902#ifdef CONFIG_X86_MCE
902ENTRY(machine_check) 903ENTRY(machine_check)
diff --git a/arch/x86_64/kernel/entry.S b/arch/x86_64/kernel/entry.S
index 2092f565aa87..780f9b26169f 100644
--- a/arch/x86_64/kernel/entry.S
+++ b/arch/x86_64/kernel/entry.S
@@ -819,7 +819,7 @@ paranoid_schedule\trace:
819 * Exception entry point. This expects an error code/orig_rax on the stack 819 * Exception entry point. This expects an error code/orig_rax on the stack
820 * and the exception handler in %rax. 820 * and the exception handler in %rax.
821 */ 821 */
822ENTRY(error_entry) 822KPROBE_ENTRY(error_entry)
823 _frame RDI 823 _frame RDI
824 /* rdi slot contains rax, oldrax contains error code */ 824 /* rdi slot contains rax, oldrax contains error code */
825 cld 825 cld
@@ -903,7 +903,7 @@ error_kernelspace:
903 cmpq $gs_change,RIP(%rsp) 903 cmpq $gs_change,RIP(%rsp)
904 je error_swapgs 904 je error_swapgs
905 jmp error_sti 905 jmp error_sti
906END(error_entry) 906KPROBE_END(error_entry)
907 907
908 /* Reload gs selector with exception handling */ 908 /* Reload gs selector with exception handling */
909 /* edi: new selector */ 909 /* edi: new selector */
@@ -1025,8 +1025,7 @@ ENDPROC(execve)
1025 1025
1026KPROBE_ENTRY(page_fault) 1026KPROBE_ENTRY(page_fault)
1027 errorentry do_page_fault 1027 errorentry do_page_fault
1028END(page_fault) 1028KPROBE_END(page_fault)
1029 .previous .text
1030 1029
1031ENTRY(coprocessor_error) 1030ENTRY(coprocessor_error)
1032 zeroentry do_coprocessor_error 1031 zeroentry do_coprocessor_error
@@ -1047,8 +1046,7 @@ KPROBE_ENTRY(debug)
1047 CFI_ADJUST_CFA_OFFSET 8 1046 CFI_ADJUST_CFA_OFFSET 8
1048 paranoidentry do_debug, DEBUG_STACK 1047 paranoidentry do_debug, DEBUG_STACK
1049 paranoidexit 1048 paranoidexit
1050END(debug) 1049KPROBE_END(debug)
1051 .previous .text
1052 1050
1053 /* runs on exception stack */ 1051 /* runs on exception stack */
1054KPROBE_ENTRY(nmi) 1052KPROBE_ENTRY(nmi)
@@ -1062,8 +1060,7 @@ KPROBE_ENTRY(nmi)
1062 jmp paranoid_exit1 1060 jmp paranoid_exit1
1063 CFI_ENDPROC 1061 CFI_ENDPROC
1064#endif 1062#endif
1065END(nmi) 1063KPROBE_END(nmi)
1066 .previous .text
1067 1064
1068KPROBE_ENTRY(int3) 1065KPROBE_ENTRY(int3)
1069 INTR_FRAME 1066 INTR_FRAME
@@ -1072,8 +1069,7 @@ KPROBE_ENTRY(int3)
1072 paranoidentry do_int3, DEBUG_STACK 1069 paranoidentry do_int3, DEBUG_STACK
1073 jmp paranoid_exit1 1070 jmp paranoid_exit1
1074 CFI_ENDPROC 1071 CFI_ENDPROC
1075END(int3) 1072KPROBE_END(int3)
1076 .previous .text
1077 1073
1078ENTRY(overflow) 1074ENTRY(overflow)
1079 zeroentry do_overflow 1075 zeroentry do_overflow
@@ -1121,8 +1117,7 @@ END(stack_segment)
1121 1117
1122KPROBE_ENTRY(general_protection) 1118KPROBE_ENTRY(general_protection)
1123 errorentry do_general_protection 1119 errorentry do_general_protection
1124END(general_protection) 1120KPROBE_END(general_protection)
1125 .previous .text
1126 1121
1127ENTRY(alignment_check) 1122ENTRY(alignment_check)
1128 errorentry do_alignment_check 1123 errorentry do_alignment_check
diff --git a/include/linux/linkage.h b/include/linux/linkage.h
index 932021f872d5..6c9873f88287 100644
--- a/include/linux/linkage.h
+++ b/include/linux/linkage.h
@@ -35,9 +35,13 @@
35#endif 35#endif
36 36
37#define KPROBE_ENTRY(name) \ 37#define KPROBE_ENTRY(name) \
38 .section .kprobes.text, "ax"; \ 38 .pushsection .kprobes.text, "ax"; \
39 ENTRY(name) 39 ENTRY(name)
40 40
41#define KPROBE_END(name) \
42 END(name); \
43 .popsection
44
41#ifndef END 45#ifndef END
42#define END(name) \ 46#define END(name) \
43 .size name, .-name 47 .size name, .-name