summaryrefslogtreecommitdiff
path: root/arch/xtensa
diff options
context:
space:
mode:
authorMax Filippov <jcmvbkbc@gmail.com>2020-01-31 18:48:43 -0800
committerMax Filippov <jcmvbkbc@gmail.com>2020-02-04 21:53:39 -0800
commit50722f0bf631cfcbcce18dac6b3fb5c2b6432628 (patch)
tree23ec7b5989f9cf6f1c987daeafd1ee60d148dbb6 /arch/xtensa
parent58bc6c69afe51ed19d1294ab0bb319b7df1cf75a (diff)
xtensa: move fast exception handlers close to vectors
On XIP kernels it makes sense to have exception vectors and fast exception handlers together (in a fast memory). In addition, with MTD XIP support both vectors and fast exception handlers must be outside of the FLASH. Add section .exception.text and move fast exception handlers to it. Put it together with vectors when vectors are outside of the .text. Signed-off-by: Max Filippov <jcmvbkbc@gmail.com>
Diffstat (limited to 'arch/xtensa')
-rw-r--r--arch/xtensa/include/asm/asmmacro.h2
-rw-r--r--arch/xtensa/kernel/coprocessor.S5
-rw-r--r--arch/xtensa/kernel/entry.S18
-rw-r--r--arch/xtensa/kernel/setup.c4
-rw-r--r--arch/xtensa/kernel/vectors.S3
-rw-r--r--arch/xtensa/kernel/vmlinux.lds.S19
6 files changed, 38 insertions, 13 deletions
diff --git a/arch/xtensa/include/asm/asmmacro.h b/arch/xtensa/include/asm/asmmacro.h
index 71a7e846bc1f..bfc89e11f469 100644
--- a/arch/xtensa/include/asm/asmmacro.h
+++ b/arch/xtensa/include/asm/asmmacro.h
@@ -237,4 +237,6 @@
#error Unsupported Xtensa ABI
#endif
+#define __XTENSA_HANDLER .section ".exception.text", "ax"
+
#endif /* _XTENSA_ASMMACRO_H */
diff --git a/arch/xtensa/kernel/coprocessor.S b/arch/xtensa/kernel/coprocessor.S
index c53ce6d8794f..c426b846beef 100644
--- a/arch/xtensa/kernel/coprocessor.S
+++ b/arch/xtensa/kernel/coprocessor.S
@@ -58,6 +58,8 @@
.endif; \
.long THREAD_XTREGS_CP##x
+ __XTENSA_HANDLER
+
SAVE_CP_REGS(0)
SAVE_CP_REGS(1)
SAVE_CP_REGS(2)
@@ -76,7 +78,6 @@
LOAD_CP_REGS(6)
LOAD_CP_REGS(7)
- .section ".rodata", "a"
.align 4
.Lsave_cp_regs_jump_table:
SAVE_CP_REGS_TAB(0)
@@ -98,8 +99,6 @@
LOAD_CP_REGS_TAB(6)
LOAD_CP_REGS_TAB(7)
- .previous
-
/*
* coprocessor_flush(struct thread_info*, index)
* a2 a3
diff --git a/arch/xtensa/kernel/entry.S b/arch/xtensa/kernel/entry.S
index be897803834a..9d2e22d9f3c3 100644
--- a/arch/xtensa/kernel/entry.S
+++ b/arch/xtensa/kernel/entry.S
@@ -939,6 +939,9 @@ ENDPROC(unrecoverable_exception)
/* -------------------------- FAST EXCEPTION HANDLERS ----------------------- */
+ __XTENSA_HANDLER
+ .literal_position
+
/*
* Fast-handler for alloca exceptions
*
@@ -1024,7 +1027,7 @@ ENDPROC(fast_alloca)
ENTRY(fast_illegal_instruction_user)
rsr a0, ps
- bbsi.l a0, PS_WOE_BIT, user_exception
+ bbsi.l a0, PS_WOE_BIT, 1f
s32i a3, a2, PT_AREG3
movi a3, PS_WOE_MASK
or a0, a0, a3
@@ -1033,6 +1036,8 @@ ENTRY(fast_illegal_instruction_user)
l32i a0, a2, PT_AREG0
rsr a2, depc
rfe
+1:
+ call0 user_exception
ENDPROC(fast_illegal_instruction_user)
#endif
@@ -1071,7 +1076,7 @@ ENTRY(fast_syscall_user)
_beqz a0, fast_syscall_spill_registers
_beqi a0, __NR_xtensa, fast_syscall_xtensa
- j user_exception
+ call0 user_exception
ENDPROC(fast_syscall_user)
@@ -1762,8 +1767,8 @@ ENTRY(fast_second_level_miss)
rsr a2, ps
bbsi.l a2, PS_UM_BIT, 1f
- j _kernel_exception
-1: j _user_exception
+ call0 _kernel_exception
+1: call0 _user_exception
ENDPROC(fast_second_level_miss)
@@ -1859,13 +1864,14 @@ ENTRY(fast_store_prohibited)
rsr a2, ps
bbsi.l a2, PS_UM_BIT, 1f
- j _kernel_exception
-1: j _user_exception
+ call0 _kernel_exception
+1: call0 _user_exception
ENDPROC(fast_store_prohibited)
#endif /* CONFIG_MMU */
+ .text
/*
* System Calls.
*
diff --git a/arch/xtensa/kernel/setup.c b/arch/xtensa/kernel/setup.c
index 0f93b67c7a5a..fefbdce1db99 100644
--- a/arch/xtensa/kernel/setup.c
+++ b/arch/xtensa/kernel/setup.c
@@ -284,6 +284,8 @@ extern char _UserExceptionVector_text_start;
extern char _UserExceptionVector_text_end;
extern char _DoubleExceptionVector_text_start;
extern char _DoubleExceptionVector_text_end;
+extern char _exception_text_start;
+extern char _exception_text_end;
#if XCHAL_EXCM_LEVEL >= 2
extern char _Level2InterruptVector_text_start;
extern char _Level2InterruptVector_text_end;
@@ -363,6 +365,8 @@ void __init setup_arch(char **cmdline_p)
mem_reserve(__pa(&_DoubleExceptionVector_text_start),
__pa(&_DoubleExceptionVector_text_end));
+ mem_reserve(__pa(&_exception_text_start),
+ __pa(&_exception_text_end));
#if XCHAL_EXCM_LEVEL >= 2
mem_reserve(__pa(&_Level2InterruptVector_text_start),
__pa(&_Level2InterruptVector_text_end));
diff --git a/arch/xtensa/kernel/vectors.S b/arch/xtensa/kernel/vectors.S
index 841503d3307c..95ad1e773991 100644
--- a/arch/xtensa/kernel/vectors.S
+++ b/arch/xtensa/kernel/vectors.S
@@ -43,6 +43,7 @@
*/
#include <linux/linkage.h>
+#include <asm/asmmacro.h>
#include <asm/ptrace.h>
#include <asm/current.h>
#include <asm/asm-offsets.h>
@@ -477,7 +478,6 @@ _DoubleExceptionVector_handle_exception:
ENDPROC(_DoubleExceptionVector)
- .text
/*
* Fixup handler for TLB miss in double exception handler for window owerflow.
* We get here with windowbase set to the window that was being spilled and
@@ -505,6 +505,7 @@ ENDPROC(_DoubleExceptionVector)
* a3: exctable, original value in excsave1
*/
+ __XTENSA_HANDLER
.literal_position
ENTRY(window_overflow_restore_a0_fixup)
diff --git a/arch/xtensa/kernel/vmlinux.lds.S b/arch/xtensa/kernel/vmlinux.lds.S
index 409c05cac15e..37a3205c404c 100644
--- a/arch/xtensa/kernel/vmlinux.lds.S
+++ b/arch/xtensa/kernel/vmlinux.lds.S
@@ -110,6 +110,8 @@ SECTIONS
SECTION_VECTOR (.KernelExceptionVector.text, KERNEL_VECTOR_VADDR)
SECTION_VECTOR (.UserExceptionVector.text, USER_VECTOR_VADDR)
SECTION_VECTOR (.DoubleExceptionVector.text, DOUBLEEXC_VECTOR_VADDR)
+
+ *(.exception.text)
#endif
IRQENTRY_TEXT
@@ -190,6 +192,8 @@ SECTIONS
.DoubleExceptionVector.text);
RELOCATE_ENTRY(_DebugInterruptVector_text,
.DebugInterruptVector.text);
+ RELOCATE_ENTRY(_exception_text,
+ .exception.text);
#endif
#ifdef CONFIG_XIP_KERNEL
RELOCATE_ENTRY(_xip_data, .data);
@@ -282,8 +286,7 @@ SECTIONS
.DoubleExceptionVector.text,
DOUBLEEXC_VECTOR_VADDR,
.UserExceptionVector.text)
-
- . = (LOADADDR( .DoubleExceptionVector.text ) + SIZEOF( .DoubleExceptionVector.text ) + 3) & ~ 3;
+#define LAST .DoubleExceptionVector.text
#endif
#if !defined(CONFIG_XIP_KERNEL) && defined(CONFIG_SMP)
@@ -292,10 +295,20 @@ SECTIONS
.SecondaryResetVector.text,
RESET_VECTOR1_VADDR,
.DoubleExceptionVector.text)
+#undef LAST
+#define LAST .SecondaryResetVector.text
- . = LOADADDR(.SecondaryResetVector.text)+SIZEOF(.SecondaryResetVector.text);
+#endif
+#ifdef CONFIG_VECTORS_OFFSET
+ SECTION_VECTOR (_exception_text,
+ .exception.text,
+ ,
+ LAST)
+#undef LAST
+#define LAST .exception.text
#endif
+ . = (LOADADDR(LAST) + SIZEOF(LAST) + 3) & ~ 3;
. = ALIGN(PAGE_SIZE);