aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Howells <dhowells@redhat.com>2008-11-12 15:35:14 +0000
committerLinus Torvalds <torvalds@linux-foundation.org>2008-11-12 10:41:17 -0800
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 ab03bac497c..614c32b6325 100644
--- a/arch/mn10300/mm/misalignment.c
+++ b/arch/mn10300/mm/misalignment.c
@@ -43,11 +43,11 @@
#endif
static int misalignment_addr(unsigned long *registers, unsigned params,
- unsigned opcode, unsigned disp,
+ unsigned opcode, unsigned long disp,
void **_address, unsigned long **_postinc);
static int misalignment_reg(unsigned long *registers, unsigned params,
- unsigned opcode, unsigned disp,
+ unsigned opcode, unsigned long disp,
unsigned long **_register);
static const unsigned Dreg_index[] = {
@@ -304,13 +304,13 @@ asmlinkage void misalignment(struct pt_regs *regs, enum exception_code code)
const struct exception_table_entry *fixup;
const struct mn10300_opcode *pop;
unsigned long *registers = (unsigned long *) regs;
- unsigned long data, *store, *postinc;
+ unsigned long data, *store, *postinc, disp;
mm_segment_t seg;
siginfo_t info;
- uint32_t opcode, disp, noc, xo, xm;
+ uint32_t opcode, noc, xo, xm;
uint8_t *pc, byte;
void *address;
- unsigned tmp, npop;
+ unsigned tmp, npop, dispsz, loop;
kdebug("==>misalignment({pc=%lx})", regs->pc);
@@ -445,17 +445,17 @@ found_opcode:
/* grab the extra displacement (note it's LSB first) */
disp = 0;
- tmp = format_tbl[pop->format].dispsz >> 3;
- while (tmp > 0) {
- tmp--;
- disp <<= 8;
-
+ dispsz = format_tbl[pop->format].dispsz;
+ for (loop = 0; loop < dispsz; loop += 8) {
pc++;
if (__get_user(byte, pc) != 0)
goto fetch_error;
- disp |= byte;
+ disp |= byte << loop;
+ kdebug("{%p} disp[%02x]=%02x", pc, loop, byte);
}
+ kdebug("disp=%lx", disp);
+
set_fs(KERNEL_XDS);
if (fixup || regs->epsw & EPSW_nSL)
set_fs(seg);
@@ -538,7 +538,7 @@ found_opcode:
* determine the address that was being accessed
*/
static int misalignment_addr(unsigned long *registers, unsigned params,
- unsigned opcode, unsigned disp,
+ unsigned opcode, unsigned long disp,
void **_address, unsigned long **_postinc)
{
unsigned long *postinc = NULL, address = 0, tmp;
@@ -644,7 +644,7 @@ static int misalignment_addr(unsigned long *registers, unsigned params,
* determine the register that is acting as source/dest
*/
static int misalignment_reg(unsigned long *registers, unsigned params,
- unsigned opcode, unsigned disp,
+ unsigned opcode, unsigned long disp,
unsigned long **_register)
{
params &= 0x7fffffff;