[POWERPC] Added kprobes support to ppc32

Added kprobes to ppc32 platforms that have use single_step_exception.  This
excludes 4xx and anything Book-E since their debug mechanisms for single stepping
are completely different.

Signed-off-by: Kumar Gala <galak@kernel.crashing.org>
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index aeb5309..0b6325a 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -1206,7 +1206,7 @@
 
 config KPROBES
 	bool "Kprobes (EXPERIMENTAL)"
-	depends on PPC64 && KALLSYMS && EXPERIMENTAL && MODULES
+	depends on !BOOKE && !4xx && KALLSYMS && EXPERIMENTAL && MODULES
 	help
 	  Kprobes allows you to trap at almost any kernel address and
 	  execute a callback function.  register_kprobe() establishes
diff --git a/arch/powerpc/kernel/kprobes.c b/arch/powerpc/kernel/kprobes.c
index 4657563..dd2886f 100644
--- a/arch/powerpc/kernel/kprobes.c
+++ b/arch/powerpc/kernel/kprobes.c
@@ -46,8 +46,8 @@
 	if ((unsigned long)p->addr & 0x03) {
 		printk("Attempt to register kprobe at an unaligned address\n");
 		ret = -EINVAL;
-	} else if (IS_MTMSRD(insn) || IS_RFID(insn)) {
-		printk("Cannot register a kprobe on rfid or mtmsrd\n");
+	} else if (IS_MTMSRD(insn) || IS_RFID(insn) || IS_RFI(insn)) {
+		printk("Cannot register a kprobe on rfi/rfid or mtmsr[d]\n");
 		ret = -EINVAL;
 	}
 
@@ -483,8 +483,12 @@
 	memcpy(&kcb->jprobe_saved_regs, regs, sizeof(struct pt_regs));
 
 	/* setup return addr to the jprobe handler routine */
+#ifdef CONFIG_PPC64
 	regs->nip = (unsigned long)(((func_descr_t *)jp->entry)->entry);
 	regs->gpr[2] = (unsigned long)(((func_descr_t *)jp->entry)->toc);
+#else
+	regs->nip = (unsigned long)jp->entry;
+#endif
 
 	return 1;
 }
diff --git a/arch/powerpc/lib/Makefile b/arch/powerpc/lib/Makefile
index e2d4141..4b1ba49 100644
--- a/arch/powerpc/lib/Makefile
+++ b/arch/powerpc/lib/Makefile
@@ -16,11 +16,11 @@
 			   strcase.o
 obj-$(CONFIG_QUICC_ENGINE) += rheap.o
 obj-$(CONFIG_XMON)	+= sstep.o
+obj-$(CONFIG_KPROBES)	+= sstep.o
 obj-$(CONFIG_NOT_COHERENT_CACHE)	+= dma-noncoherent.o
 
 ifeq ($(CONFIG_PPC64),y)
 obj-$(CONFIG_SMP)	+= locks.o
-obj-$(CONFIG_DEBUG_KERNEL) += sstep.o
 endif
 
 # Temporary hack until we have migrated to asm-powerpc
diff --git a/include/asm-powerpc/kprobes.h b/include/asm-powerpc/kprobes.h
index 2dafa37..3a5dd49 100644
--- a/include/asm-powerpc/kprobes.h
+++ b/include/asm-powerpc/kprobes.h
@@ -44,6 +44,7 @@
 #define IS_TDI(instr)		(((instr) & 0xfc000000) == 0x08000000)
 #define IS_TWI(instr)		(((instr) & 0xfc000000) == 0x0c000000)
 
+#ifdef CONFIG_PPC64
 /*
  * 64bit powerpc uses function descriptors.
  * Handle cases where:
@@ -67,9 +68,13 @@
 }
 
 #define JPROBE_ENTRY(pentry)	(kprobe_opcode_t *)((func_descr_t *)pentry)
-
 #define is_trap(instr)	(IS_TW(instr) || IS_TD(instr) || \
 			IS_TWI(instr) || IS_TDI(instr))
+#else
+/* Use stock kprobe_lookup_name since ppc32 doesn't use function descriptors */
+#define JPROBE_ENTRY(pentry)	(kprobe_opcode_t *)(pentry)
+#define is_trap(instr)	(IS_TW(instr) || IS_TWI(instr))
+#endif
 
 #define ARCH_SUPPORTS_KRETPROBES
 #define  ARCH_INACTIVE_KPROBE_COUNT 1
diff --git a/include/asm-powerpc/sstep.h b/include/asm-powerpc/sstep.h
index 630a988..f593b0f 100644
--- a/include/asm-powerpc/sstep.h
+++ b/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);