powerpc: Use a datatype for instructions
Currently unsigned ints are used to represent instructions on powerpc. This has worked well as instructions have always been 4 byte words. However, ISA v3.1 introduces some changes to instructions that mean this scheme will no longer work as well. This change is Prefixed Instructions. A prefixed instruction is made up of a word prefix followed by a word suffix to make an 8 byte double word instruction. No matter the endianness of the system the prefix always comes first. Prefixed instructions are only planned for powerpc64. Introduce a ppc_inst type to represent both prefixed and word instructions on powerpc64 while keeping it possible to exclusively have word instructions on powerpc32. Signed-off-by: Jordan Niethe <jniethe5@gmail.com> [mpe: Fix compile error in emulate_spe()] Signed-off-by: Michael Ellerman <mpe@ellerman.id.au> Link: https://lore.kernel.org/r/20200506034050.24806-12-jniethe5@gmail.com
This commit is contained in:

committed by
Michael Ellerman

parent
217862d9b9
commit
94afd069d9
@@ -105,7 +105,7 @@ static struct aligninfo spe_aligninfo[32] = {
|
||||
* so we don't need the address swizzling.
|
||||
*/
|
||||
static int emulate_spe(struct pt_regs *regs, unsigned int reg,
|
||||
unsigned int instr)
|
||||
struct ppc_inst ppc_instr)
|
||||
{
|
||||
int ret;
|
||||
union {
|
||||
@@ -116,8 +116,9 @@ static int emulate_spe(struct pt_regs *regs, unsigned int reg,
|
||||
} data, temp;
|
||||
unsigned char __user *p, *addr;
|
||||
unsigned long *evr = ¤t->thread.evr[reg];
|
||||
unsigned int nb, flags;
|
||||
unsigned int nb, flags, instr;
|
||||
|
||||
instr = ppc_inst_val(ppc_instr);
|
||||
instr = (instr >> 1) & 0x1f;
|
||||
|
||||
/* DAR has the operand effective address */
|
||||
@@ -294,7 +295,7 @@ static int emulate_spe(struct pt_regs *regs, unsigned int reg,
|
||||
|
||||
int fix_alignment(struct pt_regs *regs)
|
||||
{
|
||||
unsigned int instr;
|
||||
struct ppc_inst instr;
|
||||
struct instruction_op op;
|
||||
int r, type;
|
||||
|
||||
@@ -304,7 +305,7 @@ int fix_alignment(struct pt_regs *regs)
|
||||
*/
|
||||
CHECK_FULL_REGS(regs);
|
||||
|
||||
if (unlikely(__get_user(instr, (unsigned int __user *)regs->nip)))
|
||||
if (unlikely(__get_user(instr.val, (unsigned int __user *)regs->nip)))
|
||||
return -EFAULT;
|
||||
if ((regs->msr & MSR_LE) != (MSR_KERNEL & MSR_LE)) {
|
||||
/* We don't handle PPC little-endian any more... */
|
||||
|
Reference in New Issue
Block a user