xtensa: set pointer to privileged stack only if user mode

When initializing the stack at thread creation, we should not
set the pointer to privileged stack pointer yet as the thread
can be a kernel thread. Only when a thread is transitioning to
user mode, then we need to set the pointer to point to
the privileged stack. This is a purely semantic change and
should not affect any functionality.

Signed-off-by: Daniel Leung <daniel.leung@intel.com>
This commit is contained in:
Daniel Leung 2025-03-11 12:00:54 -07:00 committed by Benjamin Cabé
commit dcf75319e2

View file

@ -42,11 +42,7 @@ static void *init_stack(struct k_thread *thread, int *stack_top,
void *ret;
_xtensa_irq_stack_frame_a11_t *frame;
#ifdef CONFIG_USERSPACE
struct xtensa_thread_stack_header *header =
(struct xtensa_thread_stack_header *)thread->stack_obj;
thread->arch.psp = header->privilege_stack +
sizeof(header->privilege_stack);
thread->arch.psp = NULL;
#endif
/* Not-a-cpu ID Ensures that the first time this is run, the
@ -73,18 +69,6 @@ static void *init_stack(struct k_thread *thread, int *stack_top,
frame->bsa.ps = PS_WOE | PS_UM | PS_CALLINC(1);
#ifdef CONFIG_USERSPACE
if ((thread->base.user_options & K_USER) == K_USER) {
#ifdef CONFIG_INIT_STACKS
/* setup_thread_stack() does not initialize the architecture specific
* privileged stack. So we need to do it manually here as this function
* is called by arch_new_thread() via z_setup_new_thread() after
* setup_thread_stack() but before thread starts running.
*
* Note that only user threads have privileged stacks and kernel
* only threads do not.
*/
(void)memset(&header->privilege_stack[0], 0xaa, sizeof(header->privilege_stack));
#endif
frame->bsa.pc = (uintptr_t)arch_user_mode_enter;
} else {
frame->bsa.pc = (uintptr_t)z_thread_entry;
@ -159,6 +143,30 @@ FUNC_NORETURN void arch_user_mode_enter(k_thread_entry_t user_entry,
struct k_thread *current = _current;
size_t stack_end;
struct xtensa_thread_stack_header *header =
(struct xtensa_thread_stack_header *)current->stack_obj;
current->arch.psp = header->privilege_stack +
sizeof(header->privilege_stack);
#ifdef CONFIG_INIT_STACKS
/* setup_thread_stack() does not initialize the architecture specific
* privileged stack. So we need to do it manually here as this function
* is called by arch_new_thread() via z_setup_new_thread() after
* setup_thread_stack() but before thread starts running.
*
* Note that only user threads have privileged stacks and kernel
* only threads do not.
*/
(void)memset(&header->privilege_stack[0], 0xaa, sizeof(header->privilege_stack));
#endif
#ifdef CONFIG_KERNEL_COHERENCE
sys_cache_data_flush_and_invd_range(&header->privilege_stack[0],
sizeof(header->privilege_stack));
#endif
/* Transition will reset stack pointer to initial, discarding
* any old context since this is a one-way operation
*/