linuxppc-dev.lists.ozlabs.org archive mirror
 help / color / mirror / Atom feed
* [RFC PATCH] powerpc/uprobes: Fixup si_addr if we took an exception while single stepping
@ 2017-09-13 20:03 Naveen N. Rao
  2022-03-11 16:49 ` Christophe Leroy
  0 siblings, 1 reply; 2+ messages in thread
From: Naveen N. Rao @ 2017-09-13 20:03 UTC (permalink / raw)
  To: Michael Ellerman, Anton Blanchard
  Cc: Srikar Dronamraju, Ananth N Mavinakayanahalli, linuxppc-dev

If the single-stepped instruction causes an exception, we may end up
setting siginfo.si_addr to the address of the uprobe xol area. This is
not desirable since the address won't make sense for the process if it
wants to handle the exception. Fixup the si_addr field in such cases.

Reported-by: Anton Blanchard <anton@samba.org>
Signed-off-by: Naveen N. Rao <naveen.n.rao@linux.vnet.ibm.com>
---
 arch/powerpc/include/asm/uprobes.h |  7 +++++++
 arch/powerpc/kernel/traps.c        |  4 ++++
 arch/powerpc/kernel/uprobes.c      | 17 +++++++++++++++++
 3 files changed, 28 insertions(+)

diff --git a/arch/powerpc/include/asm/uprobes.h b/arch/powerpc/include/asm/uprobes.h
index 7422a999a39a..13fc6af3c1fd 100644
--- a/arch/powerpc/include/asm/uprobes.h
+++ b/arch/powerpc/include/asm/uprobes.h
@@ -23,6 +23,7 @@
  */
 
 #include <linux/notifier.h>
+#include <asm/siginfo.h>
 #include <asm/probes.h>
 
 typedef ppc_opcode_t uprobe_opcode_t;
@@ -45,4 +46,10 @@ struct arch_uprobe_task {
 	unsigned long	saved_trap_nr;
 };
 
+#ifdef CONFIG_UPROBES
+extern void uprobe_fixup_exception(struct pt_regs *regs, siginfo_t *info);
+#else
+static inline void uprobe_fixup_exception(struct pt_regs *regs, siginfo_t *info) { }
+#endif
+
 #endif	/* _ASM_UPROBES_H */
diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c
index ec74e203ee04..1bb858a37029 100644
--- a/arch/powerpc/kernel/traps.c
+++ b/arch/powerpc/kernel/traps.c
@@ -66,6 +66,7 @@
 #include <asm/hmi.h>
 #include <sysdev/fsl_pci.h>
 #include <asm/kprobes.h>
+#include <asm/uprobes.h>
 
 #if defined(CONFIG_DEBUGGER) || defined(CONFIG_KEXEC_CORE)
 int (*__debugger)(struct pt_regs *regs) __read_mostly;
@@ -292,6 +293,9 @@ void _exception(int signr, struct pt_regs *regs, int code, unsigned long addr)
 	info.si_signo = signr;
 	info.si_code = code;
 	info.si_addr = (void __user *) addr;
+
+	uprobe_fixup_exception(regs, &info);
+
 	force_sig_info(signr, &info, current);
 }
 
diff --git a/arch/powerpc/kernel/uprobes.c b/arch/powerpc/kernel/uprobes.c
index 5d105b8eeece..a361a56e6210 100644
--- a/arch/powerpc/kernel/uprobes.c
+++ b/arch/powerpc/kernel/uprobes.c
@@ -25,6 +25,7 @@
 #include <linux/uprobes.h>
 #include <linux/uaccess.h>
 #include <linux/kdebug.h>
+#include <linux/signal.h>
 
 #include <asm/sstep.h>
 
@@ -214,3 +215,19 @@ bool arch_uretprobe_is_alive(struct return_instance *ret, enum rp_check ctx,
 	else
 		return regs->gpr[1] < ret->stack;
 }
+
+void uprobe_fixup_exception(struct pt_regs *regs, siginfo_t *info)
+{
+	struct task_struct *t = current;
+	struct uprobe_task *utask = t->utask;
+
+	if (likely(!utask || !utask->active_uprobe))
+		return;
+
+	/*
+	 * We reset si_addr here.
+	 * regs->nip is reset during our way back through uprobe_deny_signal()
+	 */
+	if (info->si_addr == (void __user *) utask->xol_vaddr)
+		info->si_addr = (void __user *) utask->vaddr;
+}
-- 
2.14.1

^ permalink raw reply related	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2022-03-11 16:49 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2017-09-13 20:03 [RFC PATCH] powerpc/uprobes: Fixup si_addr if we took an exception while single stepping Naveen N. Rao
2022-03-11 16:49 ` Christophe Leroy

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).