blob: bc8f0d6cd6f863b13cc96eda1a49a4155810e508 [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>
Heiko Carstens1254cfbc2021-10-12 15:38:02 +02005#include <asm/asm-offsets.h>
Steven Rostedt (VMware)ae0cc3b2019-11-14 14:41:47 -05006
7void my_direct_func1(void)
8{
9 trace_printk("my direct func1\n");
10}
11
12void my_direct_func2(void)
13{
14 trace_printk("my direct func2\n");
15}
16
17extern void my_tramp1(void *);
18extern void my_tramp2(void *);
19
20static unsigned long my_ip = (unsigned long)schedule;
21
Heiko Carstens1254cfbc2021-10-12 15:38:02 +020022#ifdef CONFIG_X86_64
23
Steven Rostedt (VMware)ae0cc3b2019-11-14 14:41:47 -050024asm (
25" .pushsection .text, \"ax\", @progbits\n"
Josh Poimboeuf9d907f12020-04-24 15:40:43 -050026" .type my_tramp1, @function\n"
Sami Tolvanen983df5f2020-11-13 10:34:14 -080027" .globl my_tramp1\n"
Steven Rostedt (VMware)ae0cc3b2019-11-14 14:41:47 -050028" my_tramp1:"
29" pushq %rbp\n"
30" movq %rsp, %rbp\n"
31" call my_direct_func1\n"
32" leave\n"
Josh Poimboeuf9d907f12020-04-24 15:40:43 -050033" .size my_tramp1, .-my_tramp1\n"
Peter Zijlstrab17c2ba2021-12-04 14:43:41 +010034 ASM_RET
Josh Poimboeuf9d907f12020-04-24 15:40:43 -050035" .type my_tramp2, @function\n"
Sami Tolvanen983df5f2020-11-13 10:34:14 -080036" .globl my_tramp2\n"
Steven Rostedt (VMware)ae0cc3b2019-11-14 14:41:47 -050037" my_tramp2:"
38" pushq %rbp\n"
39" movq %rsp, %rbp\n"
40" call my_direct_func2\n"
41" leave\n"
Peter Zijlstrab17c2ba2021-12-04 14:43:41 +010042 ASM_RET
Josh Poimboeuf9d907f12020-04-24 15:40:43 -050043" .size my_tramp2, .-my_tramp2\n"
Steven Rostedt (VMware)ae0cc3b2019-11-14 14:41:47 -050044" .popsection\n"
45);
46
Heiko Carstens1254cfbc2021-10-12 15:38:02 +020047#endif /* CONFIG_X86_64 */
48
49#ifdef CONFIG_S390
50
51asm (
52" .pushsection .text, \"ax\", @progbits\n"
53" .type my_tramp1, @function\n"
54" .globl my_tramp1\n"
55" my_tramp1:"
56" lgr %r1,%r15\n"
57" stmg %r0,%r5,"__stringify(__SF_GPRS)"(%r15)\n"
58" stg %r14,"__stringify(__SF_GPRS+8*8)"(%r15)\n"
59" aghi %r15,"__stringify(-STACK_FRAME_OVERHEAD)"\n"
60" stg %r1,"__stringify(__SF_BACKCHAIN)"(%r15)\n"
61" brasl %r14,my_direct_func1\n"
62" aghi %r15,"__stringify(STACK_FRAME_OVERHEAD)"\n"
63" lmg %r0,%r5,"__stringify(__SF_GPRS)"(%r15)\n"
64" lg %r14,"__stringify(__SF_GPRS+8*8)"(%r15)\n"
65" lgr %r1,%r0\n"
66" br %r1\n"
67" .size my_tramp1, .-my_tramp1\n"
68" .type my_tramp2, @function\n"
69" .globl my_tramp2\n"
70" my_tramp2:"
71" lgr %r1,%r15\n"
72" stmg %r0,%r5,"__stringify(__SF_GPRS)"(%r15)\n"
73" stg %r14,"__stringify(__SF_GPRS+8*8)"(%r15)\n"
74" aghi %r15,"__stringify(-STACK_FRAME_OVERHEAD)"\n"
75" stg %r1,"__stringify(__SF_BACKCHAIN)"(%r15)\n"
76" brasl %r14,my_direct_func2\n"
77" aghi %r15,"__stringify(STACK_FRAME_OVERHEAD)"\n"
78" lmg %r0,%r5,"__stringify(__SF_GPRS)"(%r15)\n"
79" lg %r14,"__stringify(__SF_GPRS+8*8)"(%r15)\n"
80" lgr %r1,%r0\n"
81" br %r1\n"
82" .size my_tramp2, .-my_tramp2\n"
83" .popsection\n"
84);
85
86#endif /* CONFIG_S390 */
87
Steven Rostedt (VMware)ae0cc3b2019-11-14 14:41:47 -050088static unsigned long my_tramp = (unsigned long)my_tramp1;
89static unsigned long tramps[2] = {
90 (unsigned long)my_tramp1,
91 (unsigned long)my_tramp2,
92};
93
94static int simple_thread(void *arg)
95{
96 static int t;
97 int ret = 0;
98
99 while (!kthread_should_stop()) {
100 set_current_state(TASK_INTERRUPTIBLE);
101 schedule_timeout(2 * HZ);
102
103 if (ret)
104 continue;
105 t ^= 1;
106 ret = modify_ftrace_direct(my_ip, my_tramp, tramps[t]);
107 if (!ret)
108 my_tramp = tramps[t];
109 WARN_ON_ONCE(ret);
110 }
111
112 return 0;
113}
114
115static struct task_struct *simple_tsk;
116
117static int __init ftrace_direct_init(void)
118{
119 int ret;
120
121 ret = register_ftrace_direct(my_ip, my_tramp);
122 if (!ret)
123 simple_tsk = kthread_run(simple_thread, NULL, "event-sample-fn");
124 return ret;
125}
126
127static void __exit ftrace_direct_exit(void)
128{
129 kthread_stop(simple_tsk);
130 unregister_ftrace_direct(my_ip, my_tramp);
131}
132
133module_init(ftrace_direct_init);
134module_exit(ftrace_direct_exit);
135
136MODULE_AUTHOR("Steven Rostedt");
137MODULE_DESCRIPTION("Example use case of using modify_ftrace_direct()");
138MODULE_LICENSE("GPL");