diff options
| author | Arnd Bergmann <arnd@arndb.de> | 2013-02-28 18:53:01 +0100 |
|---|---|---|
| committer | Arnd Bergmann <arnd@arndb.de> | 2013-02-28 18:53:01 +0100 |
| commit | 168268a225d24da3768a88c1029fb3014b0837ca (patch) | |
| tree | afde019a1ac79366df0b96a2fcc8ba50bc5298fa /arch/mips/kernel/ftrace.c | |
| parent | 04ee16bdf486061147c608410c2c9181352aaa3a (diff) | |
| parent | 6f1989bc982bc176b0d63e028e9b7f23ae1b4583 (diff) | |
Merge 'mmc/upstream' into late/mvebu2
These patches from the mmc tree were merged into v3.9 already
and the later mvebu patches depend on them.
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
Diffstat (limited to 'arch/mips/kernel/ftrace.c')
| -rw-r--r-- | arch/mips/kernel/ftrace.c | 36 |
1 files changed, 35 insertions, 1 deletions
diff --git a/arch/mips/kernel/ftrace.c b/arch/mips/kernel/ftrace.c index 6a2d758dd8e9..83fa1460e294 100644 --- a/arch/mips/kernel/ftrace.c +++ b/arch/mips/kernel/ftrace.c @@ -25,6 +25,12 @@ #define MCOUNT_OFFSET_INSNS 4 #endif +/* Arch override because MIPS doesn't need to run this from stop_machine() */ +void arch_ftrace_update_code(int command) +{ + ftrace_modify_all_code(command); +} + /* * Check if the address is in kernel space * @@ -89,6 +95,24 @@ static int ftrace_modify_code(unsigned long ip, unsigned int new_code) return 0; } +#ifndef CONFIG_64BIT +static int ftrace_modify_code_2(unsigned long ip, unsigned int new_code1, + unsigned int new_code2) +{ + int faulted; + + safe_store_code(new_code1, ip, faulted); + if (unlikely(faulted)) + return -EFAULT; + ip += 4; + safe_store_code(new_code2, ip, faulted); + if (unlikely(faulted)) + return -EFAULT; + flush_icache_range(ip, ip + 8); /* original ip + 12 */ + return 0; +} +#endif + /* * The details about the calling site of mcount on MIPS * @@ -131,8 +155,18 @@ int ftrace_make_nop(struct module *mod, * needed. */ new = in_kernel_space(ip) ? INSN_NOP : INSN_B_1F; - +#ifdef CONFIG_64BIT return ftrace_modify_code(ip, new); +#else + /* + * On 32 bit MIPS platforms, gcc adds a stack adjust + * instruction in the delay slot after the branch to + * mcount and expects mcount to restore the sp on return. + * This is based on a legacy API and does nothing but + * waste instructions so it's being removed at runtime. + */ + return ftrace_modify_code_2(ip, new, INSN_NOP); +#endif } int ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr) |
