All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/4] Add support for kprobes on ftrace
@ 2019-07-23 20:37 Sven Schnelle
  2019-07-23 20:37 ` [PATCH 1/4] parisc/ftrace: Add ARCH_SUPPORTS_FTRACE_OPS support Sven Schnelle
                   ` (3 more replies)
  0 siblings, 4 replies; 5+ messages in thread
From: Sven Schnelle @ 2019-07-23 20:37 UTC (permalink / raw)
  To: deller; +Cc: linux-parisc, Sven Schnelle

Hi,

these patches add support for running Kprobes on ftrace infrastructure. While
at it i also fixed on bug in the code patching function and add Jump labels
to the supported features list for PA-RISC.

Regards
Sven

Sven Schnelle (4):
  parisc/ftrace: Add ARCH_SUPPORTS_FTRACE_OPS support
  parisc/ftrace: Add KPROBES_ON_FTRACE
  parisc: Update feature list
  parisc: fix race condition in patching code

 .../core/jump-labels/arch-support.txt         |  2 +-
 .../debug/kprobes-on-ftrace/arch-support.txt  |  2 +-
 arch/parisc/Kconfig                           |  2 +
 arch/parisc/include/asm/ftrace.h              |  1 +
 arch/parisc/kernel/entry.S                    | 99 +++++++++++++++++++
 arch/parisc/kernel/ftrace.c                   | 67 ++++++++++++-
 6 files changed, 166 insertions(+), 7 deletions(-)

-- 
2.20.1


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

* [PATCH 1/4] parisc/ftrace: Add ARCH_SUPPORTS_FTRACE_OPS support
  2019-07-23 20:37 [PATCH 0/4] Add support for kprobes on ftrace Sven Schnelle
@ 2019-07-23 20:37 ` Sven Schnelle
  2019-07-23 20:37 ` [PATCH 2/4] parisc/ftrace: Add KPROBES_ON_FTRACE Sven Schnelle
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 5+ messages in thread
From: Sven Schnelle @ 2019-07-23 20:37 UTC (permalink / raw)
  To: deller; +Cc: linux-parisc, Sven Schnelle

Pass ftrace_ops to ftrace functions to ftrace_trace_function().

Signed-off-by: Sven Schnelle <svens@stackframe.org>
---
 arch/parisc/include/asm/ftrace.h | 1 +
 arch/parisc/kernel/ftrace.c      | 8 ++++++--
 2 files changed, 7 insertions(+), 2 deletions(-)

diff --git a/arch/parisc/include/asm/ftrace.h b/arch/parisc/include/asm/ftrace.h
index 958c0aa5dbb2..a7cf0d05ccf4 100644
--- a/arch/parisc/include/asm/ftrace.h
+++ b/arch/parisc/include/asm/ftrace.h
@@ -8,6 +8,7 @@ extern void mcount(void);
 #define MCOUNT_ADDR		((unsigned long)mcount)
 #define MCOUNT_INSN_SIZE	4
 #define CC_USING_NOP_MCOUNT
+#define ARCH_SUPPORTS_FTRACE_OPS 1
 extern unsigned long sys_call_table[];
 
 extern unsigned long return_address(unsigned int);
diff --git a/arch/parisc/kernel/ftrace.c b/arch/parisc/kernel/ftrace.c
index d784ccdd8fef..ea5c50de0b65 100644
--- a/arch/parisc/kernel/ftrace.c
+++ b/arch/parisc/kernel/ftrace.c
@@ -53,8 +53,12 @@ void notrace __hot ftrace_function_trampoline(unsigned long parent,
 #ifndef CONFIG_DYNAMIC_FTRACE
 	extern ftrace_func_t ftrace_trace_function;
 #endif
-	if (ftrace_trace_function != ftrace_stub)
-		ftrace_trace_function(self_addr, parent, NULL, NULL);
+	extern struct ftrace_ops *function_trace_op;
+
+	if (function_trace_op->flags & FTRACE_OPS_FL_ENABLED &&
+	    ftrace_trace_function != ftrace_stub)
+		ftrace_trace_function(self_addr, parent,
+				function_trace_op, NULL);
 
 #ifdef CONFIG_FUNCTION_GRAPH_TRACER
 	if (ftrace_graph_return != (trace_func_graph_ret_t) ftrace_stub ||
-- 
2.20.1


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

* [PATCH 2/4] parisc/ftrace: Add KPROBES_ON_FTRACE
  2019-07-23 20:37 [PATCH 0/4] Add support for kprobes on ftrace Sven Schnelle
  2019-07-23 20:37 ` [PATCH 1/4] parisc/ftrace: Add ARCH_SUPPORTS_FTRACE_OPS support Sven Schnelle
@ 2019-07-23 20:37 ` Sven Schnelle
  2019-07-23 20:37 ` [PATCH 3/4] parisc: Update feature list Sven Schnelle
  2019-07-23 20:37 ` [PATCH 4/4] parisc: fix race condition in patching code Sven Schnelle
  3 siblings, 0 replies; 5+ messages in thread
From: Sven Schnelle @ 2019-07-23 20:37 UTC (permalink / raw)
  To: deller; +Cc: linux-parisc, Sven Schnelle

Allow KPROBES to use the ftrace infrastructure on PA-RISC.

Signed-off-by: Sven Schnelle <svens@stackframe.org>
---
 .../debug/kprobes-on-ftrace/arch-support.txt  |  2 +-
 arch/parisc/Kconfig                           |  2 +
 arch/parisc/kernel/entry.S                    | 99 +++++++++++++++++++
 arch/parisc/kernel/ftrace.c                   | 58 ++++++++++-
 4 files changed, 157 insertions(+), 4 deletions(-)

diff --git a/Documentation/features/debug/kprobes-on-ftrace/arch-support.txt b/Documentation/features/debug/kprobes-on-ftrace/arch-support.txt
index 68f266944d5f..4fae0464ddff 100644
--- a/Documentation/features/debug/kprobes-on-ftrace/arch-support.txt
+++ b/Documentation/features/debug/kprobes-on-ftrace/arch-support.txt
@@ -21,7 +21,7 @@
     |       nds32: | TODO |
     |       nios2: | TODO |
     |    openrisc: | TODO |
-    |      parisc: | TODO |
+    |      parisc: |  ok  |
     |     powerpc: |  ok  |
     |       riscv: | TODO |
     |        s390: | TODO |
diff --git a/arch/parisc/Kconfig b/arch/parisc/Kconfig
index 6d732e451071..ee59171edffe 100644
--- a/arch/parisc/Kconfig
+++ b/arch/parisc/Kconfig
@@ -61,6 +61,8 @@ config PARISC
 	select HAVE_KRETPROBES
 	select HAVE_DYNAMIC_FTRACE if $(cc-option,-fpatchable-function-entry=1,1)
 	select HAVE_FTRACE_MCOUNT_RECORD if HAVE_DYNAMIC_FTRACE
+	select HAVE_KPROBES_ON_FTRACE
+	select HAVE_DYNAMIC_FTRACE_WITH_REGS
 
 	help
 	  The PA-RISC microprocessor is designed by Hewlett-Packard and used
diff --git a/arch/parisc/kernel/entry.S b/arch/parisc/kernel/entry.S
index d9d3387f7c47..1d1d748c227f 100644
--- a/arch/parisc/kernel/entry.S
+++ b/arch/parisc/kernel/entry.S
@@ -1996,6 +1996,7 @@ _mcount:
 	 * calling mcount(), and 2 instructions for ftrace_stub().  That way we
 	 * have all on one L1 cacheline.
 	 */
+	ldi	0, %arg3
 	b	ftrace_function_trampoline
 	copy	%r3, %arg2	/* caller original %sp */
 ftrace_stub:
@@ -2048,6 +2049,7 @@ ftrace_caller:
 	LDREG	0(%r3), %r25
 	copy	%rp, %r26
 	ldo	-8(%r25), %r25
+	ldi	0, %r23		/* no pt_regs */
 	b,l	ftrace_function_trampoline, %rp
 	copy	%r3, %r24
 
@@ -2075,6 +2077,103 @@ ftrace_caller:
 
 ENDPROC_CFI(ftrace_caller)
 
+#ifdef CONFIG_HAVE_DYNAMIC_FTRACE_WITH_REGS
+ENTRY_CFI(ftrace_regs_caller,caller,frame=FTRACE_FRAME_SIZE+PT_SZ_ALGN,
+	CALLS,SAVE_RP,SAVE_SP)
+ftrace_regs_caller:
+	.global ftrace_regs_caller
+
+	ldo	-FTRACE_FRAME_SIZE(%sp), %r1
+	STREG	%rp, -RP_OFFSET(%r1)
+
+	copy	%sp, %r1
+	ldo	PT_SZ_ALGN(%sp), %sp
+
+	STREG	%rp, PT_GR2(%r1)
+	STREG	%r3, PT_GR3(%r1)
+	STREG	%r4, PT_GR4(%r1)
+	STREG	%r5, PT_GR5(%r1)
+	STREG	%r6, PT_GR6(%r1)
+	STREG	%r7, PT_GR7(%r1)
+	STREG	%r8, PT_GR8(%r1)
+	STREG	%r9, PT_GR9(%r1)
+	STREG   %r10, PT_GR10(%r1)
+	STREG   %r11, PT_GR11(%r1)
+	STREG   %r12, PT_GR12(%r1)
+	STREG   %r13, PT_GR13(%r1)
+	STREG   %r14, PT_GR14(%r1)
+	STREG   %r15, PT_GR15(%r1)
+	STREG   %r16, PT_GR16(%r1)
+	STREG   %r17, PT_GR17(%r1)
+	STREG   %r18, PT_GR18(%r1)
+	STREG	%r19, PT_GR19(%r1)
+	STREG	%r20, PT_GR20(%r1)
+	STREG	%r21, PT_GR21(%r1)
+	STREG	%r22, PT_GR22(%r1)
+	STREG	%r23, PT_GR23(%r1)
+	STREG	%r24, PT_GR24(%r1)
+	STREG	%r25, PT_GR25(%r1)
+	STREG	%r26, PT_GR26(%r1)
+	STREG	%r27, PT_GR27(%r1)
+	STREG	%r28, PT_GR28(%r1)
+	STREG	%r29, PT_GR29(%r1)
+	STREG	%r30, PT_GR30(%r1)
+	STREG	%r31, PT_GR31(%r1)
+	mfctl	%cr11, %r26
+	STREG	%r26, PT_SAR(%r1)
+
+	copy	%rp, %r26
+	LDREG	-FTRACE_FRAME_SIZE-PT_SZ_ALGN(%sp), %r25
+	ldo	-8(%r25), %r25
+	copy	%r3, %arg2
+	b,l	ftrace_function_trampoline, %rp
+	copy	%r1, %arg3 /* struct pt_regs */
+
+	ldo	-PT_SZ_ALGN(%sp), %r1
+
+	LDREG	PT_SAR(%r1), %rp
+	mtctl	%rp, %cr11
+
+	LDREG	PT_GR2(%r1), %rp
+	LDREG	PT_GR3(%r1), %r3
+	LDREG	PT_GR4(%r1), %r4
+	LDREG	PT_GR5(%r1), %r5
+	LDREG	PT_GR6(%r1), %r6
+	LDREG	PT_GR7(%r1), %r7
+	LDREG	PT_GR8(%r1), %r8
+	LDREG	PT_GR9(%r1), %r9
+	LDREG   PT_GR10(%r1),%r10
+	LDREG   PT_GR11(%r1),%r11
+	LDREG   PT_GR12(%r1),%r12
+	LDREG   PT_GR13(%r1),%r13
+	LDREG   PT_GR14(%r1),%r14
+	LDREG   PT_GR15(%r1),%r15
+	LDREG   PT_GR16(%r1),%r16
+	LDREG   PT_GR17(%r1),%r17
+	LDREG   PT_GR18(%r1),%r18
+	LDREG   PT_GR19(%r1),%r19
+	LDREG   PT_GR20(%r1),%r20
+	LDREG   PT_GR21(%r1),%r21
+	LDREG   PT_GR22(%r1),%r22
+	LDREG   PT_GR23(%r1),%r23
+	LDREG   PT_GR24(%r1),%r24
+	LDREG   PT_GR25(%r1),%r25
+	LDREG   PT_GR26(%r1),%r26
+	LDREG   PT_GR27(%r1),%r27
+	LDREG   PT_GR28(%r1),%r28
+	LDREG   PT_GR29(%r1),%r29
+	LDREG   PT_GR30(%r1),%r30
+	LDREG   PT_GR31(%r1),%r31
+
+	ldo	-PT_SZ_ALGN(%sp), %sp
+	LDREGM	-FTRACE_FRAME_SIZE(%sp), %r1
+	/* Adjust return point to jump back to beginning of traced function */
+	ldo	-4(%r1), %r1
+	bv,n	(%r1)
+
+ENDPROC_CFI(ftrace_regs_caller)
+
+#endif
 #endif
 
 #ifdef CONFIG_FUNCTION_GRAPH_TRACER
diff --git a/arch/parisc/kernel/ftrace.c b/arch/parisc/kernel/ftrace.c
index ea5c50de0b65..2c6086dbfe68 100644
--- a/arch/parisc/kernel/ftrace.c
+++ b/arch/parisc/kernel/ftrace.c
@@ -13,6 +13,8 @@
 #include <linux/init.h>
 #include <linux/ftrace.h>
 #include <linux/uaccess.h>
+#include <linux/kprobes.h>
+#include <linux/ptrace.h>
 
 #include <asm/assembly.h>
 #include <asm/sections.h>
@@ -48,7 +50,8 @@ static void __hot prepare_ftrace_return(unsigned long *parent,
 
 void notrace __hot ftrace_function_trampoline(unsigned long parent,
 				unsigned long self_addr,
-				unsigned long org_sp_gr3)
+				unsigned long org_sp_gr3,
+				struct pt_regs *regs)
 {
 #ifndef CONFIG_DYNAMIC_FTRACE
 	extern ftrace_func_t ftrace_trace_function;
@@ -58,11 +61,11 @@ void notrace __hot ftrace_function_trampoline(unsigned long parent,
 	if (function_trace_op->flags & FTRACE_OPS_FL_ENABLED &&
 	    ftrace_trace_function != ftrace_stub)
 		ftrace_trace_function(self_addr, parent,
-				function_trace_op, NULL);
+				function_trace_op, regs);
 
 #ifdef CONFIG_FUNCTION_GRAPH_TRACER
 	if (ftrace_graph_return != (trace_func_graph_ret_t) ftrace_stub ||
-		ftrace_graph_entry != ftrace_graph_entry_stub) {
+	    ftrace_graph_entry != ftrace_graph_entry_stub) {
 		unsigned long *parent_rp;
 
 		/* calculate pointer to %rp in stack */
@@ -100,6 +103,12 @@ int ftrace_update_ftrace_func(ftrace_func_t func)
 	return 0;
 }
 
+int ftrace_modify_call(struct dyn_ftrace *rec, unsigned long old_addr,
+			unsigned long addr)
+{
+	return 0;
+}
+
 unsigned long ftrace_call_adjust(unsigned long addr)
 {
 	return addr+(FTRACE_PATCHABLE_FUNCTION_SIZE-1)*4;
@@ -190,3 +199,46 @@ int ftrace_make_nop(struct module *mod, struct dyn_ftrace *rec,
 	return 0;
 }
 #endif
+
+#ifdef CONFIG_KPROBES_ON_FTRACE
+void kprobe_ftrace_handler(unsigned long ip, unsigned long parent_ip,
+			   struct ftrace_ops *ops, struct pt_regs *regs)
+{
+	struct kprobe_ctlblk *kcb;
+	struct kprobe *p = get_kprobe((kprobe_opcode_t *)ip);
+
+	if (unlikely(!p) || kprobe_disabled(p))
+		return;
+
+	if (kprobe_running()) {
+		kprobes_inc_nmissed_count(p);
+		return;
+	}
+
+	__this_cpu_write(current_kprobe, p);
+
+	kcb = get_kprobe_ctlblk();
+	kcb->kprobe_status = KPROBE_HIT_ACTIVE;
+
+	regs->iaoq[0] = ip;
+	regs->iaoq[1] = ip + 4;
+
+	if (!p->pre_handler || !p->pre_handler(p, regs)) {
+		regs->iaoq[0] = ip + 4;
+		regs->iaoq[1] = ip + 8;
+
+		if (unlikely(p->post_handler)) {
+			kcb->kprobe_status = KPROBE_HIT_SSDONE;
+			p->post_handler(p, regs, 0);
+		}
+	}
+	__this_cpu_write(current_kprobe, NULL);
+}
+NOKPROBE_SYMBOL(kprobe_ftrace_handler);
+
+int arch_prepare_kprobe_ftrace(struct kprobe *p)
+{
+	p->ainsn.insn = NULL;
+	return 0;
+}
+#endif
-- 
2.20.1


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

* [PATCH 3/4] parisc: Update feature list
  2019-07-23 20:37 [PATCH 0/4] Add support for kprobes on ftrace Sven Schnelle
  2019-07-23 20:37 ` [PATCH 1/4] parisc/ftrace: Add ARCH_SUPPORTS_FTRACE_OPS support Sven Schnelle
  2019-07-23 20:37 ` [PATCH 2/4] parisc/ftrace: Add KPROBES_ON_FTRACE Sven Schnelle
@ 2019-07-23 20:37 ` Sven Schnelle
  2019-07-23 20:37 ` [PATCH 4/4] parisc: fix race condition in patching code Sven Schnelle
  3 siblings, 0 replies; 5+ messages in thread
From: Sven Schnelle @ 2019-07-23 20:37 UTC (permalink / raw)
  To: deller; +Cc: linux-parisc, Sven Schnelle

Add jump labels to the list of supported features.

Signed-off-by: Sven Schnelle <svens@stackframe.org>
---
 Documentation/features/core/jump-labels/arch-support.txt | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/Documentation/features/core/jump-labels/arch-support.txt b/Documentation/features/core/jump-labels/arch-support.txt
index 7fc2e243dee9..cae7be2f7725 100644
--- a/Documentation/features/core/jump-labels/arch-support.txt
+++ b/Documentation/features/core/jump-labels/arch-support.txt
@@ -21,7 +21,7 @@
     |       nds32: | TODO |
     |       nios2: | TODO |
     |    openrisc: | TODO |
-    |      parisc: | TODO |
+    |      parisc: |  ok  |
     |     powerpc: |  ok  |
     |       riscv: | TODO |
     |        s390: |  ok  |
-- 
2.20.1


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

* [PATCH 4/4] parisc: fix race condition in patching code
  2019-07-23 20:37 [PATCH 0/4] Add support for kprobes on ftrace Sven Schnelle
                   ` (2 preceding siblings ...)
  2019-07-23 20:37 ` [PATCH 3/4] parisc: Update feature list Sven Schnelle
@ 2019-07-23 20:37 ` Sven Schnelle
  3 siblings, 0 replies; 5+ messages in thread
From: Sven Schnelle @ 2019-07-23 20:37 UTC (permalink / raw)
  To: deller; +Cc: linux-parisc, Sven Schnelle

Assume the following ftrace code sequence that was patched in earlier by
ftrace_make_call():

PAGE A:
ffc:	addr of ftrace_caller()
PAGE B:
000:	0x6fc10080 /* stw,ma r1,40(sp) */
004:	0x48213fd1 /* ldw -18(r1),r1 */
008:	0xe820c002 /* bv,n r0(r1) */
00c:	0xe83f1fdf /* b,l,n .-c,r1 */

When a Code sequences that is to be patched spans a page break, we might
have already cleared the part on the PAGE A. If an interrupt is coming in
during the remap of the fixed mapping to PAGE B, it might execute the
patched function with only parts of the FTRACE code cleared. To prevent
this, clear the jump to our mini trampoline first, and clear the remaining
parts after this. This might also happen when patch_text() patches a
function that it calls during remap.

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

diff --git a/arch/parisc/kernel/ftrace.c b/arch/parisc/kernel/ftrace.c
index 2c6086dbfe68..b836fc61a24f 100644
--- a/arch/parisc/kernel/ftrace.c
+++ b/arch/parisc/kernel/ftrace.c
@@ -194,8 +194,9 @@ int ftrace_make_nop(struct module *mod, struct dyn_ftrace *rec,
 	for (i = 0; i < ARRAY_SIZE(insn); i++)
 		insn[i] = INSN_NOP;
 
+	__patch_text((void *)rec->ip, INSN_NOP);
 	__patch_text_multiple((void *)rec->ip + 4 - sizeof(insn),
-			      insn, sizeof(insn));
+			      insn, sizeof(insn)-4);
 	return 0;
 }
 #endif
-- 
2.20.1


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

end of thread, other threads:[~2019-07-23 20:38 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-07-23 20:37 [PATCH 0/4] Add support for kprobes on ftrace Sven Schnelle
2019-07-23 20:37 ` [PATCH 1/4] parisc/ftrace: Add ARCH_SUPPORTS_FTRACE_OPS support Sven Schnelle
2019-07-23 20:37 ` [PATCH 2/4] parisc/ftrace: Add KPROBES_ON_FTRACE Sven Schnelle
2019-07-23 20:37 ` [PATCH 3/4] parisc: Update feature list Sven Schnelle
2019-07-23 20:37 ` [PATCH 4/4] parisc: fix race condition in patching code Sven Schnelle

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.