18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only 28c2ecf20Sopenharmony_ci#include <linux/module.h> 38c2ecf20Sopenharmony_ci 48c2ecf20Sopenharmony_ci#include <linux/mm.h> /* for handle_mm_fault() */ 58c2ecf20Sopenharmony_ci#include <linux/ftrace.h> 68c2ecf20Sopenharmony_ci 78c2ecf20Sopenharmony_ciextern void my_direct_func(struct vm_area_struct *vma, unsigned long address, 88c2ecf20Sopenharmony_ci unsigned int flags, struct pt_regs *regs); 98c2ecf20Sopenharmony_ci 108c2ecf20Sopenharmony_civoid my_direct_func(struct vm_area_struct *vma, unsigned long address, 118c2ecf20Sopenharmony_ci unsigned int flags, struct pt_regs *regs) 128c2ecf20Sopenharmony_ci{ 138c2ecf20Sopenharmony_ci trace_printk("handle mm fault vma=%p address=%lx flags=%x regs=%p\n", 148c2ecf20Sopenharmony_ci vma, address, flags, regs); 158c2ecf20Sopenharmony_ci} 168c2ecf20Sopenharmony_ci 178c2ecf20Sopenharmony_ciextern void my_tramp(void *); 188c2ecf20Sopenharmony_ci 198c2ecf20Sopenharmony_ciasm ( 208c2ecf20Sopenharmony_ci" .pushsection .text, \"ax\", @progbits\n" 218c2ecf20Sopenharmony_ci" .type my_tramp, @function\n" 228c2ecf20Sopenharmony_ci" .globl my_tramp\n" 238c2ecf20Sopenharmony_ci" my_tramp:" 248c2ecf20Sopenharmony_ci" pushq %rbp\n" 258c2ecf20Sopenharmony_ci" movq %rsp, %rbp\n" 268c2ecf20Sopenharmony_ci" pushq %rdi\n" 278c2ecf20Sopenharmony_ci" pushq %rsi\n" 288c2ecf20Sopenharmony_ci" pushq %rdx\n" 298c2ecf20Sopenharmony_ci" pushq %rcx\n" 308c2ecf20Sopenharmony_ci" call my_direct_func\n" 318c2ecf20Sopenharmony_ci" popq %rcx\n" 328c2ecf20Sopenharmony_ci" popq %rdx\n" 338c2ecf20Sopenharmony_ci" popq %rsi\n" 348c2ecf20Sopenharmony_ci" popq %rdi\n" 358c2ecf20Sopenharmony_ci" leave\n" 368c2ecf20Sopenharmony_ci ASM_RET 378c2ecf20Sopenharmony_ci" .size my_tramp, .-my_tramp\n" 388c2ecf20Sopenharmony_ci" .popsection\n" 398c2ecf20Sopenharmony_ci); 408c2ecf20Sopenharmony_ci 418c2ecf20Sopenharmony_ci 428c2ecf20Sopenharmony_cistatic int __init ftrace_direct_init(void) 438c2ecf20Sopenharmony_ci{ 448c2ecf20Sopenharmony_ci return register_ftrace_direct((unsigned long)handle_mm_fault, 458c2ecf20Sopenharmony_ci (unsigned long)my_tramp); 468c2ecf20Sopenharmony_ci} 478c2ecf20Sopenharmony_ci 488c2ecf20Sopenharmony_cistatic void __exit ftrace_direct_exit(void) 498c2ecf20Sopenharmony_ci{ 508c2ecf20Sopenharmony_ci unregister_ftrace_direct((unsigned long)handle_mm_fault, 518c2ecf20Sopenharmony_ci (unsigned long)my_tramp); 528c2ecf20Sopenharmony_ci} 538c2ecf20Sopenharmony_ci 548c2ecf20Sopenharmony_cimodule_init(ftrace_direct_init); 558c2ecf20Sopenharmony_cimodule_exit(ftrace_direct_exit); 568c2ecf20Sopenharmony_ci 578c2ecf20Sopenharmony_ciMODULE_AUTHOR("Steven Rostedt"); 588c2ecf20Sopenharmony_ciMODULE_DESCRIPTION("Another example use case of using register_ftrace_direct()"); 598c2ecf20Sopenharmony_ciMODULE_LICENSE("GPL"); 60