18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only 28c2ecf20Sopenharmony_ci#include <linux/module.h> 38c2ecf20Sopenharmony_ci#include <linux/kthread.h> 48c2ecf20Sopenharmony_ci#include <linux/ftrace.h> 58c2ecf20Sopenharmony_ci 68c2ecf20Sopenharmony_ciextern void my_direct_func1(void); 78c2ecf20Sopenharmony_ciextern void my_direct_func2(void); 88c2ecf20Sopenharmony_ci 98c2ecf20Sopenharmony_civoid my_direct_func1(void) 108c2ecf20Sopenharmony_ci{ 118c2ecf20Sopenharmony_ci trace_printk("my direct func1\n"); 128c2ecf20Sopenharmony_ci} 138c2ecf20Sopenharmony_ci 148c2ecf20Sopenharmony_civoid my_direct_func2(void) 158c2ecf20Sopenharmony_ci{ 168c2ecf20Sopenharmony_ci trace_printk("my direct func2\n"); 178c2ecf20Sopenharmony_ci} 188c2ecf20Sopenharmony_ci 198c2ecf20Sopenharmony_ciextern void my_tramp1(void *); 208c2ecf20Sopenharmony_ciextern void my_tramp2(void *); 218c2ecf20Sopenharmony_ci 228c2ecf20Sopenharmony_cistatic unsigned long my_ip = (unsigned long)schedule; 238c2ecf20Sopenharmony_ci 248c2ecf20Sopenharmony_ciasm ( 258c2ecf20Sopenharmony_ci" .pushsection .text, \"ax\", @progbits\n" 268c2ecf20Sopenharmony_ci" .type my_tramp1, @function\n" 278c2ecf20Sopenharmony_ci" .globl my_tramp1\n" 288c2ecf20Sopenharmony_ci" my_tramp1:" 298c2ecf20Sopenharmony_ci" pushq %rbp\n" 308c2ecf20Sopenharmony_ci" movq %rsp, %rbp\n" 318c2ecf20Sopenharmony_ci" call my_direct_func1\n" 328c2ecf20Sopenharmony_ci" leave\n" 338c2ecf20Sopenharmony_ci" .size my_tramp1, .-my_tramp1\n" 348c2ecf20Sopenharmony_ci ASM_RET 358c2ecf20Sopenharmony_ci" .type my_tramp2, @function\n" 368c2ecf20Sopenharmony_ci" .globl my_tramp2\n" 378c2ecf20Sopenharmony_ci" my_tramp2:" 388c2ecf20Sopenharmony_ci" pushq %rbp\n" 398c2ecf20Sopenharmony_ci" movq %rsp, %rbp\n" 408c2ecf20Sopenharmony_ci" call my_direct_func2\n" 418c2ecf20Sopenharmony_ci" leave\n" 428c2ecf20Sopenharmony_ci ASM_RET 438c2ecf20Sopenharmony_ci" .size my_tramp2, .-my_tramp2\n" 448c2ecf20Sopenharmony_ci" .popsection\n" 458c2ecf20Sopenharmony_ci); 468c2ecf20Sopenharmony_ci 478c2ecf20Sopenharmony_cistatic unsigned long my_tramp = (unsigned long)my_tramp1; 488c2ecf20Sopenharmony_cistatic unsigned long tramps[2] = { 498c2ecf20Sopenharmony_ci (unsigned long)my_tramp1, 508c2ecf20Sopenharmony_ci (unsigned long)my_tramp2, 518c2ecf20Sopenharmony_ci}; 528c2ecf20Sopenharmony_ci 538c2ecf20Sopenharmony_cistatic int simple_thread(void *arg) 548c2ecf20Sopenharmony_ci{ 558c2ecf20Sopenharmony_ci static int t; 568c2ecf20Sopenharmony_ci int ret = 0; 578c2ecf20Sopenharmony_ci 588c2ecf20Sopenharmony_ci while (!kthread_should_stop()) { 598c2ecf20Sopenharmony_ci set_current_state(TASK_INTERRUPTIBLE); 608c2ecf20Sopenharmony_ci schedule_timeout(2 * HZ); 618c2ecf20Sopenharmony_ci 628c2ecf20Sopenharmony_ci if (ret) 638c2ecf20Sopenharmony_ci continue; 648c2ecf20Sopenharmony_ci t ^= 1; 658c2ecf20Sopenharmony_ci ret = modify_ftrace_direct(my_ip, my_tramp, tramps[t]); 668c2ecf20Sopenharmony_ci if (!ret) 678c2ecf20Sopenharmony_ci my_tramp = tramps[t]; 688c2ecf20Sopenharmony_ci WARN_ON_ONCE(ret); 698c2ecf20Sopenharmony_ci } 708c2ecf20Sopenharmony_ci 718c2ecf20Sopenharmony_ci return 0; 728c2ecf20Sopenharmony_ci} 738c2ecf20Sopenharmony_ci 748c2ecf20Sopenharmony_cistatic struct task_struct *simple_tsk; 758c2ecf20Sopenharmony_ci 768c2ecf20Sopenharmony_cistatic int __init ftrace_direct_init(void) 778c2ecf20Sopenharmony_ci{ 788c2ecf20Sopenharmony_ci int ret; 798c2ecf20Sopenharmony_ci 808c2ecf20Sopenharmony_ci ret = register_ftrace_direct(my_ip, my_tramp); 818c2ecf20Sopenharmony_ci if (!ret) 828c2ecf20Sopenharmony_ci simple_tsk = kthread_run(simple_thread, NULL, "event-sample-fn"); 838c2ecf20Sopenharmony_ci return ret; 848c2ecf20Sopenharmony_ci} 858c2ecf20Sopenharmony_ci 868c2ecf20Sopenharmony_cistatic void __exit ftrace_direct_exit(void) 878c2ecf20Sopenharmony_ci{ 888c2ecf20Sopenharmony_ci kthread_stop(simple_tsk); 898c2ecf20Sopenharmony_ci unregister_ftrace_direct(my_ip, my_tramp); 908c2ecf20Sopenharmony_ci} 918c2ecf20Sopenharmony_ci 928c2ecf20Sopenharmony_cimodule_init(ftrace_direct_init); 938c2ecf20Sopenharmony_cimodule_exit(ftrace_direct_exit); 948c2ecf20Sopenharmony_ci 958c2ecf20Sopenharmony_ciMODULE_AUTHOR("Steven Rostedt"); 968c2ecf20Sopenharmony_ciMODULE_DESCRIPTION("Example use case of using modify_ftrace_direct()"); 978c2ecf20Sopenharmony_ciMODULE_LICENSE("GPL"); 98