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