1 // SPDX-License-Identifier: GPL-2.0-only 2 #include <linux/module.h> 3 #include <linux/kthread.h> 4 #include <linux/ftrace.h> 5 6 void my_direct_func1(void) 7 { 8 trace_printk("my direct func1\n"); 9 } 10 11 void my_direct_func2(void) 12 { 13 trace_printk("my direct func2\n"); 14 } 15 16 extern void my_tramp1(void *); 17 extern void my_tramp2(void *); 18 19 static unsigned long my_ip = (unsigned long)schedule; 20 21 asm ( 22 " .pushsection .text, \"ax\", @progbits\n" 23 " .type my_tramp1, @function\n" 24 " .globl my_tramp1\n" 25 " my_tramp1:" 26 " pushq %rbp\n" 27 " movq %rsp, %rbp\n" 28 " call my_direct_func1\n" 29 " leave\n" 30 " .size my_tramp1, .-my_tramp1\n" 31 " ret\n" 32 " .type my_tramp2, @function\n" 33 " .globl my_tramp2\n" 34 " my_tramp2:" 35 " pushq %rbp\n" 36 " movq %rsp, %rbp\n" 37 " call my_direct_func2\n" 38 " leave\n" 39 " ret\n" 40 " .size my_tramp2, .-my_tramp2\n" 41 " .popsection\n" 42 ); 43 44 static unsigned long my_tramp = (unsigned long)my_tramp1; 45 static unsigned long tramps[2] = { 46 (unsigned long)my_tramp1, 47 (unsigned long)my_tramp2, 48 }; 49 50 static int simple_thread(void *arg) 51 { 52 static int t; 53 int ret = 0; 54 55 while (!kthread_should_stop()) { 56 set_current_state(TASK_INTERRUPTIBLE); 57 schedule_timeout(2 * HZ); 58 59 if (ret) 60 continue; 61 t ^= 1; 62 ret = modify_ftrace_direct(my_ip, my_tramp, tramps[t]); 63 if (!ret) 64 my_tramp = tramps[t]; 65 WARN_ON_ONCE(ret); 66 } 67 68 return 0; 69 } 70 71 static struct task_struct *simple_tsk; 72 73 static int __init ftrace_direct_init(void) 74 { 75 int ret; 76 77 ret = register_ftrace_direct(my_ip, my_tramp); 78 if (!ret) 79 simple_tsk = kthread_run(simple_thread, NULL, "event-sample-fn"); 80 return ret; 81 } 82 83 static void __exit ftrace_direct_exit(void) 84 { 85 kthread_stop(simple_tsk); 86 unregister_ftrace_direct(my_ip, my_tramp); 87 } 88 89 module_init(ftrace_direct_init); 90 module_exit(ftrace_direct_exit); 91 92 MODULE_AUTHOR("Steven Rostedt"); 93 MODULE_DESCRIPTION("Example use case of using modify_ftrace_direct()"); 94 MODULE_LICENSE("GPL"); 95