Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

powerpc: Unaligned stores and stmw are broken in emulation code

The stmw instruction was incorrectly decoded as an update form instruction
and thus the RA register was being clobbered.

Also, the utility routine to write memory to unaligned addresses breaks the
operation into smaller aligned accesses but was incorrectly incrementing
the address by only one; it needs to increment the address by the size of
the smaller aligned chunk.

Signed-off-by: Tom Musta <tmusta@us.ibm.com>
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>

authored by

Tom Musta and committed by
Benjamin Herrenschmidt
17e8de7e f748edaf

+5 -3
+5 -3
arch/powerpc/lib/sstep.c
··· 100 100 ea = (signed short) instr; /* sign-extend */ 101 101 if (ra) { 102 102 ea += regs->gpr[ra]; 103 - if (instr & 0x04000000) /* update forms */ 104 - regs->gpr[ra] = ea; 103 + if (instr & 0x04000000) { /* update forms */ 104 + if ((instr>>26) != 47) /* stmw is not an update form */ 105 + regs->gpr[ra] = ea; 106 + } 105 107 } 106 108 107 109 return truncate_if_32bit(regs->msr, ea); ··· 281 279 err = write_mem_aligned(val >> (nb - c) * 8, ea, c); 282 280 if (err) 283 281 return err; 284 - ++ea; 282 + ea += c; 285 283 } 286 284 return 0; 287 285 }