]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blame - releases/4.14.67/openrisc-entry-fix-delay-slot-exception-detection.patch
4.14-stable patches
[thirdparty/kernel/stable-queue.git] / releases / 4.14.67 / openrisc-entry-fix-delay-slot-exception-detection.patch
CommitLineData
f5ab4f51
GKH
1From foo@baz Wed Aug 22 09:33:46 CEST 2018
2From: Stafford Horne <shorne@gmail.com>
3Date: Sun, 1 Jul 2018 14:17:36 +0900
4Subject: openrisc: entry: Fix delay slot exception detection
5
6From: Stafford Horne <shorne@gmail.com>
7
8[ Upstream commit ae15a41a641449f536578b0d9ec0e4ade130deb5 ]
9
10Originally in patch e6d20c55a4 ("openrisc: entry: Fix delay slot
11detection") I fixed delay slot detection, but only for QEMU. We missed
12that hardware delay slot detection using delay slot exception flag (DSX)
13was still broken. This was because QEMU set the DSX flag in both
14pre-exception supervision register (ESR) and supervision register (SR)
15register, but on real hardware the DSX flag is only set on the SR
16register during exceptions.
17
18Fix this by carrying the DSX flag into the SR register during exception.
19We also update the DSX flag read locations to read the value from the SR
20register not the pt_regs SR register which represents ESR. The ESR
21should never have the DSX flag set.
22
23In the process I updated/removed a few comments to match the current
24state. Including removing a comment saying that the DSX detection logic
25was inefficient and needed to be rewritten.
26
27I have tested this on QEMU with a patch ensuring it matches the hardware
28specification.
29
30Link: https://lists.gnu.org/archive/html/qemu-devel/2018-07/msg00000.html
31Fixes: e6d20c55a4 ("openrisc: entry: Fix delay slot detection")
32Signed-off-by: Stafford Horne <shorne@gmail.com>
33Signed-off-by: Sasha Levin <alexander.levin@microsoft.com>
34Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
35---
36 arch/openrisc/kernel/entry.S | 8 +-------
37 arch/openrisc/kernel/head.S | 9 ++++++---
38 arch/openrisc/kernel/traps.c | 2 +-
39 3 files changed, 8 insertions(+), 11 deletions(-)
40
41--- a/arch/openrisc/kernel/entry.S
42+++ b/arch/openrisc/kernel/entry.S
43@@ -221,12 +221,6 @@ EXCEPTION_ENTRY(_data_page_fault_handler
44 l.addi r3,r1,0 // pt_regs
45 /* r4 set be EXCEPTION_HANDLE */ // effective address of fault
46
47- /*
48- * __PHX__: TODO
49- *
50- * all this can be written much simpler. look at
51- * DTLB miss handler in the CONFIG_GUARD_PROTECTED_CORE part
52- */
53 #ifdef CONFIG_OPENRISC_NO_SPR_SR_DSX
54 l.lwz r6,PT_PC(r3) // address of an offending insn
55 l.lwz r6,0(r6) // instruction that caused pf
56@@ -258,7 +252,7 @@ EXCEPTION_ENTRY(_data_page_fault_handler
57
58 #else
59
60- l.lwz r6,PT_SR(r3) // SR
61+ l.mfspr r6,r0,SPR_SR // SR
62 l.andi r6,r6,SPR_SR_DSX // check for delay slot exception
63 l.sfne r6,r0 // exception happened in delay slot
64 l.bnf 7f
65--- a/arch/openrisc/kernel/head.S
66+++ b/arch/openrisc/kernel/head.S
67@@ -141,8 +141,7 @@
68 * r4 - EEAR exception EA
69 * r10 - current pointing to current_thread_info struct
70 * r12 - syscall 0, since we didn't come from syscall
71- * r13 - temp it actually contains new SR, not needed anymore
72- * r31 - handler address of the handler we'll jump to
73+ * r30 - handler address of the handler we'll jump to
74 *
75 * handler has to save remaining registers to the exception
76 * ksp frame *before* tainting them!
77@@ -178,6 +177,7 @@
78 /* r1 is KSP, r30 is __pa(KSP) */ ;\
79 tophys (r30,r1) ;\
80 l.sw PT_GPR12(r30),r12 ;\
81+ /* r4 use for tmp before EA */ ;\
82 l.mfspr r12,r0,SPR_EPCR_BASE ;\
83 l.sw PT_PC(r30),r12 ;\
84 l.mfspr r12,r0,SPR_ESR_BASE ;\
85@@ -197,7 +197,10 @@
86 /* r12 == 1 if we come from syscall */ ;\
87 CLEAR_GPR(r12) ;\
88 /* ----- turn on MMU ----- */ ;\
89- l.ori r30,r0,(EXCEPTION_SR) ;\
90+ /* Carry DSX into exception SR */ ;\
91+ l.mfspr r30,r0,SPR_SR ;\
92+ l.andi r30,r30,SPR_SR_DSX ;\
93+ l.ori r30,r30,(EXCEPTION_SR) ;\
94 l.mtspr r0,r30,SPR_ESR_BASE ;\
95 /* r30: EA address of handler */ ;\
96 LOAD_SYMBOL_2_GPR(r30,handler) ;\
97--- a/arch/openrisc/kernel/traps.c
98+++ b/arch/openrisc/kernel/traps.c
99@@ -358,7 +358,7 @@ static inline int in_delay_slot(struct p
100 return 0;
101 }
102 #else
103- return regs->sr & SPR_SR_DSX;
104+ return mfspr(SPR_SR) & SPR_SR_DSX;
105 #endif
106 }
107