aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMax Filippov <jcmvbkbc@gmail.com>2014-08-06 17:03:01 -0400
committerMax Filippov <jcmvbkbc@gmail.com>2014-08-14 03:59:32 -0400
commit3cfc096e4c4fbc234634cf8a30d40348a25fc9ba (patch)
treeb97d650f595268a33c0023bfbe407922e7c3f6b2
parentd1b6ba82a50cecf94be540a3a153aa89d97511a0 (diff)
xtensa: don't allow overflow/underflow on unaligned stack
Double exceptions that happen during register window overflow/underflow are handled in the topmost stack frame, as if it was the only exception that occured. However unaligned access exception handler is special because it needs to analyze instruction that caused the exception, but the userspace instruction that triggered window exception is completely irrelevant. Unaligned data access is rather normal in the generic userspace code, but stack pointer manipulation must always be done by architecture-aware code and thus unaligned stack means a serious problem anyway. Use the default unaligned access handler that raises SIGBUS in case of unaligned access in window overflow/underflow handler. Signed-off-by: Max Filippov <jcmvbkbc@gmail.com>
-rw-r--r--arch/xtensa/kernel/traps.c5
-rw-r--r--arch/xtensa/kernel/vectors.S8
-rw-r--r--arch/xtensa/kernel/vmlinux.lds.S4
3 files changed, 10 insertions, 7 deletions
diff --git a/arch/xtensa/kernel/traps.c b/arch/xtensa/kernel/traps.c
index eebbfd8c26fc..9d2f45f010ef 100644
--- a/arch/xtensa/kernel/traps.c
+++ b/arch/xtensa/kernel/traps.c
@@ -101,9 +101,8 @@ static dispatch_init_table_t __initdata dispatch_init_table[] = {
101#if XCHAL_UNALIGNED_LOAD_EXCEPTION || XCHAL_UNALIGNED_STORE_EXCEPTION 101#if XCHAL_UNALIGNED_LOAD_EXCEPTION || XCHAL_UNALIGNED_STORE_EXCEPTION
102#ifdef CONFIG_XTENSA_UNALIGNED_USER 102#ifdef CONFIG_XTENSA_UNALIGNED_USER
103{ EXCCAUSE_UNALIGNED, USER, fast_unaligned }, 103{ EXCCAUSE_UNALIGNED, USER, fast_unaligned },
104#else
105{ EXCCAUSE_UNALIGNED, 0, do_unaligned_user },
106#endif 104#endif
105{ EXCCAUSE_UNALIGNED, 0, do_unaligned_user },
107{ EXCCAUSE_UNALIGNED, KRNL, fast_unaligned }, 106{ EXCCAUSE_UNALIGNED, KRNL, fast_unaligned },
108#endif 107#endif
109#ifdef CONFIG_MMU 108#ifdef CONFIG_MMU
@@ -264,7 +263,6 @@ do_illegal_instruction(struct pt_regs *regs)
264 */ 263 */
265 264
266#if XCHAL_UNALIGNED_LOAD_EXCEPTION || XCHAL_UNALIGNED_STORE_EXCEPTION 265#if XCHAL_UNALIGNED_LOAD_EXCEPTION || XCHAL_UNALIGNED_STORE_EXCEPTION
267#ifndef CONFIG_XTENSA_UNALIGNED_USER
268void 266void
269do_unaligned_user (struct pt_regs *regs) 267do_unaligned_user (struct pt_regs *regs)
270{ 268{
@@ -286,7 +284,6 @@ do_unaligned_user (struct pt_regs *regs)
286 284
287} 285}
288#endif 286#endif
289#endif
290 287
291void 288void
292do_debug(struct pt_regs *regs) 289do_debug(struct pt_regs *regs)
diff --git a/arch/xtensa/kernel/vectors.S b/arch/xtensa/kernel/vectors.S
index 8453e6e39895..1b397a902292 100644
--- a/arch/xtensa/kernel/vectors.S
+++ b/arch/xtensa/kernel/vectors.S
@@ -454,8 +454,14 @@ _DoubleExceptionVector_WindowOverflow:
454 s32i a0, a2, PT_DEPC 454 s32i a0, a2, PT_DEPC
455 455
456_DoubleExceptionVector_handle_exception: 456_DoubleExceptionVector_handle_exception:
457 addi a0, a0, -EXCCAUSE_UNALIGNED
458 beqz a0, 2f
457 addx4 a0, a0, a3 459 addx4 a0, a0, a3
458 l32i a0, a0, EXC_TABLE_FAST_USER 460 l32i a0, a0, EXC_TABLE_FAST_USER + 4 * EXCCAUSE_UNALIGNED
461 xsr a3, excsave1
462 jx a0
4632:
464 movi a0, user_exception
459 xsr a3, excsave1 465 xsr a3, excsave1
460 jx a0 466 jx a0
461 467
diff --git a/arch/xtensa/kernel/vmlinux.lds.S b/arch/xtensa/kernel/vmlinux.lds.S
index d16db6df86f8..fc1bc2ba8d5d 100644
--- a/arch/xtensa/kernel/vmlinux.lds.S
+++ b/arch/xtensa/kernel/vmlinux.lds.S
@@ -269,13 +269,13 @@ SECTIONS
269 .UserExceptionVector.literal) 269 .UserExceptionVector.literal)
270 SECTION_VECTOR (_DoubleExceptionVector_literal, 270 SECTION_VECTOR (_DoubleExceptionVector_literal,
271 .DoubleExceptionVector.literal, 271 .DoubleExceptionVector.literal,
272 DOUBLEEXC_VECTOR_VADDR - 40, 272 DOUBLEEXC_VECTOR_VADDR - 48,
273 SIZEOF(.UserExceptionVector.text), 273 SIZEOF(.UserExceptionVector.text),
274 .UserExceptionVector.text) 274 .UserExceptionVector.text)
275 SECTION_VECTOR (_DoubleExceptionVector_text, 275 SECTION_VECTOR (_DoubleExceptionVector_text,
276 .DoubleExceptionVector.text, 276 .DoubleExceptionVector.text,
277 DOUBLEEXC_VECTOR_VADDR, 277 DOUBLEEXC_VECTOR_VADDR,
278 40, 278 48,
279 .DoubleExceptionVector.literal) 279 .DoubleExceptionVector.literal)
280 280
281 . = (LOADADDR( .DoubleExceptionVector.text ) + SIZEOF( .DoubleExceptionVector.text ) + 3) & ~ 3; 281 . = (LOADADDR( .DoubleExceptionVector.text ) + SIZEOF( .DoubleExceptionVector.text ) + 3) & ~ 3;