MIPS: math-emu: Fix delay-slot emulation cache incoherency
authorMaciej W. Rozycki <macro@linux-mips.org>
Fri, 3 Apr 2015 22:26:37 +0000 (23:26 +0100)
committerRalf Baechle <ralf@linux-mips.org>
Tue, 7 Apr 2015 23:10:00 +0000 (01:10 +0200)
Correct a cache coherency regression introduced with be1664c4 [Another
round of fixes for the fp emulator.] for the emulation frame used in
delay-slot emulation.

Two instructions are copied into the frame and as from the commit
referred a cache synchronisation call is made for the second instruction
aka `badinst' of the two only.  The `flush_cache_sigtramp' interface is
reused that guarantees that synchronisation will be made for 8 bytes or
2 instructions starting from the address requested, although if cache
lines are wider then a larger area may be synchronised.

Change the call to point to the first of the two instructions aka `emul'
instead, removing unpredictable behaviour resulting from cache
incoherency.

This bug only ever manifested itself on systems implementing 4-byte
cache lines, typically MIPS I systems, causing all kinds of weirdness.
This is because the sequence of two instructions starting from `emul' is
8-byte aligned and for 8-byte or wider cache lines the line synchronised
will span both, so the vast majority of systems have escaped unharmed.

Signed-off-by: Maciej W. Rozycki <macro@linux-mips.org>
Cc: linux-mips@linux-mips.org
Patchwork: https://patchwork.linux-mips.org/patch/9698/
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
arch/mips/math-emu/dsemul.c

index 58f58185f1c485506cad5b7a2b68ba6236173b7b..00ad7365e453c8d06a50c4b2abf69352dcbb51cb 100644 (file)
@@ -94,7 +94,7 @@ int mips_dsemul(struct pt_regs *regs, mips_instruction ir, unsigned long cpc)
        regs->cp0_epc = ((unsigned long) &fr->emul) |
                get_isa16_mode(regs->cp0_epc);
 
-       flush_cache_sigtramp((unsigned long)&fr->badinst);
+       flush_cache_sigtramp((unsigned long)&fr->emul);
 
        return SIGILL;          /* force out of emulation loop */
 }