diff options
Diffstat (limited to 'arch/mips/include/asm/ftrace.h')
-rw-r--r-- | arch/mips/include/asm/ftrace.h | 57 |
1 files changed, 57 insertions, 0 deletions
diff --git a/arch/mips/include/asm/ftrace.h b/arch/mips/include/asm/ftrace.h index 7094a40b96d..3986cd8704f 100644 --- a/arch/mips/include/asm/ftrace.h +++ b/arch/mips/include/asm/ftrace.h @@ -19,6 +19,62 @@ extern void _mcount(void); #define mcount _mcount +#define safe_load(load, src, dst, error) \ +do { \ + asm volatile ( \ + "1: " load " %[" STR(dst) "], 0(%[" STR(src) "])\n"\ + " li %[" STR(error) "], 0\n" \ + "2:\n" \ + \ + ".section .fixup, \"ax\"\n" \ + "3: li %[" STR(error) "], 1\n" \ + " j 2b\n" \ + ".previous\n" \ + \ + ".section\t__ex_table,\"a\"\n\t" \ + STR(PTR) "\t1b, 3b\n\t" \ + ".previous\n" \ + \ + : [dst] "=&r" (dst), [error] "=r" (error)\ + : [src] "r" (src) \ + : "memory" \ + ); \ +} while (0) + +#define safe_store(store, src, dst, error) \ +do { \ + asm volatile ( \ + "1: " store " %[" STR(src) "], 0(%[" STR(dst) "])\n"\ + " li %[" STR(error) "], 0\n" \ + "2:\n" \ + \ + ".section .fixup, \"ax\"\n" \ + "3: li %[" STR(error) "], 1\n" \ + " j 2b\n" \ + ".previous\n" \ + \ + ".section\t__ex_table,\"a\"\n\t"\ + STR(PTR) "\t1b, 3b\n\t" \ + ".previous\n" \ + \ + : [error] "=r" (error) \ + : [dst] "r" (dst), [src] "r" (src)\ + : "memory" \ + ); \ +} while (0) + +#define safe_load_code(dst, src, error) \ + safe_load(STR(lw), src, dst, error) +#define safe_store_code(src, dst, error) \ + safe_store(STR(sw), src, dst, error) + +#define safe_load_stack(dst, src, error) \ + safe_load(STR(PTR_L), src, dst, error) + +#define safe_store_stack(src, dst, error) \ + safe_store(STR(PTR_S), src, dst, error) + + #ifdef CONFIG_DYNAMIC_FTRACE static inline unsigned long ftrace_call_adjust(unsigned long addr) { @@ -27,6 +83,7 @@ static inline unsigned long ftrace_call_adjust(unsigned long addr) struct dyn_arch_ftrace { }; + #endif /* CONFIG_DYNAMIC_FTRACE */ #endif /* __ASSEMBLY__ */ #endif /* CONFIG_FUNCTION_TRACER */ |