^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) * Ftrace support for Microblaze.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * Copyright (C) 2009 Michal Simek <monstr@monstr.eu>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (C) 2009 PetaLogix
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * Based on MIPS and PowerPC ftrace code
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * This file is subject to the terms and conditions of the GNU General Public
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) * License. See the file "COPYING" in the main directory of this archive
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) * for more details.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <asm/cacheflush.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/ftrace.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #ifdef CONFIG_FUNCTION_GRAPH_TRACER
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) * Hook the return address and push it in the stack of return addrs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) * in current thread info.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) void prepare_ftrace_return(unsigned long *parent, unsigned long self_addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) unsigned long old;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) int faulted;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) unsigned long return_hooker = (unsigned long)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) &return_to_handler;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) if (unlikely(ftrace_graph_is_dead()))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) if (unlikely(atomic_read(¤t->tracing_graph_pause)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) * Protect against fault, even if it shouldn't
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) * happen. This tool is too much intrusive to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) * ignore such a protection.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) asm volatile(" 1: lwi %0, %2, 0;" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) "2: swi %3, %2, 0;" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) " addik %1, r0, 0;" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) "3:" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) " .section .fixup, \"ax\";" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) "4: brid 3b;" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) " addik %1, r0, 1;" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) " .previous;" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) " .section __ex_table,\"a\";" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) " .word 1b,4b;" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) " .word 2b,4b;" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) " .previous;" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) : "=&r" (old), "=r" (faulted)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) : "r" (parent), "r" (return_hooker)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) flush_dcache_range((u32)parent, (u32)parent + 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) flush_icache_range((u32)parent, (u32)parent + 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) if (unlikely(faulted)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) ftrace_graph_stop();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) WARN_ON(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) if (function_graph_enter(old, self_addr, 0, NULL))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) *parent = old;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) #endif /* CONFIG_FUNCTION_GRAPH_TRACER */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) #ifdef CONFIG_DYNAMIC_FTRACE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) /* save value to addr - it is save to do it in asm */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) static int ftrace_modify_code(unsigned long addr, unsigned int value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) int faulted = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) __asm__ __volatile__(" 1: swi %2, %1, 0;" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) " addik %0, r0, 0;" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) "2:" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) " .section .fixup, \"ax\";" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) "3: brid 2b;" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) " addik %0, r0, 1;" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) " .previous;" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) " .section __ex_table,\"a\";" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) " .word 1b,3b;" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) " .previous;" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) : "=r" (faulted)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) : "r" (addr), "r" (value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) if (unlikely(faulted))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) flush_dcache_range(addr, addr + 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) flush_icache_range(addr, addr + 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) #define MICROBLAZE_NOP 0x80000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) #define MICROBLAZE_BRI 0xb800000C
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) static unsigned int recorded; /* if save was or not */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) static unsigned int imm; /* saving whole imm instruction */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) /* There are two approaches howto solve ftrace_make nop function - look below */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) #undef USE_FTRACE_NOP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) #ifdef USE_FTRACE_NOP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) static unsigned int bralid; /* saving whole bralid instruction */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) int ftrace_make_nop(struct module *mod,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) struct dyn_ftrace *rec, unsigned long addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) /* we have this part of code which we are working with
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) * b000c000 imm -16384
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) * b9fc8e30 bralid r15, -29136 // c0008e30 <_mcount>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) * 80000000 or r0, r0, r0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) * The first solution (!USE_FTRACE_NOP-could be called branch solution)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) * b000c000 bri 12 (0xC - jump to any other instruction)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) * b9fc8e30 bralid r15, -29136 // c0008e30 <_mcount>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) * 80000000 or r0, r0, r0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) * any other instruction
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) * The second solution (USE_FTRACE_NOP) - no jump just nops
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) * 80000000 or r0, r0, r0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) * 80000000 or r0, r0, r0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) * 80000000 or r0, r0, r0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) if (recorded == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) recorded = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) imm = *(unsigned int *)rec->ip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) pr_debug("%s: imm:0x%x\n", __func__, imm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) #ifdef USE_FTRACE_NOP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) bralid = *(unsigned int *)(rec->ip + 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) pr_debug("%s: bralid 0x%x\n", __func__, bralid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) #endif /* USE_FTRACE_NOP */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) #ifdef USE_FTRACE_NOP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) ret = ftrace_modify_code(rec->ip, MICROBLAZE_NOP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) ret += ftrace_modify_code(rec->ip + 4, MICROBLAZE_NOP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) #else /* USE_FTRACE_NOP */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) ret = ftrace_modify_code(rec->ip, MICROBLAZE_BRI);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) #endif /* USE_FTRACE_NOP */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) /* I believe that first is called ftrace_make_nop before this function */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) int ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) pr_debug("%s: addr:0x%x, rec->ip: 0x%x, imm:0x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) __func__, (unsigned int)addr, (unsigned int)rec->ip, imm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) ret = ftrace_modify_code(rec->ip, imm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) #ifdef USE_FTRACE_NOP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) pr_debug("%s: bralid:0x%x\n", __func__, bralid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) ret += ftrace_modify_code(rec->ip + 4, bralid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) #endif /* USE_FTRACE_NOP */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) int __init ftrace_dyn_arch_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) int ftrace_update_ftrace_func(ftrace_func_t func)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) unsigned long ip = (unsigned long)(&ftrace_call);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) unsigned int upper = (unsigned int)func;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) unsigned int lower = (unsigned int)func;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) /* create proper saving to ftrace_call poll */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) upper = 0xb0000000 + (upper >> 16); /* imm func_upper */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) lower = 0x32800000 + (lower & 0xFFFF); /* addik r20, r0, func_lower */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) pr_debug("%s: func=0x%x, ip=0x%x, upper=0x%x, lower=0x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) __func__, (unsigned int)func, (unsigned int)ip, upper, lower);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) /* save upper and lower code */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) ret = ftrace_modify_code(ip, upper);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) ret += ftrace_modify_code(ip + 4, lower);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) /* We just need to replace the rtsd r15, 8 with NOP */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) ret += ftrace_modify_code((unsigned long)&ftrace_caller,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) MICROBLAZE_NOP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) #ifdef CONFIG_FUNCTION_GRAPH_TRACER
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) unsigned int old_jump; /* saving place for jump instruction */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) int ftrace_enable_ftrace_graph_caller(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) unsigned int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) unsigned long ip = (unsigned long)(&ftrace_call_graph);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) old_jump = *(unsigned int *)ip; /* save jump over instruction */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) ret = ftrace_modify_code(ip, MICROBLAZE_NOP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) pr_debug("%s: Replace instruction: 0x%x\n", __func__, old_jump);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) int ftrace_disable_ftrace_graph_caller(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) unsigned int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) unsigned long ip = (unsigned long)(&ftrace_call_graph);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) ret = ftrace_modify_code(ip, old_jump);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) pr_debug("%s\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) #endif /* CONFIG_FUNCTION_GRAPH_TRACER */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) #endif /* CONFIG_DYNAMIC_FTRACE */