diff options
Diffstat (limited to 'arch/x86')
-rw-r--r-- | arch/x86/Kconfig | 2 | ||||
-rw-r--r-- | arch/x86/include/asm/ftrace.h | 4 | ||||
-rw-r--r-- | arch/x86/kernel/Makefile | 3 | ||||
-rw-r--r-- | arch/x86/kernel/entry_32.S | 4 | ||||
-rw-r--r-- | arch/x86/kernel/entry_64.S | 4 | ||||
-rw-r--r-- | arch/x86/kernel/ftrace.c | 50 | ||||
-rw-r--r-- | arch/x86/kernel/i386_ksyms_32.c | 2 | ||||
-rw-r--r-- | arch/x86/kernel/x8664_ksyms_64.c | 2 | ||||
-rw-r--r-- | arch/x86/xen/Makefile | 2 |
9 files changed, 33 insertions, 40 deletions
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index 350bee1d54dc..d11d7b513191 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig | |||
@@ -28,7 +28,7 @@ config X86 | |||
28 | select HAVE_KRETPROBES | 28 | select HAVE_KRETPROBES |
29 | select HAVE_FTRACE_MCOUNT_RECORD | 29 | select HAVE_FTRACE_MCOUNT_RECORD |
30 | select HAVE_DYNAMIC_FTRACE | 30 | select HAVE_DYNAMIC_FTRACE |
31 | select HAVE_FTRACE | 31 | select HAVE_FUNCTION_TRACER |
32 | select HAVE_KVM if ((X86_32 && !X86_VOYAGER && !X86_VISWS && !X86_NUMAQ) || X86_64) | 32 | select HAVE_KVM if ((X86_32 && !X86_VOYAGER && !X86_VISWS && !X86_NUMAQ) || X86_64) |
33 | select HAVE_ARCH_KGDB if !X86_VOYAGER | 33 | select HAVE_ARCH_KGDB if !X86_VOYAGER |
34 | select HAVE_ARCH_TRACEHOOK | 34 | select HAVE_ARCH_TRACEHOOK |
diff --git a/arch/x86/include/asm/ftrace.h b/arch/x86/include/asm/ftrace.h index 47f7e65e6c1d..9e8bc29b8b17 100644 --- a/arch/x86/include/asm/ftrace.h +++ b/arch/x86/include/asm/ftrace.h | |||
@@ -1,7 +1,7 @@ | |||
1 | #ifndef _ASM_X86_FTRACE_H | 1 | #ifndef _ASM_X86_FTRACE_H |
2 | #define _ASM_X86_FTRACE_H | 2 | #define _ASM_X86_FTRACE_H |
3 | 3 | ||
4 | #ifdef CONFIG_FTRACE | 4 | #ifdef CONFIG_FUNCTION_TRACER |
5 | #define MCOUNT_ADDR ((long)(mcount)) | 5 | #define MCOUNT_ADDR ((long)(mcount)) |
6 | #define MCOUNT_INSN_SIZE 5 /* sizeof mcount call */ | 6 | #define MCOUNT_INSN_SIZE 5 /* sizeof mcount call */ |
7 | 7 | ||
@@ -19,6 +19,6 @@ static inline unsigned long ftrace_call_adjust(unsigned long addr) | |||
19 | } | 19 | } |
20 | #endif | 20 | #endif |
21 | 21 | ||
22 | #endif /* CONFIG_FTRACE */ | 22 | #endif /* CONFIG_FUNCTION_TRACER */ |
23 | 23 | ||
24 | #endif /* _ASM_X86_FTRACE_H */ | 24 | #endif /* _ASM_X86_FTRACE_H */ |
diff --git a/arch/x86/kernel/Makefile b/arch/x86/kernel/Makefile index d7e5a58ee22f..e489ff9cb3e2 100644 --- a/arch/x86/kernel/Makefile +++ b/arch/x86/kernel/Makefile | |||
@@ -6,11 +6,12 @@ extra-y := head_$(BITS).o head$(BITS).o head.o init_task.o vmlinu | |||
6 | 6 | ||
7 | CPPFLAGS_vmlinux.lds += -U$(UTS_MACHINE) | 7 | CPPFLAGS_vmlinux.lds += -U$(UTS_MACHINE) |
8 | 8 | ||
9 | ifdef CONFIG_FTRACE | 9 | ifdef CONFIG_FUNCTION_TRACER |
10 | # Do not profile debug and lowlevel utilities | 10 | # Do not profile debug and lowlevel utilities |
11 | CFLAGS_REMOVE_tsc.o = -pg | 11 | CFLAGS_REMOVE_tsc.o = -pg |
12 | CFLAGS_REMOVE_rtc.o = -pg | 12 | CFLAGS_REMOVE_rtc.o = -pg |
13 | CFLAGS_REMOVE_paravirt-spinlocks.o = -pg | 13 | CFLAGS_REMOVE_paravirt-spinlocks.o = -pg |
14 | CFLAGS_REMOVE_ftrace.o = -pg | ||
14 | endif | 15 | endif |
15 | 16 | ||
16 | # | 17 | # |
diff --git a/arch/x86/kernel/entry_32.S b/arch/x86/kernel/entry_32.S index dd65143941a8..28b597ef9ca1 100644 --- a/arch/x86/kernel/entry_32.S +++ b/arch/x86/kernel/entry_32.S | |||
@@ -1149,7 +1149,7 @@ ENDPROC(xen_failsafe_callback) | |||
1149 | 1149 | ||
1150 | #endif /* CONFIG_XEN */ | 1150 | #endif /* CONFIG_XEN */ |
1151 | 1151 | ||
1152 | #ifdef CONFIG_FTRACE | 1152 | #ifdef CONFIG_FUNCTION_TRACER |
1153 | #ifdef CONFIG_DYNAMIC_FTRACE | 1153 | #ifdef CONFIG_DYNAMIC_FTRACE |
1154 | 1154 | ||
1155 | ENTRY(mcount) | 1155 | ENTRY(mcount) |
@@ -1204,7 +1204,7 @@ trace: | |||
1204 | jmp ftrace_stub | 1204 | jmp ftrace_stub |
1205 | END(mcount) | 1205 | END(mcount) |
1206 | #endif /* CONFIG_DYNAMIC_FTRACE */ | 1206 | #endif /* CONFIG_DYNAMIC_FTRACE */ |
1207 | #endif /* CONFIG_FTRACE */ | 1207 | #endif /* CONFIG_FUNCTION_TRACER */ |
1208 | 1208 | ||
1209 | .section .rodata,"a" | 1209 | .section .rodata,"a" |
1210 | #include "syscall_table_32.S" | 1210 | #include "syscall_table_32.S" |
diff --git a/arch/x86/kernel/entry_64.S b/arch/x86/kernel/entry_64.S index 09e7145484c5..b86f332c96a6 100644 --- a/arch/x86/kernel/entry_64.S +++ b/arch/x86/kernel/entry_64.S | |||
@@ -61,7 +61,7 @@ | |||
61 | 61 | ||
62 | .code64 | 62 | .code64 |
63 | 63 | ||
64 | #ifdef CONFIG_FTRACE | 64 | #ifdef CONFIG_FUNCTION_TRACER |
65 | #ifdef CONFIG_DYNAMIC_FTRACE | 65 | #ifdef CONFIG_DYNAMIC_FTRACE |
66 | ENTRY(mcount) | 66 | ENTRY(mcount) |
67 | retq | 67 | retq |
@@ -138,7 +138,7 @@ trace: | |||
138 | jmp ftrace_stub | 138 | jmp ftrace_stub |
139 | END(mcount) | 139 | END(mcount) |
140 | #endif /* CONFIG_DYNAMIC_FTRACE */ | 140 | #endif /* CONFIG_DYNAMIC_FTRACE */ |
141 | #endif /* CONFIG_FTRACE */ | 141 | #endif /* CONFIG_FUNCTION_TRACER */ |
142 | 142 | ||
143 | #ifndef CONFIG_PREEMPT | 143 | #ifndef CONFIG_PREEMPT |
144 | #define retint_kernel retint_restore_args | 144 | #define retint_kernel retint_restore_args |
diff --git a/arch/x86/kernel/ftrace.c b/arch/x86/kernel/ftrace.c index d073d981a730..50ea0ac8c9bf 100644 --- a/arch/x86/kernel/ftrace.c +++ b/arch/x86/kernel/ftrace.c | |||
@@ -21,8 +21,7 @@ | |||
21 | #include <asm/nops.h> | 21 | #include <asm/nops.h> |
22 | 22 | ||
23 | 23 | ||
24 | /* Long is fine, even if it is only 4 bytes ;-) */ | 24 | static unsigned char ftrace_nop[MCOUNT_INSN_SIZE]; |
25 | static unsigned long *ftrace_nop; | ||
26 | 25 | ||
27 | union ftrace_code_union { | 26 | union ftrace_code_union { |
28 | char code[MCOUNT_INSN_SIZE]; | 27 | char code[MCOUNT_INSN_SIZE]; |
@@ -33,17 +32,17 @@ union ftrace_code_union { | |||
33 | }; | 32 | }; |
34 | 33 | ||
35 | 34 | ||
36 | static int notrace ftrace_calc_offset(long ip, long addr) | 35 | static int ftrace_calc_offset(long ip, long addr) |
37 | { | 36 | { |
38 | return (int)(addr - ip); | 37 | return (int)(addr - ip); |
39 | } | 38 | } |
40 | 39 | ||
41 | notrace unsigned char *ftrace_nop_replace(void) | 40 | unsigned char *ftrace_nop_replace(void) |
42 | { | 41 | { |
43 | return (char *)ftrace_nop; | 42 | return ftrace_nop; |
44 | } | 43 | } |
45 | 44 | ||
46 | notrace unsigned char *ftrace_call_replace(unsigned long ip, unsigned long addr) | 45 | unsigned char *ftrace_call_replace(unsigned long ip, unsigned long addr) |
47 | { | 46 | { |
48 | static union ftrace_code_union calc; | 47 | static union ftrace_code_union calc; |
49 | 48 | ||
@@ -57,7 +56,7 @@ notrace unsigned char *ftrace_call_replace(unsigned long ip, unsigned long addr) | |||
57 | return calc.code; | 56 | return calc.code; |
58 | } | 57 | } |
59 | 58 | ||
60 | notrace int | 59 | int |
61 | ftrace_modify_code(unsigned long ip, unsigned char *old_code, | 60 | ftrace_modify_code(unsigned long ip, unsigned char *old_code, |
62 | unsigned char *new_code) | 61 | unsigned char *new_code) |
63 | { | 62 | { |
@@ -66,26 +65,31 @@ ftrace_modify_code(unsigned long ip, unsigned char *old_code, | |||
66 | /* | 65 | /* |
67 | * Note: Due to modules and __init, code can | 66 | * Note: Due to modules and __init, code can |
68 | * disappear and change, we need to protect against faulting | 67 | * disappear and change, we need to protect against faulting |
69 | * as well as code changing. | 68 | * as well as code changing. We do this by using the |
69 | * probe_kernel_* functions. | ||
70 | * | 70 | * |
71 | * No real locking needed, this code is run through | 71 | * No real locking needed, this code is run through |
72 | * kstop_machine, or before SMP starts. | 72 | * kstop_machine, or before SMP starts. |
73 | */ | 73 | */ |
74 | if (__copy_from_user_inatomic(replaced, (char __user *)ip, MCOUNT_INSN_SIZE)) | ||
75 | return 1; | ||
76 | 74 | ||
75 | /* read the text we want to modify */ | ||
76 | if (probe_kernel_read(replaced, (void *)ip, MCOUNT_INSN_SIZE)) | ||
77 | return -EFAULT; | ||
78 | |||
79 | /* Make sure it is what we expect it to be */ | ||
77 | if (memcmp(replaced, old_code, MCOUNT_INSN_SIZE) != 0) | 80 | if (memcmp(replaced, old_code, MCOUNT_INSN_SIZE) != 0) |
78 | return 2; | 81 | return -EINVAL; |
79 | 82 | ||
80 | WARN_ON_ONCE(__copy_to_user_inatomic((char __user *)ip, new_code, | 83 | /* replace the text with the new text */ |
81 | MCOUNT_INSN_SIZE)); | 84 | if (probe_kernel_write((void *)ip, new_code, MCOUNT_INSN_SIZE)) |
85 | return -EPERM; | ||
82 | 86 | ||
83 | sync_core(); | 87 | sync_core(); |
84 | 88 | ||
85 | return 0; | 89 | return 0; |
86 | } | 90 | } |
87 | 91 | ||
88 | notrace int ftrace_update_ftrace_func(ftrace_func_t func) | 92 | int ftrace_update_ftrace_func(ftrace_func_t func) |
89 | { | 93 | { |
90 | unsigned long ip = (unsigned long)(&ftrace_call); | 94 | unsigned long ip = (unsigned long)(&ftrace_call); |
91 | unsigned char old[MCOUNT_INSN_SIZE], *new; | 95 | unsigned char old[MCOUNT_INSN_SIZE], *new; |
@@ -98,13 +102,6 @@ notrace int ftrace_update_ftrace_func(ftrace_func_t func) | |||
98 | return ret; | 102 | return ret; |
99 | } | 103 | } |
100 | 104 | ||
101 | notrace int ftrace_mcount_set(unsigned long *data) | ||
102 | { | ||
103 | /* mcount is initialized as a nop */ | ||
104 | *data = 0; | ||
105 | return 0; | ||
106 | } | ||
107 | |||
108 | int __init ftrace_dyn_arch_init(void *data) | 105 | int __init ftrace_dyn_arch_init(void *data) |
109 | { | 106 | { |
110 | extern const unsigned char ftrace_test_p6nop[]; | 107 | extern const unsigned char ftrace_test_p6nop[]; |
@@ -127,9 +124,6 @@ int __init ftrace_dyn_arch_init(void *data) | |||
127 | * TODO: check the cpuid to determine the best nop. | 124 | * TODO: check the cpuid to determine the best nop. |
128 | */ | 125 | */ |
129 | asm volatile ( | 126 | asm volatile ( |
130 | "jmp ftrace_test_jmp\n" | ||
131 | /* This code needs to stay around */ | ||
132 | ".section .text, \"ax\"\n" | ||
133 | "ftrace_test_jmp:" | 127 | "ftrace_test_jmp:" |
134 | "jmp ftrace_test_p6nop\n" | 128 | "jmp ftrace_test_p6nop\n" |
135 | "nop\n" | 129 | "nop\n" |
@@ -140,8 +134,6 @@ int __init ftrace_dyn_arch_init(void *data) | |||
140 | "jmp 1f\n" | 134 | "jmp 1f\n" |
141 | "ftrace_test_nop5:" | 135 | "ftrace_test_nop5:" |
142 | ".byte 0x66,0x66,0x66,0x66,0x90\n" | 136 | ".byte 0x66,0x66,0x66,0x66,0x90\n" |
143 | "jmp 1f\n" | ||
144 | ".previous\n" | ||
145 | "1:" | 137 | "1:" |
146 | ".section .fixup, \"ax\"\n" | 138 | ".section .fixup, \"ax\"\n" |
147 | "2: movl $1, %0\n" | 139 | "2: movl $1, %0\n" |
@@ -156,15 +148,15 @@ int __init ftrace_dyn_arch_init(void *data) | |||
156 | switch (faulted) { | 148 | switch (faulted) { |
157 | case 0: | 149 | case 0: |
158 | pr_info("ftrace: converting mcount calls to 0f 1f 44 00 00\n"); | 150 | pr_info("ftrace: converting mcount calls to 0f 1f 44 00 00\n"); |
159 | ftrace_nop = (unsigned long *)ftrace_test_p6nop; | 151 | memcpy(ftrace_nop, ftrace_test_p6nop, MCOUNT_INSN_SIZE); |
160 | break; | 152 | break; |
161 | case 1: | 153 | case 1: |
162 | pr_info("ftrace: converting mcount calls to 66 66 66 66 90\n"); | 154 | pr_info("ftrace: converting mcount calls to 66 66 66 66 90\n"); |
163 | ftrace_nop = (unsigned long *)ftrace_test_nop5; | 155 | memcpy(ftrace_nop, ftrace_test_nop5, MCOUNT_INSN_SIZE); |
164 | break; | 156 | break; |
165 | case 2: | 157 | case 2: |
166 | pr_info("ftrace: converting mcount calls to jmp . + 5\n"); | 158 | pr_info("ftrace: converting mcount calls to jmp . + 5\n"); |
167 | ftrace_nop = (unsigned long *)ftrace_test_jmp; | 159 | memcpy(ftrace_nop, ftrace_test_jmp, MCOUNT_INSN_SIZE); |
168 | break; | 160 | break; |
169 | } | 161 | } |
170 | 162 | ||
diff --git a/arch/x86/kernel/i386_ksyms_32.c b/arch/x86/kernel/i386_ksyms_32.c index dd7ebee446af..43cec6bdda63 100644 --- a/arch/x86/kernel/i386_ksyms_32.c +++ b/arch/x86/kernel/i386_ksyms_32.c | |||
@@ -5,7 +5,7 @@ | |||
5 | #include <asm/desc.h> | 5 | #include <asm/desc.h> |
6 | #include <asm/ftrace.h> | 6 | #include <asm/ftrace.h> |
7 | 7 | ||
8 | #ifdef CONFIG_FTRACE | 8 | #ifdef CONFIG_FUNCTION_TRACER |
9 | /* mcount is defined in assembly */ | 9 | /* mcount is defined in assembly */ |
10 | EXPORT_SYMBOL(mcount); | 10 | EXPORT_SYMBOL(mcount); |
11 | #endif | 11 | #endif |
diff --git a/arch/x86/kernel/x8664_ksyms_64.c b/arch/x86/kernel/x8664_ksyms_64.c index b545f371b5f5..695e426aa354 100644 --- a/arch/x86/kernel/x8664_ksyms_64.c +++ b/arch/x86/kernel/x8664_ksyms_64.c | |||
@@ -12,7 +12,7 @@ | |||
12 | #include <asm/desc.h> | 12 | #include <asm/desc.h> |
13 | #include <asm/ftrace.h> | 13 | #include <asm/ftrace.h> |
14 | 14 | ||
15 | #ifdef CONFIG_FTRACE | 15 | #ifdef CONFIG_FUNCTION_TRACER |
16 | /* mcount is defined in assembly */ | 16 | /* mcount is defined in assembly */ |
17 | EXPORT_SYMBOL(mcount); | 17 | EXPORT_SYMBOL(mcount); |
18 | #endif | 18 | #endif |
diff --git a/arch/x86/xen/Makefile b/arch/x86/xen/Makefile index 313947940a1a..6dcefba7836f 100644 --- a/arch/x86/xen/Makefile +++ b/arch/x86/xen/Makefile | |||
@@ -1,4 +1,4 @@ | |||
1 | ifdef CONFIG_FTRACE | 1 | ifdef CONFIG_FUNCTION_TRACER |
2 | # Do not profile debug and lowlevel utilities | 2 | # Do not profile debug and lowlevel utilities |
3 | CFLAGS_REMOVE_spinlock.o = -pg | 3 | CFLAGS_REMOVE_spinlock.o = -pg |
4 | CFLAGS_REMOVE_time.o = -pg | 4 | CFLAGS_REMOVE_time.o = -pg |