csky: Implement ftrace with regs
authorGuo Ren <guoren@linux.alibaba.com>
Tue, 18 Feb 2020 12:27:39 +0000 (20:27 +0800)
committerGuo Ren <guoren@linux.alibaba.com>
Sun, 8 Mar 2020 12:55:14 +0000 (20:55 +0800)
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>
arch/csky/Kconfig
arch/csky/abiv2/inc/abi/entry.h
arch/csky/abiv2/mcount.S
arch/csky/include/asm/ftrace.h
arch/csky/kernel/asm-offsets.c
arch/csky/kernel/ftrace.c

index 0e9b143..6cf169a 100644 (file)
@@ -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
index 94a7a58..6a40439 100644 (file)
        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)
index 326402e..9331c7e 100644 (file)
@@ -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:
        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 */
index ba35d93..fae72b0 100644 (file)
@@ -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__
index 9b48b1b..f8be348 100644 (file)
@@ -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,
index 44f4880..b4502cd 100644 (file)
@@ -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)