diff options
| -rw-r--r-- | arch/mips/kernel/ftrace.c | 48 |
1 files changed, 26 insertions, 22 deletions
diff --git a/arch/mips/kernel/ftrace.c b/arch/mips/kernel/ftrace.c index c4042cad836e..628e90b992d1 100644 --- a/arch/mips/kernel/ftrace.c +++ b/arch/mips/kernel/ftrace.c | |||
| @@ -146,7 +146,7 @@ int __init ftrace_dyn_arch_init(void *data) | |||
| 146 | 146 | ||
| 147 | return 0; | 147 | return 0; |
| 148 | } | 148 | } |
| 149 | #endif /* CONFIG_DYNAMIC_FTRACE */ | 149 | #endif /* CONFIG_DYNAMIC_FTRACE */ |
| 150 | 150 | ||
| 151 | #ifdef CONFIG_FUNCTION_GRAPH_TRACER | 151 | #ifdef CONFIG_FUNCTION_GRAPH_TRACER |
| 152 | 152 | ||
| @@ -166,9 +166,10 @@ int ftrace_disable_ftrace_graph_caller(void) | |||
| 166 | return ftrace_modify_code(FTRACE_GRAPH_CALL_IP, INSN_NOP); | 166 | return ftrace_modify_code(FTRACE_GRAPH_CALL_IP, INSN_NOP); |
| 167 | } | 167 | } |
| 168 | 168 | ||
| 169 | #endif /* !CONFIG_DYNAMIC_FTRACE */ | 169 | #endif /* CONFIG_DYNAMIC_FTRACE */ |
| 170 | 170 | ||
| 171 | #ifndef KBUILD_MCOUNT_RA_ADDRESS | 171 | #ifndef KBUILD_MCOUNT_RA_ADDRESS |
| 172 | |||
| 172 | #define S_RA_SP (0xafbf << 16) /* s{d,w} ra, offset(sp) */ | 173 | #define S_RA_SP (0xafbf << 16) /* s{d,w} ra, offset(sp) */ |
| 173 | #define S_R_SP (0xafb0 << 16) /* s{d,w} R, offset(sp) */ | 174 | #define S_R_SP (0xafb0 << 16) /* s{d,w} R, offset(sp) */ |
| 174 | #define OFFSET_MASK 0xffff /* stack offset range: 0 ~ PT_SIZE */ | 175 | #define OFFSET_MASK 0xffff /* stack offset range: 0 ~ PT_SIZE */ |
| @@ -182,17 +183,17 @@ unsigned long ftrace_get_parent_addr(unsigned long self_addr, | |||
| 182 | unsigned int code; | 183 | unsigned int code; |
| 183 | int faulted; | 184 | int faulted; |
| 184 | 185 | ||
| 185 | /* in module or kernel? */ | 186 | /* |
| 186 | if (self_addr & 0x40000000) { | 187 | * For module, move the ip from calling site of mcount to the |
| 187 | /* module: move to the instruction "lui v1, HI_16BIT_OF_MCOUNT" */ | 188 | * instruction "lui v1, hi_16bit_of_mcount"(offset is 20), but for |
| 188 | ip = self_addr - 20; | 189 | * kernel, move to the instruction "move ra, at"(offset is 12) |
| 189 | } else { | 190 | */ |
| 190 | /* kernel: move to the instruction "move ra, at" */ | 191 | ip = self_addr - ((self_addr & 0x40000000) ? 20 : 12); |
| 191 | ip = self_addr - 12; | ||
| 192 | } | ||
| 193 | 192 | ||
| 194 | /* search the text until finding the non-store instruction or "s{d,w} | 193 | /* |
| 195 | * ra, offset(sp)" instruction */ | 194 | * search the text until finding the non-store instruction or "s{d,w} |
| 195 | * ra, offset(sp)" instruction | ||
| 196 | */ | ||
| 196 | do { | 197 | do { |
| 197 | ip -= 4; | 198 | ip -= 4; |
| 198 | 199 | ||
| @@ -201,10 +202,11 @@ unsigned long ftrace_get_parent_addr(unsigned long self_addr, | |||
| 201 | 202 | ||
| 202 | if (unlikely(faulted)) | 203 | if (unlikely(faulted)) |
| 203 | return 0; | 204 | return 0; |
| 204 | 205 | /* | |
| 205 | /* If we hit the non-store instruction before finding where the | 206 | * If we hit the non-store instruction before finding where the |
| 206 | * ra is stored, then this is a leaf function and it does not | 207 | * ra is stored, then this is a leaf function and it does not |
| 207 | * store the ra on the stack. */ | 208 | * store the ra on the stack |
| 209 | */ | ||
| 208 | if ((code & S_R_SP) != S_R_SP) | 210 | if ((code & S_R_SP) != S_R_SP) |
| 209 | return parent_addr; | 211 | return parent_addr; |
| 210 | 212 | ||
| @@ -222,7 +224,7 @@ unsigned long ftrace_get_parent_addr(unsigned long self_addr, | |||
| 222 | return 0; | 224 | return 0; |
| 223 | } | 225 | } |
| 224 | 226 | ||
| 225 | #endif | 227 | #endif /* !KBUILD_MCOUNT_RA_ADDRESS */ |
| 226 | 228 | ||
| 227 | /* | 229 | /* |
| 228 | * Hook the return address and push it in the stack of return addrs | 230 | * Hook the return address and push it in the stack of return addrs |
| @@ -240,7 +242,8 @@ void prepare_ftrace_return(unsigned long *parent, unsigned long self_addr, | |||
| 240 | if (unlikely(atomic_read(¤t->tracing_graph_pause))) | 242 | if (unlikely(atomic_read(¤t->tracing_graph_pause))) |
| 241 | return; | 243 | return; |
| 242 | 244 | ||
| 243 | /* "parent" is the stack address saved the return address of the caller | 245 | /* |
| 246 | * "parent" is the stack address saved the return address of the caller | ||
| 244 | * of _mcount. | 247 | * of _mcount. |
| 245 | * | 248 | * |
| 246 | * if the gcc < 4.5, a leaf function does not save the return address | 249 | * if the gcc < 4.5, a leaf function does not save the return address |
| @@ -262,10 +265,11 @@ void prepare_ftrace_return(unsigned long *parent, unsigned long self_addr, | |||
| 262 | goto out; | 265 | goto out; |
| 263 | #ifndef KBUILD_MCOUNT_RA_ADDRESS | 266 | #ifndef KBUILD_MCOUNT_RA_ADDRESS |
| 264 | parent = (unsigned long *)ftrace_get_parent_addr(self_addr, old, | 267 | parent = (unsigned long *)ftrace_get_parent_addr(self_addr, old, |
| 265 | (unsigned long)parent, | 268 | (unsigned long)parent, fp); |
| 266 | fp); | 269 | /* |
| 267 | /* If fails when getting the stack address of the non-leaf function's | 270 | * If fails when getting the stack address of the non-leaf function's |
| 268 | * ra, stop function graph tracer and return */ | 271 | * ra, stop function graph tracer and return |
| 272 | */ | ||
| 269 | if (parent == 0) | 273 | if (parent == 0) |
| 270 | goto out; | 274 | goto out; |
| 271 | #endif | 275 | #endif |
| @@ -292,4 +296,4 @@ out: | |||
| 292 | ftrace_graph_stop(); | 296 | ftrace_graph_stop(); |
| 293 | WARN_ON(1); | 297 | WARN_ON(1); |
| 294 | } | 298 | } |
| 295 | #endif /* CONFIG_FUNCTION_GRAPH_TRACER */ | 299 | #endif /* CONFIG_FUNCTION_GRAPH_TRACER */ |
