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