linux-parisc.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/4] kretprobes for parisc / cleanups
@ 2019-04-09 17:30 Sven Schnelle
  2019-04-09 17:30 ` [PATCH 1/4] parisc: remove kprobes.h from generic-y Sven Schnelle
                   ` (4 more replies)
  0 siblings, 5 replies; 6+ messages in thread
From: Sven Schnelle @ 2019-04-09 17:30 UTC (permalink / raw)
  To: deller; +Cc: linux-parisc, Sven Schnelle

Hi,

this patchset implements kretprobes for PA-RISC. While working on
kretprobes i've also made some minor fixes.

Sven Schnelle (4):
  parisc: remove kprobes.h from generic-y
  parisc: Implement kretprobes
  doc: update kprobes supported architecture list
  parisc: remove unused flags parameter in __patch_text()

 .../features/debug/kprobes/arch-support.txt   |   2 +-
 Documentation/kprobes.txt                     |   1 +
 arch/parisc/Kconfig                           |   1 +
 arch/parisc/include/asm/Kbuild                |   1 -
 arch/parisc/kernel/kprobes.c                  | 110 +++++++++++++++++-
 arch/parisc/kernel/patch.c                    |   9 +-
 6 files changed, 116 insertions(+), 8 deletions(-)

-- 
2.20.1


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

* [PATCH 1/4] parisc: remove kprobes.h from generic-y
  2019-04-09 17:30 [PATCH 0/4] kretprobes for parisc / cleanups Sven Schnelle
@ 2019-04-09 17:30 ` Sven Schnelle
  2019-04-09 17:30 ` [PATCH 2/4] parisc: Implement kretprobes Sven Schnelle
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 6+ messages in thread
From: Sven Schnelle @ 2019-04-09 17:30 UTC (permalink / raw)
  To: deller; +Cc: linux-parisc, Sven Schnelle

We're providing our own version now.

Signed-off-by: Sven Schnelle <svens@stackframe.org>
---
 arch/parisc/include/asm/Kbuild | 1 -
 1 file changed, 1 deletion(-)

diff --git a/arch/parisc/include/asm/Kbuild b/arch/parisc/include/asm/Kbuild
index 9bcd0c903dbb..630a179363c2 100644
--- a/arch/parisc/include/asm/Kbuild
+++ b/arch/parisc/include/asm/Kbuild
@@ -10,7 +10,6 @@ generic-y += hw_irq.h
 generic-y += irq_regs.h
 generic-y += irq_work.h
 generic-y += kdebug.h
-generic-y += kprobes.h
 generic-y += kvm_para.h
 generic-y += local.h
 generic-y += local64.h
-- 
2.20.1


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

* [PATCH 2/4] parisc: Implement kretprobes
  2019-04-09 17:30 [PATCH 0/4] kretprobes for parisc / cleanups Sven Schnelle
  2019-04-09 17:30 ` [PATCH 1/4] parisc: remove kprobes.h from generic-y Sven Schnelle
@ 2019-04-09 17:30 ` Sven Schnelle
  2019-04-09 17:30 ` [PATCH 3/4] doc: update kprobes supported architecture list Sven Schnelle
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 6+ messages in thread
From: Sven Schnelle @ 2019-04-09 17:30 UTC (permalink / raw)
  To: deller; +Cc: linux-parisc, Sven Schnelle

Implement kretprobes on parisc, parts stolen from powerpc.

Signed-off-by: Sven Schnelle <svens@stackframe.org>
---
 arch/parisc/Kconfig          |   1 +
 arch/parisc/kernel/kprobes.c | 110 ++++++++++++++++++++++++++++++++++-
 2 files changed, 110 insertions(+), 1 deletion(-)

diff --git a/arch/parisc/Kconfig b/arch/parisc/Kconfig
index 7712688608f4..c8038165b81f 100644
--- a/arch/parisc/Kconfig
+++ b/arch/parisc/Kconfig
@@ -56,6 +56,7 @@ config PARISC
 	select NEED_SG_DMA_LENGTH
 	select HAVE_ARCH_KGDB
 	select HAVE_KPROBES
+	select HAVE_KRETPROBES
 
 	help
 	  The PA-RISC microprocessor is designed by Hewlett-Packard and used
diff --git a/arch/parisc/kernel/kprobes.c b/arch/parisc/kernel/kprobes.c
index 8b1977cd3eb9..d58960b33bda 100644
--- a/arch/parisc/kernel/kprobes.c
+++ b/arch/parisc/kernel/kprobes.c
@@ -172,6 +172,112 @@ int __kprobes parisc_kprobe_ss_handler(struct pt_regs *regs)
 	return 1;
 }
 
+static inline void kretprobe_trampoline(void)
+{
+	asm volatile("nop");
+	asm volatile("nop");
+}
+
+static int __kprobes trampoline_probe_handler(struct kprobe *p,
+					      struct pt_regs *regs);
+
+static struct kprobe trampoline_p = {
+	.pre_handler = trampoline_probe_handler
+};
+
+static int __kprobes trampoline_probe_handler(struct kprobe *p,
+					      struct pt_regs *regs)
+{
+	struct kretprobe_instance *ri = NULL;
+	struct hlist_head *head, empty_rp;
+	struct hlist_node *tmp;
+	unsigned long flags, orig_ret_address = 0;
+	unsigned long trampoline_address = (unsigned long)trampoline_p.addr;
+	kprobe_opcode_t *correct_ret_addr = NULL;
+
+	INIT_HLIST_HEAD(&empty_rp);
+	kretprobe_hash_lock(current, &head, &flags);
+
+	/*
+	 * It is possible to have multiple instances associated with a given
+	 * task either because multiple functions in the call path have
+	 * a return probe installed on them, and/or more than one return
+	 * probe was registered for a target function.
+	 *
+	 * We can handle this because:
+	 *     - instances are always inserted at the head of the list
+	 *     - when multiple return probes are registered for the same
+	 *       function, the first instance's ret_addr will point to the
+	 *       real return address, and all the rest will point to
+	 *       kretprobe_trampoline
+	 */
+	hlist_for_each_entry_safe(ri, tmp, head, hlist) {
+		if (ri->task != current)
+			/* another task is sharing our hash bucket */
+			continue;
+
+		orig_ret_address = (unsigned long)ri->ret_addr;
+
+		if (orig_ret_address != trampoline_address)
+			/*
+			 * This is the real return address. Any other
+			 * instances associated with this task are for
+			 * other calls deeper on the call stack
+			 */
+			break;
+	}
+
+	kretprobe_assert(ri, orig_ret_address, trampoline_address);
+
+	correct_ret_addr = ri->ret_addr;
+	hlist_for_each_entry_safe(ri, tmp, head, hlist) {
+		if (ri->task != current)
+			/* another task is sharing our hash bucket */
+			continue;
+
+		orig_ret_address = (unsigned long)ri->ret_addr;
+		if (ri->rp && ri->rp->handler) {
+			__this_cpu_write(current_kprobe, &ri->rp->kp);
+			get_kprobe_ctlblk()->kprobe_status = KPROBE_HIT_ACTIVE;
+			ri->ret_addr = correct_ret_addr;
+			ri->rp->handler(ri, regs);
+			__this_cpu_write(current_kprobe, NULL);
+		}
+
+		recycle_rp_inst(ri, &empty_rp);
+
+		if (orig_ret_address != trampoline_address)
+			/*
+			 * This is the real return address. Any other
+			 * instances associated with this task are for
+			 * other calls deeper on the call stack
+			 */
+			break;
+	}
+
+	kretprobe_hash_unlock(current, &flags);
+
+	hlist_for_each_entry_safe(ri, tmp, &empty_rp, hlist) {
+		hlist_del(&ri->hlist);
+		kfree(ri);
+	}
+	instruction_pointer_set(regs, orig_ret_address);
+	return 1;
+}
+
+void __kprobes arch_prepare_kretprobe(struct kretprobe_instance *ri,
+				      struct pt_regs *regs)
+{
+	ri->ret_addr = (kprobe_opcode_t *)regs->gr[2];
+
+	/* Replace the return addr with trampoline addr. */
+	regs->gr[2] = (unsigned long)trampoline_p.addr;
+}
+
+int __kprobes arch_trampoline_kprobe(struct kprobe *p)
+{
+	return p->addr == trampoline_p.addr;
+}
 bool arch_kprobe_on_func_entry(unsigned long offset)
 {
 	return !offset;
@@ -179,5 +285,7 @@ bool arch_kprobe_on_func_entry(unsigned long offset)
 
 int __init arch_init_kprobes(void)
 {
-	return 0;
+	trampoline_p.addr = (kprobe_opcode_t *)
+		dereference_function_descriptor(kretprobe_trampoline);
+	return register_kprobe(&trampoline_p);
 }
-- 
2.20.1


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

* [PATCH 3/4] doc: update kprobes supported architecture list
  2019-04-09 17:30 [PATCH 0/4] kretprobes for parisc / cleanups Sven Schnelle
  2019-04-09 17:30 ` [PATCH 1/4] parisc: remove kprobes.h from generic-y Sven Schnelle
  2019-04-09 17:30 ` [PATCH 2/4] parisc: Implement kretprobes Sven Schnelle
@ 2019-04-09 17:30 ` Sven Schnelle
  2019-04-09 17:30 ` [PATCH 4/4] parisc: remove unused flags parameter in __patch_text() Sven Schnelle
  2019-04-09 17:53 ` [PATCH 0/4] kretprobes for parisc / cleanups Helge Deller
  4 siblings, 0 replies; 6+ messages in thread
From: Sven Schnelle @ 2019-04-09 17:30 UTC (permalink / raw)
  To: deller; +Cc: linux-parisc, Sven Schnelle

Now that kprobes and kretprobes are implemented, update the list in
Documentation to reflect that.

Signed-off-by: Sven Schnelle <svens@stackframe.org>
---
 Documentation/features/debug/kprobes/arch-support.txt | 2 +-
 Documentation/kprobes.txt                             | 1 +
 2 files changed, 2 insertions(+), 1 deletion(-)

diff --git a/Documentation/features/debug/kprobes/arch-support.txt b/Documentation/features/debug/kprobes/arch-support.txt
index f4e45bd58fea..e68239b5d2f0 100644
--- a/Documentation/features/debug/kprobes/arch-support.txt
+++ b/Documentation/features/debug/kprobes/arch-support.txt
@@ -21,7 +21,7 @@
     |       nds32: | TODO |
     |       nios2: | TODO |
     |    openrisc: | TODO |
-    |      parisc: | TODO |
+    |      parisc: |  ok  |
     |     powerpc: |  ok  |
     |       riscv: |  ok  |
     |        s390: |  ok  |
diff --git a/Documentation/kprobes.txt b/Documentation/kprobes.txt
index 10f4499e677c..33041300d1ee 100644
--- a/Documentation/kprobes.txt
+++ b/Documentation/kprobes.txt
@@ -321,6 +321,7 @@ architectures:
 - ppc
 - mips
 - s390
+- parisc
 
 Configuring Kprobes
 ===================
-- 
2.20.1


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

* [PATCH 4/4] parisc: remove unused flags parameter in __patch_text()
  2019-04-09 17:30 [PATCH 0/4] kretprobes for parisc / cleanups Sven Schnelle
                   ` (2 preceding siblings ...)
  2019-04-09 17:30 ` [PATCH 3/4] doc: update kprobes supported architecture list Sven Schnelle
@ 2019-04-09 17:30 ` Sven Schnelle
  2019-04-09 17:53 ` [PATCH 0/4] kretprobes for parisc / cleanups Helge Deller
  4 siblings, 0 replies; 6+ messages in thread
From: Sven Schnelle @ 2019-04-09 17:30 UTC (permalink / raw)
  To: deller; +Cc: linux-parisc, Sven Schnelle

It's not used by patch_map()/patch_unmap(), so lets remove
it.

Signed-off-by: Sven Schnelle <svens@stackframe.org>
---
 arch/parisc/kernel/patch.c | 9 ++++-----
 1 file changed, 4 insertions(+), 5 deletions(-)

diff --git a/arch/parisc/kernel/patch.c b/arch/parisc/kernel/patch.c
index 4a3bff87b177..64b0867b09d7 100644
--- a/arch/parisc/kernel/patch.c
+++ b/arch/parisc/kernel/patch.c
@@ -20,7 +20,7 @@ struct patch {
 	unsigned int insn;
 };
 
-static void __kprobes *patch_map(void *addr, int fixmap, unsigned long *flags)
+static void __kprobes *patch_map(void *addr, int fixmap)
 {
 	unsigned int uintaddr = (uintptr_t) addr;
 	bool module = !core_kernel_text(uintaddr);
@@ -38,22 +38,21 @@ static void __kprobes *patch_map(void *addr, int fixmap, unsigned long *flags)
 	return (void *) (__fix_to_virt(fixmap) + (uintaddr & ~PAGE_MASK));
 }
 
-static void __kprobes patch_unmap(int fixmap, unsigned long *flags)
+static void __kprobes patch_unmap(int fixmap)
 {
 	clear_fixmap(fixmap);
 }
 
 void __kprobes __patch_text(void *addr, unsigned int insn)
 {
-	unsigned long flags;
 	void *waddr = addr;
 	int size;
 
-	waddr = patch_map(addr, FIX_TEXT_POKE0, &flags);
+	waddr = patch_map(addr, FIX_TEXT_POKE0);
 	*(u32 *)waddr = insn;
 	size = sizeof(u32);
 	flush_kernel_vmap_range(waddr, size);
-	patch_unmap(FIX_TEXT_POKE0, &flags);
+	patch_unmap(FIX_TEXT_POKE0);
 	flush_icache_range((uintptr_t)(addr),
 			   (uintptr_t)(addr) + size);
 }
-- 
2.20.1


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

* Re: [PATCH 0/4] kretprobes for parisc / cleanups
  2019-04-09 17:30 [PATCH 0/4] kretprobes for parisc / cleanups Sven Schnelle
                   ` (3 preceding siblings ...)
  2019-04-09 17:30 ` [PATCH 4/4] parisc: remove unused flags parameter in __patch_text() Sven Schnelle
@ 2019-04-09 17:53 ` Helge Deller
  4 siblings, 0 replies; 6+ messages in thread
From: Helge Deller @ 2019-04-09 17:53 UTC (permalink / raw)
  To: Sven Schnelle; +Cc: linux-parisc

On 09.04.19 19:30, Sven Schnelle wrote:
> this patchset implements kretprobes for PA-RISC. While working on
> kretprobes i've also made some minor fixes.
>
> Sven Schnelle (4):
>   parisc: remove kprobes.h from generic-y
>   parisc: Implement kretprobes
>   doc: update kprobes supported architecture list
>   parisc: remove unused flags parameter in __patch_text()
>
>  .../features/debug/kprobes/arch-support.txt   |   2 +-
>  Documentation/kprobes.txt                     |   1 +
>  arch/parisc/Kconfig                           |   1 +
>  arch/parisc/include/asm/Kbuild                |   1 -
>  arch/parisc/kernel/kprobes.c                  | 110 +++++++++++++++++-
>  arch/parisc/kernel/patch.c                    |   9 +-
>  6 files changed, 116 insertions(+), 8 deletions(-)

Thanks!
Applied to my for-next branch.

Helge

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

end of thread, other threads:[~2019-04-09 17:53 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-04-09 17:30 [PATCH 0/4] kretprobes for parisc / cleanups Sven Schnelle
2019-04-09 17:30 ` [PATCH 1/4] parisc: remove kprobes.h from generic-y Sven Schnelle
2019-04-09 17:30 ` [PATCH 2/4] parisc: Implement kretprobes Sven Schnelle
2019-04-09 17:30 ` [PATCH 3/4] doc: update kprobes supported architecture list Sven Schnelle
2019-04-09 17:30 ` [PATCH 4/4] parisc: remove unused flags parameter in __patch_text() Sven Schnelle
2019-04-09 17:53 ` [PATCH 0/4] kretprobes for parisc / cleanups Helge Deller

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).