|
|
@@ -53,7 +53,7 @@ int ftrace_arch_code_modify_post_process(void)
|
|
|
union ftrace_code_union {
|
|
|
char code[MCOUNT_INSN_SIZE];
|
|
|
struct {
|
|
|
- unsigned char e8;
|
|
|
+ unsigned char op;
|
|
|
int offset;
|
|
|
} __attribute__((packed));
|
|
|
};
|
|
|
@@ -63,20 +63,23 @@ static int ftrace_calc_offset(long ip, long addr)
|
|
|
return (int)(addr - ip);
|
|
|
}
|
|
|
|
|
|
-static unsigned char *ftrace_call_replace(unsigned long ip, unsigned long addr)
|
|
|
+static unsigned char *
|
|
|
+ftrace_text_replace(unsigned char op, unsigned long ip, unsigned long addr)
|
|
|
{
|
|
|
static union ftrace_code_union calc;
|
|
|
|
|
|
- calc.e8 = 0xe8;
|
|
|
+ calc.op = op;
|
|
|
calc.offset = ftrace_calc_offset(ip + MCOUNT_INSN_SIZE, addr);
|
|
|
|
|
|
- /*
|
|
|
- * No locking needed, this must be called via kstop_machine
|
|
|
- * which in essence is like running on a uniprocessor machine.
|
|
|
- */
|
|
|
return calc.code;
|
|
|
}
|
|
|
|
|
|
+static unsigned char *
|
|
|
+ftrace_call_replace(unsigned long ip, unsigned long addr)
|
|
|
+{
|
|
|
+ return ftrace_text_replace(0xe8, ip, addr);
|
|
|
+}
|
|
|
+
|
|
|
static inline int
|
|
|
within(unsigned long addr, unsigned long start, unsigned long end)
|
|
|
{
|
|
|
@@ -686,22 +689,6 @@ int __init ftrace_dyn_arch_init(void)
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
-#if defined(CONFIG_X86_64) || defined(CONFIG_FUNCTION_GRAPH_TRACER)
|
|
|
-static unsigned char *ftrace_jmp_replace(unsigned long ip, unsigned long addr)
|
|
|
-{
|
|
|
- static union ftrace_code_union calc;
|
|
|
-
|
|
|
- /* Jmp not a call (ignore the .e8) */
|
|
|
- calc.e8 = 0xe9;
|
|
|
- calc.offset = ftrace_calc_offset(ip + MCOUNT_INSN_SIZE, addr);
|
|
|
-
|
|
|
- /*
|
|
|
- * ftrace external locks synchronize the access to the static variable.
|
|
|
- */
|
|
|
- return calc.code;
|
|
|
-}
|
|
|
-#endif
|
|
|
-
|
|
|
/* Currently only x86_64 supports dynamic trampolines */
|
|
|
#ifdef CONFIG_X86_64
|
|
|
|
|
|
@@ -923,8 +910,8 @@ static void *addr_from_call(void *ptr)
|
|
|
return NULL;
|
|
|
|
|
|
/* Make sure this is a call */
|
|
|
- if (WARN_ON_ONCE(calc.e8 != 0xe8)) {
|
|
|
- pr_warn("Expected e8, got %x\n", calc.e8);
|
|
|
+ if (WARN_ON_ONCE(calc.op != 0xe8)) {
|
|
|
+ pr_warn("Expected e8, got %x\n", calc.op);
|
|
|
return NULL;
|
|
|
}
|
|
|
|
|
|
@@ -995,6 +982,11 @@ void arch_ftrace_trampoline_free(struct ftrace_ops *ops)
|
|
|
#ifdef CONFIG_DYNAMIC_FTRACE
|
|
|
extern void ftrace_graph_call(void);
|
|
|
|
|
|
+static unsigned char *ftrace_jmp_replace(unsigned long ip, unsigned long addr)
|
|
|
+{
|
|
|
+ return ftrace_text_replace(0xe9, ip, addr);
|
|
|
+}
|
|
|
+
|
|
|
static int ftrace_mod_jmp(unsigned long ip, void *func)
|
|
|
{
|
|
|
unsigned char *new;
|