15eedf9feSChristophe Leroy // SPDX-License-Identifier: GPL-2.0-only 25eedf9feSChristophe Leroy 35eedf9feSChristophe Leroy #include <linux/uaccess.h> 45eedf9feSChristophe Leroy #include <linux/kernel.h> 55eedf9feSChristophe Leroy 6*39352430SChristophe Leroy #include <asm/disassemble.h> 7*39352430SChristophe Leroy #include <asm/inst.h> 8*39352430SChristophe Leroy #include <asm/ppc-opcode.h> 9*39352430SChristophe Leroy 105eedf9feSChristophe Leroy bool copy_from_kernel_nofault_allowed(const void *unsafe_src, size_t size) 115eedf9feSChristophe Leroy { 125eedf9feSChristophe Leroy return is_kernel_addr((unsigned long)unsafe_src); 135eedf9feSChristophe Leroy } 14*39352430SChristophe Leroy 15*39352430SChristophe Leroy int copy_inst_from_kernel_nofault(struct ppc_inst *inst, struct ppc_inst *src) 16*39352430SChristophe Leroy { 17*39352430SChristophe Leroy unsigned int val, suffix; 18*39352430SChristophe Leroy int err; 19*39352430SChristophe Leroy 20*39352430SChristophe Leroy err = copy_from_kernel_nofault(&val, src, sizeof(val)); 21*39352430SChristophe Leroy if (err) 22*39352430SChristophe Leroy return err; 23*39352430SChristophe Leroy if (IS_ENABLED(CONFIG_PPC64) && get_op(val) == OP_PREFIX) { 24*39352430SChristophe Leroy err = copy_from_kernel_nofault(&suffix, (void *)src + 4, 4); 25*39352430SChristophe Leroy *inst = ppc_inst_prefix(val, suffix); 26*39352430SChristophe Leroy } else { 27*39352430SChristophe Leroy *inst = ppc_inst(val); 28*39352430SChristophe Leroy } 29*39352430SChristophe Leroy return err; 30*39352430SChristophe Leroy } 31