MIPS: Fix exception entry when CONFIG_EVA enabled
authorMatt Redfearn <matt.redfearn@mips.com>
Wed, 11 Oct 2017 08:59:20 +0000 (09:59 +0100)
committerJames Hogan <jhogan@kernel.org>
Tue, 31 Oct 2017 23:49:33 +0000 (23:49 +0000)
Commit 9fef68686317b ("MIPS: Make SAVE_SOME more standard") made several
changes to the order in which registers are saved in the SAVE_SOME
macro, used by exception handlers to save the processor state. In
particular, it removed the
move   k1, sp
in the delay slot of the branch testing if the processor is already in
kernel mode. This is replaced later in the macro by a
move   k0, sp
When CONFIG_EVA is disabled, this instruction actually appears in the
delay slot of the branch. However, when CONFIG_EVA is enabled, instead
the RPS workaround of
MFC0 k0, CP0_ENTRYHI
appears in the delay slot. This results in k0 not containing the stack
pointer, but some unrelated value, which is then saved to the kernel
stack. On exit from the exception, this bogus value is restored to the
stack pointer, resulting in an OOPS.

Fix this by moving the save of SP in k0 explicitly in the delay slot of
the branch, outside of the CONFIG_EVA section, restoring the expected
instruction ordering when CONFIG_EVA is active.

Fixes: 9fef68686317b ("MIPS: Make SAVE_SOME more standard")
Signed-off-by: Matt Redfearn <matt.redfearn@mips.com>
Reported-by: Vladimir Kondratiev <vladimir.kondratiev@intel.com>
Reviewed-by: Corey Minyard <cminyard@mvista.com>
Reviewed-by: James Hogan <jhogan@kernel.org>
Patchwork: https://patchwork.linux-mips.org/patch/17471/
Signed-off-by: James Hogan <jhogan@kernel.org>
arch/mips/include/asm/stackframe.h

index 5d3563c55e0c224bc62d20815568d61953f9902c..2161357cc68f094fb5b9c1287c38232dd19d390c 100644 (file)
                sll     k0, 3           /* extract cu0 bit */
                .set    noreorder
                bltz    k0, 8f
+                move   k0, sp
+               .if \docfi
+               .cfi_register sp, k0
+               .endif
 #ifdef CONFIG_EVA
                /*
                 * Flush interAptiv's Return Prediction Stack (RPS) by writing
                MTC0    k0, CP0_ENTRYHI
 #endif
                .set    reorder
-                move   k0, sp
-               .if \docfi
-               .cfi_register sp, k0
-               .endif
                /* Called from user mode, new stack. */
                get_saved_sp docfi=\docfi tosp=1
 8: