Commit ecaed3b9 authored by Alexei Starovoitov's avatar Alexei Starovoitov
Browse files

Revert "ARM: rethook: Add rethook arm implementation"



This reverts commit 515a4917.

Signed-off-by: default avatarAlexei Starovoitov <ast@kernel.org>
parent f97b8b9b
Loading
Loading
Loading
Loading
+0 −1
Original line number Diff line number Diff line
@@ -107,7 +107,6 @@ config ARM
	select HAVE_MOD_ARCH_SPECIFIC
	select HAVE_NMI
	select HAVE_OPTPROBES if !THUMB2_KERNEL
	select HAVE_RETHOOK
	select HAVE_PERF_EVENTS
	select HAVE_PERF_REGS
	select HAVE_PERF_USER_STACK_DUMP
+2 −2
Original line number Diff line number Diff line
@@ -14,7 +14,7 @@ struct stackframe {
	unsigned long sp;
	unsigned long lr;
	unsigned long pc;
#if defined(CONFIG_KRETPROBES) || defined(CONFIG_RETHOOK)
#ifdef CONFIG_KRETPROBES
	struct llist_node *kr_cur;
	struct task_struct *tsk;
#endif
@@ -27,7 +27,7 @@ void arm_get_current_stackframe(struct pt_regs *regs, struct stackframe *frame)
		frame->sp = regs->ARM_sp;
		frame->lr = regs->ARM_lr;
		frame->pc = regs->ARM_pc;
#if defined(CONFIG_KRETPROBES) || defined(CONFIG_RETHOOK)
#ifdef CONFIG_KRETPROBES
		frame->kr_cur = NULL;
		frame->tsk = current;
#endif
+0 −6
Original line number Diff line number Diff line
// SPDX-License-Identifier: GPL-2.0-only
#include <linux/export.h>
#include <linux/kprobes.h>
#include <linux/rethook.h>
#include <linux/sched.h>
#include <linux/sched/debug.h>
#include <linux/stacktrace.h>
@@ -67,11 +66,6 @@ int notrace unwind_frame(struct stackframe *frame)
	frame->sp = *(unsigned long *)(fp - 8);
	frame->pc = *(unsigned long *)(fp - 4);
#endif
#ifdef CONFIG_RETHOOK
	if (is_rethook_trampoline(frame->pc))
		frame->pc = rethook_find_ret_addr(frame->tsk, frame->fp,
						  &frame->kr_cur);
#endif
#ifdef CONFIG_KRETPROBES
	if (is_kretprobe_trampoline(frame->pc))
		frame->pc = kretprobe_find_ret_addr(frame->tsk,
+0 −1
Original line number Diff line number Diff line
@@ -6,4 +6,3 @@ obj-$(CONFIG_KPROBES) += decode-thumb.o
else
obj-$(CONFIG_KPROBES)		+= decode-arm.o
endif
obj-$(CONFIG_RETHOOK)		+= rethook.o

arch/arm/probes/rethook.c

deleted100644 → 0
+0 −103
Original line number Diff line number Diff line
// SPDX-License-Identifier: GPL-2.0-only
/*
 * arm implementation of rethook. Mostly copied from arch/arm/probes/kprobes/core.c
 */

#include <linux/kprobes.h>
#include <linux/rethook.h>

/* Called from arch_rethook_trampoline */
static __used unsigned long arch_rethook_trampoline_callback(struct pt_regs *regs)
{
	return rethook_trampoline_handler(regs, regs->ARM_fp);
}
NOKPROBE_SYMBOL(arch_rethook_trampoline_callback);

/*
 * When a rethook'ed function returns, it returns to arch_rethook_trampoline
 * which calls rethook callback. We construct a struct pt_regs to
 * give a view of registers r0-r11, sp, lr, and pc to the user
 * return-handler. This is not a complete pt_regs structure, but that
 * should be enough for stacktrace from the return handler with or
 * without pt_regs.
 */
asm(
	".text\n"
	".global arch_rethook_trampoline\n"
	".type arch_rethook_trampoline, %function\n"
	"arch_rethook_trampoline:\n"
#ifdef CONFIG_FRAME_POINTER
	"ldr	lr, =arch_rethook_trampoline	\n\t"
	/* this makes a framepointer on pt_regs. */
#ifdef CONFIG_CC_IS_CLANG
	"stmdb	sp, {sp, lr, pc}	\n\t"
	"sub	sp, sp, #12		\n\t"
	/* In clang case, pt_regs->ip = lr. */
	"stmdb	sp!, {r0 - r11, lr}	\n\t"
	/* fp points regs->r11 (fp) */
	"add	fp, sp,	#44		\n\t"
#else /* !CONFIG_CC_IS_CLANG */
	/* In gcc case, pt_regs->ip = fp. */
	"stmdb	sp, {fp, sp, lr, pc}	\n\t"
	"sub	sp, sp, #16		\n\t"
	"stmdb	sp!, {r0 - r11}		\n\t"
	/* fp points regs->r15 (pc) */
	"add	fp, sp, #60		\n\t"
#endif /* CONFIG_CC_IS_CLANG */
#else /* !CONFIG_FRAME_POINTER */
	"sub	sp, sp, #16		\n\t"
	"stmdb	sp!, {r0 - r11}		\n\t"
#endif /* CONFIG_FRAME_POINTER */
	"mov	r0, sp			\n\t"
	"bl	arch_rethook_trampoline_callback	\n\t"
	"mov	lr, r0			\n\t"
	"ldmia	sp!, {r0 - r11}		\n\t"
	"add	sp, sp, #16		\n\t"
#ifdef CONFIG_THUMB2_KERNEL
	"bx	lr			\n\t"
#else
	"mov	pc, lr			\n\t"
#endif
	".size arch_rethook_trampoline, .-arch_rethook_trampoline\n"
);
NOKPROBE_SYMBOL(arch_rethook_trampoline);

/*
 * At the entry of function with mcount. The stack and registers are prepared
 * for the mcount function as below.
 *
 * mov     ip, sp
 * push    {fp, ip, lr, pc}
 * sub     fp, ip, #4	; FP[0] = PC, FP[-4] = LR, and FP[-12] = call-site FP.
 * push    {lr}
 * bl      <__gnu_mcount_nc> ; call ftrace
 *
 * And when returning from the function, call-site FP, SP and PC are restored
 * from stack as below;
 *
 * ldm     sp, {fp, sp, pc}
 *
 * Thus, if the arch_rethook_prepare() is called from real function entry,
 * it must change the LR and save FP in pt_regs. But if it is called via
 * mcount context (ftrace), it must change the LR on stack, which is next
 * to the PC (= FP[-4]), and save the FP value at FP[-12].
 */
void arch_rethook_prepare(struct rethook_node *rh, struct pt_regs *regs, bool mcount)
{
	unsigned long *ret_addr, *frame;

	if (mcount) {
		ret_addr = (unsigned long *)(regs->ARM_fp - 4);
		frame = (unsigned long *)(regs->ARM_fp - 12);
	} else {
		ret_addr = &regs->ARM_lr;
		frame = &regs->ARM_fp;
	}

	rh->ret_addr = *ret_addr;
	rh->frame = *frame;

	/* Replace the return addr with trampoline addr. */
	*ret_addr = (unsigned long)arch_rethook_trampoline;
}
NOKPROBE_SYMBOL(arch_rethook_prepare);