176 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2#include <linux/module.h>3 4#include <linux/mm.h> /* for handle_mm_fault() */5#include <linux/ftrace.h>6#ifndef CONFIG_ARM647#include <asm/asm-offsets.h>8#endif9 10extern void my_direct_func(struct vm_area_struct *vma, unsigned long address,11 unsigned int flags, struct pt_regs *regs);12 13void my_direct_func(struct vm_area_struct *vma, unsigned long address,14 unsigned int flags, struct pt_regs *regs)15{16 trace_printk("handle mm fault vma=%p address=%lx flags=%x regs=%p\n",17 vma, address, flags, regs);18}19 20extern void my_tramp(void *);21 22#ifdef CONFIG_RISCV23#include <asm/asm.h>24 25asm (26" .pushsection .text, \"ax\", @progbits\n"27" .type my_tramp, @function\n"28" .globl my_tramp\n"29" my_tramp:\n"30" addi sp,sp,-5*"SZREG"\n"31" "REG_S" a0,0*"SZREG"(sp)\n"32" "REG_S" a1,1*"SZREG"(sp)\n"33" "REG_S" a2,2*"SZREG"(sp)\n"34" "REG_S" t0,3*"SZREG"(sp)\n"35" "REG_S" ra,4*"SZREG"(sp)\n"36" call my_direct_func\n"37" "REG_L" a0,0*"SZREG"(sp)\n"38" "REG_L" a1,1*"SZREG"(sp)\n"39" "REG_L" a2,2*"SZREG"(sp)\n"40" "REG_L" t0,3*"SZREG"(sp)\n"41" "REG_L" ra,4*"SZREG"(sp)\n"42" addi sp,sp,5*"SZREG"\n"43" jr t0\n"44" .size my_tramp, .-my_tramp\n"45" .popsection\n"46);47 48#endif /* CONFIG_RISCV */49 50#ifdef CONFIG_X86_6451 52#include <asm/ibt.h>53#include <asm/nospec-branch.h>54 55asm (56" .pushsection .text, \"ax\", @progbits\n"57" .type my_tramp, @function\n"58" .globl my_tramp\n"59" my_tramp:"60 ASM_ENDBR61" pushq %rbp\n"62" movq %rsp, %rbp\n"63 CALL_DEPTH_ACCOUNT64" pushq %rdi\n"65" pushq %rsi\n"66" pushq %rdx\n"67" pushq %rcx\n"68" call my_direct_func\n"69" popq %rcx\n"70" popq %rdx\n"71" popq %rsi\n"72" popq %rdi\n"73" leave\n"74 ASM_RET75" .size my_tramp, .-my_tramp\n"76" .popsection\n"77);78 79#endif /* CONFIG_X86_64 */80 81#ifdef CONFIG_S39082 83asm (84" .pushsection .text, \"ax\", @progbits\n"85" .type my_tramp, @function\n"86" .globl my_tramp\n"87" my_tramp:"88" lgr %r1,%r15\n"89" stmg %r0,%r5,"__stringify(__SF_GPRS)"(%r15)\n"90" stg %r14,"__stringify(__SF_GPRS+8*8)"(%r15)\n"91" aghi %r15,"__stringify(-STACK_FRAME_OVERHEAD)"\n"92" stg %r1,"__stringify(__SF_BACKCHAIN)"(%r15)\n"93" brasl %r14,my_direct_func\n"94" aghi %r15,"__stringify(STACK_FRAME_OVERHEAD)"\n"95" lmg %r0,%r5,"__stringify(__SF_GPRS)"(%r15)\n"96" lg %r14,"__stringify(__SF_GPRS+8*8)"(%r15)\n"97" lgr %r1,%r0\n"98" br %r1\n"99" .size my_tramp, .-my_tramp\n"100" .popsection\n"101);102 103#endif /* CONFIG_S390 */104 105#ifdef CONFIG_ARM64106 107asm (108" .pushsection .text, \"ax\", @progbits\n"109" .type my_tramp, @function\n"110" .globl my_tramp\n"111" my_tramp:"112" hint 34\n" // bti c113" sub sp, sp, #48\n"114" stp x9, x30, [sp]\n"115" stp x0, x1, [sp, #16]\n"116" stp x2, x3, [sp, #32]\n"117" bl my_direct_func\n"118" ldp x30, x9, [sp]\n"119" ldp x0, x1, [sp, #16]\n"120" ldp x2, x3, [sp, #32]\n"121" add sp, sp, #48\n"122" ret x9\n"123" .size my_tramp, .-my_tramp\n"124" .popsection\n"125);126 127#endif /* CONFIG_ARM64 */128 129#ifdef CONFIG_LOONGARCH130 131asm (132" .pushsection .text, \"ax\", @progbits\n"133" .type my_tramp, @function\n"134" .globl my_tramp\n"135" my_tramp:\n"136" addi.d $sp, $sp, -48\n"137" st.d $a0, $sp, 0\n"138" st.d $a1, $sp, 8\n"139" st.d $a2, $sp, 16\n"140" st.d $t0, $sp, 24\n"141" st.d $ra, $sp, 32\n"142" bl my_direct_func\n"143" ld.d $a0, $sp, 0\n"144" ld.d $a1, $sp, 8\n"145" ld.d $a2, $sp, 16\n"146" ld.d $t0, $sp, 24\n"147" ld.d $ra, $sp, 32\n"148" addi.d $sp, $sp, 48\n"149" jr $t0\n"150" .size my_tramp, .-my_tramp\n"151" .popsection\n"152);153 154#endif /* CONFIG_LOONGARCH */155 156static struct ftrace_ops direct;157 158static int __init ftrace_direct_init(void)159{160 ftrace_set_filter_ip(&direct, (unsigned long) handle_mm_fault, 0, 0);161 162 return register_ftrace_direct(&direct, (unsigned long) my_tramp);163}164 165static void __exit ftrace_direct_exit(void)166{167 unregister_ftrace_direct(&direct, (unsigned long)my_tramp, true);168}169 170module_init(ftrace_direct_init);171module_exit(ftrace_direct_exit);172 173MODULE_AUTHOR("Steven Rostedt");174MODULE_DESCRIPTION("Another example use case of using register_ftrace_direct()");175MODULE_LICENSE("GPL");176