* [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