at for-next 5.2 kB view raw
1// SPDX-License-Identifier: GPL-2.0-only 2#include <linux/module.h> 3 4#include <linux/sched.h> /* for wake_up_process() */ 5#include <linux/ftrace.h> 6#if !defined(CONFIG_ARM64) && !defined(CONFIG_PPC32) 7#include <asm/asm-offsets.h> 8#endif 9 10extern void my_direct_func(struct task_struct *p); 11 12void my_direct_func(struct task_struct *p) 13{ 14 trace_printk("waking up %s-%d\n", p->comm, p->pid); 15} 16 17extern void my_tramp(void *); 18 19#ifdef CONFIG_RISCV 20#include <asm/asm.h> 21 22asm ( 23" .pushsection .text, \"ax\", @progbits\n" 24" .type my_tramp, @function\n" 25" .globl my_tramp\n" 26" my_tramp:\n" 27" addi sp,sp,-3*"SZREG"\n" 28" "REG_S" a0,0*"SZREG"(sp)\n" 29" "REG_S" t0,1*"SZREG"(sp)\n" 30" "REG_S" ra,2*"SZREG"(sp)\n" 31" call my_direct_func\n" 32" "REG_L" a0,0*"SZREG"(sp)\n" 33" "REG_L" t0,1*"SZREG"(sp)\n" 34" "REG_L" ra,2*"SZREG"(sp)\n" 35" addi sp,sp,3*"SZREG"\n" 36" jr t0\n" 37" .size my_tramp, .-my_tramp\n" 38" .popsection\n" 39); 40 41#endif /* CONFIG_RISCV */ 42 43#ifdef CONFIG_X86_64 44 45#include <asm/ibt.h> 46#include <asm/nospec-branch.h> 47 48asm ( 49" .pushsection .text, \"ax\", @progbits\n" 50" .type my_tramp, @function\n" 51" .globl my_tramp\n" 52" my_tramp:" 53 ASM_ENDBR 54" pushq %rbp\n" 55" movq %rsp, %rbp\n" 56 CALL_DEPTH_ACCOUNT 57" pushq %rdi\n" 58" call my_direct_func\n" 59" popq %rdi\n" 60" leave\n" 61 ASM_RET 62" .size my_tramp, .-my_tramp\n" 63" .popsection\n" 64); 65 66#endif /* CONFIG_X86_64 */ 67 68#ifdef CONFIG_S390 69 70asm ( 71" .pushsection .text, \"ax\", @progbits\n" 72" .type my_tramp, @function\n" 73" .globl my_tramp\n" 74" my_tramp:" 75" lgr %r1,%r15\n" 76" stmg %r0,%r5,"__stringify(__SF_GPRS)"(%r15)\n" 77" stg %r14,"__stringify(__SF_GPRS+8*8)"(%r15)\n" 78" aghi %r15,"__stringify(-STACK_FRAME_OVERHEAD)"\n" 79" stg %r1,"__stringify(__SF_BACKCHAIN)"(%r15)\n" 80" brasl %r14,my_direct_func\n" 81" aghi %r15,"__stringify(STACK_FRAME_OVERHEAD)"\n" 82" lmg %r0,%r5,"__stringify(__SF_GPRS)"(%r15)\n" 83" lg %r14,"__stringify(__SF_GPRS+8*8)"(%r15)\n" 84" lgr %r1,%r0\n" 85" br %r1\n" 86" .size my_tramp, .-my_tramp\n" 87" .popsection\n" 88); 89 90#endif /* CONFIG_S390 */ 91 92#ifdef CONFIG_ARM64 93 94asm ( 95" .pushsection .text, \"ax\", @progbits\n" 96" .type my_tramp, @function\n" 97" .globl my_tramp\n" 98" my_tramp:" 99" hint 34\n" // bti c 100" sub sp, sp, #32\n" 101" stp x9, x30, [sp]\n" 102" str x0, [sp, #16]\n" 103" bl my_direct_func\n" 104" ldp x30, x9, [sp]\n" 105" ldr x0, [sp, #16]\n" 106" add sp, sp, #32\n" 107" ret x9\n" 108" .size my_tramp, .-my_tramp\n" 109" .popsection\n" 110); 111 112#endif /* CONFIG_ARM64 */ 113 114#ifdef CONFIG_LOONGARCH 115 116asm ( 117" .pushsection .text, \"ax\", @progbits\n" 118" .type my_tramp, @function\n" 119" .globl my_tramp\n" 120" my_tramp:\n" 121" addi.d $sp, $sp, -32\n" 122" st.d $a0, $sp, 0\n" 123" st.d $t0, $sp, 8\n" 124" st.d $ra, $sp, 16\n" 125" bl my_direct_func\n" 126" ld.d $a0, $sp, 0\n" 127" ld.d $t0, $sp, 8\n" 128" ld.d $ra, $sp, 16\n" 129" addi.d $sp, $sp, 32\n" 130" jr $t0\n" 131" .size my_tramp, .-my_tramp\n" 132" .popsection\n" 133); 134 135#endif /* CONFIG_LOONGARCH */ 136 137#ifdef CONFIG_PPC 138#include <asm/ppc_asm.h> 139 140#ifdef CONFIG_PPC64 141#define STACK_FRAME_SIZE 48 142#else 143#define STACK_FRAME_SIZE 24 144#endif 145 146#if defined(CONFIG_PPC64_ELF_ABI_V2) && !defined(CONFIG_PPC_KERNEL_PCREL) 147#define PPC64_TOC_SAVE_AND_UPDATE \ 148" std 2, 24(1)\n" \ 149" bcl 20, 31, 1f\n" \ 150" 1: mflr 12\n" \ 151" ld 2, (99f - 1b)(12)\n" 152#define PPC64_TOC_RESTORE \ 153" ld 2, 24(1)\n" 154#define PPC64_TOC \ 155" 99: .quad .TOC.@tocbase\n" 156#else 157#define PPC64_TOC_SAVE_AND_UPDATE "" 158#define PPC64_TOC_RESTORE "" 159#define PPC64_TOC "" 160#endif 161 162#ifdef CONFIG_PPC_FTRACE_OUT_OF_LINE 163#define PPC_FTRACE_RESTORE_LR \ 164 PPC_LL" 0, "__stringify(PPC_LR_STKOFF)"(1)\n" \ 165" mtlr 0\n" 166#define PPC_FTRACE_RET \ 167" blr\n" 168#else 169#define PPC_FTRACE_RESTORE_LR \ 170 PPC_LL" 0, "__stringify(PPC_LR_STKOFF)"(1)\n" \ 171" mtctr 0\n" 172#define PPC_FTRACE_RET \ 173" mtlr 0\n" \ 174" bctr\n" 175#endif 176 177asm ( 178" .pushsection .text, \"ax\", @progbits\n" 179" .type my_tramp, @function\n" 180" .globl my_tramp\n" 181" my_tramp:\n" 182 PPC_STL" 0, "__stringify(PPC_LR_STKOFF)"(1)\n" 183 PPC_STLU" 1, -"__stringify(STACK_FRAME_MIN_SIZE)"(1)\n" 184" mflr 0\n" 185 PPC_STL" 0, "__stringify(PPC_LR_STKOFF)"(1)\n" 186 PPC_STLU" 1, -"__stringify(STACK_FRAME_SIZE)"(1)\n" 187 PPC64_TOC_SAVE_AND_UPDATE 188 PPC_STL" 3, "__stringify(STACK_FRAME_MIN_SIZE)"(1)\n" 189" bl my_direct_func\n" 190 PPC_LL" 3, "__stringify(STACK_FRAME_MIN_SIZE)"(1)\n" 191 PPC64_TOC_RESTORE 192" addi 1, 1, "__stringify(STACK_FRAME_SIZE)"\n" 193 PPC_FTRACE_RESTORE_LR 194" addi 1, 1, "__stringify(STACK_FRAME_MIN_SIZE)"\n" 195 PPC_LL" 0, "__stringify(PPC_LR_STKOFF)"(1)\n" 196 PPC_FTRACE_RET 197 PPC64_TOC 198" .size my_tramp, .-my_tramp\n" 199" .popsection\n" 200); 201 202#endif /* CONFIG_PPC */ 203 204static struct ftrace_ops direct; 205 206static int __init ftrace_direct_init(void) 207{ 208 ftrace_set_filter_ip(&direct, (unsigned long) wake_up_process, 0, 0); 209 210 return register_ftrace_direct(&direct, (unsigned long) my_tramp); 211} 212 213static void __exit ftrace_direct_exit(void) 214{ 215 unregister_ftrace_direct(&direct, (unsigned long)my_tramp, true); 216} 217 218module_init(ftrace_direct_init); 219module_exit(ftrace_direct_exit); 220 221MODULE_AUTHOR("Steven Rostedt"); 222MODULE_DESCRIPTION("Example use case of using register_ftrace_direct()"); 223MODULE_LICENSE("GPL");