Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os 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>

Guo Ren 89a3927a 9866d141

+123
+1
arch/csky/Kconfig
··· 38 38 select HAVE_ARCH_AUDITSYSCALL 39 39 select HAVE_COPY_THREAD_TLS 40 40 select HAVE_DYNAMIC_FTRACE 41 + select HAVE_DYNAMIC_FTRACE_WITH_REGS 41 42 select HAVE_FUNCTION_TRACER 42 43 select HAVE_FUNCTION_GRAPH_TRACER 43 44 select HAVE_FTRACE_MCOUNT_RECORD
+60
arch/csky/abiv2/inc/abi/entry.h
··· 100 100 rte 101 101 .endm 102 102 103 + .macro SAVE_REGS_FTRACE 104 + subi sp, 152 105 + stw tls, (sp, 0) 106 + stw lr, (sp, 4) 107 + 108 + mfcr lr, psr 109 + stw lr, (sp, 12) 110 + 111 + addi lr, sp, 152 112 + stw lr, (sp, 16) 113 + 114 + stw a0, (sp, 20) 115 + stw a0, (sp, 24) 116 + stw a1, (sp, 28) 117 + stw a2, (sp, 32) 118 + stw a3, (sp, 36) 119 + 120 + addi sp, 40 121 + stm r4-r13, (sp) 122 + 123 + addi sp, 40 124 + stm r16-r30, (sp) 125 + #ifdef CONFIG_CPU_HAS_HILO 126 + mfhi lr 127 + stw lr, (sp, 60) 128 + mflo lr 129 + stw lr, (sp, 64) 130 + mfcr lr, cr14 131 + stw lr, (sp, 68) 132 + #endif 133 + subi sp, 80 134 + .endm 135 + 136 + .macro RESTORE_REGS_FTRACE 137 + ldw tls, (sp, 0) 138 + ldw a0, (sp, 16) 139 + mtcr a0, ss0 140 + 141 + #ifdef CONFIG_CPU_HAS_HILO 142 + ldw a0, (sp, 140) 143 + mthi a0 144 + ldw a0, (sp, 144) 145 + mtlo a0 146 + ldw a0, (sp, 148) 147 + mtcr a0, cr14 148 + #endif 149 + 150 + ldw a0, (sp, 24) 151 + ldw a1, (sp, 28) 152 + ldw a2, (sp, 32) 153 + ldw a3, (sp, 36) 154 + 155 + addi sp, 40 156 + ldm r4-r13, (sp) 157 + addi sp, 40 158 + ldm r16-r30, (sp) 159 + addi sp, 72 160 + mfcr sp, ss0 161 + .endm 162 + 103 163 .macro SAVE_SWITCH_STACK 104 164 subi sp, 64 105 165 stm r4-r11, (sp)
+48
arch/csky/abiv2/mcount.S
··· 3 3 4 4 #include <linux/linkage.h> 5 5 #include <asm/ftrace.h> 6 + #include <abi/entry.h> 7 + #include <asm/asm-offsets.h> 6 8 7 9 /* 8 10 * csky-gcc with -pg will put the following asm after prologue: ··· 43 41 ldw r8, (sp, 20) 44 42 ldw lr, (sp, 24) 45 43 addi sp, 28 44 + jmp t1 45 + .endm 46 + 47 + .macro mcount_enter_regs 48 + subi sp, 8 49 + stw lr, (sp, 0) 50 + stw r8, (sp, 4) 51 + SAVE_REGS_FTRACE 52 + .endm 53 + 54 + .macro mcount_exit_regs 55 + RESTORE_REGS_FTRACE 56 + ldw t1, (sp, 0) 57 + ldw r8, (sp, 4) 58 + ldw lr, (sp, 8) 59 + addi sp, 12 46 60 jmp t1 47 61 .endm 48 62 ··· 140 122 ldw a0, (sp, 16) 141 123 subi a0, 4 142 124 ldw a1, (sp, 24) 125 + lrw a2, function_trace_op 126 + ldw a2, (a2, 0) 143 127 144 128 nop 145 129 GLOBAL(ftrace_call) ··· 177 157 jmp lr 178 158 END(return_to_handler) 179 159 #endif 160 + 161 + #ifdef CONFIG_DYNAMIC_FTRACE_WITH_REGS 162 + ENTRY(ftrace_regs_caller) 163 + mcount_enter_regs 164 + 165 + lrw t1, PT_FRAME_SIZE 166 + add t1, sp 167 + 168 + ldw a0, (t1, 0) 169 + subi a0, 4 170 + ldw a1, (t1, 8) 171 + lrw a2, function_trace_op 172 + ldw a2, (a2, 0) 173 + mov a3, sp 174 + 175 + nop 176 + GLOBAL(ftrace_regs_call) 177 + nop32_stub 178 + 179 + #ifdef CONFIG_FUNCTION_GRAPH_TRACER 180 + nop 181 + GLOBAL(ftrace_graph_regs_call) 182 + nop32_stub 183 + #endif 184 + 185 + mcount_exit_regs 186 + ENDPROC(ftrace_regs_caller) 187 + #endif /* CONFIG_DYNAMIC_FTRACE */
+2
arch/csky/include/asm/ftrace.h
··· 10 10 11 11 #define HAVE_FUNCTION_GRAPH_RET_ADDR_PTR 12 12 13 + #define ARCH_SUPPORTS_FTRACE_OPS 1 14 + 13 15 #define MCOUNT_ADDR ((unsigned long)_mcount) 14 16 15 17 #ifndef __ASSEMBLY__
+1
arch/csky/kernel/asm-offsets.c
··· 72 72 DEFINE(PT_RLO, offsetof(struct pt_regs, rlo)); 73 73 #endif 74 74 DEFINE(PT_USP, offsetof(struct pt_regs, usp)); 75 + DEFINE(PT_FRAME_SIZE, sizeof(struct pt_regs)); 75 76 76 77 /* offsets into the irq_cpustat_t struct */ 77 78 DEFINE(CPUSTAT_SOFTIRQ_PENDING, offsetof(irq_cpustat_t,
+11
arch/csky/kernel/ftrace.c
··· 126 126 { 127 127 int ret = ftrace_modify_code((unsigned long)&ftrace_call, 128 128 (unsigned long)func, true, true); 129 + if (!ret) 130 + ret = ftrace_modify_code((unsigned long)&ftrace_regs_call, 131 + (unsigned long)func, true, true); 129 132 return ret; 130 133 } 131 134 ··· 137 134 return 0; 138 135 } 139 136 #endif /* CONFIG_DYNAMIC_FTRACE */ 137 + 138 + #ifdef CONFIG_DYNAMIC_FTRACE_WITH_REGS 139 + int ftrace_modify_call(struct dyn_ftrace *rec, unsigned long old_addr, 140 + unsigned long addr) 141 + { 142 + return ftrace_modify_code(rec->ip, addr, true, true); 143 + } 144 + #endif 140 145 141 146 #ifdef CONFIG_FUNCTION_GRAPH_TRACER 142 147 void prepare_ftrace_return(unsigned long *parent, unsigned long self_addr,