Path: blob/master/samples/ftrace/ftrace-direct-modify.c
26295 views
// SPDX-License-Identifier: GPL-2.0-only1#include <linux/module.h>2#include <linux/kthread.h>3#include <linux/ftrace.h>4#if !defined(CONFIG_ARM64) && !defined(CONFIG_PPC32)5#include <asm/asm-offsets.h>6#endif78extern void my_direct_func1(void);9extern void my_direct_func2(void);1011void my_direct_func1(void)12{13trace_printk("my direct func1\n");14}1516void my_direct_func2(void)17{18trace_printk("my direct func2\n");19}2021extern void my_tramp1(void *);22extern void my_tramp2(void *);2324static unsigned long my_ip = (unsigned long)schedule;2526#ifdef CONFIG_RISCV27#include <asm/asm.h>2829asm (30" .pushsection .text, \"ax\", @progbits\n"31" .type my_tramp1, @function\n"32" .globl my_tramp1\n"33" my_tramp1:\n"34" addi sp,sp,-2*"SZREG"\n"35" "REG_S" t0,0*"SZREG"(sp)\n"36" "REG_S" ra,1*"SZREG"(sp)\n"37" call my_direct_func1\n"38" "REG_L" t0,0*"SZREG"(sp)\n"39" "REG_L" ra,1*"SZREG"(sp)\n"40" addi sp,sp,2*"SZREG"\n"41" jr t0\n"42" .size my_tramp1, .-my_tramp1\n"43" .type my_tramp2, @function\n"44" .globl my_tramp2\n"4546" my_tramp2:\n"47" addi sp,sp,-2*"SZREG"\n"48" "REG_S" t0,0*"SZREG"(sp)\n"49" "REG_S" ra,1*"SZREG"(sp)\n"50" call my_direct_func2\n"51" "REG_L" t0,0*"SZREG"(sp)\n"52" "REG_L" ra,1*"SZREG"(sp)\n"53" addi sp,sp,2*"SZREG"\n"54" jr t0\n"55" .size my_tramp2, .-my_tramp2\n"56" .popsection\n"57);5859#endif /* CONFIG_RISCV */6061#ifdef CONFIG_X86_646263#include <asm/ibt.h>64#include <asm/nospec-branch.h>6566asm (67" .pushsection .text, \"ax\", @progbits\n"68" .type my_tramp1, @function\n"69" .globl my_tramp1\n"70" my_tramp1:"71ASM_ENDBR72" pushq %rbp\n"73" movq %rsp, %rbp\n"74CALL_DEPTH_ACCOUNT75" call my_direct_func1\n"76" leave\n"77" .size my_tramp1, .-my_tramp1\n"78ASM_RET7980" .type my_tramp2, @function\n"81" .globl my_tramp2\n"82" my_tramp2:"83ASM_ENDBR84" pushq %rbp\n"85" movq %rsp, %rbp\n"86CALL_DEPTH_ACCOUNT87" call my_direct_func2\n"88" leave\n"89ASM_RET90" .size my_tramp2, .-my_tramp2\n"91" .popsection\n"92);9394#endif /* CONFIG_X86_64 */9596#ifdef CONFIG_S3909798asm (99" .pushsection .text, \"ax\", @progbits\n"100" .type my_tramp1, @function\n"101" .globl my_tramp1\n"102" my_tramp1:"103" lgr %r1,%r15\n"104" stmg %r0,%r5,"__stringify(__SF_GPRS)"(%r15)\n"105" stg %r14,"__stringify(__SF_GPRS+8*8)"(%r15)\n"106" aghi %r15,"__stringify(-STACK_FRAME_OVERHEAD)"\n"107" stg %r1,"__stringify(__SF_BACKCHAIN)"(%r15)\n"108" brasl %r14,my_direct_func1\n"109" aghi %r15,"__stringify(STACK_FRAME_OVERHEAD)"\n"110" lmg %r0,%r5,"__stringify(__SF_GPRS)"(%r15)\n"111" lg %r14,"__stringify(__SF_GPRS+8*8)"(%r15)\n"112" lgr %r1,%r0\n"113" br %r1\n"114" .size my_tramp1, .-my_tramp1\n"115" .type my_tramp2, @function\n"116" .globl my_tramp2\n"117" my_tramp2:"118" lgr %r1,%r15\n"119" stmg %r0,%r5,"__stringify(__SF_GPRS)"(%r15)\n"120" stg %r14,"__stringify(__SF_GPRS+8*8)"(%r15)\n"121" aghi %r15,"__stringify(-STACK_FRAME_OVERHEAD)"\n"122" stg %r1,"__stringify(__SF_BACKCHAIN)"(%r15)\n"123" brasl %r14,my_direct_func2\n"124" aghi %r15,"__stringify(STACK_FRAME_OVERHEAD)"\n"125" lmg %r0,%r5,"__stringify(__SF_GPRS)"(%r15)\n"126" lg %r14,"__stringify(__SF_GPRS+8*8)"(%r15)\n"127" lgr %r1,%r0\n"128" br %r1\n"129" .size my_tramp2, .-my_tramp2\n"130" .popsection\n"131);132133#endif /* CONFIG_S390 */134135#ifdef CONFIG_ARM64136137asm (138" .pushsection .text, \"ax\", @progbits\n"139" .type my_tramp1, @function\n"140" .globl my_tramp1\n"141" my_tramp1:"142" hint 34\n" // bti c143" sub sp, sp, #16\n"144" stp x9, x30, [sp]\n"145" bl my_direct_func1\n"146" ldp x30, x9, [sp]\n"147" add sp, sp, #16\n"148" ret x9\n"149" .size my_tramp1, .-my_tramp1\n"150151" .type my_tramp2, @function\n"152" .globl my_tramp2\n"153" my_tramp2:"154" hint 34\n" // bti c155" sub sp, sp, #16\n"156" stp x9, x30, [sp]\n"157" bl my_direct_func2\n"158" ldp x30, x9, [sp]\n"159" add sp, sp, #16\n"160" ret x9\n"161" .size my_tramp2, .-my_tramp2\n"162" .popsection\n"163);164165#endif /* CONFIG_ARM64 */166167#ifdef CONFIG_LOONGARCH168169asm (170" .pushsection .text, \"ax\", @progbits\n"171" .type my_tramp1, @function\n"172" .globl my_tramp1\n"173" my_tramp1:\n"174" addi.d $sp, $sp, -16\n"175" st.d $t0, $sp, 0\n"176" st.d $ra, $sp, 8\n"177" bl my_direct_func1\n"178" ld.d $t0, $sp, 0\n"179" ld.d $ra, $sp, 8\n"180" addi.d $sp, $sp, 16\n"181" jr $t0\n"182" .size my_tramp1, .-my_tramp1\n"183184" .type my_tramp2, @function\n"185" .globl my_tramp2\n"186" my_tramp2:\n"187" addi.d $sp, $sp, -16\n"188" st.d $t0, $sp, 0\n"189" st.d $ra, $sp, 8\n"190" bl my_direct_func2\n"191" ld.d $t0, $sp, 0\n"192" ld.d $ra, $sp, 8\n"193" addi.d $sp, $sp, 16\n"194" jr $t0\n"195" .size my_tramp2, .-my_tramp2\n"196" .popsection\n"197);198199#endif /* CONFIG_LOONGARCH */200201#ifdef CONFIG_PPC202#include <asm/ppc_asm.h>203204#ifdef CONFIG_PPC64205#define STACK_FRAME_SIZE 48206#else207#define STACK_FRAME_SIZE 24208#endif209210#if defined(CONFIG_PPC64_ELF_ABI_V2) && !defined(CONFIG_PPC_KERNEL_PCREL)211#define PPC64_TOC_SAVE_AND_UPDATE \212" std 2, 24(1)\n" \213" bcl 20, 31, 1f\n" \214" 1: mflr 12\n" \215" ld 2, (99f - 1b)(12)\n"216#define PPC64_TOC_RESTORE \217" ld 2, 24(1)\n"218#define PPC64_TOC \219" 99: .quad .TOC.@tocbase\n"220#else221#define PPC64_TOC_SAVE_AND_UPDATE ""222#define PPC64_TOC_RESTORE ""223#define PPC64_TOC ""224#endif225226#ifdef CONFIG_PPC_FTRACE_OUT_OF_LINE227#define PPC_FTRACE_RESTORE_LR \228PPC_LL" 0, "__stringify(PPC_LR_STKOFF)"(1)\n" \229" mtlr 0\n"230#define PPC_FTRACE_RET \231" blr\n"232#else233#define PPC_FTRACE_RESTORE_LR \234PPC_LL" 0, "__stringify(PPC_LR_STKOFF)"(1)\n" \235" mtctr 0\n"236#define PPC_FTRACE_RET \237" mtlr 0\n" \238" bctr\n"239#endif240241asm (242" .pushsection .text, \"ax\", @progbits\n"243" .type my_tramp1, @function\n"244" .globl my_tramp1\n"245" my_tramp1:\n"246PPC_STL" 0, "__stringify(PPC_LR_STKOFF)"(1)\n"247PPC_STLU" 1, -"__stringify(STACK_FRAME_MIN_SIZE)"(1)\n"248" mflr 0\n"249PPC_STL" 0, "__stringify(PPC_LR_STKOFF)"(1)\n"250PPC_STLU" 1, -"__stringify(STACK_FRAME_SIZE)"(1)\n"251PPC64_TOC_SAVE_AND_UPDATE252" bl my_direct_func1\n"253PPC64_TOC_RESTORE254" addi 1, 1, "__stringify(STACK_FRAME_SIZE)"\n"255PPC_FTRACE_RESTORE_LR256" addi 1, 1, "__stringify(STACK_FRAME_MIN_SIZE)"\n"257PPC_LL" 0, "__stringify(PPC_LR_STKOFF)"(1)\n"258PPC_FTRACE_RET259" .size my_tramp1, .-my_tramp1\n"260261" .type my_tramp2, @function\n"262" .globl my_tramp2\n"263" my_tramp2:\n"264PPC_STL" 0, "__stringify(PPC_LR_STKOFF)"(1)\n"265PPC_STLU" 1, -"__stringify(STACK_FRAME_MIN_SIZE)"(1)\n"266" mflr 0\n"267PPC_STL" 0, "__stringify(PPC_LR_STKOFF)"(1)\n"268PPC_STLU" 1, -"__stringify(STACK_FRAME_SIZE)"(1)\n"269PPC64_TOC_SAVE_AND_UPDATE270" bl my_direct_func2\n"271PPC64_TOC_RESTORE272" addi 1, 1, "__stringify(STACK_FRAME_SIZE)"\n"273PPC_FTRACE_RESTORE_LR274" addi 1, 1, "__stringify(STACK_FRAME_MIN_SIZE)"\n"275PPC_LL" 0, "__stringify(PPC_LR_STKOFF)"(1)\n"276PPC_FTRACE_RET277PPC64_TOC278" .size my_tramp2, .-my_tramp2\n"279" .popsection\n"280);281282#endif /* CONFIG_PPC */283284static struct ftrace_ops direct;285286static unsigned long my_tramp = (unsigned long)my_tramp1;287static unsigned long tramps[2] = {288(unsigned long)my_tramp1,289(unsigned long)my_tramp2,290};291292static int simple_thread(void *arg)293{294static int t;295int ret = 0;296297while (!kthread_should_stop()) {298set_current_state(TASK_INTERRUPTIBLE);299schedule_timeout(2 * HZ);300301if (ret)302continue;303t ^= 1;304ret = modify_ftrace_direct(&direct, tramps[t]);305if (!ret)306my_tramp = tramps[t];307WARN_ON_ONCE(ret);308}309310return 0;311}312313static struct task_struct *simple_tsk;314315static int __init ftrace_direct_init(void)316{317int ret;318319ftrace_set_filter_ip(&direct, (unsigned long) my_ip, 0, 0);320ret = register_ftrace_direct(&direct, my_tramp);321322if (!ret)323simple_tsk = kthread_run(simple_thread, NULL, "event-sample-fn");324return ret;325}326327static void __exit ftrace_direct_exit(void)328{329kthread_stop(simple_tsk);330unregister_ftrace_direct(&direct, my_tramp, true);331}332333module_init(ftrace_direct_init);334module_exit(ftrace_direct_exit);335336MODULE_AUTHOR("Steven Rostedt");337MODULE_DESCRIPTION("Example use case of using modify_ftrace_direct()");338MODULE_LICENSE("GPL");339340341