Commit 89a3927a authored by Guo Ren's avatar Guo Ren

csky: Implement ftrace with regs

This patch implements FTRACE_WITH_REGS for csky, which allows a traced
function's arguments (and some other registers) to be captured into a
struct pt_regs, allowing these to be inspected and/or modified.
Signed-off-by: default avatarGuo Ren <guoren@linux.alibaba.com>
parent 9866d141
...@@ -38,6 +38,7 @@ config CSKY ...@@ -38,6 +38,7 @@ config CSKY
select HAVE_ARCH_AUDITSYSCALL select HAVE_ARCH_AUDITSYSCALL
select HAVE_COPY_THREAD_TLS select HAVE_COPY_THREAD_TLS
select HAVE_DYNAMIC_FTRACE select HAVE_DYNAMIC_FTRACE
select HAVE_DYNAMIC_FTRACE_WITH_REGS
select HAVE_FUNCTION_TRACER select HAVE_FUNCTION_TRACER
select HAVE_FUNCTION_GRAPH_TRACER select HAVE_FUNCTION_GRAPH_TRACER
select HAVE_FTRACE_MCOUNT_RECORD select HAVE_FTRACE_MCOUNT_RECORD
......
...@@ -100,6 +100,66 @@ ...@@ -100,6 +100,66 @@
rte rte
.endm .endm
.macro SAVE_REGS_FTRACE
subi sp, 152
stw tls, (sp, 0)
stw lr, (sp, 4)
mfcr lr, psr
stw lr, (sp, 12)
addi lr, sp, 152
stw lr, (sp, 16)
stw a0, (sp, 20)
stw a0, (sp, 24)
stw a1, (sp, 28)
stw a2, (sp, 32)
stw a3, (sp, 36)
addi sp, 40
stm r4-r13, (sp)
addi sp, 40
stm r16-r30, (sp)
#ifdef CONFIG_CPU_HAS_HILO
mfhi lr
stw lr, (sp, 60)
mflo lr
stw lr, (sp, 64)
mfcr lr, cr14
stw lr, (sp, 68)
#endif
subi sp, 80
.endm
.macro RESTORE_REGS_FTRACE
ldw tls, (sp, 0)
ldw a0, (sp, 16)
mtcr a0, ss0
#ifdef CONFIG_CPU_HAS_HILO
ldw a0, (sp, 140)
mthi a0
ldw a0, (sp, 144)
mtlo a0
ldw a0, (sp, 148)
mtcr a0, cr14
#endif
ldw a0, (sp, 24)
ldw a1, (sp, 28)
ldw a2, (sp, 32)
ldw a3, (sp, 36)
addi sp, 40
ldm r4-r13, (sp)
addi sp, 40
ldm r16-r30, (sp)
addi sp, 72
mfcr sp, ss0
.endm
.macro SAVE_SWITCH_STACK .macro SAVE_SWITCH_STACK
subi sp, 64 subi sp, 64
stm r4-r11, (sp) stm r4-r11, (sp)
......
...@@ -3,6 +3,8 @@ ...@@ -3,6 +3,8 @@
#include <linux/linkage.h> #include <linux/linkage.h>
#include <asm/ftrace.h> #include <asm/ftrace.h>
#include <abi/entry.h>
#include <asm/asm-offsets.h>
/* /*
* csky-gcc with -pg will put the following asm after prologue: * csky-gcc with -pg will put the following asm after prologue:
...@@ -44,6 +46,22 @@ ...@@ -44,6 +46,22 @@
jmp t1 jmp t1
.endm .endm
.macro mcount_enter_regs
subi sp, 8
stw lr, (sp, 0)
stw r8, (sp, 4)
SAVE_REGS_FTRACE
.endm
.macro mcount_exit_regs
RESTORE_REGS_FTRACE
ldw t1, (sp, 0)
ldw r8, (sp, 4)
ldw lr, (sp, 8)
addi sp, 12
jmp t1
.endm
.macro save_return_regs .macro save_return_regs
subi sp, 16 subi sp, 16
stw a0, (sp, 0) stw a0, (sp, 0)
...@@ -122,6 +140,8 @@ ENTRY(ftrace_caller) ...@@ -122,6 +140,8 @@ ENTRY(ftrace_caller)
ldw a0, (sp, 16) ldw a0, (sp, 16)
subi a0, 4 subi a0, 4
ldw a1, (sp, 24) ldw a1, (sp, 24)
lrw a2, function_trace_op
ldw a2, (a2, 0)
nop nop
GLOBAL(ftrace_call) GLOBAL(ftrace_call)
...@@ -157,3 +177,31 @@ ENTRY(return_to_handler) ...@@ -157,3 +177,31 @@ ENTRY(return_to_handler)
jmp lr jmp lr
END(return_to_handler) END(return_to_handler)
#endif #endif
#ifdef CONFIG_DYNAMIC_FTRACE_WITH_REGS
ENTRY(ftrace_regs_caller)
mcount_enter_regs
lrw t1, PT_FRAME_SIZE
add t1, sp
ldw a0, (t1, 0)
subi a0, 4
ldw a1, (t1, 8)
lrw a2, function_trace_op
ldw a2, (a2, 0)
mov a3, sp
nop
GLOBAL(ftrace_regs_call)
nop32_stub
#ifdef CONFIG_FUNCTION_GRAPH_TRACER
nop
GLOBAL(ftrace_graph_regs_call)
nop32_stub
#endif
mcount_exit_regs
ENDPROC(ftrace_regs_caller)
#endif /* CONFIG_DYNAMIC_FTRACE */
...@@ -10,6 +10,8 @@ ...@@ -10,6 +10,8 @@
#define HAVE_FUNCTION_GRAPH_RET_ADDR_PTR #define HAVE_FUNCTION_GRAPH_RET_ADDR_PTR
#define ARCH_SUPPORTS_FTRACE_OPS 1
#define MCOUNT_ADDR ((unsigned long)_mcount) #define MCOUNT_ADDR ((unsigned long)_mcount)
#ifndef __ASSEMBLY__ #ifndef __ASSEMBLY__
......
...@@ -72,6 +72,7 @@ int main(void) ...@@ -72,6 +72,7 @@ int main(void)
DEFINE(PT_RLO, offsetof(struct pt_regs, rlo)); DEFINE(PT_RLO, offsetof(struct pt_regs, rlo));
#endif #endif
DEFINE(PT_USP, offsetof(struct pt_regs, usp)); DEFINE(PT_USP, offsetof(struct pt_regs, usp));
DEFINE(PT_FRAME_SIZE, sizeof(struct pt_regs));
/* offsets into the irq_cpustat_t struct */ /* offsets into the irq_cpustat_t struct */
DEFINE(CPUSTAT_SOFTIRQ_PENDING, offsetof(irq_cpustat_t, DEFINE(CPUSTAT_SOFTIRQ_PENDING, offsetof(irq_cpustat_t,
......
...@@ -126,6 +126,9 @@ int ftrace_update_ftrace_func(ftrace_func_t func) ...@@ -126,6 +126,9 @@ int ftrace_update_ftrace_func(ftrace_func_t func)
{ {
int ret = ftrace_modify_code((unsigned long)&ftrace_call, int ret = ftrace_modify_code((unsigned long)&ftrace_call,
(unsigned long)func, true, true); (unsigned long)func, true, true);
if (!ret)
ret = ftrace_modify_code((unsigned long)&ftrace_regs_call,
(unsigned long)func, true, true);
return ret; return ret;
} }
...@@ -135,6 +138,14 @@ int __init ftrace_dyn_arch_init(void) ...@@ -135,6 +138,14 @@ int __init ftrace_dyn_arch_init(void)
} }
#endif /* CONFIG_DYNAMIC_FTRACE */ #endif /* CONFIG_DYNAMIC_FTRACE */
#ifdef CONFIG_DYNAMIC_FTRACE_WITH_REGS
int ftrace_modify_call(struct dyn_ftrace *rec, unsigned long old_addr,
unsigned long addr)
{
return ftrace_modify_code(rec->ip, addr, true, true);
}
#endif
#ifdef CONFIG_FUNCTION_GRAPH_TRACER #ifdef CONFIG_FUNCTION_GRAPH_TRACER
void prepare_ftrace_return(unsigned long *parent, unsigned long self_addr, void prepare_ftrace_return(unsigned long *parent, unsigned long self_addr,
unsigned long frame_pointer) unsigned long frame_pointer)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment