aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVineet Gupta <vgupta@synopsys.com>2014-10-07 04:42:13 -0400
committerVineet Gupta <vgupta@synopsys.com>2015-06-22 04:36:55 -0400
commit0d7b8855a05c099a5c65a8d49a1e604198021f56 (patch)
treeca804ebd88dfcf49965c23251577e505aa440a2e
parent4255b07f2c9c43540149ed823faf5ac8476cccee (diff)
ARCv2: STAR 9000808988: signals involving Delay Slot
Reported by Anton as LTP:munmap01 failing with Illegal Instruction Exception. --------------------->8-------------------------------------- mmap2(NULL, 24576, PROT_READ|PROT_WRITE, MAP_SHARED, 3, 0) = 0x200d2000 munmap(0x200d2000, 24576) = 0 --- SIGSEGV {si_signo=SIGSEGV, si_code=SEGV_MAPERR, si_addr=0x200d2000} --- potentially unexpected fatal signal 4. Path: /munmap01 CPU: 0 PID: 61 Comm: munmap01 Not tainted 3.13.0-g5d5c46d9a556 #8 task: 9f1a8000 ti: 9f154000 task.ti: 9f154000 [ECR ]: 0x00020100 => Illegal Insn [EFA ]: 0x0001354c [BLINK ]: 0x200515d4 [ERET ]: 0x1354c @off 0x1354c in [/munmap01] VMA: 0x00010000 to 0x00018000 [STAT32]: 0x800802c0 ... --------------------->8-------------------------------------- The issue was 1. munmap01 accessed unmapped memory (on purpose) with signal handler installed for SIGSEGV 2. The faulting instruction happened to be in Delay Slot 00011864 <main>: 11908: bl.d 13284 <tst_resm> 1190c: stb r16,[r2] 3. kernel sets up the reg file for signal handler and correctly clears the DE bit in pt_regs->status32 placeholder 4. However RESTORE_CALLEE_SAVED_USER macro is not adjusted for ARCv2, and it over-writes the above with orig/stale value of status32 5. After RTIE, userspace signal handler executes a non branch instruction with DE bit set, triggering Illegal Instruction Exception. Reported-by: Anton Kolesov <akolesov@synopsys.com> Signed-off-by: Vineet Gupta <vgupta@synopsys.com>
-rw-r--r--arch/arc/include/asm/entry.h17
-rw-r--r--arch/arc/kernel/asm-offsets.c2
2 files changed, 12 insertions, 7 deletions
diff --git a/arch/arc/include/asm/entry.h b/arch/arc/include/asm/entry.h
index 29d0ab6e10f5..ad7860c5ce15 100644
--- a/arch/arc/include/asm/entry.h
+++ b/arch/arc/include/asm/entry.h
@@ -125,8 +125,6 @@
125 POP r13 125 POP r13
126.endm 126.endm
127 127
128#define OFF_USER_R25_FROM_R24 (SZ_CALLEE_REGS + SZ_PT_REGS - 8)/4
129
130/*-------------------------------------------------------------- 128/*--------------------------------------------------------------
131 * Collect User Mode callee regs as struct callee_regs - needed by 129 * Collect User Mode callee regs as struct callee_regs - needed by
132 * fork/do_signal/unaligned-access-emulation. 130 * fork/do_signal/unaligned-access-emulation.
@@ -139,12 +137,13 @@
139 *-------------------------------------------------------------*/ 137 *-------------------------------------------------------------*/
140.macro SAVE_CALLEE_SAVED_USER 138.macro SAVE_CALLEE_SAVED_USER
141 139
140 mov r12, sp ; save SP as ref to pt_regs
142 SAVE_R13_TO_R24 141 SAVE_R13_TO_R24
143 142
144#ifdef CONFIG_ARC_CURR_IN_REG 143#ifdef CONFIG_ARC_CURR_IN_REG
145 ; Retrieve orig r25 and save it on stack 144 ; Retrieve orig r25 and save it with rest of callee_regs
146 ld.as r12, [sp, OFF_USER_R25_FROM_R24] 145 ld.as r12, [r12, PT_user_r25]
147 st.a r12, [sp, -4] 146 PUSH r12
148#else 147#else
149 PUSH r25 148 PUSH r25
150#endif 149#endif
@@ -191,12 +190,16 @@
191.macro RESTORE_CALLEE_SAVED_USER 190.macro RESTORE_CALLEE_SAVED_USER
192 191
193#ifdef CONFIG_ARC_CURR_IN_REG 192#ifdef CONFIG_ARC_CURR_IN_REG
194 ld.ab r12, [sp, 4] 193 POP r12
195 st.as r12, [sp, OFF_USER_R25_FROM_R24]
196#else 194#else
197 POP r25 195 POP r25
198#endif 196#endif
199 RESTORE_R24_TO_R13 197 RESTORE_R24_TO_R13
198
199 ; SP is back to start of pt_regs
200#ifdef CONFIG_ARC_CURR_IN_REG
201 st.as r12, [sp, PT_user_r25]
202#endif
200.endm 203.endm
201 204
202/*-------------------------------------------------------------- 205/*--------------------------------------------------------------
diff --git a/arch/arc/kernel/asm-offsets.c b/arch/arc/kernel/asm-offsets.c
index b9cf23313273..605281f5b301 100644
--- a/arch/arc/kernel/asm-offsets.c
+++ b/arch/arc/kernel/asm-offsets.c
@@ -60,5 +60,7 @@ int main(void)
60 60
61 DEFINE(SZ_CALLEE_REGS, sizeof(struct callee_regs)); 61 DEFINE(SZ_CALLEE_REGS, sizeof(struct callee_regs));
62 DEFINE(SZ_PT_REGS, sizeof(struct pt_regs)); 62 DEFINE(SZ_PT_REGS, sizeof(struct pt_regs));
63 DEFINE(PT_user_r25, offsetof(struct pt_regs, user_r25));
64
63 return 0; 65 return 0;
64} 66}