Commit 82090035 authored by Kumar Gala's avatar Kumar Gala

[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: default avatarKumar Gala <galak@kernel.crashing.org>
parent 84232005
...@@ -1206,7 +1206,7 @@ source "arch/powerpc/oprofile/Kconfig" ...@@ -1206,7 +1206,7 @@ source "arch/powerpc/oprofile/Kconfig"
config KPROBES config KPROBES
bool "Kprobes (EXPERIMENTAL)" bool "Kprobes (EXPERIMENTAL)"
depends on PPC64 && KALLSYMS && EXPERIMENTAL && MODULES depends on !BOOKE && !4xx && KALLSYMS && EXPERIMENTAL && MODULES
help help
Kprobes allows you to trap at almost any kernel address and Kprobes allows you to trap at almost any kernel address and
execute a callback function. register_kprobe() establishes execute a callback function. register_kprobe() establishes
......
...@@ -46,8 +46,8 @@ int __kprobes arch_prepare_kprobe(struct kprobe *p) ...@@ -46,8 +46,8 @@ int __kprobes arch_prepare_kprobe(struct kprobe *p)
if ((unsigned long)p->addr & 0x03) { if ((unsigned long)p->addr & 0x03) {
printk("Attempt to register kprobe at an unaligned address\n"); printk("Attempt to register kprobe at an unaligned address\n");
ret = -EINVAL; ret = -EINVAL;
} else if (IS_MTMSRD(insn) || IS_RFID(insn)) { } else if (IS_MTMSRD(insn) || IS_RFID(insn) || IS_RFI(insn)) {
printk("Cannot register a kprobe on rfid or mtmsrd\n"); printk("Cannot register a kprobe on rfi/rfid or mtmsr[d]\n");
ret = -EINVAL; ret = -EINVAL;
} }
...@@ -483,8 +483,12 @@ int __kprobes setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs) ...@@ -483,8 +483,12 @@ int __kprobes setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs)
memcpy(&kcb->jprobe_saved_regs, regs, sizeof(struct pt_regs)); memcpy(&kcb->jprobe_saved_regs, regs, sizeof(struct pt_regs));
/* setup return addr to the jprobe handler routine */ /* setup return addr to the jprobe handler routine */
#ifdef CONFIG_PPC64
regs->nip = (unsigned long)(((func_descr_t *)jp->entry)->entry); regs->nip = (unsigned long)(((func_descr_t *)jp->entry)->entry);
regs->gpr[2] = (unsigned long)(((func_descr_t *)jp->entry)->toc); regs->gpr[2] = (unsigned long)(((func_descr_t *)jp->entry)->toc);
#else
regs->nip = (unsigned long)jp->entry;
#endif
return 1; return 1;
} }
......
...@@ -16,11 +16,11 @@ obj-$(CONFIG_PPC64) += checksum_64.o copypage_64.o copyuser_64.o \ ...@@ -16,11 +16,11 @@ obj-$(CONFIG_PPC64) += checksum_64.o copypage_64.o copyuser_64.o \
strcase.o strcase.o
obj-$(CONFIG_QUICC_ENGINE) += rheap.o obj-$(CONFIG_QUICC_ENGINE) += rheap.o
obj-$(CONFIG_XMON) += sstep.o obj-$(CONFIG_XMON) += sstep.o
obj-$(CONFIG_KPROBES) += sstep.o
obj-$(CONFIG_NOT_COHERENT_CACHE) += dma-noncoherent.o obj-$(CONFIG_NOT_COHERENT_CACHE) += dma-noncoherent.o
ifeq ($(CONFIG_PPC64),y) ifeq ($(CONFIG_PPC64),y)
obj-$(CONFIG_SMP) += locks.o obj-$(CONFIG_SMP) += locks.o
obj-$(CONFIG_DEBUG_KERNEL) += sstep.o
endif endif
# Temporary hack until we have migrated to asm-powerpc # Temporary hack until we have migrated to asm-powerpc
......
...@@ -44,6 +44,7 @@ typedef unsigned int kprobe_opcode_t; ...@@ -44,6 +44,7 @@ typedef unsigned int kprobe_opcode_t;
#define IS_TDI(instr) (((instr) & 0xfc000000) == 0x08000000) #define IS_TDI(instr) (((instr) & 0xfc000000) == 0x08000000)
#define IS_TWI(instr) (((instr) & 0xfc000000) == 0x0c000000) #define IS_TWI(instr) (((instr) & 0xfc000000) == 0x0c000000)
#ifdef CONFIG_PPC64
/* /*
* 64bit powerpc uses function descriptors. * 64bit powerpc uses function descriptors.
* Handle cases where: * Handle cases where:
...@@ -67,9 +68,13 @@ typedef unsigned int kprobe_opcode_t; ...@@ -67,9 +68,13 @@ typedef unsigned int kprobe_opcode_t;
} }
#define JPROBE_ENTRY(pentry) (kprobe_opcode_t *)((func_descr_t *)pentry) #define JPROBE_ENTRY(pentry) (kprobe_opcode_t *)((func_descr_t *)pentry)
#define is_trap(instr) (IS_TW(instr) || IS_TD(instr) || \ #define is_trap(instr) (IS_TW(instr) || IS_TD(instr) || \
IS_TWI(instr) || IS_TDI(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_SUPPORTS_KRETPROBES
#define ARCH_INACTIVE_KPROBE_COUNT 1 #define ARCH_INACTIVE_KPROBE_COUNT 1
......
...@@ -21,6 +21,7 @@ struct pt_regs; ...@@ -21,6 +21,7 @@ struct pt_regs;
*/ */
#define IS_MTMSRD(instr) (((instr) & 0xfc0007be) == 0x7c000124) #define IS_MTMSRD(instr) (((instr) & 0xfc0007be) == 0x7c000124)
#define IS_RFID(instr) (((instr) & 0xfc0007fe) == 0x4c000024) #define IS_RFID(instr) (((instr) & 0xfc0007fe) == 0x4c000024)
#define IS_RFI(instr) (((instr) & 0xfc0007fe) == 0x4c000064)
/* Emulate instructions that cause a transfer of control. */ /* Emulate instructions that cause a transfer of control. */
extern int emulate_step(struct pt_regs *regs, unsigned int instr); extern int emulate_step(struct pt_regs *regs, unsigned int instr);
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment