kernel/userspace: Fix dynamic thread stack allocation at userspace

It wasn't saving adjusted stack size at either the private stack or the
k_object, thus failing subsequent checks.

Test added to check for this case and prevent regressions.

Signed-off-by: Ederson de Souza <ederson.desouza@intel.com>
This commit is contained in:
Ederson de Souza 2024-02-15 20:31:50 -08:00 committed by Henrik Brix Andersen
commit 4440d6a189
3 changed files with 40 additions and 0 deletions

View file

@ -341,6 +341,7 @@ static struct k_object *dynamic_object_create(enum k_objects otype, size_t align
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)
dyn->kobj.name = (void *)ROUND_UP(
@ -351,6 +352,7 @@ static struct k_object *dynamic_object_create(enum k_objects otype, size_t align
#endif
#else
dyn->kobj.name = dyn->data;
dyn->kobj.data.stack_size = adjusted_size;
#endif
} else {
dyn->data = z_thread_aligned_alloc(align, obj_size_get(otype) + size);

View file

@ -10,3 +10,5 @@ CONFIG_MAIN_STACK_SIZE=2048
CONFIG_HW_STACK_PROTECTION=n
CONFIG_TEST_HW_STACK_PROTECTION=n
CONFIG_DYNAMIC_OBJECTS=y

View file

@ -35,6 +35,42 @@ static void func(void *arg1, void *arg2, void *arg3)
*flag = true;
}
/** @brief Check we can create a thread from userspace, using dynamic objects */
ZTEST_USER(dynamic_thread_stack, test_dynamic_thread_stack_userspace_dyn_obj)
{
k_tid_t tid;
struct k_thread *th;
k_thread_stack_t *stack;
if (!IS_ENABLED(CONFIG_USERSPACE)) {
ztest_test_skip();
}
if (!IS_ENABLED(CONFIG_DYNAMIC_THREAD_PREFER_ALLOC)) {
ztest_test_skip();
}
if (!IS_ENABLED(CONFIG_DYNAMIC_THREAD_ALLOC)) {
ztest_test_skip();
}
stack = k_thread_stack_alloc(CONFIG_DYNAMIC_THREAD_STACK_SIZE, K_USER);
zassert_not_null(stack);
th = k_object_alloc(K_OBJ_THREAD);
zassert_not_null(th);
tid = k_thread_create(th, stack, CONFIG_DYNAMIC_THREAD_STACK_SIZE, func,
&tflag[0], NULL, NULL, 0,
K_USER | K_INHERIT_PERMS, K_NO_WAIT);
zassert_not_null(tid);
zassert_ok(k_thread_join(tid, K_MSEC(TIMEOUT_MS)));
zassert_true(tflag[0]);
zassert_ok(k_thread_stack_free(stack));
}
/** @brief Exercise the pool-based thread stack allocator */
ZTEST(dynamic_thread_stack, test_dynamic_thread_stack_pool)
{