aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Howells <dhowells@redhat.com>2008-11-12 10:35:14 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2008-11-12 13:41:17 -0500
commitb308bf3be1f75207c307eea9ada90e0b76194911 (patch)
treea782544532bf58b9475e2ebdd68ef811b6d3596e
parentee6e740cf7e5605b353af539eb9a6e17948747b6 (diff)
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>
-rw-r--r--arch/mn10300/mm/misalignment.c26
1 files changed, 13 insertions, 13 deletions
diff --git a/arch/mn10300/mm/misalignment.c b/arch/mn10300/mm/misalignment.c
index ab03bac497cb..614c32b6325b 100644
--- a/arch/mn10300/mm/misalignment.c
+++ b/arch/mn10300/mm/misalignment.c
@@ -43,11 +43,11 @@
43#endif 43#endif
44 44
45static int misalignment_addr(unsigned long *registers, unsigned params, 45static int misalignment_addr(unsigned long *registers, unsigned params,
46 unsigned opcode, unsigned disp, 46 unsigned opcode, unsigned long disp,
47 void **_address, unsigned long **_postinc); 47 void **_address, unsigned long **_postinc);
48 48
49static int misalignment_reg(unsigned long *registers, unsigned params, 49static int misalignment_reg(unsigned long *registers, unsigned params,
50 unsigned opcode, unsigned disp, 50 unsigned opcode, unsigned long disp,
51 unsigned long **_register); 51 unsigned long **_register);
52 52
53static const unsigned Dreg_index[] = { 53static const unsigned Dreg_index[] = {
@@ -304,13 +304,13 @@ asmlinkage void misalignment(struct pt_regs *regs, enum exception_code code)
304 const struct exception_table_entry *fixup; 304 const struct exception_table_entry *fixup;
305 const struct mn10300_opcode *pop; 305 const struct mn10300_opcode *pop;
306 unsigned long *registers = (unsigned long *) regs; 306 unsigned long *registers = (unsigned long *) regs;
307 unsigned long data, *store, *postinc; 307 unsigned long data, *store, *postinc, disp;
308 mm_segment_t seg; 308 mm_segment_t seg;
309 siginfo_t info; 309 siginfo_t info;
310 uint32_t opcode, disp, noc, xo, xm; 310 uint32_t opcode, noc, xo, xm;
311 uint8_t *pc, byte; 311 uint8_t *pc, byte;
312 void *address; 312 void *address;
313 unsigned tmp, npop; 313 unsigned tmp, npop, dispsz, loop;
314 314
315 kdebug("==>misalignment({pc=%lx})", regs->pc); 315 kdebug("==>misalignment({pc=%lx})", regs->pc);
316 316
@@ -445,17 +445,17 @@ found_opcode:
445 445
446 /* grab the extra displacement (note it's LSB first) */ 446 /* grab the extra displacement (note it's LSB first) */
447 disp = 0; 447 disp = 0;
448 tmp = format_tbl[pop->format].dispsz >> 3; 448 dispsz = format_tbl[pop->format].dispsz;
449 while (tmp > 0) { 449 for (loop = 0; loop < dispsz; loop += 8) {
450 tmp--;
451 disp <<= 8;
452
453 pc++; 450 pc++;
454 if (__get_user(byte, pc) != 0) 451 if (__get_user(byte, pc) != 0)
455 goto fetch_error; 452 goto fetch_error;
456 disp |= byte; 453 disp |= byte << loop;
454 kdebug("{%p} disp[%02x]=%02x", pc, loop, byte);
457 } 455 }
458 456
457 kdebug("disp=%lx", disp);
458
459 set_fs(KERNEL_XDS); 459 set_fs(KERNEL_XDS);
460 if (fixup || regs->epsw & EPSW_nSL) 460 if (fixup || regs->epsw & EPSW_nSL)
461 set_fs(seg); 461 set_fs(seg);
@@ -538,7 +538,7 @@ found_opcode:
538 * determine the address that was being accessed 538 * determine the address that was being accessed
539 */ 539 */
540static int misalignment_addr(unsigned long *registers, unsigned params, 540static int misalignment_addr(unsigned long *registers, unsigned params,
541 unsigned opcode, unsigned disp, 541 unsigned opcode, unsigned long disp,
542 void **_address, unsigned long **_postinc) 542 void **_address, unsigned long **_postinc)
543{ 543{
544 unsigned long *postinc = NULL, address = 0, tmp; 544 unsigned long *postinc = NULL, address = 0, tmp;
@@ -644,7 +644,7 @@ static int misalignment_addr(unsigned long *registers, unsigned params,
644 * determine the register that is acting as source/dest 644 * determine the register that is acting as source/dest
645 */ 645 */
646static int misalignment_reg(unsigned long *registers, unsigned params, 646static int misalignment_reg(unsigned long *registers, unsigned params,
647 unsigned opcode, unsigned disp, 647 unsigned opcode, unsigned long disp,
648 unsigned long **_register) 648 unsigned long **_register)
649{ 649{
650 params &= 0x7fffffff; 650 params &= 0x7fffffff;