aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorMatt Redfearn <matt.redfearn@mips.com>2017-10-11 09:59:20 +0100
committerJames Hogan <jhogan@kernel.org>2017-10-31 23:49:33 +0000
commitc496f3c08a83e57359509828e5b19eeb920b81b1 (patch)
treec985388d48c8fe9d931eca9a31c2058e16e32bbb /arch
parentMIPS: generic: Fix NI 169445 its build (diff)
downloadlinux-dev-c496f3c08a83e57359509828e5b19eeb920b81b1.tar.xz
linux-dev-c496f3c08a83e57359509828e5b19eeb920b81b1.zip
MIPS: Fix exception entry when CONFIG_EVA enabled
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>
Diffstat (limited to 'arch')
-rw-r--r--arch/mips/include/asm/stackframe.h8
1 files changed, 4 insertions, 4 deletions
diff --git a/arch/mips/include/asm/stackframe.h b/arch/mips/include/asm/stackframe.h
index 5d3563c55e0c..2161357cc68f 100644
--- a/arch/mips/include/asm/stackframe.h
+++ b/arch/mips/include/asm/stackframe.h
@@ -199,6 +199,10 @@
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
@@ -225,10 +229,6 @@
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: