diff options
| -rw-r--r-- | arch/mips/Makefile | 7 | ||||
| -rw-r--r-- | arch/mips/kernel/ftrace.c | 24 | ||||
| -rw-r--r-- | arch/mips/kernel/mcount.S | 14 |
3 files changed, 38 insertions, 7 deletions
diff --git a/arch/mips/Makefile b/arch/mips/Makefile index 3725ee923d05..d2c39fdcdfeb 100644 --- a/arch/mips/Makefile +++ b/arch/mips/Makefile | |||
| @@ -51,6 +51,13 @@ endif | |||
| 51 | ifndef CONFIG_FUNCTION_TRACER | 51 | ifndef CONFIG_FUNCTION_TRACER |
| 52 | cflags-y := -ffunction-sections | 52 | cflags-y := -ffunction-sections |
| 53 | endif | 53 | endif |
| 54 | ifdef CONFIG_FUNCTION_GRAPH_TRACER | ||
| 55 | ifndef KBUILD_MCOUNT_RA_ADDRESS | ||
| 56 | ifeq ($(call cc-option-yn,-mmcount-ra-address), y) | ||
| 57 | cflags-y += -mmcount-ra-address -DKBUILD_MCOUNT_RA_ADDRESS | ||
| 58 | endif | ||
| 59 | endif | ||
| 60 | endif | ||
| 54 | cflags-y += $(call cc-option, -mno-check-zero-division) | 61 | cflags-y += $(call cc-option, -mno-check-zero-division) |
| 55 | 62 | ||
| 56 | ifdef CONFIG_32BIT | 63 | ifdef CONFIG_32BIT |
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 */ |
