Skip to content

Commit

Permalink
csky: Implement ftrace with regs
Browse files Browse the repository at this point in the history
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 <[email protected]>
  • Loading branch information
guoren83 committed Mar 8, 2020
1 parent 9866d14 commit 89a3927
Show file tree
Hide file tree
Showing 6 changed files with 123 additions and 0 deletions.
1 change: 1 addition & 0 deletions arch/csky/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
60 changes: 60 additions & 0 deletions arch/csky/abiv2/inc/abi/entry.h
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
48 changes: 48 additions & 0 deletions arch/csky/abiv2/mcount.S
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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 */
2 changes: 2 additions & 0 deletions arch/csky/include/asm/ftrace.h
Original file line number Diff line number Diff line change
Expand Up @@ -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__
Expand Down
1 change: 1 addition & 0 deletions arch/csky/kernel/asm-offsets.c
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
11 changes: 11 additions & 0 deletions arch/csky/kernel/ftrace.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

Expand All @@ -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)
Expand Down

0 comments on commit 89a3927

Please sign in to comment.