riscv: drop user stack guard area when using separate privileged stacks

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 <npitre@baylibre.com>
This commit is contained in:
Nicolas Pitre 2022-05-14 15:59:57 -04:00 committed by Carles Cufí
commit 92409f36de
2 changed files with 19 additions and 1 deletions

View file

@ -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 */

View file

@ -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
{
@ -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);