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