Skip to contentSkip to conversation

powerpc: handle unaligned ldbrx/stdbrx

PATCH In review Anton Blanchard 2 participants 2 messages Jul 31, 2013 PowerPC

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 powerpc: handle unaligned ldbrx/stdbrx

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.

---

arch/powerpc/kernel/align.c +10 -0
Index: b/arch/powerpc/kernel/align.c
===================================================================
@@ -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) {
#1 lore raw

Hi Anton,

arch/powerpc/kernel/align.c int fix_alignment(struct pt_regs *regs) · line 768

Quoted 8 lines · On Wed, 31 Jul 2013 15:05:21 +1000 Anton Blanchard <[email protected]> wrote:

+++ b/arch/powerpc/kernel/align.c

arch/powerpc/kernel/align.c +2 -0
@@ -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) {

We have get_xop() in asm/disassemble.h (which is unfortunately not included by this file) ...

arch/powerpc/kernel/align.c int fix_alignment(struct pt_regs *regs) · line 772

Quoted 4 lines
arch/powerpc/kernel/align.c +4 -0
+		nb = 8;
+		flags = LD+SW;
+	} else if (IS_XFORM(instruction) &&
+		   ((instruction >> 1) & 0x3ff) == 660) {

ditto

/me points at a bike shed :-)

Signature · 2 lines
Cheers,
Stephen Rothwell                    [email protected]