Skip to contentSkip to conversation

parisc: add kprobes

PATCH In review Sven Schnelle 2 participants 4 messages Apr 7, 2019

Subsystems (2)
lore
Share & tools
lore
#0 lore raw

cover parisc: add kprobes

Hi List,

these two patches implement kprobes for PA-RISC.

Sven Schnelle (2):
parisc: add functions required by KPROBE_EVENTS
parisc: Implement kprobes

 arch/parisc/Kconfig               |   1 +
 arch/parisc/include/asm/kprobes.h |  55 +++++++++
 arch/parisc/include/asm/ptrace.h  |  13 +++
 arch/parisc/kernel/Makefile       |   1 +
 arch/parisc/kernel/kprobes.c      | 183 ++++++++++++++++++++++++++++++
 arch/parisc/kernel/ptrace.c       |  35 ++++++
 arch/parisc/kernel/traps.c        |  14 +++
 7 files changed, 302 insertions(+)
 create mode 100644 arch/parisc/include/asm/kprobes.h
 create mode 100644 arch/parisc/kernel/kprobes.c
Signature · 1 line
2.20.1
#1 lore raw

PATCH 1/2 parisc: add functions required by KPROBE_EVENTS

implement regs_get_register(), regs_get_kernel_stack_nth() and regs_within_kernel_stack()

---
 arch/parisc/include/asm/ptrace.h | 13 ++++++++++++
 arch/parisc/kernel/ptrace.c      | 35 ++++++++++++++++++++++++++++++++
 2 files changed, 48 insertions(+)
arch/parisc/include/asm/ptrace.h +13 -0
index 9ff033d261ab..143fb2a89dd8 100644
@@ -37,4 +37,17 @@ extern int regs_query_register_offset(const char *name);
 extern const char *regs_query_register_name(unsigned int offset);
 #define MAX_REG_OFFSET (offsetof(struct pt_regs, ipsw))
 
+#define kernel_stack_pointer(regs) ((regs)->gr[30])
+
+static inline unsigned long regs_get_register(struct pt_regs *regs,
+					      unsigned int offset)
+{
+	if (unlikely(offset > MAX_REG_OFFSET))
+		return 0;
+	return *(unsigned long *)((unsigned long)regs + offset);
+}
+
+unsigned long regs_get_kernel_stack_nth(struct pt_regs *regs, unsigned int n);
+int regs_within_kernel_stack(struct pt_regs *regs, unsigned long addr);
+
 #endif
arch/parisc/kernel/ptrace.c +35 -0
index 0964c236e3e5..a3d2fb4e6dd2 100644
@@ -789,3 +789,38 @@ const char *regs_query_register_name(unsigned int offset)
 			return roff->name;
 	return NULL;
 }
+
+/**
+ * regs_within_kernel_stack() - check the address in the stack
+ * @regs:      pt_regs which contains kernel stack pointer.
+ * @addr:      address which is checked.
+ *
+ * regs_within_kernel_stack() checks @addr is within the kernel stack page(s).
+ * If @addr is within the kernel stack, it returns true. If not, returns false.
+ */
+int regs_within_kernel_stack(struct pt_regs *regs, unsigned long addr)
+{
+	return ((addr & ~(THREAD_SIZE - 1))  ==
+		(kernel_stack_pointer(regs) & ~(THREAD_SIZE - 1)));
+}
+
+/**
+ * regs_get_kernel_stack_nth() - get Nth entry of the stack
+ * @regs:	pt_regs which contains kernel stack pointer.
+ * @n:		stack entry number.
+ *
+ * regs_get_kernel_stack_nth() returns @n th entry of the kernel stack which
+ * is specified by @regs. If the @n th entry is NOT in the kernel stack,
+ * this returns 0.
+ */
+unsigned long regs_get_kernel_stack_nth(struct pt_regs *regs, unsigned int n)
+{
+	unsigned long *addr = (unsigned long *)kernel_stack_pointer(regs);
+
+	addr -= n;
+
+	if (!regs_within_kernel_stack(regs, (unsigned long)addr))
+		return 0;
+
+	return *addr;
+}
Signature · 1 line
2.20.1
#2 lore raw

PATCH 2/2 parisc: Implement kprobes

In reply to Sven Schnelle

Implement kprobes support for PA-RISC.

---
 arch/parisc/Kconfig               |   1 +
 arch/parisc/include/asm/kprobes.h |  55 +++++++++
 arch/parisc/kernel/Makefile       |   1 +
 arch/parisc/kernel/kprobes.c      | 183 ++++++++++++++++++++++++++++++
 arch/parisc/kernel/traps.c        |  14 +++
 5 files changed, 254 insertions(+)
 create mode 100644 arch/parisc/include/asm/kprobes.h
 create mode 100644 arch/parisc/kernel/kprobes.c
arch/parisc/Kconfig +1 -0
index a80c19c7fc0e..7712688608f4 100644
@@ -55,6 +55,7 @@ config PARISC
 	select NEED_DMA_MAP_STATE
 	select NEED_SG_DMA_LENGTH
 	select HAVE_ARCH_KGDB
+	select HAVE_KPROBES
 
 	help
 	  The PA-RISC microprocessor is designed by Hewlett-Packard and used
arch/parisc/include/asm/kprobes.h new file +55 -0

55 lines not on this page · raw message

arch/parisc/kernel/Makefile +1 -0
index 5012da96c196..b818b28c8a99 100644
@@ -34,3 +34,4 @@ obj-$(CONFIG_PARISC_CPU_TOPOLOGY)	+= topology.o
 obj-$(CONFIG_FUNCTION_TRACER)		+= ftrace.o
 obj-$(CONFIG_FUNCTION_GRAPH_TRACER)	+= ftrace.o
 obj-$(CONFIG_KGDB)			+= kgdb.o
+obj-$(CONFIG_KPROBES)			+= kprobes.o
arch/parisc/kernel/kprobes.c new file +183 -0

183 lines not on this page · raw message

arch/parisc/kernel/traps.c +14 -0
index 4a0516524f2a..096e319adeb3 100644
@@ -43,6 +43,7 @@
 #include <asm/tlbflush.h>
 #include <asm/cacheflush.h>
 #include <linux/kgdb.h>
+#include <linux/kprobes.h>
 
 #include "../math-emu/math-emu.h"	/* for handle_fpe() */
 
@@ -294,6 +295,14 @@ static void handle_break(struct pt_regs *regs)
 			(tt == BUG_TRAP_TYPE_NONE) ? 9 : 0);
 	}
 
+#ifdef CONFIG_KPROBES
+	if (unlikely(iir == PARISC_KPROBES_BREAK_INSN)) {
+		parisc_kprobe_break_handler(regs);
+		return;
+	}
+
+#endif
+
 #ifdef CONFIG_KGDB
 	if (unlikely(iir == PARISC_KGDB_COMPILED_BREAK_INSN ||
 		iir == PARISC_KGDB_BREAK_INSN)) {
@@ -528,6 +537,11 @@ void notrace handle_interruption(int code, struct pt_regs *regs)
 		/* Recovery counter trap */
 		regs->gr[0] &= ~PSW_R;
 
+#ifdef CONFIG_KPROBES
+		if (parisc_kprobe_ss_handler(regs))
+			return;
+#endif
+
 #ifdef CONFIG_KGDB
 		if (kgdb_single_step) {
 			kgdb_handle_exception(0, SIGTRAP, 0, regs);
Signature · 1 line
2.20.1