xtensa: move fast exception handlers close to vectors
authorMax Filippov <jcmvbkbc@gmail.com>
Sat, 1 Feb 2020 02:48:43 +0000 (18:48 -0800)
committerMax Filippov <jcmvbkbc@gmail.com>
Wed, 5 Feb 2020 05:53:39 +0000 (21:53 -0800)
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>
arch/xtensa/include/asm/asmmacro.h
arch/xtensa/kernel/coprocessor.S
arch/xtensa/kernel/entry.S
arch/xtensa/kernel/setup.c
arch/xtensa/kernel/vectors.S
arch/xtensa/kernel/vmlinux.lds.S

index 71a7e846bc1f9b21cf14a0d42a8be3c5e440ef11..bfc89e11f4698ee5f7dee1de89d6d89dd6e16358 100644 (file)
 #error Unsupported Xtensa ABI
 #endif
 
+#define __XTENSA_HANDLER       .section ".exception.text", "ax"
+
 #endif /* _XTENSA_ASMMACRO_H */
index c53ce6d8794fd8e909a4689a912760b2a4ca34b2..c426b846beefbcbd6a6d9ed6439506f92e9ec070 100644 (file)
@@ -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
index be897803834a48a3734ccd021780ba82b992a932..9d2e22d9f3c3c2dbd0a8e59e3334aeb93cd54ddb 100644 (file)
@@ -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.
  *
index 0f93b67c7a5a5c11d6309c47a97834affe755c0b..fefbdce1db99a3545e95d1fec82efa27516c48e1 100644 (file)
@@ -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));
index 841503d3307cb590ec3ad380aeeb2434d6e53d30..95ad1e7739912520516350441dec98abf006d225 100644 (file)
@@ -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)
index 409c05cac15e485e20ecdc8d5e9674c662b2b3ec..37a3205c404c8c0b7525200e988f4537d51992ba 100644 (file)
@@ -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);