diff options
Diffstat (limited to 'arch/xtensa/include/asm/processor.h')
-rw-r--r-- | arch/xtensa/include/asm/processor.h | 18 |
1 files changed, 11 insertions, 7 deletions
diff --git a/arch/xtensa/include/asm/processor.h b/arch/xtensa/include/asm/processor.h index 19f6b54e358b..7f63aca6a0d3 100644 --- a/arch/xtensa/include/asm/processor.h +++ b/arch/xtensa/include/asm/processor.h @@ -176,18 +176,26 @@ struct thread_struct { /* * Do necessary setup to start up a newly executed thread. - * Note: We set-up ps as if we did a call4 to the new pc. + * Note: When windowed ABI is used for userspace we set-up ps + * as if we did a call4 to the new pc. * set_thread_state in signal.c depends on it. */ -#define USER_PS_VALUE ((1 << PS_WOE_BIT) | \ +#if IS_ENABLED(CONFIG_USER_ABI_CALL0) +#define USER_PS_VALUE ((USER_RING << PS_RING_SHIFT) | \ + (1 << PS_UM_BIT) | \ + (1 << PS_EXCM_BIT)) +#else +#define USER_PS_VALUE (PS_WOE_MASK | \ (1 << PS_CALLINC_SHIFT) | \ (USER_RING << PS_RING_SHIFT) | \ (1 << PS_UM_BIT) | \ (1 << PS_EXCM_BIT)) +#endif /* Clearing a0 terminates the backtrace. */ #define start_thread(regs, new_pc, new_sp) \ do { \ + unsigned long syscall = (regs)->syscall; \ memset((regs), 0, sizeof(*(regs))); \ (regs)->pc = (new_pc); \ (regs)->ps = USER_PS_VALUE; \ @@ -197,7 +205,7 @@ struct thread_struct { (regs)->depc = 0; \ (regs)->windowbase = 0; \ (regs)->windowstart = 1; \ - (regs)->syscall = NO_SYSCALL; \ + (regs)->syscall = syscall; \ } while (0) /* Forward declaration */ @@ -229,10 +237,6 @@ extern unsigned long get_wchan(struct task_struct *p); v; \ }) -#ifndef XCHAL_HAVE_EXTERN_REGS -#define XCHAL_HAVE_EXTERN_REGS 0 -#endif - #if XCHAL_HAVE_EXTERN_REGS static inline void set_er(unsigned long value, unsigned long addr) |