Commit b308bf3b authored by David Howells's avatar David Howells Committed by Linus Torvalds

MN10300: Extract the displacement from an insn correctly in misalignment fixup

Extract the displacement from an MN10300 instruction correctly in the
misalignment fixup handler.

The code should extract the displacement in LSB order, not MSB order.
Signed-off-by: default avatarDavid Howells <dhowells@redhat.com>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent ee6e740c
...@@ -43,11 +43,11 @@ ...@@ -43,11 +43,11 @@
#endif #endif
static int misalignment_addr(unsigned long *registers, unsigned params, static int misalignment_addr(unsigned long *registers, unsigned params,
unsigned opcode, unsigned disp, unsigned opcode, unsigned long disp,
void **_address, unsigned long **_postinc); void **_address, unsigned long **_postinc);
static int misalignment_reg(unsigned long *registers, unsigned params, static int misalignment_reg(unsigned long *registers, unsigned params,
unsigned opcode, unsigned disp, unsigned opcode, unsigned long disp,
unsigned long **_register); unsigned long **_register);
static const unsigned Dreg_index[] = { static const unsigned Dreg_index[] = {
...@@ -304,13 +304,13 @@ asmlinkage void misalignment(struct pt_regs *regs, enum exception_code code) ...@@ -304,13 +304,13 @@ asmlinkage void misalignment(struct pt_regs *regs, enum exception_code code)
const struct exception_table_entry *fixup; const struct exception_table_entry *fixup;
const struct mn10300_opcode *pop; const struct mn10300_opcode *pop;
unsigned long *registers = (unsigned long *) regs; unsigned long *registers = (unsigned long *) regs;
unsigned long data, *store, *postinc; unsigned long data, *store, *postinc, disp;
mm_segment_t seg; mm_segment_t seg;
siginfo_t info; siginfo_t info;
uint32_t opcode, disp, noc, xo, xm; uint32_t opcode, noc, xo, xm;
uint8_t *pc, byte; uint8_t *pc, byte;
void *address; void *address;
unsigned tmp, npop; unsigned tmp, npop, dispsz, loop;
kdebug("==>misalignment({pc=%lx})", regs->pc); kdebug("==>misalignment({pc=%lx})", regs->pc);
...@@ -445,17 +445,17 @@ asmlinkage void misalignment(struct pt_regs *regs, enum exception_code code) ...@@ -445,17 +445,17 @@ asmlinkage void misalignment(struct pt_regs *regs, enum exception_code code)
/* grab the extra displacement (note it's LSB first) */ /* grab the extra displacement (note it's LSB first) */
disp = 0; disp = 0;
tmp = format_tbl[pop->format].dispsz >> 3; dispsz = format_tbl[pop->format].dispsz;
while (tmp > 0) { for (loop = 0; loop < dispsz; loop += 8) {
tmp--;
disp <<= 8;
pc++; pc++;
if (__get_user(byte, pc) != 0) if (__get_user(byte, pc) != 0)
goto fetch_error; goto fetch_error;
disp |= byte; disp |= byte << loop;
kdebug("{%p} disp[%02x]=%02x", pc, loop, byte);
} }
kdebug("disp=%lx", disp);
set_fs(KERNEL_XDS); set_fs(KERNEL_XDS);
if (fixup || regs->epsw & EPSW_nSL) if (fixup || regs->epsw & EPSW_nSL)
set_fs(seg); set_fs(seg);
...@@ -538,7 +538,7 @@ asmlinkage void misalignment(struct pt_regs *regs, enum exception_code code) ...@@ -538,7 +538,7 @@ asmlinkage void misalignment(struct pt_regs *regs, enum exception_code code)
* determine the address that was being accessed * determine the address that was being accessed
*/ */
static int misalignment_addr(unsigned long *registers, unsigned params, static int misalignment_addr(unsigned long *registers, unsigned params,
unsigned opcode, unsigned disp, unsigned opcode, unsigned long disp,
void **_address, unsigned long **_postinc) void **_address, unsigned long **_postinc)
{ {
unsigned long *postinc = NULL, address = 0, tmp; unsigned long *postinc = NULL, address = 0, tmp;
...@@ -644,7 +644,7 @@ static int misalignment_addr(unsigned long *registers, unsigned params, ...@@ -644,7 +644,7 @@ static int misalignment_addr(unsigned long *registers, unsigned params,
* determine the register that is acting as source/dest * determine the register that is acting as source/dest
*/ */
static int misalignment_reg(unsigned long *registers, unsigned params, static int misalignment_reg(unsigned long *registers, unsigned params,
unsigned opcode, unsigned disp, unsigned opcode, unsigned long disp,
unsigned long **_register) unsigned long **_register)
{ {
params &= 0x7fffffff; params &= 0x7fffffff;
......
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