Skip to content

Commit

Permalink
powerpc: Handle unaligned ldbrx/stdbrx
Browse files Browse the repository at this point in the history
Normally when we haven't implemented an alignment handler for
a load or store instruction the process will be terminated.

The alignment handler uses the DSISR (or a pseudo one) to locate
the right handler. Unfortunately ldbrx and stdbrx overlap lfs and
stfs so we incorrectly think ldbrx is an lfs and stdbrx is an
stfs.

This bug is particularly nasty - instead of terminating the
process we apply an incorrect fixup and continue on.

With more and more overlapping instructions we should stop
creating a pseudo DSISR and index using the instruction directly,
but for now add a special case to catch ldbrx/stdbrx.

Signed-off-by: Anton Blanchard <[email protected]>
Cc: <[email protected]>
Signed-off-by: Benjamin Herrenschmidt <[email protected]>
  • Loading branch information
antonblanchard authored and ozbenh committed Aug 14, 2013

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
1 parent 5b63fee commit 230aef7
Showing 1 changed file with 10 additions and 0 deletions.
10 changes: 10 additions & 0 deletions arch/powerpc/kernel/align.c
Original file line number Diff line number Diff line change
@@ -764,6 +764,16 @@ int fix_alignment(struct pt_regs *regs)
nb = aligninfo[instr].len;
flags = aligninfo[instr].flags;

/* ldbrx/stdbrx overlap lfs/stfs in the DSISR unfortunately */
if (IS_XFORM(instruction) && ((instruction >> 1) & 0x3ff) == 532) {
nb = 8;
flags = LD+SW;
} else if (IS_XFORM(instruction) &&
((instruction >> 1) & 0x3ff) == 660) {
nb = 8;
flags = ST+SW;
}

/* Byteswap little endian loads and stores */
swiz = 0;
if (regs->msr & MSR_LE) {

0 comments on commit 230aef7

Please sign in to comment.