diff options
Diffstat (limited to 'arch/powerpc')
-rw-r--r-- | arch/powerpc/include/asm/inst.h | 13 | ||||
-rw-r--r-- | arch/powerpc/kernel/uprobes.c | 2 | ||||
-rw-r--r-- | arch/powerpc/lib/feature-fixups.c | 15 | ||||
-rw-r--r-- | arch/powerpc/xmon/xmon.c | 2 |
4 files changed, 23 insertions, 9 deletions
diff --git a/arch/powerpc/include/asm/inst.h b/arch/powerpc/include/asm/inst.h index d82e0c99cfa1..5b756ba77ed2 100644 --- a/arch/powerpc/include/asm/inst.h +++ b/arch/powerpc/include/asm/inst.h @@ -100,6 +100,19 @@ static inline int ppc_inst_len(struct ppc_inst x) return ppc_inst_prefixed(x) ? 8 : 4; } +/* + * Return the address of the next instruction, if the instruction @value was + * located at @location. + */ +static inline struct ppc_inst *ppc_inst_next(void *location, struct ppc_inst *value) +{ + struct ppc_inst tmp; + + tmp = ppc_inst_read(value); + + return location + ppc_inst_len(tmp); +} + int probe_user_read_inst(struct ppc_inst *inst, struct ppc_inst __user *nip); diff --git a/arch/powerpc/kernel/uprobes.c b/arch/powerpc/kernel/uprobes.c index 83e883e1a42d..d200e7df7167 100644 --- a/arch/powerpc/kernel/uprobes.c +++ b/arch/powerpc/kernel/uprobes.c @@ -112,7 +112,7 @@ int arch_uprobe_post_xol(struct arch_uprobe *auprobe, struct pt_regs *regs) * support doesn't exist and have to fix-up the next instruction * to be executed. */ - regs->nip = utask->vaddr + ppc_inst_len(ppc_inst_read(&auprobe->insn)); + regs->nip = (unsigned long)ppc_inst_next((void *)utask->vaddr, &auprobe->insn); user_disable_single_step(current); return 0; diff --git a/arch/powerpc/lib/feature-fixups.c b/arch/powerpc/lib/feature-fixups.c index 80f320c2e189..4c0a7ee9fa00 100644 --- a/arch/powerpc/lib/feature-fixups.c +++ b/arch/powerpc/lib/feature-fixups.c @@ -68,7 +68,7 @@ static int patch_alt_instruction(struct ppc_inst *src, struct ppc_inst *dest, static int patch_feature_section(unsigned long value, struct fixup_entry *fcur) { - struct ppc_inst *start, *end, *alt_start, *alt_end, *src, *dest; + struct ppc_inst *start, *end, *alt_start, *alt_end, *src, *dest, nop; start = calc_addr(fcur, fcur->start_off); end = calc_addr(fcur, fcur->end_off); @@ -84,14 +84,15 @@ static int patch_feature_section(unsigned long value, struct fixup_entry *fcur) src = alt_start; dest = start; - for (; src < alt_end; src = (void *)src + ppc_inst_len(ppc_inst_read(src)), - (dest = (void *)dest + ppc_inst_len(ppc_inst_read(dest)))) { + for (; src < alt_end; src = ppc_inst_next(src, src), + dest = ppc_inst_next(dest, dest)) { if (patch_alt_instruction(src, dest, alt_start, alt_end)) return 1; } - for (; dest < end; dest = (void *)dest + ppc_inst_len(ppc_inst(PPC_INST_NOP))) - raw_patch_instruction(dest, ppc_inst(PPC_INST_NOP)); + nop = ppc_inst(PPC_INST_NOP); + for (; dest < end; dest = ppc_inst_next(dest, &nop)) + raw_patch_instruction(dest, nop); return 0; } @@ -405,8 +406,8 @@ static void do_final_fixups(void) while (src < end) { inst = ppc_inst_read(src); raw_patch_instruction(dest, inst); - src = (void *)src + ppc_inst_len(inst); - dest = (void *)dest + ppc_inst_len(inst); + src = ppc_inst_next(src, src); + dest = ppc_inst_next(dest, dest); } #endif } diff --git a/arch/powerpc/xmon/xmon.c b/arch/powerpc/xmon/xmon.c index de585204d1d2..16ee6639a60c 100644 --- a/arch/powerpc/xmon/xmon.c +++ b/arch/powerpc/xmon/xmon.c @@ -939,7 +939,7 @@ static void insert_bpts(void) } patch_instruction(bp->instr, instr); - patch_instruction((void *)bp->instr + ppc_inst_len(instr), + patch_instruction(ppc_inst_next(bp->instr, &instr), ppc_inst(bpinstr)); if (bp->enabled & BP_CIABR) continue; |