forked from Minki/linux
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: Guo Ren <guoren@linux.alibaba.com>
This commit is contained in:
parent
9866d141a0
commit
89a3927a77
@ -38,6 +38,7 @@ config CSKY
|
||||
select HAVE_ARCH_AUDITSYSCALL
|
||||
select HAVE_COPY_THREAD_TLS
|
||||
select HAVE_DYNAMIC_FTRACE
|
||||
select HAVE_DYNAMIC_FTRACE_WITH_REGS
|
||||
select HAVE_FUNCTION_TRACER
|
||||
select HAVE_FUNCTION_GRAPH_TRACER
|
||||
select HAVE_FTRACE_MCOUNT_RECORD
|
||||
|
@ -100,6 +100,66 @@
|
||||
rte
|
||||
.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
|
||||
subi sp, 64
|
||||
stm r4-r11, (sp)
|
||||
|
@ -3,6 +3,8 @@
|
||||
|
||||
#include <linux/linkage.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:
|
||||
@ -44,6 +46,22 @@
|
||||
jmp t1
|
||||
.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
|
||||
subi sp, 16
|
||||
stw a0, (sp, 0)
|
||||
@ -122,6 +140,8 @@ ENTRY(ftrace_caller)
|
||||
ldw a0, (sp, 16)
|
||||
subi a0, 4
|
||||
ldw a1, (sp, 24)
|
||||
lrw a2, function_trace_op
|
||||
ldw a2, (a2, 0)
|
||||
|
||||
nop
|
||||
GLOBAL(ftrace_call)
|
||||
@ -157,3 +177,31 @@ ENTRY(return_to_handler)
|
||||
jmp lr
|
||||
END(return_to_handler)
|
||||
#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 @@
|
||||
|
||||
#define HAVE_FUNCTION_GRAPH_RET_ADDR_PTR
|
||||
|
||||
#define ARCH_SUPPORTS_FTRACE_OPS 1
|
||||
|
||||
#define MCOUNT_ADDR ((unsigned long)_mcount)
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
|
@ -72,6 +72,7 @@ int main(void)
|
||||
DEFINE(PT_RLO, offsetof(struct pt_regs, rlo));
|
||||
#endif
|
||||
DEFINE(PT_USP, offsetof(struct pt_regs, usp));
|
||||
DEFINE(PT_FRAME_SIZE, sizeof(struct pt_regs));
|
||||
|
||||
/* offsets into the irq_cpustat_t struct */
|
||||
DEFINE(CPUSTAT_SOFTIRQ_PENDING, offsetof(irq_cpustat_t,
|
||||
|
@ -126,6 +126,9 @@ int ftrace_update_ftrace_func(ftrace_func_t func)
|
||||
{
|
||||
int ret = ftrace_modify_code((unsigned long)&ftrace_call,
|
||||
(unsigned long)func, true, true);
|
||||
if (!ret)
|
||||
ret = ftrace_modify_code((unsigned long)&ftrace_regs_call,
|
||||
(unsigned long)func, true, true);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -135,6 +138,14 @@ int __init ftrace_dyn_arch_init(void)
|
||||
}
|
||||
#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
|
||||
void prepare_ftrace_return(unsigned long *parent, unsigned long self_addr,
|
||||
unsigned long frame_pointer)
|
||||
|
Loading…
Reference in New Issue
Block a user