Loading arch/s390/kernel/ftrace.c +45 −16 Original line number Diff line number Diff line Loading @@ -57,6 +57,44 @@ unsigned long ftrace_plt; static inline void ftrace_generate_orig_insn(struct ftrace_insn *insn) { #ifdef CC_USING_HOTPATCH /* brcl 0,0 */ insn->opc = 0xc004; insn->disp = 0; #else /* stg r14,8(r15) */ insn->opc = 0xe3e0; insn->disp = 0xf0080024; #endif } static inline int is_kprobe_on_ftrace(struct ftrace_insn *insn) { #ifdef CONFIG_KPROBES if (insn->opc == BREAKPOINT_INSTRUCTION) return 1; #endif return 0; } static inline void ftrace_generate_kprobe_nop_insn(struct ftrace_insn *insn) { #ifdef CONFIG_KPROBES insn->opc = BREAKPOINT_INSTRUCTION; insn->disp = KPROBE_ON_FTRACE_NOP; #endif } static inline void ftrace_generate_kprobe_call_insn(struct ftrace_insn *insn) { #ifdef CONFIG_KPROBES insn->opc = BREAKPOINT_INSTRUCTION; insn->disp = KPROBE_ON_FTRACE_CALL; #endif } int ftrace_modify_call(struct dyn_ftrace *rec, unsigned long old_addr, unsigned long addr) { Loading @@ -72,16 +110,9 @@ int ftrace_make_nop(struct module *mod, struct dyn_ftrace *rec, return -EFAULT; if (addr == MCOUNT_ADDR) { /* Initial code replacement */ #ifdef CC_USING_HOTPATCH /* We expect to see brcl 0,0 */ ftrace_generate_nop_insn(&orig); #else /* We expect to see stg r14,8(r15) */ orig.opc = 0xe3e0; orig.disp = 0xf0080024; #endif ftrace_generate_orig_insn(&orig); ftrace_generate_nop_insn(&new); } else if (old.opc == BREAKPOINT_INSTRUCTION) { } else if (is_kprobe_on_ftrace(&old)) { /* * If we find a breakpoint instruction, a kprobe has been * placed at the beginning of the function. We write the Loading @@ -89,9 +120,8 @@ int ftrace_make_nop(struct module *mod, struct dyn_ftrace *rec, * bytes of the original instruction so that the kprobes * handler can execute a nop, if it reaches this breakpoint. */ new.opc = orig.opc = BREAKPOINT_INSTRUCTION; orig.disp = KPROBE_ON_FTRACE_CALL; new.disp = KPROBE_ON_FTRACE_NOP; ftrace_generate_kprobe_call_insn(&orig); ftrace_generate_kprobe_nop_insn(&new); } else { /* Replace ftrace call with a nop. */ ftrace_generate_call_insn(&orig, rec->ip); Loading @@ -111,7 +141,7 @@ int ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr) if (probe_kernel_read(&old, (void *) rec->ip, sizeof(old))) return -EFAULT; if (old.opc == BREAKPOINT_INSTRUCTION) { if (is_kprobe_on_ftrace(&old)) { /* * If we find a breakpoint instruction, a kprobe has been * placed at the beginning of the function. We write the Loading @@ -119,9 +149,8 @@ int ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr) * bytes of the original instruction so that the kprobes * handler can execute a brasl if it reaches this breakpoint. */ new.opc = orig.opc = BREAKPOINT_INSTRUCTION; orig.disp = KPROBE_ON_FTRACE_NOP; new.disp = KPROBE_ON_FTRACE_CALL; ftrace_generate_kprobe_nop_insn(&orig); ftrace_generate_kprobe_call_insn(&new); } else { /* Replace nop with an ftrace call. */ ftrace_generate_nop_insn(&orig); Loading Loading
arch/s390/kernel/ftrace.c +45 −16 Original line number Diff line number Diff line Loading @@ -57,6 +57,44 @@ unsigned long ftrace_plt; static inline void ftrace_generate_orig_insn(struct ftrace_insn *insn) { #ifdef CC_USING_HOTPATCH /* brcl 0,0 */ insn->opc = 0xc004; insn->disp = 0; #else /* stg r14,8(r15) */ insn->opc = 0xe3e0; insn->disp = 0xf0080024; #endif } static inline int is_kprobe_on_ftrace(struct ftrace_insn *insn) { #ifdef CONFIG_KPROBES if (insn->opc == BREAKPOINT_INSTRUCTION) return 1; #endif return 0; } static inline void ftrace_generate_kprobe_nop_insn(struct ftrace_insn *insn) { #ifdef CONFIG_KPROBES insn->opc = BREAKPOINT_INSTRUCTION; insn->disp = KPROBE_ON_FTRACE_NOP; #endif } static inline void ftrace_generate_kprobe_call_insn(struct ftrace_insn *insn) { #ifdef CONFIG_KPROBES insn->opc = BREAKPOINT_INSTRUCTION; insn->disp = KPROBE_ON_FTRACE_CALL; #endif } int ftrace_modify_call(struct dyn_ftrace *rec, unsigned long old_addr, unsigned long addr) { Loading @@ -72,16 +110,9 @@ int ftrace_make_nop(struct module *mod, struct dyn_ftrace *rec, return -EFAULT; if (addr == MCOUNT_ADDR) { /* Initial code replacement */ #ifdef CC_USING_HOTPATCH /* We expect to see brcl 0,0 */ ftrace_generate_nop_insn(&orig); #else /* We expect to see stg r14,8(r15) */ orig.opc = 0xe3e0; orig.disp = 0xf0080024; #endif ftrace_generate_orig_insn(&orig); ftrace_generate_nop_insn(&new); } else if (old.opc == BREAKPOINT_INSTRUCTION) { } else if (is_kprobe_on_ftrace(&old)) { /* * If we find a breakpoint instruction, a kprobe has been * placed at the beginning of the function. We write the Loading @@ -89,9 +120,8 @@ int ftrace_make_nop(struct module *mod, struct dyn_ftrace *rec, * bytes of the original instruction so that the kprobes * handler can execute a nop, if it reaches this breakpoint. */ new.opc = orig.opc = BREAKPOINT_INSTRUCTION; orig.disp = KPROBE_ON_FTRACE_CALL; new.disp = KPROBE_ON_FTRACE_NOP; ftrace_generate_kprobe_call_insn(&orig); ftrace_generate_kprobe_nop_insn(&new); } else { /* Replace ftrace call with a nop. */ ftrace_generate_call_insn(&orig, rec->ip); Loading @@ -111,7 +141,7 @@ int ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr) if (probe_kernel_read(&old, (void *) rec->ip, sizeof(old))) return -EFAULT; if (old.opc == BREAKPOINT_INSTRUCTION) { if (is_kprobe_on_ftrace(&old)) { /* * If we find a breakpoint instruction, a kprobe has been * placed at the beginning of the function. We write the Loading @@ -119,9 +149,8 @@ int ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr) * bytes of the original instruction so that the kprobes * handler can execute a brasl if it reaches this breakpoint. */ new.opc = orig.opc = BREAKPOINT_INSTRUCTION; orig.disp = KPROBE_ON_FTRACE_NOP; new.disp = KPROBE_ON_FTRACE_CALL; ftrace_generate_kprobe_nop_insn(&orig); ftrace_generate_kprobe_call_insn(&new); } else { /* Replace nop with an ftrace call. */ ftrace_generate_nop_insn(&orig); Loading