summaryrefslogtreecommitdiff
path: root/arch/mips/math-emu
diff options
context:
space:
mode:
authorMaciej W. Rozycki <macro@linux-mips.org>2015-04-03 23:26:37 +0100
committerRalf Baechle <ralf@linux-mips.org>2015-04-08 01:10:00 +0200
commit7737b20b9e071f3595582686e894bf56377c43e4 (patch)
treed006dc30148a28730a1bf871747ab19a30fb06f8 /arch/mips/math-emu
parentc9875032015ec94033295382a098657d4e38bf89 (diff)
MIPS: math-emu: Fix delay-slot emulation cache incoherency
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>
Diffstat (limited to 'arch/mips/math-emu')
-rw-r--r--arch/mips/math-emu/dsemul.c2
1 files changed, 1 insertions, 1 deletions
diff --git a/arch/mips/math-emu/dsemul.c b/arch/mips/math-emu/dsemul.c
index 58f58185f1c4..00ad7365e453 100644
--- a/arch/mips/math-emu/dsemul.c
+++ b/arch/mips/math-emu/dsemul.c
@@ -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 */
}