Skip to contentSkip to conversation

Kprobes for PPC32(BOOKE)

RFC PATCH In review [email protected] 2 participants 3 messages Apr 20, 2007 – Apr 23, 2007

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

RFC PATCH 1/1 Kprobes for PPC32(BOOKE)

Hi Kumar,

This is regarding the kprobes patches for
PPC32 BOOKE version. The attached patches
contain the implementation for this version.

I saw your earlier postings and commits to 2.6.21
regarding kprobes for PPC32. Since the single
step mechanism in BookE is quite different, I
thought i can share some of the issues faced
in this implementation and get your review
feedback for those patches.

Last month, i had posted the patches for
PPC32(BookE) version in the below thread.

http://ozlabs.org/pipermail/linuxppc-dev/2007-March/033058.html

Kernel Version:- 2.6.16.39
Target: Ebony (ppc440_gp processor)

I had mentioned some issues regarding the preempt count in the above thread with some issues. In today released patches, these issues are fixed with some additional patches to head_booke.h and traps.c. With these changes, there are no issues noticed and kprobes behavior is same as other architetcures.

Regarding the below issue mentioned in my earlier mail...

Quoted 7 lines

2. It was noticed that having preempt_disable() at the beginning of kprobe_handler, generates OOPS and kprobes doesnot work. But this is against the original kprobes design implemented in other already working
archs (that is, preemption is disabled for the entire duration of pre and post
handlers execution). The basic problem noticed is, change in

Quoted 9 lines

the preempt
count after generating single step exception. Even though the preemption
is disabled at the beginning of kprobe_handler(), after generating the single step exception, preempt count gets printed as zero in DebugException()
handler of traps.c. This causes the problem and system generates OOPS!!

The core issue was the way debug exception was getting handled in PPC32 BookE versions. The debug exception gets executed using exception stack which doesnot contain the original stack preempt count status. This exact sequence can be explained as below

After executing pre handler, the DEBUG_EXCEPTION gets called because of setting DE bit in MSR and IC, IDM bits of DBCR0. As part of DEBUG_EXCEPTION in head_booke.h, the exception stack is prepared by storing current registers and original sp. But the current preempt count value is not set in exception stack. Because of this, preempt_count=ZERO. This will enable preemption and at any point, it can be rescheduled because of higher priority interrupts. Also as part of post_kprobe_handler(), preempt_enable_no_resched() gets called, which will try to decrement the preempt_count value by 1. But since exception stack contains the preempt_count as ZERO, this operation will make its value as NEGATIVE and that results in OOPS. Execution stops after this point and system reboots

Two solutions are incorporated to solve this fix
1. The head_booke.h is modified before setting the exception stack. This patch takes care of copying the original stack preempt_count value to exception stack before Stack Pointer gets changed
2. Also as part of traps.c within DebugException(), the original stack thread_info contents are copied to exception stack since other contents of current thread_info is also required.

With the above 2 fixes, the system is stable and the kprobes behavior is same as other architectures.

I am porting these patches to 2.6.21-rc7 and will resubmit these patches after testing.

Originally i thought of combining the 2nd patch contents as part of 1st patch in the form of assembly, but i could not do it because of my limited PPC assembly knowledge.
If you have any comments regarding the above patches or better solution, please let me know and i shall try it in 2.6.21.rc7..

Regards
Madhvesh

kprobes-ppc-1.patch:

This patch is to add Kprobes support for BOOKE version of PPC32

arch/powerpc/lib/Makefile +1 -1
Index: linux-2.6.16.39/arch/powerpc/lib/Makefile
===================================================================
@@ -13,8 +13,8 @@
 			   strcase.o
 obj-$(CONFIG_PPC_ISERIES) += e2a.o
 obj-$(CONFIG_XMON)	+= sstep.o
+obj-$(CONFIG_KPROBES)	+= sstep.o
 
 ifeq ($(CONFIG_PPC64),y)
 obj-$(CONFIG_SMP)	+= locks.o
-obj-$(CONFIG_DEBUG_KERNEL) += sstep.o
 endif
arch/ppc/Kconfig +14 -0
Index: linux-2.6.16.39/arch/ppc/Kconfig
===================================================================
@@ -1397,3 +1397,17 @@
 source "security/Kconfig"
 
 source "crypto/Kconfig"
+
+menu "Instrumentation Support"
+
+config KPROBES
+	bool "Kprobes"
+	depends on DEBUG_KERNEL
+	help
+	  Kprobes allows you to trap at almost any kernel address and
+	  execute a callback function.  register_kprobe() establishes
+	  a probepoint and specifies the callback.  Kprobes is useful
+	  for kernel debugging, non-intrusive instrumentation and testing.
+	  If in doubt, say "N".
+
+endmenu
arch/ppc/kernel/Makefile +1 -0
Index: linux-2.6.16.39/arch/ppc/kernel/Makefile
===================================================================
@@ -21,6 +21,7 @@
 obj-$(CONFIG_PCI)		+= pci.o
 obj-$(CONFIG_RAPIDIO)		+= rio.o
 obj-$(CONFIG_KGDB)		+= ppc-stub.o
+obj-$(CONFIG_KPROBES)		+= kprobes.o
 obj-$(CONFIG_SMP)		+= smp.o smp-tbsync.o
 obj-$(CONFIG_TAU)		+= temp.o
 ifndef CONFIG_E200
arch/ppc/kernel/kprobes.c new file +371 -0

371 lines not on this page · raw message

arch/ppc/kernel/misc.S +1 -1
Index: linux-2.6.16.39/arch/ppc/kernel/misc.S
===================================================================
@@ -427,7 +427,7 @@
  *
  * __flush_icache_range(unsigned long start, unsigned long stop)
  */
-_GLOBAL(__flush_icache_range)
+_KPROBE(__flush_icache_range)
 BEGIN_FTR_SECTION
 	blr				/* for 601, do nothing */
 END_FTR_SECTION_IFCLR(CPU_FTR_SPLIT_ID_CACHE)
arch/ppc/kernel/traps.c +65 -1

110 lines not on this page · raw message

arch/ppc/kernel/vmlinux.lds.S +1 -0
Index: linux-2.6.16.39/arch/ppc/kernel/vmlinux.lds.S
===================================================================
@@ -33,6 +33,7 @@
     *(.text)
     SCHED_TEXT
     LOCK_TEXT
+    KPROBES_TEXT
     *(.fixup)
     *(.got1)
     __got2_start = .;
arch/ppc/mm/fault.c +10 -1
Index: linux-2.6.16.39/arch/ppc/mm/fault.c
===================================================================
@@ -28,6 +28,7 @@
 #include <linux/interrupt.h>
 #include <linux/highmem.h>
 #include <linux/module.h>
+#include <linux/kprobes.h>
 
 #include <asm/page.h>
 #include <asm/pgtable.h>
@@ -36,6 +37,7 @@
 #include <asm/system.h>
 #include <asm/uaccess.h>
 #include <asm/tlbflush.h>
+#include <asm/kdebug.h>
 
 #if defined(CONFIG_XMON) || defined(CONFIG_KGDB)
 extern void (*debugger)(struct pt_regs *);
@@ -92,7 +94,7 @@
  * the error_code parameter is ESR for a data fault, 0 for an instruction
  * fault.
  */
-int do_page_fault(struct pt_regs *regs, unsigned long address,
+int __kprobes do_page_fault(struct pt_regs *regs, unsigned long address,
 		  unsigned long error_code)
 {
 	struct vm_area_struct * vma;
@@ -116,6 +118,13 @@
 		is_write = error_code & 0x02000000;
 #endif /* CONFIG_4xx || CONFIG_BOOKE */
 
+#ifdef CONFIG_KPROBES
+	if (notify_die(DIE_PAGE_FAULT, "page_fault", regs, error_code,
+		       11, SIGSEGV) == NOTIFY_STOP) {
+		return 0;
+	}
+#endif
+
 #if defined(CONFIG_XMON) || defined(CONFIG_KGDB)
 	if (debugger_fault_handler && TRAP(regs) == 0x300) {
 		debugger_fault_handler(regs);
include/asm-powerpc/sstep.h +1 -0
Index: linux-2.6.16.39/include/asm-powerpc/sstep.h
===================================================================
@@ -21,6 +21,7 @@
  */
 #define IS_MTMSRD(instr)	(((instr) & 0xfc0007be) == 0x7c000124)
 #define IS_RFID(instr)		(((instr) & 0xfc0007fe) == 0x4c000024)
+#define IS_RFI(instr)		(((instr) & 0xfc0007fe) == 0x4c000064)
 
 /* Emulate instructions that cause a transfer of control. */
 extern int emulate_step(struct pt_regs *regs, unsigned int instr);
include/asm-ppc/kdebug.h new file +60 -0

60 lines not on this page · raw message

include/asm-ppc/kprobes.h new file +71 -0

71 lines not on this page · raw message

arch/ppc/kernel/head_booke.h +30 -5
Index: linux-2.6.16.39/arch/ppc/kernel/head_booke.h
===================================================================
@@ -85,6 +85,35 @@
 #endif
 
 /*
+ * The below macro is specific to kprobes support which addresses copying
+ * preempt count value from current stack to exception stack. This is
+ * required because kprobes has to be processed by disabling preemption.
+ * Even though it is disabled in kprobe_handler, since exception stack
+ * gets used for debug exception, this copy is taken care explicitly.
+ * Other fields of thread information is copied as part of DebugException
+ * before jumping to kprobe post handler.
+ */
+#ifdef CONFIG_KPROBES
+#define COPY_PREEMPT_STATUS						     \
+	SAVE_4GPRS(3, r11);						     \
+	SAVE_2GPRS(7, r11);						     \
+	rlwinm  r6,r1,0,0,18;						     \
+	lwz     r6,TI_PREEMPT(r6);					     \
+	rlwinm  r7,r11,0,0,18;						     \
+	stw     r6,TI_PREEMPT(r7);					     \
+	mr      r1,r11;							     \
+	rlwinm	r9,r9,0,14,12;		/* clear MSR_WE (necessary?)	   */\
+	stw     r0,GPR0(r11)
+#else
+#define COPY_PREEMPT_STATUS						     \
+	mr      r1,r11;							     \
+	rlwinm	r9,r9,0,14,12;		/* clear MSR_WE (necessary?)	   */\
+	stw     r0,GPR0(r11);						     \
+	SAVE_4GPRS(3, r11);						     \
+	SAVE_2GPRS(7, r11)
+#endif
+
+/*
  * Exception prolog for critical/machine check exceptions.  This is a
  * little different from the normal exception prolog above since a
  * critical/machine check exception can potentially occur at any point
@@ -121,11 +150,7 @@
 	stw	r1,GPR1(r11);						     \
 	mfspr	r9,exc_level_srr1;					     \
 	stw	r1,0(r11);						     \
-	mr	r1,r11;							     \
-	rlwinm	r9,r9,0,14,12;		/* clear MSR_WE (necessary?)	   */\
-	stw	r0,GPR0(r11);						     \
-	SAVE_4GPRS(3, r11);						     \
-	SAVE_2GPRS(7, r11)
+	COPY_PREEMPT_STATUS
 
 #define CRITICAL_EXCEPTION_PROLOG \
 		EXC_LEVEL_EXCEPTION_PROLOG(CRIT, SPRN_CSRR0, SPRN_CSRR1)

kprobes-kernel-test-module.patch :

Kernel Probes test modules

Kprobes is a kernel debugging technique. This can be tested using kernel modules. These kernel module will hook the user defined pre handler, post handler and fault handler to the probed point.

Makefile +1 -1
Index: linux-2.6.16.39/Makefile
===================================================================
@@ -559,7 +559,7 @@
 
 
 ifeq ($(KBUILD_EXTMOD),)
-core-y		+= kernel/ mm/ fs/ ipc/ security/ crypto/ block/
+core-y		+= kernel/ mm/ fs/ ipc/ security/ crypto/ block/ kprobe-tests/
 
 vmlinux-dirs	:= $(patsubst %/,%,$(filter %/, $(init-y) $(init-m) \
 		     $(core-y) $(core-m) $(drivers-y) $(drivers-m) \
kprobe-tests/Kconfig new file +13 -0
Index: linux-2.6.16.39/kprobe-tests/Kconfig
===================================================================
@@ -0,0 +1,13 @@
+#
+# Kprobes test modules configuration
+#
+config KPROBESTEST
+	tristate "Kprobes test modules"
+	depends on KPROBES
+	default m if KPROBES=y
+	help
+	  This support if enabled, will be used to test the kprobes support.
+
+	  To compile this kprobe test support as a module, choose M here: the
+	  module will be called k-00x(x will be any number in 1,2,....9).
+	  If in doubt, say "N"
kprobe-tests/Makefile new file +5 -0
Index: linux-2.6.16.39/kprobe-tests/Makefile
===================================================================
@@ -0,0 +1,5 @@
+#
+# Makefile for the Kprobes test modules kernel.
+#
+obj-$(CONFIG_KPROBESTEST) += k-001.o k-002.o k-003.o k-004.o k-005.o k-006.o \
+				k-007.o k-008.o k-009.o
kprobe-tests/k-001.c new file +91 -0

91 lines not on this page · raw message

kprobe-tests/k-002.c new file +95 -0

95 lines not on this page · raw message

kprobe-tests/k-003.c new file +97 -0

97 lines not on this page · raw message

kprobe-tests/k-004.c new file +124 -0

124 lines not on this page · raw message

kprobe-tests/k-005.c new file +72 -0

72 lines not on this page · raw message

kprobe-tests/k-006.c new file +72 -0

72 lines not on this page · raw message

kprobe-tests/k-007.c new file +80 -0

80 lines not on this page · raw message

kprobe-tests/k-008.c new file +68 -0

68 lines not on this page · raw message

kprobe-tests/k-009.c new file +74 -0

74 lines not on this page · raw message

Documentation/kprobe-tests.txt new file +299 -0

299 lines not on this page · raw message

kprobe-tests/kprobes-test.h new file +101 -0

101 lines not on this page · raw message

arch/ppc/Kconfig +1 -0
Index: linux-2.6.16.39/arch/ppc/Kconfig
===================================================================
@@ -1410,4 +1410,5 @@
 	  for kernel debugging, non-intrusive instrumentation and testing.
 	  If in doubt, say "N".
 
+source "kprobe-tests/Kconfig"
 endmenu
#1 lore raw
Quoted 6 lines · On Apr 20, 2007, at 2:24 AM, [email protected] wrote:

Hi Kumar,

This is regarding the kprobes patches for PPC32 BOOKE version. The attached patches contain the implementation for this version.

Quoted 6 lines

I saw your earlier postings and commits to 2.6.21 regarding kprobes for PPC32. Since the single step mechanism in BookE is quite different, I thought i can share some of the issues faced in this implementation and get your review feedback for those patches.

I'd love to review these patches. Is there any possibility that I could get you to build them for arch/powerpc on top of David Gibson's port of ebony to arch/powerpc.

http://ozlabs.org/pipermail/linuxppc-dev/2007-April/034483.html

I dont see much value in adding kprobes into arch/ppc and have been trying to push any 'new' functionality get added to arch/powerpc and only bug fixes to arch/ppc.

- k

#2 lore raw

Hi Kumar,

Kumar Gala <[email protected]> wrote on Saturday, April 21, 2007 1:04 am

Quoted 21 lines · On Apr 20, 2007, at 2:24 AM, [email protected] wrote:
Quoted 7 lines

Hi Kumar,

This is regarding the kprobes patches for PPC32 BOOKE version. The attached patches contain the implementation for this version.

Quoted 6 lines

I saw your earlier postings and commits to 2.6.21 regarding kprobes for PPC32. Since the single step mechanism in BookE is quite different, I thought i can share some of the issues faced in this implementation and get your review feedback for those patches.

I'd love to review these patches. Is there any possibility that I could get you to build them for arch/powerpc on top of David Gibson's
port of ebony to arch/powerpc.

Quoted 7 lines

http://ozlabs.org/pipermail/linuxppc-dev/2007-April/034483.html

I dont see much value in adding kprobes into arch/ppc and have been

trying to push any 'new' functionality get added to arch/powerpc and
only bug fixes to arch/ppc.

Thanks for taking interest in reviewing my patches.
I understand the recent discussions in merging ppc to powerpc and now i can as well start merging my patches to powerpc. I will repost my patches after this, but if you find any bugs in my code, please let me know.

-Madhvesh