@@ -143,6 +143,69 @@ unsigned long ftrace_call_adjust(unsigned long addr)
143143 return addr ;
144144}
145145
146+ /* Convert fentry_ip to the symbol address without kallsyms */
147+ unsigned long arch_ftrace_get_symaddr (unsigned long fentry_ip )
148+ {
149+ u32 insn ;
150+
151+ /*
152+ * When using patchable-function-entry without pre-function NOPS, ftrace
153+ * entry is the address of the first NOP after the function entry point.
154+ *
155+ * The compiler has either generated:
156+ *
157+ * func+00: func: NOP // To be patched to MOV X9, LR
158+ * func+04: NOP // To be patched to BL <caller>
159+ *
160+ * Or:
161+ *
162+ * func-04: BTI C
163+ * func+00: func: NOP // To be patched to MOV X9, LR
164+ * func+04: NOP // To be patched to BL <caller>
165+ *
166+ * The fentry_ip is the address of `BL <caller>` which is at `func + 4`
167+ * bytes in either case.
168+ */
169+ if (!IS_ENABLED (CONFIG_DYNAMIC_FTRACE_WITH_CALL_OPS ))
170+ return fentry_ip - AARCH64_INSN_SIZE ;
171+
172+ /*
173+ * When using patchable-function-entry with pre-function NOPs, BTI is
174+ * a bit different.
175+ *
176+ * func+00: func: NOP // To be patched to MOV X9, LR
177+ * func+04: NOP // To be patched to BL <caller>
178+ *
179+ * Or:
180+ *
181+ * func+00: func: BTI C
182+ * func+04: NOP // To be patched to MOV X9, LR
183+ * func+08: NOP // To be patched to BL <caller>
184+ *
185+ * The fentry_ip is the address of `BL <caller>` which is at either
186+ * `func + 4` or `func + 8` depends on whether there is a BTI.
187+ */
188+
189+ /* If there is no BTI, the func address should be one instruction before. */
190+ if (!IS_ENABLED (CONFIG_ARM64_BTI_KERNEL ))
191+ return fentry_ip - AARCH64_INSN_SIZE ;
192+
193+ /* We want to be extra safe in case entry ip is on the page edge,
194+ * but otherwise we need to avoid get_kernel_nofault()'s overhead.
195+ */
196+ if ((fentry_ip & ~PAGE_MASK ) < AARCH64_INSN_SIZE * 2 ) {
197+ if (get_kernel_nofault (insn , (u32 * )(fentry_ip - AARCH64_INSN_SIZE * 2 )))
198+ return 0 ;
199+ } else {
200+ insn = * (u32 * )(fentry_ip - AARCH64_INSN_SIZE * 2 );
201+ }
202+
203+ if (aarch64_insn_is_bti (le32_to_cpu ((__le32 )insn )))
204+ return fentry_ip - AARCH64_INSN_SIZE * 2 ;
205+
206+ return fentry_ip - AARCH64_INSN_SIZE ;
207+ }
208+
146209/*
147210 * Replace a single instruction, which may be a branch or NOP.
148211 * If @validate == true, a replaced instruction is checked against 'old'.
0 commit comments