Skip to content

Commit eab5ff7

Browse files
Wayne Rennashif
authored andcommitted
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 <[email protected]>
1 parent fa9fb83 commit eab5ff7

File tree

3 files changed

+47
-28
lines changed

3 files changed

+47
-28
lines changed

arch/arc/core/swap.S

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -164,15 +164,6 @@ _swap_return_from_coop:
164164
pop_s blink /* pc into blink */
165165
#ifdef CONFIG_ARC_HAS_SECURE
166166
pop_s r3 /* pop SEC_STAT */
167-
#endif
168-
pop_s r2 /* status32 into r2 */
169-
/*
170-
* the above pop may happen in the unprivileged stack, but now it's
171-
* kernel mode, the write to status32/sec_stat before pop may cause
172-
* stack check fail.
173-
*/
174-
kflag r2 /* write status32 */
175-
#ifdef CONFIG_ARC_HAS_SECURE
176167
/* sflag r3 */
177168
/* sflag instruction is not supported in current ARC GNU */
178169
.long 0x00ff302f
@@ -182,6 +173,9 @@ _swap_return_from_coop:
182173
#endif
183174
return_loc:
184175

176+
pop_s r3 /* status32 into r3 */
177+
kflag r3 /* write status32 */
178+
185179
j_s.d [blink] /* always execute delay slot */
186180
seti r1 /* delay slot */
187181

arch/arc/core/thread.c

Lines changed: 30 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,23 @@ void _new_thread(struct k_thread *thread, k_thread_stack_t *stack,
8888
(u32_t)(stackEnd + STACK_GUARD_SIZE);
8989
thread->arch.priv_stack_size =
9090
(u32_t)(CONFIG_PRIVILEGED_STACK_SIZE);
91+
92+
stackAdjEnd = (char *)STACK_ROUND_DOWN(stackEnd + STACK_GUARD_SIZE +
93+
CONFIG_PRIVILEGED_STACK_SIZE);
94+
95+
/* reserve 4 bytes for the start of user sp */
96+
stackAdjEnd -= 4;
97+
(*(u32_t *)stackAdjEnd) = (u32_t)stackEnd;
98+
99+
#ifdef CONFIG_THREAD_USERSPACE_LOCAL_DATA
100+
/* reserve stack space for the userspace local data struct */
101+
thread->userspace_local_data =
102+
(struct _thread_userspace_local_data *)
103+
STACK_ROUND_DOWN(stackEnd - sizeof(*thread->userspace_local_data));
104+
/* update the start of user sp */
105+
(*(u32_t *)stackAdjEnd) = (u32_t) thread->userspace_local_data;
106+
#endif
107+
91108
} else {
92109
/* for kernel thread, the privilege stack is merged into thread stack */
93110
/* 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,
105122

106123
thread->arch.priv_stack_start = 0;
107124
thread->arch.priv_stack_size = 0;
125+
126+
stackAdjEnd = (char *)STACK_ROUND_DOWN(stackEnd);
127+
128+
#ifdef CONFIG_THREAD_USERSPACE_LOCAL_DATA
129+
/* reserve stack space for the userspace local data struct */
130+
stackAdjEnd = (char *)STACK_ROUND_DOWN(stackEnd
131+
- sizeof(*thread->userspace_local_data));
132+
thread->userspace_local_data =
133+
(struct _thread_userspace_local_data *)stackAdjEnd;
134+
#endif
108135
}
109136

110137
_new_thread_init(thread, pStackMem, stackSize, priority, options);
111138

112-
stackAdjEnd = stackEnd;
113139

114-
#ifdef CONFIG_THREAD_USERSPACE_LOCAL_DATA
115-
/* reserve stack space for the userspace local data struct */
116-
stackAdjEnd = (char *)STACK_ROUND_DOWN(stackEnd
117-
- sizeof(*thread->userspace_local_data));
118-
thread->userspace_local_data =
119-
(struct _thread_userspace_local_data *)stackAdjEnd;
120-
#endif
121140
/* carve the thread entry struct from the "base" of
122-
the user stack */
141+
the privileged stack */
123142
pInitCtx = (struct init_stack_frame *)(
124-
STACK_ROUND_DOWN(stackAdjEnd) -
125-
sizeof(struct init_stack_frame));
143+
stackAdjEnd - sizeof(struct init_stack_frame));
126144

127145
/* fill init context */
146+
pInitCtx->status32 = 0;
128147
if (options & K_USER) {
129-
/* through exception return to user mode */
130-
pInitCtx->status32 = _ARC_V2_STATUS32_AE;
131148
pInitCtx->pc = ((u32_t)_user_thread_entry_wrapper);
132149
} else {
133-
pInitCtx->status32 = 0;
134150
pInitCtx->pc = ((u32_t)_thread_entry_wrapper);
135151
}
136152

arch/arc/core/userspace.S

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -53,14 +53,24 @@ GTEXT(z_arch_user_string_nlen_fault_end)
5353
GTEXT(z_arch_user_string_nlen_fixup)
5454
/*
5555
* @brief Wrapper for _thread_entry in the case of user thread
56+
* The init parameters are in privileged stack
5657
*
5758
* @return N/A
5859
*/
5960
SECTION_FUNC(TEXT, _user_thread_entry_wrapper)
60-
/* sp the user stack pointer, r0-r4 are in stack */
61-
mov r5, sp
62-
/* start of privilege stack */
63-
add blink, r5, CONFIG_PRIVILEGED_STACK_SIZE+STACK_GUARD_SIZE+16
61+
pop_s r3
62+
pop_s r2
63+
pop_s r1
64+
pop_s r0
65+
/* the start of user sp is in r5 */
66+
pop r5
67+
/* start of privilege stack in blink */
68+
mov blink, sp
69+
70+
st.aw r0, [r5, -4]
71+
st.aw r1, [r5, -4]
72+
st.aw r2, [r5, -4]
73+
st.aw r3, [r5, -4]
6474

6575
/*
6676
* when CONFIG_INIT_STACKS is enable, stack will be initialized
@@ -140,7 +150,6 @@ _clear_user_stack:
140150
_arc_go_to_user_space:
141151
lr r0, [_ARC_V2_STATUS32]
142152
bset r0, r0, _ARC_V2_STATUS32_U_BIT
143-
bclr r0, r0, _ARC_V2_STATUS32_AE_BIT
144153

145154
mov r1, _thread_entry_wrapper
146155

0 commit comments

Comments
 (0)