powerpc: Use a function for reading instructions
Prefixed instructions will mean there are instructions of different length. As a result dereferencing a pointer to an instruction will not necessarily give the desired result. Introduce a function for reading instructions from memory into the instruction data type. Signed-off-by: Jordan Niethe <jniethe5@gmail.com> Signed-off-by: Michael Ellerman <mpe@ellerman.id.au> Reviewed-by: Alistair Popple <alistair@popple.id.au> Link: https://lore.kernel.org/r/20200506034050.24806-13-jniethe5@gmail.com
This commit is contained in:

committed by
Michael Ellerman

parent
94afd069d9
commit
f8faaffaa7
@@ -106,7 +106,7 @@ kprobe_opcode_t *kprobe_lookup_name(const char *name, unsigned int offset)
|
||||
int arch_prepare_kprobe(struct kprobe *p)
|
||||
{
|
||||
int ret = 0;
|
||||
struct ppc_inst insn = *(struct ppc_inst *)p->addr;
|
||||
struct ppc_inst insn = ppc_inst_read((struct ppc_inst *)p->addr);
|
||||
|
||||
if ((unsigned long)p->addr & 0x03) {
|
||||
printk("Attempt to register kprobe at an unaligned address\n");
|
||||
@@ -127,7 +127,7 @@ int arch_prepare_kprobe(struct kprobe *p)
|
||||
if (!ret) {
|
||||
memcpy(p->ainsn.insn, p->addr,
|
||||
MAX_INSN_SIZE * sizeof(kprobe_opcode_t));
|
||||
p->opcode = *p->addr;
|
||||
p->opcode = ppc_inst_val(insn);
|
||||
flush_icache_range((unsigned long)p->ainsn.insn,
|
||||
(unsigned long)p->ainsn.insn + sizeof(kprobe_opcode_t));
|
||||
}
|
||||
@@ -217,7 +217,7 @@ NOKPROBE_SYMBOL(arch_prepare_kretprobe);
|
||||
static int try_to_emulate(struct kprobe *p, struct pt_regs *regs)
|
||||
{
|
||||
int ret;
|
||||
struct ppc_inst insn = *(struct ppc_inst *)p->ainsn.insn;
|
||||
struct ppc_inst insn = ppc_inst_read((struct ppc_inst *)p->ainsn.insn);
|
||||
|
||||
/* regs->nip is also adjusted if emulate_step returns 1 */
|
||||
ret = emulate_step(regs, insn);
|
||||
|
@@ -378,7 +378,7 @@ static int mce_find_instr_ea_and_phys(struct pt_regs *regs, uint64_t *addr,
|
||||
pfn = addr_to_pfn(regs, regs->nip);
|
||||
if (pfn != ULONG_MAX) {
|
||||
instr_addr = (pfn << PAGE_SHIFT) + (regs->nip & ~PAGE_MASK);
|
||||
instr = *(struct ppc_inst *)(instr_addr);
|
||||
instr = ppc_inst_read((struct ppc_inst *)instr_addr);
|
||||
if (!analyse_instr(&op, &tmp, instr)) {
|
||||
pfn = addr_to_pfn(regs, op.ea);
|
||||
*addr = op.ea;
|
||||
|
@@ -100,9 +100,9 @@ static unsigned long can_optimize(struct kprobe *p)
|
||||
* Ensure that the instruction is not a conditional branch,
|
||||
* and that can be emulated.
|
||||
*/
|
||||
if (!is_conditional_branch(*(struct ppc_inst *)p->ainsn.insn) &&
|
||||
if (!is_conditional_branch(ppc_inst_read((struct ppc_inst *)p->ainsn.insn)) &&
|
||||
analyse_instr(&op, ®s,
|
||||
*(struct ppc_inst *)p->ainsn.insn) == 1) {
|
||||
ppc_inst_read((struct ppc_inst *)p->ainsn.insn)) == 1) {
|
||||
emulate_update_regs(®s, &op);
|
||||
nip = regs.nip;
|
||||
}
|
||||
|
@@ -848,7 +848,7 @@ int ftrace_update_ftrace_func(ftrace_func_t func)
|
||||
struct ppc_inst old, new;
|
||||
int ret;
|
||||
|
||||
old = *(struct ppc_inst *)&ftrace_call;
|
||||
old = ppc_inst_read((struct ppc_inst *)&ftrace_call);
|
||||
new = ftrace_call_replace(ip, (unsigned long)func, 1);
|
||||
ret = ftrace_modify_code(ip, old, new);
|
||||
|
||||
@@ -856,7 +856,7 @@ int ftrace_update_ftrace_func(ftrace_func_t func)
|
||||
/* Also update the regs callback function */
|
||||
if (!ret) {
|
||||
ip = (unsigned long)(&ftrace_regs_call);
|
||||
old = *(struct ppc_inst *)&ftrace_regs_call;
|
||||
old = ppc_inst_read((struct ppc_inst *)&ftrace_regs_call);
|
||||
new = ftrace_call_replace(ip, (unsigned long)func, 1);
|
||||
ret = ftrace_modify_code(ip, old, new);
|
||||
}
|
||||
|
@@ -174,7 +174,7 @@ bool arch_uprobe_skip_sstep(struct arch_uprobe *auprobe, struct pt_regs *regs)
|
||||
* emulate_step() returns 1 if the insn was successfully emulated.
|
||||
* For all other cases, we need to single-step in hardware.
|
||||
*/
|
||||
ret = emulate_step(regs, auprobe->insn);
|
||||
ret = emulate_step(regs, ppc_inst_read(&auprobe->insn));
|
||||
if (ret > 0)
|
||||
return true;
|
||||
|
||||
|
Reference in New Issue
Block a user