arch: arc: put the init context into privileged stack

as the thread is created in privileged mode, the init
context should also be in privileged stack.

Signed-off-by: Wayne Ren <wei.ren@synopsys.com>
This commit is contained in:
Wayne Ren 2018-08-20 22:39:39 +08:00 committed by Anas Nashif
commit eab5ff725d
3 changed files with 47 additions and 28 deletions

View file

@ -164,15 +164,6 @@ _swap_return_from_coop:
pop_s blink /* pc into blink */
#ifdef CONFIG_ARC_HAS_SECURE
pop_s r3 /* pop SEC_STAT */
#endif
pop_s r2 /* status32 into r2 */
/*
* the above pop may happen in the unprivileged stack, but now it's
* kernel mode, the write to status32/sec_stat before pop may cause
* stack check fail.
*/
kflag r2 /* write status32 */
#ifdef CONFIG_ARC_HAS_SECURE
/* sflag r3 */
/* sflag instruction is not supported in current ARC GNU */
.long 0x00ff302f
@ -182,6 +173,9 @@ _swap_return_from_coop:
#endif
return_loc:
pop_s r3 /* status32 into r3 */
kflag r3 /* write status32 */
j_s.d [blink] /* always execute delay slot */
seti r1 /* delay slot */

View file

@ -88,6 +88,23 @@ void _new_thread(struct k_thread *thread, k_thread_stack_t *stack,
(u32_t)(stackEnd + STACK_GUARD_SIZE);
thread->arch.priv_stack_size =
(u32_t)(CONFIG_PRIVILEGED_STACK_SIZE);
stackAdjEnd = (char *)STACK_ROUND_DOWN(stackEnd + STACK_GUARD_SIZE +
CONFIG_PRIVILEGED_STACK_SIZE);
/* reserve 4 bytes for the start of user sp */
stackAdjEnd -= 4;
(*(u32_t *)stackAdjEnd) = (u32_t)stackEnd;
#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));
/* update the start of user sp */
(*(u32_t *)stackAdjEnd) = (u32_t) thread->userspace_local_data;
#endif
} else {
/* for kernel thread, the privilege stack is merged into thread stack */
/* if MPU_STACK_GUARD is enabled, reserve the the stack area
@ -105,32 +122,31 @@ void _new_thread(struct k_thread *thread, k_thread_stack_t *stack,
thread->arch.priv_stack_start = 0;
thread->arch.priv_stack_size = 0;
stackAdjEnd = (char *)STACK_ROUND_DOWN(stackEnd);
#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));
thread->userspace_local_data =
(struct _thread_userspace_local_data *)stackAdjEnd;
#endif
}
_new_thread_init(thread, pStackMem, stackSize, priority, options);
stackAdjEnd = stackEnd;
#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));
thread->userspace_local_data =
(struct _thread_userspace_local_data *)stackAdjEnd;
#endif
/* carve the thread entry struct from the "base" of
the user stack */
the privileged stack */
pInitCtx = (struct init_stack_frame *)(
STACK_ROUND_DOWN(stackAdjEnd) -
sizeof(struct init_stack_frame));
stackAdjEnd - sizeof(struct init_stack_frame));
/* fill init context */
pInitCtx->status32 = 0;
if (options & K_USER) {
/* through exception return to user mode */
pInitCtx->status32 = _ARC_V2_STATUS32_AE;
pInitCtx->pc = ((u32_t)_user_thread_entry_wrapper);
} else {
pInitCtx->status32 = 0;
pInitCtx->pc = ((u32_t)_thread_entry_wrapper);
}

View file

@ -53,14 +53,24 @@ GTEXT(z_arch_user_string_nlen_fault_end)
GTEXT(z_arch_user_string_nlen_fixup)
/*
* @brief Wrapper for _thread_entry in the case of user thread
* The init parameters are in privileged stack
*
* @return N/A
*/
SECTION_FUNC(TEXT, _user_thread_entry_wrapper)
/* sp the user stack pointer, r0-r4 are in stack */
mov r5, sp
/* start of privilege stack */
add blink, r5, CONFIG_PRIVILEGED_STACK_SIZE+STACK_GUARD_SIZE+16
pop_s r3
pop_s r2
pop_s r1
pop_s r0
/* the start of user sp is in r5 */
pop r5
/* start of privilege stack in blink */
mov blink, sp
st.aw r0, [r5, -4]
st.aw r1, [r5, -4]
st.aw r2, [r5, -4]
st.aw r3, [r5, -4]
/*
* when CONFIG_INIT_STACKS is enable, stack will be initialized
@ -140,7 +150,6 @@ _clear_user_stack:
_arc_go_to_user_space:
lr r0, [_ARC_V2_STATUS32]
bset r0, r0, _ARC_V2_STATUS32_U_BIT
bclr r0, r0, _ARC_V2_STATUS32_AE_BIT
mov r1, _thread_entry_wrapper