diff options
Diffstat (limited to 'arch/mips/kernel')
| -rw-r--r-- | arch/mips/kernel/ftrace.c | 24 | ||||
| -rw-r--r-- | arch/mips/kernel/mcount.S | 14 | 
2 files changed, 31 insertions, 7 deletions
| diff --git a/arch/mips/kernel/ftrace.c b/arch/mips/kernel/ftrace.c index e363fc69aabd..68b067040d8b 100644 --- a/arch/mips/kernel/ftrace.c +++ b/arch/mips/kernel/ftrace.c | |||
| @@ -148,6 +148,7 @@ int ftrace_disable_ftrace_graph_caller(void) | |||
| 148 | 148 | ||
| 149 | #endif /* !CONFIG_DYNAMIC_FTRACE */ | 149 | #endif /* !CONFIG_DYNAMIC_FTRACE */ | 
| 150 | 150 | ||
| 151 | #ifndef KBUILD_MCOUNT_RA_ADDRESS | ||
| 151 | #define S_RA_SP (0xafbf << 16) /* s{d,w} ra, offset(sp) */ | 152 | #define S_RA_SP (0xafbf << 16) /* s{d,w} ra, offset(sp) */ | 
| 152 | #define S_R_SP (0xafb0 << 16) /* s{d,w} R, offset(sp) */ | 153 | #define S_R_SP (0xafb0 << 16) /* s{d,w} R, offset(sp) */ | 
| 153 | #define OFFSET_MASK 0xffff /* stack offset range: 0 ~ PT_SIZE */ | 154 | #define OFFSET_MASK 0xffff /* stack offset range: 0 ~ PT_SIZE */ | 
| @@ -201,6 +202,8 @@ unsigned long ftrace_get_parent_addr(unsigned long self_addr, | |||
| 201 | return 0; | 202 | return 0; | 
| 202 | } | 203 | } | 
| 203 | 204 | ||
| 205 | #endif | ||
| 206 | |||
| 204 | /* | 207 | /* | 
| 205 | * Hook the return address and push it in the stack of return addrs | 208 | * Hook the return address and push it in the stack of return addrs | 
| 206 | * in current thread info. | 209 | * in current thread info. | 
| @@ -218,19 +221,26 @@ void prepare_ftrace_return(unsigned long *parent, unsigned long self_addr, | |||
| 218 | return; | 221 | return; | 
| 219 | 222 | ||
| 220 | /* "parent" is the stack address saved the return address of the caller | 223 | /* "parent" is the stack address saved the return address of the caller | 
| 221 | * of _mcount, for a leaf function not save the return address in the | 224 | * of _mcount. | 
| 222 | * stack address, so, we "emulate" one in _mcount's stack space, and | 225 | * | 
| 223 | * hijack it directly, but for a non-leaf function, it will save the | 226 | * if the gcc < 4.5, a leaf function does not save the return address | 
| 224 | * return address to the its stack space, so, we can not hijack the | 227 | * in the stack address, so, we "emulate" one in _mcount's stack space, | 
| 225 | * "parent" directly, but need to find the real stack address, | 228 | * and hijack it directly, but for a non-leaf function, it save the | 
| 229 | * return address to the its own stack space, we can not hijack it | ||
| 230 | * directly, but need to find the real stack address, | ||
| 226 | * ftrace_get_parent_addr() does it! | 231 | * ftrace_get_parent_addr() does it! | 
| 232 | * | ||
| 233 | * if gcc>= 4.5, with the new -mmcount-ra-address option, for a | ||
| 234 | * non-leaf function, the location of the return address will be saved | ||
| 235 | * to $12 for us, and for a leaf function, only put a zero into $12. we | ||
| 236 | * do it in ftrace_graph_caller of mcount.S. | ||
| 227 | */ | 237 | */ | 
| 228 | 238 | ||
| 229 | /* old = *parent; */ | 239 | /* old = *parent; */ | 
| 230 | safe_load_stack(old, parent, faulted); | 240 | safe_load_stack(old, parent, faulted); | 
| 231 | if (unlikely(faulted)) | 241 | if (unlikely(faulted)) | 
| 232 | goto out; | 242 | goto out; | 
| 233 | 243 | #ifndef KBUILD_MCOUNT_RA_ADDRESS | |
| 234 | parent = (unsigned long *)ftrace_get_parent_addr(self_addr, old, | 244 | parent = (unsigned long *)ftrace_get_parent_addr(self_addr, old, | 
| 235 | (unsigned long)parent, | 245 | (unsigned long)parent, | 
| 236 | fp); | 246 | fp); | 
| @@ -238,7 +248,7 @@ void prepare_ftrace_return(unsigned long *parent, unsigned long self_addr, | |||
| 238 | * ra, stop function graph tracer and return */ | 248 | * ra, stop function graph tracer and return */ | 
| 239 | if (parent == 0) | 249 | if (parent == 0) | 
| 240 | goto out; | 250 | goto out; | 
| 241 | 251 | #endif | |
| 242 | /* *parent = return_hooker; */ | 252 | /* *parent = return_hooker; */ | 
| 243 | safe_store_stack(return_hooker, parent, faulted); | 253 | safe_store_stack(return_hooker, parent, faulted); | 
| 244 | if (unlikely(faulted)) | 254 | if (unlikely(faulted)) | 
| diff --git a/arch/mips/kernel/mcount.S b/arch/mips/kernel/mcount.S index 522e91c688fc..0a9cfdb271dd 100644 --- a/arch/mips/kernel/mcount.S +++ b/arch/mips/kernel/mcount.S | |||
| @@ -70,6 +70,9 @@ _mcount: | |||
| 70 | nop | 70 | nop | 
| 71 | 71 | ||
| 72 | MCOUNT_SAVE_REGS | 72 | MCOUNT_SAVE_REGS | 
| 73 | #ifdef KBUILD_MCOUNT_RA_ADDRESS | ||
| 74 | PTR_S t0, PT_R12(sp) /* t0 saved the location of the return address(at) by -mmcount-ra-address */ | ||
| 75 | #endif | ||
| 73 | 76 | ||
| 74 | move a0, ra /* arg1: next ip, selfaddr */ | 77 | move a0, ra /* arg1: next ip, selfaddr */ | 
| 75 | .globl ftrace_call | 78 | .globl ftrace_call | 
| @@ -133,11 +136,22 @@ ftrace_stub: | |||
| 133 | NESTED(ftrace_graph_caller, PT_SIZE, ra) | 136 | NESTED(ftrace_graph_caller, PT_SIZE, ra) | 
| 134 | #ifdef CONFIG_DYNAMIC_FTRACE | 137 | #ifdef CONFIG_DYNAMIC_FTRACE | 
| 135 | PTR_L a1, PT_R31(sp) /* load the original ra from the stack */ | 138 | PTR_L a1, PT_R31(sp) /* load the original ra from the stack */ | 
| 139 | #ifdef KBUILD_MCOUNT_RA_ADDRESS | ||
| 140 | PTR_L t0, PT_R12(sp) /* load the original t0 from the stack */ | ||
| 141 | #endif | ||
| 136 | #else | 142 | #else | 
| 137 | MCOUNT_SAVE_REGS | 143 | MCOUNT_SAVE_REGS | 
| 138 | move a1, ra /* arg2: next ip, selfaddr */ | 144 | move a1, ra /* arg2: next ip, selfaddr */ | 
| 139 | #endif | 145 | #endif | 
| 146 | |||
| 147 | #ifdef KBUILD_MCOUNT_RA_ADDRESS | ||
| 148 | bnez t0, 1f /* non-leaf func: t0 saved the location of the return address */ | ||
| 149 | nop | ||
| 150 | PTR_LA t0, PT_R1(sp) /* leaf func: get the location of at(old ra) from our own stack */ | ||
| 151 | 1: move a0, t0 /* arg1: the location of the return address */ | ||
| 152 | #else | ||
| 140 | PTR_LA a0, PT_R1(sp) /* arg1: &AT -> a0 */ | 153 | PTR_LA a0, PT_R1(sp) /* arg1: &AT -> a0 */ | 
| 154 | #endif | ||
| 141 | jal prepare_ftrace_return | 155 | jal prepare_ftrace_return | 
| 142 | #ifdef CONFIG_FRAME_POINTER | 156 | #ifdef CONFIG_FRAME_POINTER | 
| 143 | move a2, fp /* arg3: frame pointer */ | 157 | move a2, fp /* arg3: frame pointer */ | 
