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: David Howells <dhowells@redhat.com>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

authored by David Howells and committed by Linus Torvalds b308bf3b ee6e740c

+13 -13
+13 -13
arch/mn10300/mm/misalignment.c
··· 43 43 #endif 44 44 45 45 static int misalignment_addr(unsigned long *registers, unsigned params, 46 - unsigned opcode, unsigned disp, 46 + unsigned opcode, unsigned long disp, 47 47 void **_address, unsigned long **_postinc); 48 48 49 49 static int misalignment_reg(unsigned long *registers, unsigned params, 50 - unsigned opcode, unsigned disp, 50 + unsigned opcode, unsigned long disp, 51 51 unsigned long **_register); 52 52 53 53 static const unsigned Dreg_index[] = { ··· 304 304 const struct exception_table_entry *fixup; 305 305 const struct mn10300_opcode *pop; 306 306 unsigned long *registers = (unsigned long *) regs; 307 - unsigned long data, *store, *postinc; 307 + unsigned long data, *store, *postinc, disp; 308 308 mm_segment_t seg; 309 309 siginfo_t info; 310 - uint32_t opcode, disp, noc, xo, xm; 310 + uint32_t opcode, noc, xo, xm; 311 311 uint8_t *pc, byte; 312 312 void *address; 313 - unsigned tmp, npop; 313 + unsigned tmp, npop, dispsz, loop; 314 314 315 315 kdebug("==>misalignment({pc=%lx})", regs->pc); 316 316 ··· 445 445 446 446 /* grab the extra displacement (note it's LSB first) */ 447 447 disp = 0; 448 - tmp = format_tbl[pop->format].dispsz >> 3; 449 - while (tmp > 0) { 450 - tmp--; 451 - disp <<= 8; 452 - 448 + dispsz = format_tbl[pop->format].dispsz; 449 + for (loop = 0; loop < dispsz; loop += 8) { 453 450 pc++; 454 451 if (__get_user(byte, pc) != 0) 455 452 goto fetch_error; 456 - disp |= byte; 453 + disp |= byte << loop; 454 + kdebug("{%p} disp[%02x]=%02x", pc, loop, byte); 457 455 } 456 + 457 + kdebug("disp=%lx", disp); 458 458 459 459 set_fs(KERNEL_XDS); 460 460 if (fixup || regs->epsw & EPSW_nSL) ··· 538 538 * determine the address that was being accessed 539 539 */ 540 540 static int misalignment_addr(unsigned long *registers, unsigned params, 541 - unsigned opcode, unsigned disp, 541 + unsigned opcode, unsigned long disp, 542 542 void **_address, unsigned long **_postinc) 543 543 { 544 544 unsigned long *postinc = NULL, address = 0, tmp; ··· 644 644 * determine the register that is acting as source/dest 645 645 */ 646 646 static int misalignment_reg(unsigned long *registers, unsigned params, 647 - unsigned opcode, unsigned disp, 647 + unsigned opcode, unsigned long disp, 648 648 unsigned long **_register) 649 649 { 650 650 params &= 0x7fffffff;