Skip to content

Commit

Permalink
riscv: drop user stack guard area when using separate privileged stacks
Browse files Browse the repository at this point in the history
A separate privileged stack is used when CONFIG_GEN_PRIV_STACKS=y. The
main stack guard area is no longer needed and can be made available to
the application upon transitioning to user mode. And that's actually
required if we want a naturally aligned power-of-two buffer to let the
PMP map a NAPOT entry on it which is the whole point of having this
CONFIG_PMP_POWER_OF_TWO_ALIGNMENT option in the first place.

Signed-off-by: Nicolas Pitre <[email protected]>
  • Loading branch information
Nicolas Pitre authored and carlescufi committed May 18, 2022
1 parent 6051ea7 commit 92409f3
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 1 deletion.
3 changes: 3 additions & 0 deletions arch/riscv/core/thread.c
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,9 @@ FUNC_NORETURN void arch_user_mode_enter(k_thread_entry_t user_entry,
#ifdef CONFIG_GEN_PRIV_STACKS
_current->arch.priv_stack_start =
(ulong_t)z_priv_stack_find(_current->stack_obj);
/* remove the stack guard from the main stack */
_current->stack_info.start -= K_THREAD_STACK_RESERVED;
_current->stack_info.size += K_THREAD_STACK_RESERVED;
#else
_current->arch.priv_stack_start = (ulong_t)_current->stack_obj;
#endif /* CONFIG_GEN_PRIV_STACKS */
Expand Down
17 changes: 16 additions & 1 deletion tests/kernel/threads/thread_stack/src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,8 @@ void stack_buffer_scenarios(void)
if (scenario_data.is_user) {
reserved = K_THREAD_STACK_RESERVED;
stack_buf = Z_THREAD_STACK_BUFFER(stack_obj);
alignment = Z_THREAD_STACK_OBJ_ALIGN(stack_size);
/* always use the original size here */
alignment = Z_THREAD_STACK_OBJ_ALIGN(STEST_STACKSIZE);
} else
#endif
{
Expand Down Expand Up @@ -191,6 +192,20 @@ void stack_buffer_scenarios(void)
zassert_true(check_perms(stack_end, 1, 0),
"user mode access to memory %p past end of stack object",
obj_end);

/*
* The reserved area, when it exists, is dropped at run time
* when transitioning to user mode on RISC-V. Reinstate that
* reserved area here for the next tests to work properly
* with a static non-zero K_THREAD_STACK_RESERVED definition.
*/
if (IS_ENABLED(CONFIG_RISCV) &&
IS_ENABLED(CONFIG_GEN_PRIV_STACKS) &&
K_THREAD_STACK_RESERVED != 0) {
stack_start += reserved;
stack_size -= reserved;
}

zassert_true(stack_size <= obj_size - reserved,
"bad stack size %zu in thread struct",
stack_size);
Expand Down

0 comments on commit 92409f3

Please sign in to comment.