Commit 1a280f48 authored by Vasily Gorbik's avatar Vasily Gorbik Committed by Heiko Carstens
Browse files

s390/kprobes: replace kretprobe with rethook



That's an adaptation of commit f3a112c0 ("x86,rethook,kprobes:
Replace kretprobe with rethook on x86") to s390.

Replaces the kretprobe code with rethook on s390. With this patch,
kretprobe on s390 uses the rethook instead of kretprobe specific
trampoline code.

Tested-by: default avatarIlya Leoshkevich <iii@linux.ibm.com>
Signed-off-by: default avatarVasily Gorbik <gor@linux.ibm.com>
Signed-off-by: default avatarHeiko Carstens <hca@linux.ibm.com>
parent d924ecdb
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -187,6 +187,7 @@ config S390
	select HAVE_KPROBES
	select HAVE_KPROBES_ON_FTRACE
	select HAVE_KRETPROBES
	select HAVE_RETHOOK
	select HAVE_KVM
	select HAVE_LIVEPATCH
	select HAVE_MEMBLOCK_PHYS_MAP
+1 −2
Original line number Diff line number Diff line
@@ -70,8 +70,7 @@ struct kprobe_ctlblk {
};

void arch_remove_kprobe(struct kprobe *p);
void __kretprobe_trampoline(void);
void trampoline_probe_handler(struct pt_regs *regs);
unsigned long arch_rethook_trampoline_callback(struct pt_regs *regs);

int kprobe_fault_handler(struct pt_regs *regs, int trapnr);
int kprobe_exceptions_notify(struct notifier_block *self,
+6 −4
Original line number Diff line number Diff line
@@ -4,7 +4,7 @@

#include <linux/sched.h>
#include <linux/ftrace.h>
#include <linux/kprobes.h>
#include <linux/rethook.h>
#include <linux/llist.h>
#include <asm/ptrace.h>
#include <asm/stacktrace.h>
@@ -43,13 +43,15 @@ struct unwind_state {
	bool error;
};

/* Recover the return address modified by kretprobe and ftrace_graph. */
/* Recover the return address modified by rethook and ftrace_graph. */
static inline unsigned long unwind_recover_ret_addr(struct unwind_state *state,
						    unsigned long ip)
{
	ip = ftrace_graph_ret_addr(state->task, &state->graph_idx, ip, (void *)state->sp);
	if (is_kretprobe_trampoline(ip))
		ip = kretprobe_find_ret_addr(state->task, (void *)state->sp, &state->kr_cur);
#ifdef CONFIG_RETHOOK
	if (is_rethook_trampoline(ip))
		ip = rethook_find_ret_addr(state->task, state->sp, &state->kr_cur);
#endif
	return ip;
}

+1 −0
Original line number Diff line number Diff line
@@ -58,6 +58,7 @@ obj-$(CONFIG_EARLY_PRINTK) += early_printk.o
obj-$(CONFIG_KPROBES)		+= kprobes.o
obj-$(CONFIG_KPROBES)		+= kprobes_insn_page.o
obj-$(CONFIG_KPROBES)		+= mcount.o
obj-$(CONFIG_RETHOOK)		+= rethook.o
obj-$(CONFIG_FUNCTION_TRACER)	+= ftrace.o
obj-$(CONFIG_FUNCTION_TRACER)	+= mcount.o
obj-$(CONFIG_CRASH_DUMP)	+= crash_dump.o
+0 −30
Original line number Diff line number Diff line
@@ -281,16 +281,6 @@ static void pop_kprobe(struct kprobe_ctlblk *kcb)
}
NOKPROBE_SYMBOL(pop_kprobe);

void arch_prepare_kretprobe(struct kretprobe_instance *ri, struct pt_regs *regs)
{
	ri->ret_addr = (kprobe_opcode_t *)regs->gprs[14];
	ri->fp = (void *)regs->gprs[15];

	/* Replace the return addr with trampoline addr */
	regs->gprs[14] = (unsigned long)&__kretprobe_trampoline;
}
NOKPROBE_SYMBOL(arch_prepare_kretprobe);

static void kprobe_reenter_check(struct kprobe_ctlblk *kcb, struct kprobe *p)
{
	switch (kcb->kprobe_status) {
@@ -371,26 +361,6 @@ static int kprobe_handler(struct pt_regs *regs)
}
NOKPROBE_SYMBOL(kprobe_handler);

void arch_kretprobe_fixup_return(struct pt_regs *regs,
				 kprobe_opcode_t *correct_ret_addr)
{
	/* Replace fake return address with real one. */
	regs->gprs[14] = (unsigned long)correct_ret_addr;
}
NOKPROBE_SYMBOL(arch_kretprobe_fixup_return);

/*
 * Called from __kretprobe_trampoline
 */
void trampoline_probe_handler(struct pt_regs *regs)
{
	kretprobe_trampoline_handler(regs, (void *)regs->gprs[15]);
}
NOKPROBE_SYMBOL(trampoline_probe_handler);

/* assembler function that handles the kretprobes must not be probed itself */
NOKPROBE_SYMBOL(__kretprobe_trampoline);

/*
 * Called after single-stepping.  p->addr is the address of the
 * instruction whose first byte has been replaced by the "breakpoint"
Loading