diff options
author | Wu Zhangjin <wuzhangjin@gmail.com> | 2011-01-19 14:28:29 -0500 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2011-03-14 16:07:24 -0400 |
commit | d9cdb2f1038143c945fcb1a366aae4fa2998419e (patch) | |
tree | f6b0e9b0dd338e1c704cd9f4c7013d9af3476acf /arch/mips/kernel | |
parent | 9a620a559be65023b5fd5d0eaf37dae884c4f404 (diff) |
MIPS, Tracing: Substitute in_kernel_space() for in_module()
The old in_module() may not work in some situations(e.g. when module &
kernel are in the same address space when CONFIG_MAPPED_KERNEL=y), The
in_kernel_space() is more generic and it is also easy to be implemented
via cloning the existing core_kernel_text(), so, replace the in_module()
with in_kernel_space().
Signed-off-by: Wu Zhangjin <wuzhangjin@gmail.com>
Cc: Steven Rostedt <srostedt@redhat.com>
Cc: linux-mips@linux-mips.org
Patchwork: https://patchwork.linux-mips.org/patch/2005/
Signed-off-by: Ralf Baechle <ralf@duck.linux-mips.net>
Diffstat (limited to 'arch/mips/kernel')
-rw-r--r-- | arch/mips/kernel/ftrace.c | 54 |
1 files changed, 27 insertions, 27 deletions
diff --git a/arch/mips/kernel/ftrace.c b/arch/mips/kernel/ftrace.c index 635c1dcdc4fc..5970286131dd 100644 --- a/arch/mips/kernel/ftrace.c +++ b/arch/mips/kernel/ftrace.c | |||
@@ -17,21 +17,7 @@ | |||
17 | #include <asm/cacheflush.h> | 17 | #include <asm/cacheflush.h> |
18 | #include <asm/uasm.h> | 18 | #include <asm/uasm.h> |
19 | 19 | ||
20 | /* | 20 | #include <asm-generic/sections.h> |
21 | * If the Instruction Pointer is in module space (0xc0000000), return true; | ||
22 | * otherwise, it is in kernel space (0x80000000), return false. | ||
23 | * | ||
24 | * FIXME: This will not work when the kernel space and module space are the | ||
25 | * same. If they are the same, we need to modify scripts/recordmcount.pl, | ||
26 | * ftrace_make_nop/call() and the other related parts to ensure the | ||
27 | * enabling/disabling of the calling site to _mcount is right for both kernel | ||
28 | * and module. | ||
29 | */ | ||
30 | |||
31 | static inline int in_module(unsigned long ip) | ||
32 | { | ||
33 | return ip & 0x40000000; | ||
34 | } | ||
35 | 21 | ||
36 | #ifdef CONFIG_DYNAMIC_FTRACE | 22 | #ifdef CONFIG_DYNAMIC_FTRACE |
37 | 23 | ||
@@ -69,6 +55,20 @@ static inline void ftrace_dyn_arch_init_insns(void) | |||
69 | #endif | 55 | #endif |
70 | } | 56 | } |
71 | 57 | ||
58 | /* | ||
59 | * Check if the address is in kernel space | ||
60 | * | ||
61 | * Clone core_kernel_text() from kernel/extable.c, but doesn't call | ||
62 | * init_kernel_text() for Ftrace doesn't trace functions in init sections. | ||
63 | */ | ||
64 | static inline int in_kernel_space(unsigned long ip) | ||
65 | { | ||
66 | if (ip >= (unsigned long)_stext && | ||
67 | ip <= (unsigned long)_etext) | ||
68 | return 1; | ||
69 | return 0; | ||
70 | } | ||
71 | |||
72 | static int ftrace_modify_code(unsigned long ip, unsigned int new_code) | 72 | static int ftrace_modify_code(unsigned long ip, unsigned int new_code) |
73 | { | 73 | { |
74 | int faulted; | 74 | int faulted; |
@@ -91,10 +91,16 @@ int ftrace_make_nop(struct module *mod, | |||
91 | unsigned long ip = rec->ip; | 91 | unsigned long ip = rec->ip; |
92 | 92 | ||
93 | /* | 93 | /* |
94 | * We have compiled module with -mlong-calls, but compiled the kernel | 94 | * If ip is in kernel space, no long call, otherwise, long call is |
95 | * without it, we need to cope with them respectively. | 95 | * needed. |
96 | */ | 96 | */ |
97 | if (in_module(ip)) { | 97 | if (in_kernel_space(ip)) { |
98 | /* | ||
99 | * move at, ra | ||
100 | * jal _mcount --> nop | ||
101 | */ | ||
102 | new = INSN_NOP; | ||
103 | } else { | ||
98 | #if defined(KBUILD_MCOUNT_RA_ADDRESS) && defined(CONFIG_32BIT) | 104 | #if defined(KBUILD_MCOUNT_RA_ADDRESS) && defined(CONFIG_32BIT) |
99 | /* | 105 | /* |
100 | * lui v1, hi_16bit_of_mcount --> b 1f (0x10000005) | 106 | * lui v1, hi_16bit_of_mcount --> b 1f (0x10000005) |
@@ -117,12 +123,6 @@ int ftrace_make_nop(struct module *mod, | |||
117 | */ | 123 | */ |
118 | new = INSN_B_1F_4; | 124 | new = INSN_B_1F_4; |
119 | #endif | 125 | #endif |
120 | } else { | ||
121 | /* | ||
122 | * move at, ra | ||
123 | * jal _mcount --> nop | ||
124 | */ | ||
125 | new = INSN_NOP; | ||
126 | } | 126 | } |
127 | return ftrace_modify_code(ip, new); | 127 | return ftrace_modify_code(ip, new); |
128 | } | 128 | } |
@@ -132,8 +132,8 @@ int ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr) | |||
132 | unsigned int new; | 132 | unsigned int new; |
133 | unsigned long ip = rec->ip; | 133 | unsigned long ip = rec->ip; |
134 | 134 | ||
135 | /* ip, module: 0xc0000000, kernel: 0x80000000 */ | 135 | new = in_kernel_space(ip) ? insn_jal_ftrace_caller : |
136 | new = in_module(ip) ? insn_lui_v1_hi16_mcount : insn_jal_ftrace_caller; | 136 | insn_lui_v1_hi16_mcount; |
137 | 137 | ||
138 | return ftrace_modify_code(ip, new); | 138 | return ftrace_modify_code(ip, new); |
139 | } | 139 | } |
@@ -204,7 +204,7 @@ unsigned long ftrace_get_parent_addr(unsigned long self_addr, | |||
204 | * instruction "lui v1, hi_16bit_of_mcount"(offset is 24), but for | 204 | * instruction "lui v1, hi_16bit_of_mcount"(offset is 24), but for |
205 | * kernel, move after the instruction "move ra, at"(offset is 16) | 205 | * kernel, move after the instruction "move ra, at"(offset is 16) |
206 | */ | 206 | */ |
207 | ip = self_addr - (in_module(self_addr) ? 24 : 16); | 207 | ip = self_addr - (in_kernel_space(self_addr) ? 16 : 24); |
208 | 208 | ||
209 | /* | 209 | /* |
210 | * search the text until finding the non-store instruction or "s{d,w} | 210 | * search the text until finding the non-store instruction or "s{d,w} |