165 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#include <linux/sched/stat.h>7#ifndef CONFIG_ARM648#include <asm/asm-offsets.h>9#endif10 11extern void my_direct_func(unsigned long ip);12 13void my_direct_func(unsigned long ip)14{15 trace_printk("ip %lx\n", ip);16}17 18extern void my_tramp(void *);19 20#ifdef CONFIG_RISCV21#include <asm/asm.h>22 23asm (24" .pushsection .text, \"ax\", @progbits\n"25" .type my_tramp, @function\n"26" .globl my_tramp\n"27" my_tramp:\n"28" addi sp,sp,-3*"SZREG"\n"29" "REG_S" a0,0*"SZREG"(sp)\n"30" "REG_S" t0,1*"SZREG"(sp)\n"31" "REG_S" ra,2*"SZREG"(sp)\n"32" mv a0,t0\n"33" call my_direct_func\n"34" "REG_L" a0,0*"SZREG"(sp)\n"35" "REG_L" t0,1*"SZREG"(sp)\n"36" "REG_L" ra,2*"SZREG"(sp)\n"37" addi sp,sp,3*"SZREG"\n"38" jr t0\n"39" .size my_tramp, .-my_tramp\n"40" .popsection\n"41);42 43#endif /* CONFIG_RISCV */44 45#ifdef CONFIG_X86_6446 47#include <asm/ibt.h>48#include <asm/nospec-branch.h>49 50asm (51" .pushsection .text, \"ax\", @progbits\n"52" .type my_tramp, @function\n"53" .globl my_tramp\n"54" my_tramp:"55 ASM_ENDBR56" pushq %rbp\n"57" movq %rsp, %rbp\n"58 CALL_DEPTH_ACCOUNT59" pushq %rdi\n"60" movq 8(%rbp), %rdi\n"61" call my_direct_func\n"62" popq %rdi\n"63" leave\n"64 ASM_RET65" .size my_tramp, .-my_tramp\n"66" .popsection\n"67);68 69#endif /* CONFIG_X86_64 */70 71#ifdef CONFIG_S39072 73asm (74" .pushsection .text, \"ax\", @progbits\n"75" .type my_tramp, @function\n"76" .globl my_tramp\n"77" my_tramp:"78" lgr %r1,%r15\n"79" stmg %r0,%r5,"__stringify(__SF_GPRS)"(%r15)\n"80" stg %r14,"__stringify(__SF_GPRS+8*8)"(%r15)\n"81" aghi %r15,"__stringify(-STACK_FRAME_OVERHEAD)"\n"82" stg %r1,"__stringify(__SF_BACKCHAIN)"(%r15)\n"83" lgr %r2,%r0\n"84" brasl %r14,my_direct_func\n"85" aghi %r15,"__stringify(STACK_FRAME_OVERHEAD)"\n"86" lmg %r0,%r5,"__stringify(__SF_GPRS)"(%r15)\n"87" lg %r14,"__stringify(__SF_GPRS+8*8)"(%r15)\n"88" lgr %r1,%r0\n"89" br %r1\n"90" .size my_tramp, .-my_tramp\n"91" .popsection\n"92);93 94#endif /* CONFIG_S390 */95 96#ifdef CONFIG_ARM6497 98asm (99" .pushsection .text, \"ax\", @progbits\n"100" .type my_tramp, @function\n"101" .globl my_tramp\n"102" my_tramp:"103" hint 34\n" // bti c104" sub sp, sp, #32\n"105" stp x9, x30, [sp]\n"106" str x0, [sp, #16]\n"107" mov x0, x30\n"108" bl my_direct_func\n"109" ldp x30, x9, [sp]\n"110" ldr x0, [sp, #16]\n"111" add sp, sp, #32\n"112" ret x9\n"113" .size my_tramp, .-my_tramp\n"114" .popsection\n"115);116 117#endif /* CONFIG_ARM64 */118 119#ifdef CONFIG_LOONGARCH120 121#include <asm/asm.h>122asm (123" .pushsection .text, \"ax\", @progbits\n"124" .type my_tramp, @function\n"125" .globl my_tramp\n"126" my_tramp:\n"127" addi.d $sp, $sp, -32\n"128" st.d $a0, $sp, 0\n"129" st.d $t0, $sp, 8\n"130" st.d $ra, $sp, 16\n"131" move $a0, $t0\n"132" bl my_direct_func\n"133" ld.d $a0, $sp, 0\n"134" ld.d $t0, $sp, 8\n"135" ld.d $ra, $sp, 16\n"136" addi.d $sp, $sp, 32\n"137" jr $t0\n"138" .size my_tramp, .-my_tramp\n"139" .popsection\n"140);141 142#endif /* CONFIG_LOONGARCH */143 144static struct ftrace_ops direct;145 146static int __init ftrace_direct_multi_init(void)147{148 ftrace_set_filter_ip(&direct, (unsigned long) wake_up_process, 0, 0);149 ftrace_set_filter_ip(&direct, (unsigned long) schedule, 0, 0);150 151 return register_ftrace_direct(&direct, (unsigned long) my_tramp);152}153 154static void __exit ftrace_direct_multi_exit(void)155{156 unregister_ftrace_direct(&direct, (unsigned long) my_tramp, true);157}158 159module_init(ftrace_direct_multi_init);160module_exit(ftrace_direct_multi_exit);161 162MODULE_AUTHOR("Jiri Olsa");163MODULE_DESCRIPTION("Example use case of using register_ftrace_direct_multi()");164MODULE_LICENSE("GPL");165