Skip to content

Commit 0798beb

Browse files
vineetgarcSasha Levin
authored andcommitted
ARCv2: STAR 9000808988: signals involving Delay Slot
[ Upstream commit 0d7b885 ] 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 <[email protected]> Signed-off-by: Vineet Gupta <[email protected]> Signed-off-by: Sasha Levin <[email protected]>
1 parent bc78e69 commit 0798beb

File tree

2 files changed

+12
-7
lines changed

2 files changed

+12
-7
lines changed

arch/arc/include/asm/entry.h

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -143,8 +143,6 @@
143143
POP r13
144144
.endm
145145

146-
#define OFF_USER_R25_FROM_R24 (SZ_CALLEE_REGS + SZ_PT_REGS - 8)/4
147-
148146
/*--------------------------------------------------------------
149147
* Collect User Mode callee regs as struct callee_regs - needed by
150148
* fork/do_signal/unaligned-access-emulation.
@@ -157,12 +155,13 @@
157155
*-------------------------------------------------------------*/
158156
.macro SAVE_CALLEE_SAVED_USER
159157

158+
mov r12, sp ; save SP as ref to pt_regs
160159
SAVE_R13_TO_R24
161160

162161
#ifdef CONFIG_ARC_CURR_IN_REG
163-
; Retrieve orig r25 and save it on stack
164-
ld.as r12, [sp, OFF_USER_R25_FROM_R24]
165-
st.a r12, [sp, -4]
162+
; Retrieve orig r25 and save it with rest of callee_regs
163+
ld.as r12, [r12, PT_user_r25]
164+
PUSH r12
166165
#else
167166
PUSH r25
168167
#endif
@@ -209,12 +208,16 @@
209208
.macro RESTORE_CALLEE_SAVED_USER
210209

211210
#ifdef CONFIG_ARC_CURR_IN_REG
212-
ld.ab r12, [sp, 4]
213-
st.as r12, [sp, OFF_USER_R25_FROM_R24]
211+
POP r12
214212
#else
215213
POP r25
216214
#endif
217215
RESTORE_R24_TO_R13
216+
217+
; SP is back to start of pt_regs
218+
#ifdef CONFIG_ARC_CURR_IN_REG
219+
st.as r12, [sp, PT_user_r25]
220+
#endif
218221
.endm
219222

220223
/*--------------------------------------------------------------

arch/arc/kernel/asm-offsets.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,5 +59,7 @@ int main(void)
5959

6060
DEFINE(SZ_CALLEE_REGS, sizeof(struct callee_regs));
6161
DEFINE(SZ_PT_REGS, sizeof(struct pt_regs));
62+
DEFINE(PT_user_r25, offsetof(struct pt_regs, user_r25));
63+
6264
return 0;
6365
}

0 commit comments

Comments
 (0)