Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

+39 -14
+2
arch/xtensa/include/asm/asmmacro.h
··· 237 237 #error Unsupported Xtensa ABI 238 238 #endif 239 239 240 + #define __XTENSA_HANDLER .section ".exception.text", "ax" 241 + 240 242 #endif /* _XTENSA_ASMMACRO_H */
+2 -3
arch/xtensa/kernel/coprocessor.S
··· 58 58 .endif; \ 59 59 .long THREAD_XTREGS_CP##x 60 60 61 + __XTENSA_HANDLER 62 + 61 63 SAVE_CP_REGS(0) 62 64 SAVE_CP_REGS(1) 63 65 SAVE_CP_REGS(2) ··· 78 76 LOAD_CP_REGS(6) 79 77 LOAD_CP_REGS(7) 80 78 81 - .section ".rodata", "a" 82 79 .align 4 83 80 .Lsave_cp_regs_jump_table: 84 81 SAVE_CP_REGS_TAB(0) ··· 98 97 LOAD_CP_REGS_TAB(5) 99 98 LOAD_CP_REGS_TAB(6) 100 99 LOAD_CP_REGS_TAB(7) 101 - 102 - .previous 103 100 104 101 /* 105 102 * coprocessor_flush(struct thread_info*, index)
+12 -6
arch/xtensa/kernel/entry.S
··· 939 939 940 940 /* -------------------------- FAST EXCEPTION HANDLERS ----------------------- */ 941 941 942 + __XTENSA_HANDLER 943 + .literal_position 944 + 942 945 /* 943 946 * Fast-handler for alloca exceptions 944 947 * ··· 1027 1024 ENTRY(fast_illegal_instruction_user) 1028 1025 1029 1026 rsr a0, ps 1030 - bbsi.l a0, PS_WOE_BIT, user_exception 1027 + bbsi.l a0, PS_WOE_BIT, 1f 1031 1028 s32i a3, a2, PT_AREG3 1032 1029 movi a3, PS_WOE_MASK 1033 1030 or a0, a0, a3 ··· 1036 1033 l32i a0, a2, PT_AREG0 1037 1034 rsr a2, depc 1038 1035 rfe 1036 + 1: 1037 + call0 user_exception 1039 1038 1040 1039 ENDPROC(fast_illegal_instruction_user) 1041 1040 #endif ··· 1076 1071 _beqz a0, fast_syscall_spill_registers 1077 1072 _beqi a0, __NR_xtensa, fast_syscall_xtensa 1078 1073 1079 - j user_exception 1074 + call0 user_exception 1080 1075 1081 1076 ENDPROC(fast_syscall_user) 1082 1077 ··· 1767 1762 1768 1763 rsr a2, ps 1769 1764 bbsi.l a2, PS_UM_BIT, 1f 1770 - j _kernel_exception 1771 - 1: j _user_exception 1765 + call0 _kernel_exception 1766 + 1: call0 _user_exception 1772 1767 1773 1768 ENDPROC(fast_second_level_miss) 1774 1769 ··· 1864 1859 1865 1860 rsr a2, ps 1866 1861 bbsi.l a2, PS_UM_BIT, 1f 1867 - j _kernel_exception 1868 - 1: j _user_exception 1862 + call0 _kernel_exception 1863 + 1: call0 _user_exception 1869 1864 1870 1865 ENDPROC(fast_store_prohibited) 1871 1866 1872 1867 #endif /* CONFIG_MMU */ 1873 1868 1869 + .text 1874 1870 /* 1875 1871 * System Calls. 1876 1872 *
+4
arch/xtensa/kernel/setup.c
··· 284 284 extern char _UserExceptionVector_text_end; 285 285 extern char _DoubleExceptionVector_text_start; 286 286 extern char _DoubleExceptionVector_text_end; 287 + extern char _exception_text_start; 288 + extern char _exception_text_end; 287 289 #if XCHAL_EXCM_LEVEL >= 2 288 290 extern char _Level2InterruptVector_text_start; 289 291 extern char _Level2InterruptVector_text_end; ··· 365 363 mem_reserve(__pa(&_DoubleExceptionVector_text_start), 366 364 __pa(&_DoubleExceptionVector_text_end)); 367 365 366 + mem_reserve(__pa(&_exception_text_start), 367 + __pa(&_exception_text_end)); 368 368 #if XCHAL_EXCM_LEVEL >= 2 369 369 mem_reserve(__pa(&_Level2InterruptVector_text_start), 370 370 __pa(&_Level2InterruptVector_text_end));
+2 -1
arch/xtensa/kernel/vectors.S
··· 43 43 */ 44 44 45 45 #include <linux/linkage.h> 46 + #include <asm/asmmacro.h> 46 47 #include <asm/ptrace.h> 47 48 #include <asm/current.h> 48 49 #include <asm/asm-offsets.h> ··· 478 477 479 478 ENDPROC(_DoubleExceptionVector) 480 479 481 - .text 482 480 /* 483 481 * Fixup handler for TLB miss in double exception handler for window owerflow. 484 482 * We get here with windowbase set to the window that was being spilled and ··· 505 505 * a3: exctable, original value in excsave1 506 506 */ 507 507 508 + __XTENSA_HANDLER 508 509 .literal_position 509 510 510 511 ENTRY(window_overflow_restore_a0_fixup)
+17 -4
arch/xtensa/kernel/vmlinux.lds.S
··· 110 110 SECTION_VECTOR (.KernelExceptionVector.text, KERNEL_VECTOR_VADDR) 111 111 SECTION_VECTOR (.UserExceptionVector.text, USER_VECTOR_VADDR) 112 112 SECTION_VECTOR (.DoubleExceptionVector.text, DOUBLEEXC_VECTOR_VADDR) 113 + 114 + *(.exception.text) 113 115 #endif 114 116 115 117 IRQENTRY_TEXT ··· 192 190 .DoubleExceptionVector.text); 193 191 RELOCATE_ENTRY(_DebugInterruptVector_text, 194 192 .DebugInterruptVector.text); 193 + RELOCATE_ENTRY(_exception_text, 194 + .exception.text); 195 195 #endif 196 196 #ifdef CONFIG_XIP_KERNEL 197 197 RELOCATE_ENTRY(_xip_data, .data); ··· 286 282 .DoubleExceptionVector.text, 287 283 DOUBLEEXC_VECTOR_VADDR, 288 284 .UserExceptionVector.text) 289 - 290 - . = (LOADADDR( .DoubleExceptionVector.text ) + SIZEOF( .DoubleExceptionVector.text ) + 3) & ~ 3; 285 + #define LAST .DoubleExceptionVector.text 291 286 292 287 #endif 293 288 #if !defined(CONFIG_XIP_KERNEL) && defined(CONFIG_SMP) ··· 295 292 .SecondaryResetVector.text, 296 293 RESET_VECTOR1_VADDR, 297 294 .DoubleExceptionVector.text) 298 - 299 - . = LOADADDR(.SecondaryResetVector.text)+SIZEOF(.SecondaryResetVector.text); 295 + #undef LAST 296 + #define LAST .SecondaryResetVector.text 300 297 301 298 #endif 299 + #ifdef CONFIG_VECTORS_OFFSET 300 + SECTION_VECTOR (_exception_text, 301 + .exception.text, 302 + , 303 + LAST) 304 + #undef LAST 305 + #define LAST .exception.text 306 + 307 + #endif 308 + . = (LOADADDR(LAST) + SIZEOF(LAST) + 3) & ~ 3; 302 309 303 310 . = ALIGN(PAGE_SIZE); 304 311