diff --git a/arch/arc/core/thread.c b/arch/arc/core/thread.c index c9041840fc8..9484af9b447 100644 --- a/arch/arc/core/thread.c +++ b/arch/arc/core/thread.c @@ -75,13 +75,21 @@ void z_new_thread(struct k_thread *thread, k_thread_stack_t *stack, struct init_stack_frame *pInitCtx; #if CONFIG_USERSPACE + + size_t stackAdjSize; + size_t offset = 0; + /* adjust stack and stack size */ #if CONFIG_ARC_MPU_VER == 2 - stackSize = POW2_CEIL(STACK_SIZE_ALIGN(stackSize)); + stackAdjSize = POW2_CEIL(STACK_SIZE_ALIGN(stackSize)); #elif CONFIG_ARC_MPU_VER == 3 - stackSize = ROUND_UP(stackSize, STACK_ALIGN); + stackAdjSize = ROUND_UP(stackSize, STACK_ALIGN); +#endif + stackEnd = pStackMem + stackAdjSize; + +#if CONFIG_STACK_POINTER_RANDOM + offset = stackAdjSize - stackSize; #endif - stackEnd = pStackMem + stackSize; if (options & K_USER) { thread->arch.priv_stack_start = @@ -92,13 +100,15 @@ void z_new_thread(struct k_thread *thread, k_thread_stack_t *stack, /* reserve 4 bytes for the start of user sp */ stackAdjEnd -= 4; - (*(u32_t *)stackAdjEnd) = (u32_t)stackEnd; + (*(u32_t *)stackAdjEnd) = STACK_ROUND_DOWN( + (u32_t)stackEnd - offset); #ifdef CONFIG_THREAD_USERSPACE_LOCAL_DATA /* reserve stack space for the userspace local data struct */ thread->userspace_local_data = (struct _thread_userspace_local_data *) - STACK_ROUND_DOWN(stackEnd - sizeof(*thread->userspace_local_data)); + STACK_ROUND_DOWN(stackEnd - + sizeof(*thread->userspace_local_data) - offset); /* update the start of user sp */ (*(u32_t *)stackAdjEnd) = (u32_t) thread->userspace_local_data; #endif @@ -115,7 +125,7 @@ void z_new_thread(struct k_thread *thread, k_thread_stack_t *stack, * --------------------------------------------- */ pStackMem += STACK_GUARD_SIZE; - stackSize = stackSize + CONFIG_PRIVILEGED_STACK_SIZE; + stackAdjSize = stackAdjSize + CONFIG_PRIVILEGED_STACK_SIZE; stackEnd += CONFIG_PRIVILEGED_STACK_SIZE + STACK_GUARD_SIZE; thread->arch.priv_stack_start = 0; @@ -123,15 +133,15 @@ void z_new_thread(struct k_thread *thread, k_thread_stack_t *stack, #ifdef CONFIG_THREAD_USERSPACE_LOCAL_DATA /* reserve stack space for the userspace local data struct */ stackAdjEnd = (char *)STACK_ROUND_DOWN(stackEnd - - sizeof(*thread->userspace_local_data)); + - sizeof(*thread->userspace_local_data) - offset); thread->userspace_local_data = (struct _thread_userspace_local_data *)stackAdjEnd; #else - stackAdjEnd = (char *)STACK_ROUND_DOWN(stackEnd); + stackAdjEnd = (char *)STACK_ROUND_DOWN(stackEnd - offset); #endif } - _new_thread_init(thread, pStackMem, stackSize, priority, options); + _new_thread_init(thread, pStackMem, stackAdjSize, priority, options); /* carve the thread entry struct from the "base" of