#error Unsupported Xtensa ABI
 #endif
 
+#define __XTENSA_HANDLER       .section ".exception.text", "ax"
+
 #endif /* _XTENSA_ASMMACRO_H */
 
        .endif;                                                         \
        .long THREAD_XTREGS_CP##x
 
+       __XTENSA_HANDLER
+
        SAVE_CP_REGS(0)
        SAVE_CP_REGS(1)
        SAVE_CP_REGS(2)
        LOAD_CP_REGS(6)
        LOAD_CP_REGS(7)
 
-       .section ".rodata", "a"
        .align 4
 .Lsave_cp_regs_jump_table:
        SAVE_CP_REGS_TAB(0)
        LOAD_CP_REGS_TAB(6)
        LOAD_CP_REGS_TAB(7)
 
-       .previous
-
 /*
  * coprocessor_flush(struct thread_info*, index)
  *                             a2        a3
 
 
 /* -------------------------- FAST EXCEPTION HANDLERS ----------------------- */
 
+       __XTENSA_HANDLER
+       .literal_position
+
 /*
  * Fast-handler for alloca exceptions
  *
 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
        l32i    a0, a2, PT_AREG0
        rsr     a2, depc
        rfe
+1:
+       call0   user_exception
 
 ENDPROC(fast_illegal_instruction_user)
 #endif
        _beqz   a0, fast_syscall_spill_registers
        _beqi   a0, __NR_xtensa, fast_syscall_xtensa
 
-       j       user_exception
+       call0   user_exception
 
 ENDPROC(fast_syscall_user)
 
 
        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)
 
 
        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.
  *
 
 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;
        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));
 
  */
 
 #include <linux/linkage.h>
+#include <asm/asmmacro.h>
 #include <asm/ptrace.h>
 #include <asm/current.h>
 #include <asm/asm-offsets.h>
 
 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
  * a3: exctable, original value in excsave1
  */
 
+       __XTENSA_HANDLER
        .literal_position
 
 ENTRY(window_overflow_restore_a0_fixup)
 
   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
                   .DoubleExceptionVector.text);
     RELOCATE_ENTRY(_DebugInterruptVector_text,
                   .DebugInterruptVector.text);
+    RELOCATE_ENTRY(_exception_text,
+                  .exception.text);
 #endif
 #ifdef CONFIG_XIP_KERNEL
     RELOCATE_ENTRY(_xip_data, .data);
                  .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)
                  .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);