Hey mpe, fixes for the issues highlighted by Christophe, except KUAP as discussed. Will make the optprobe change as a preceding patch.
diff --git a/arch/powerpc/include/asm/inst.h b/arch/powerpc/include/asm/inst.h --- a/arch/powerpc/include/asm/inst.h +++ b/arch/powerpc/include/asm/inst.h @@ -11,9 +11,9 @@ struct ppc_inst { u32 val; -#ifdef __powerpc64__ +#ifdef CONFIG_PPC64 u32 suffix; -#endif /* __powerpc64__ */ +#endif /* CONFIG_PPC64 */ } __packed; static inline u32 ppc_inst_val(struct ppc_inst x) @@ -26,7 +26,7 @@ static inline int ppc_inst_primary_opcode(struct ppc_inst x) return get_op(ppc_inst_val(x)); } -#ifdef __powerpc64__ +#ifdef CONFIG_PPC64 #define ppc_inst(x) ((struct ppc_inst){ .val = (x), .suffix = 0xff }) #define ppc_inst_prefix(x, y) ((struct ppc_inst){ .val = (x), .suffix = (y) }) @@ -52,7 +52,7 @@ static inline struct ppc_inst ppc_inst_read(const struct ppc_inst *ptr) u32 val, suffix; val = *(u32 *)ptr; - if ((val >> 26) == 1) { + if ((get_op(val)) == OP_PREFIX) { suffix = *((u32 *)ptr + 1); return ppc_inst_prefix(val, suffix); } else { @@ -94,7 +94,7 @@ static inline bool ppc_inst_equal(struct ppc_inst x, struct ppc_inst y) return ppc_inst_val(x) == ppc_inst_val(y); } -#endif /* __powerpc64__ */ +#endif /* CONFIG_PPC64 */ static inline int ppc_inst_len(struct ppc_inst x) { diff --git a/arch/powerpc/include/asm/uaccess.h b/arch/powerpc/include/asm/uaccess.h index e9027b3c641a..ac36a82321d4 100644 --- a/arch/powerpc/include/asm/uaccess.h +++ b/arch/powerpc/include/asm/uaccess.h @@ -105,7 +105,7 @@ static inline int __access_ok(unsigned long addr, unsigned long size, #define __put_user_inatomic(x, ptr) \ __put_user_nosleep((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr))) -#ifdef __powerpc64__ +#ifdef CONFIG_PPC64 #define __get_user_instr(x, ptr) \ ({ \ long __gui_ret = 0; \ @@ -113,7 +113,7 @@ static inline int __access_ok(unsigned long addr, unsigned long size, struct ppc_inst __gui_inst; \ unsigned int prefix, suffix; \ __gui_ret = __get_user(prefix, (unsigned int __user *)__gui_ptr); \ - if (!__gui_ret && (prefix >> 26) == OP_PREFIX) { \ + if (!__gui_ret && (get_op(prefix)) == OP_PREFIX) { \ __gui_ret = __get_user(suffix, \ (unsigned int __user *)__gui_ptr + 1); \ __gui_inst = ppc_inst_prefix(prefix, suffix); \ @@ -131,7 +131,7 @@ static inline int __access_ok(unsigned long addr, unsigned long size, struct ppc_inst __gui_inst; \ unsigned int prefix, suffix; \ __gui_ret = __get_user_inatomic(prefix, (unsigned int __user *)__gui_ptr); \ - if (!__gui_ret && (prefix >> 26) == OP_PREFIX) { \ + if (!__gui_ret && (get_op(prefix)) == OP_PREFIX) { \ __gui_ret = __get_user_inatomic(suffix, \ (unsigned int __user *)__gui_ptr + 1); \ __gui_inst = ppc_inst_prefix(prefix, suffix); \ diff --git a/arch/powerpc/kernel/optprobes.c b/arch/powerpc/kernel/optprobes.c index a8e66603d12b..3ac105e7faae 100644 --- a/arch/powerpc/kernel/optprobes.c +++ b/arch/powerpc/kernel/optprobes.c @@ -283,10 +283,8 @@ int arch_prepare_optimized_kprobe(struct optimized_kprobe *op, struct kprobe *p) * 3. load instruction to be emulated into relevant register, and */ temp = ppc_inst_read((struct ppc_inst *)p->ainsn.insn); - patch_imm64_load_insns(ppc_inst_val(temp) | - ((u64)ppc_inst_suffix(temp) << 32), - 4, - buff + TMPL_INSN_IDX); + patch_imm64_load_insns(ppc_inst_val(temp) | ((u64)ppc_inst_suffix(temp) << 32), + 4, buff + TMPL_INSN_IDX); /* * 4. branch back from trampoline diff --git a/arch/powerpc/lib/code-patching.c b/arch/powerpc/lib/code-patching.c index 58b67b62d5d3..bfd4e1dae0fb 100644 --- a/arch/powerpc/lib/code-patching.c +++ b/arch/powerpc/lib/code-patching.c @@ -26,8 +26,6 @@ static int __patch_instruction(struct ppc_inst *exec_addr, struct ppc_inst instr if (!ppc_inst_prefixed(instr)) { __put_user_asm(ppc_inst_val(instr), patch_addr, err, "stw"); - if (err) - return err; } else { #ifdef CONFIG_CPU_LITTLE_ENDIAN __put_user_asm((u64)ppc_inst_suffix(instr) << 32 | @@ -36,12 +34,13 @@ static int __patch_instruction(struct ppc_inst *exec_addr, struct ppc_inst instr __put_user_asm((u64)ppc_inst_val(instr) << 32 | ppc_inst_suffix(instr), patch_addr, err, "std"); #endif /* CONFIG_CPU_LITTLE_ENDIAN */ - if (err) - return err; } + if (err) + return err; asm ("dcbst 0, %0; sync; icbi 0,%1; sync; isync" :: "r" (patch_addr), "r" (exec_addr)); + return 0; } diff --git a/arch/powerpc/lib/inst.c b/arch/powerpc/lib/inst.c index e5e589994097..3c3851ffdb36 100644 --- a/arch/powerpc/lib/inst.c +++ b/arch/powerpc/lib/inst.c @@ -7,7 +7,7 @@ #include <linux/uaccess.h> #include <asm/inst.h> -#ifdef __powerpc64__ +#ifdef CONFIG_PPC64 int probe_user_read_inst(struct ppc_inst *inst, struct ppc_inst *nip) { @@ -17,9 +17,8 @@ int probe_user_read_inst(struct ppc_inst *inst, err = probe_user_read(&val, nip, sizeof(val)); if (err) return err; - if ((val >> 26) == OP_PREFIX) { - err = probe_user_read(&suffix, (void *)nip + 4, - sizeof(unsigned int)); + if (get_op(val) == OP_PREFIX) { + err = probe_user_read(&suffix, (void *)nip + 4, 4); *inst = ppc_inst_prefix(val, suffix); } else { *inst = ppc_inst(val); @@ -36,9 +35,8 @@ int probe_kernel_read_inst(struct ppc_inst *inst, err = probe_kernel_read(&val, src, sizeof(val)); if (err) return err; - if ((val >> 26) == OP_PREFIX) { - err = probe_kernel_read(&suffix, (void *)src + 4, - sizeof(unsigned int)); + if (get_op(val) == OP_PREFIX) { + err = probe_kernel_read(&suffix, (void *)src + 4, 4); *inst = ppc_inst_prefix(val, suffix); } else { *inst = ppc_inst(val); @@ -67,4 +65,4 @@ int probe_kernel_read_inst(struct ppc_inst *inst, *inst = ppc_inst(val); return err; } -#endif /* __powerpc64__ */ +#endif /* CONFIG_PPC64 */ -- 2.17.1