kernel/userspace: Dynamically allocate privileged stack after user stack

When ARM CONFIG_BUILTIN_STACK_GUARD=y, it expects that the privileged
stack has a higher memory address than that of the normal user stack.
However, dynamically allocated stacks had the other way round:
privileged stack had a lower memory address.

This was probably not caught before because relevant tests, such as
`kernel.threads.dynamic_thread.stack.pool.alloc.user` run with no
hardware stack protection. If one were to test it on HW that has stack
protection, such as frdm_mcxn947 with CONFIG_HW_STACK_PROTECTION=y, they
would see it failing.

This patch naively assumes that ARC and RISC-V PMP will be happy with
the shuffling of user and privileged stack positions.

Signed-off-by: Ederson de Souza <ederson.desouza@intel.com>
This commit is contained in:
Ederson de Souza
2025-11-04 11:05:43 -08:00
committed by Johan Hedberg
parent 1a52071392
commit d6071319b5

View File

@@ -347,16 +347,15 @@ static struct k_object *dynamic_object_create(enum k_objects otype, size_t align
#ifdef CONFIG_GEN_PRIV_STACKS
struct z_stack_data *stack_data = (struct z_stack_data *)
((uint8_t *)dyn->data + adjusted_size - sizeof(*stack_data));
stack_data->priv = (uint8_t *)dyn->data;
stack_data->size = adjusted_size;
dyn->kobj.data.stack_data = stack_data;
#if defined(CONFIG_ARM_MPU) || defined(CONFIG_ARC_MPU) || defined(CONFIG_RISCV_PMP)
dyn->kobj.name = (void *)ROUND_UP(
((uint8_t *)dyn->data + CONFIG_PRIVILEGED_STACK_SIZE),
stack_data->priv = (void *)ROUND_UP(((uint8_t *)dyn->data + size),
Z_THREAD_STACK_OBJ_ALIGN(size));
#else
dyn->kobj.name = dyn->data;
stack_data->priv = (uint8_t *)dyn->data;
#endif /* CONFIG_ARM_MPU || CONFIG_ARC_MPU || CONFIG_RISCV_PMP */
stack_data->size = adjusted_size;
dyn->kobj.data.stack_data = stack_data;
dyn->kobj.name = dyn->data;
#else
dyn->kobj.name = dyn->data;
dyn->kobj.data.stack_size = adjusted_size;