Commit 777e26f0 authored by Jordan Niethe's avatar Jordan Niethe Committed by Michael Ellerman

powerpc: Use an accessor for instructions

In preparation for introducing a more complicated instruction type to
accommodate prefixed instructions use an accessor for getting an
instruction as a u32.
Signed-off-by: default avatarJordan Niethe <jniethe5@gmail.com>
Signed-off-by: default avatarMichael Ellerman <mpe@ellerman.id.au>
Link: https://lore.kernel.org/r/20200506034050.24806-8-jniethe5@gmail.com
parent 75346251
......@@ -8,4 +8,9 @@
#define ppc_inst(x) (x)
static inline u32 ppc_inst_val(u32 x)
{
return x;
}
#endif /* _ASM_POWERPC_INST_H */
......@@ -15,9 +15,9 @@ struct pt_regs;
* Note that IS_MTMSRD returns true for both an mtmsr (32-bit)
* and an mtmsrd (64-bit).
*/
#define IS_MTMSRD(instr) (((instr) & 0xfc0007be) == 0x7c000124)
#define IS_RFID(instr) (((instr) & 0xfc0007fe) == 0x4c000024)
#define IS_RFI(instr) (((instr) & 0xfc0007fe) == 0x4c000064)
#define IS_MTMSRD(instr) ((ppc_inst_val(instr) & 0xfc0007be) == 0x7c000124)
#define IS_RFID(instr) ((ppc_inst_val(instr) & 0xfc0007fe) == 0x4c000024)
#define IS_RFI(instr) ((ppc_inst_val(instr) & 0xfc0007fe) == 0x4c000064)
enum instruction_type {
COMPUTE, /* arith/logical/CR op, etc. */
......
......@@ -314,8 +314,8 @@ int fix_alignment(struct pt_regs *regs)
}
#ifdef CONFIG_SPE
if ((instr >> 26) == 0x4) {
int reg = (instr >> 21) & 0x1f;
if ((ppc_inst_val(instr) >> 26) == 0x4) {
int reg = (ppc_inst_val(instr) >> 21) & 0x1f;
PPC_WARN_ALIGNMENT(spe, regs);
return emulate_spe(regs, reg, instr);
}
......@@ -332,7 +332,7 @@ int fix_alignment(struct pt_regs *regs)
* when pasting to a co-processor. Furthermore, paste_last is the
* synchronisation point for preceding copy/paste sequences.
*/
if ((instr & 0xfc0006fe) == (PPC_INST_COPY & 0xfc0006fe))
if ((ppc_inst_val(instr) & 0xfc0006fe) == (PPC_INST_COPY & 0xfc0006fe))
return -EIO;
r = analyse_instr(&op, regs, instr);
......
......@@ -234,7 +234,7 @@ static int try_to_emulate(struct kprobe *p, struct pt_regs *regs)
* So, we should never get here... but, its still
* good to catch them, just in case...
*/
printk("Can't step on instruction %x\n", insn);
printk("Can't step on instruction %x\n", ppc_inst_val(insn));
BUG();
} else {
/*
......
......@@ -74,7 +74,7 @@ ftrace_modify_code(unsigned long ip, unsigned int old, unsigned int new)
/* Make sure it is what we expect it to be */
if (replaced != old) {
pr_err("%p: replaced (%#x) != old (%#x)",
(void *)ip, replaced, old);
(void *)ip, ppc_inst_val(replaced), ppc_inst_val(old));
return -EINVAL;
}
......@@ -99,19 +99,19 @@ static int test_24bit_addr(unsigned long ip, unsigned long addr)
static int is_bl_op(unsigned int op)
{
return (op & 0xfc000003) == 0x48000001;
return (ppc_inst_val(op) & 0xfc000003) == 0x48000001;
}
static int is_b_op(unsigned int op)
{
return (op & 0xfc000003) == 0x48000000;
return (ppc_inst_val(op) & 0xfc000003) == 0x48000000;
}
static unsigned long find_bl_target(unsigned long ip, unsigned int op)
{
int offset;
offset = (op & 0x03fffffc);
offset = (ppc_inst_val(op) & 0x03fffffc);
/* make it signed */
if (offset & 0x02000000)
offset |= 0xfe000000;
......@@ -137,7 +137,7 @@ __ftrace_make_nop(struct module *mod,
/* Make sure that that this is still a 24bit jump */
if (!is_bl_op(op)) {
pr_err("Not expected bl: opcode is %x\n", op);
pr_err("Not expected bl: opcode is %x\n", ppc_inst_val(op));
return -EINVAL;
}
......@@ -171,7 +171,8 @@ __ftrace_make_nop(struct module *mod,
/* We expect either a mflr r0, or a std r0, LRSAVE(r1) */
if (op != ppc_inst(PPC_INST_MFLR) && op != ppc_inst(PPC_INST_STD_LR)) {
pr_err("Unexpected instruction %08x around bl _mcount\n", op);
pr_err("Unexpected instruction %08x around bl _mcount\n",
ppc_inst_val(op));
return -EINVAL;
}
#else
......@@ -201,7 +202,7 @@ __ftrace_make_nop(struct module *mod,
}
if (op != ppc_inst(PPC_INST_LD_TOC)) {
pr_err("Expected %08x found %08x\n", PPC_INST_LD_TOC, op);
pr_err("Expected %08x found %08x\n", PPC_INST_LD_TOC, ppc_inst_val(op));
return -EINVAL;
}
#endif /* CONFIG_MPROFILE_KERNEL */
......@@ -229,7 +230,7 @@ __ftrace_make_nop(struct module *mod,
/* Make sure that that this is still a 24bit jump */
if (!is_bl_op(op)) {
pr_err("Not expected bl: opcode is %x\n", op);
pr_err("Not expected bl: opcode is %x\n", ppc_inst_val(op));
return -EINVAL;
}
......@@ -403,7 +404,7 @@ static int __ftrace_make_nop_kernel(struct dyn_ftrace *rec, unsigned long addr)
/* Make sure that that this is still a 24bit jump */
if (!is_bl_op(op)) {
pr_err("Not expected bl: opcode is %x\n", op);
pr_err("Not expected bl: opcode is %x\n", ppc_inst_val(op));
return -EINVAL;
}
......@@ -497,7 +498,8 @@ expected_nop_sequence(void *ip, unsigned int op0, unsigned int op1)
* The load offset is different depending on the ABI. For simplicity
* just mask it out when doing the compare.
*/
if (op0 != ppc_inst(0x48000008) || ((op1 & 0xffff0000) != 0xe8410000))
if (op0 != ppc_inst(0x48000008) ||
(ppc_inst_val(op1) & 0xffff0000) != 0xe8410000)
return 0;
return 1;
}
......@@ -527,7 +529,7 @@ __ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr)
if (!expected_nop_sequence(ip, op[0], op[1])) {
pr_err("Unexpected call sequence at %p: %x %x\n",
ip, op[0], op[1]);
ip, ppc_inst_val(op[0]), ppc_inst_val(op[1]));
return -EINVAL;
}
......@@ -590,7 +592,7 @@ __ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr)
/* It should be pointing to a nop */
if (op != ppc_inst(PPC_INST_NOP)) {
pr_err("Expected NOP but have %x\n", op);
pr_err("Expected NOP but have %x\n", ppc_inst_val(op));
return -EINVAL;
}
......@@ -647,7 +649,7 @@ static int __ftrace_make_call_kernel(struct dyn_ftrace *rec, unsigned long addr)
}
if (op != ppc_inst(PPC_INST_NOP)) {
pr_err("Unexpected call sequence at %p: %x\n", ip, op);
pr_err("Unexpected call sequence at %p: %x\n", ip, ppc_inst_val(op));
return -EINVAL;
}
......@@ -726,7 +728,7 @@ __ftrace_modify_call(struct dyn_ftrace *rec, unsigned long old_addr,
/* Make sure that that this is still a 24bit jump */
if (!is_bl_op(op)) {
pr_err("Not expected bl: opcode is %x\n", op);
pr_err("Not expected bl: opcode is %x\n", ppc_inst_val(op));
return -EINVAL;
}
......
......@@ -260,21 +260,23 @@ static unsigned int rfin(unsigned int x)
int emulate_altivec(struct pt_regs *regs)
{
unsigned int instr, i;
unsigned int instr, i, word;
unsigned int va, vb, vc, vd;
vector128 *vrs;
if (get_user(instr, (unsigned int __user *) regs->nip))
return -EFAULT;
if ((instr >> 26) != 4)
word = ppc_inst_val(instr);
if ((word >> 26) != 4)
return -EINVAL; /* not an altivec instruction */
vd = (instr >> 21) & 0x1f;
va = (instr >> 16) & 0x1f;
vb = (instr >> 11) & 0x1f;
vc = (instr >> 6) & 0x1f;
vd = (word >> 21) & 0x1f;
va = (word >> 16) & 0x1f;
vb = (word >> 11) & 0x1f;
vc = (word >> 6) & 0x1f;
vrs = current->thread.vr_state.vr;
switch (instr & 0x3f) {
switch (word & 0x3f) {
case 10:
switch (vc) {
case 0: /* vaddfp */
......
......@@ -236,7 +236,7 @@ bool is_conditional_branch(unsigned int instr)
if (opcode == 16) /* bc, bca, bcl, bcla */
return true;
if (opcode == 19) {
switch ((instr >> 1) & 0x3ff) {
switch ((ppc_inst_val(instr) >> 1) & 0x3ff) {
case 16: /* bclr, bclrl */
case 528: /* bcctr, bcctrl */
case 560: /* bctar, bctarl */
......@@ -304,7 +304,7 @@ static int instr_is_branch_bform(unsigned int instr)
int instr_is_relative_branch(unsigned int instr)
{
if (instr & BRANCH_ABSOLUTE)
if (ppc_inst_val(instr) & BRANCH_ABSOLUTE)
return 0;
return instr_is_branch_iform(instr) || instr_is_branch_bform(instr);
......@@ -312,20 +312,20 @@ int instr_is_relative_branch(unsigned int instr)
int instr_is_relative_link_branch(unsigned int instr)
{
return instr_is_relative_branch(instr) && (instr & BRANCH_SET_LINK);
return instr_is_relative_branch(instr) && (ppc_inst_val(instr) & BRANCH_SET_LINK);
}
static unsigned long branch_iform_target(const unsigned int *instr)
{
signed long imm;
imm = *instr & 0x3FFFFFC;
imm = ppc_inst_val(*instr) & 0x3FFFFFC;
/* If the top bit of the immediate value is set this is negative */
if (imm & 0x2000000)
imm -= 0x4000000;
if ((*instr & BRANCH_ABSOLUTE) == 0)
if ((ppc_inst_val(*instr) & BRANCH_ABSOLUTE) == 0)
imm += (unsigned long)instr;
return (unsigned long)imm;
......@@ -335,13 +335,13 @@ static unsigned long branch_bform_target(const unsigned int *instr)
{
signed long imm;
imm = *instr & 0xFFFC;
imm = ppc_inst_val(*instr) & 0xFFFC;
/* If the top bit of the immediate value is set this is negative */
if (imm & 0x8000)
imm -= 0x10000;
if ((*instr & BRANCH_ABSOLUTE) == 0)
if ((ppc_inst_val(*instr) & BRANCH_ABSOLUTE) == 0)
imm += (unsigned long)instr;
return (unsigned long)imm;
......@@ -373,9 +373,9 @@ int translate_branch(unsigned int *instr, const unsigned int *dest,
target = branch_target(src);
if (instr_is_branch_iform(*src))
return create_branch(instr, dest, target, *src);
return create_branch(instr, dest, target, ppc_inst_val(*src));
else if (instr_is_branch_bform(*src))
return create_cond_branch(instr, dest, target, *src);
return create_cond_branch(instr, dest, target, ppc_inst_val(*src));
return 1;
}
......
This diff is collapsed.
......@@ -847,12 +847,12 @@ static int __init emulate_compute_instr(struct pt_regs *regs,
{
struct instruction_op op;
if (!regs || !instr)
if (!regs || !ppc_inst_val(instr))
return -EINVAL;
if (analyse_instr(&op, regs, instr) != 1 ||
GETTYPE(op.type) != COMPUTE) {
pr_info("emulation failed, instruction = 0x%08x\n", instr);
pr_info("emulation failed, instruction = 0x%08x\n", ppc_inst_val(instr));
return -EFAULT;
}
......@@ -866,13 +866,13 @@ static int __init execute_compute_instr(struct pt_regs *regs,
extern int exec_instr(struct pt_regs *regs);
extern s32 patch__exec_instr;
if (!regs || !instr)
if (!regs || !ppc_inst_val(instr))
return -EINVAL;
/* Patch the NOP with the actual instruction */
patch_instruction_site(&patch__exec_instr, instr);
if (exec_instr(regs)) {
pr_info("execution failed, instruction = 0x%08x\n", instr);
pr_info("execution failed, instruction = 0x%08x\n", ppc_inst_val(instr));
return -EFAULT;
}
......
......@@ -49,7 +49,7 @@
static bool store_updates_sp(unsigned int inst)
{
/* check for 1 in the rA field */
if (((inst >> 16) & 0x1f) != 1)
if (((ppc_inst_val(inst) >> 16) & 0x1f) != 1)
return false;
/* check major opcode */
switch (inst >> 26) {
......@@ -60,10 +60,10 @@ static bool store_updates_sp(unsigned int inst)
case OP_STFDU:
return true;
case OP_STD: /* std or stdu */
return (inst & 3) == 1;
return (ppc_inst_val(inst) & 3) == 1;
case OP_31:
/* check minor opcode */
switch ((inst >> 1) & 0x3ff) {
switch ((ppc_inst_val(inst) >> 1) & 0x3ff) {
case OP_31_XOP_STDUX:
case OP_31_XOP_STWUX:
case OP_31_XOP_STBUX:
......
......@@ -2872,9 +2872,9 @@ generic_inst_dump(unsigned long adr, long count, int praddr,
dotted = 0;
last_inst = inst;
if (praddr)
printf(REG" %.8x", adr, inst);
printf(REG" %.8x", adr, ppc_inst_val(inst));
printf("\t");
dump_func(inst, adr);
dump_func(ppc_inst_val(inst), adr);
printf("\n");
}
return adr - first_adr;
......
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