Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions kernel/userspace.c
Original file line number Diff line number Diff line change
Expand Up @@ -760,15 +760,15 @@ static u32_t handler_bad_syscall(u32_t bad_id, u32_t arg2, u32_t arg3,
{
printk("Bad system call id %u invoked\n", bad_id);
z_arch_syscall_oops(ssf);
CODE_UNREACHABLE;
CODE_UNREACHABLE; /* LCOV_EXCL_LINE */
}

static u32_t handler_no_syscall(u32_t arg1, u32_t arg2, u32_t arg3,
u32_t arg4, u32_t arg5, u32_t arg6, void *ssf)
{
printk("Unimplemented system call\n");
z_arch_syscall_oops(ssf);
CODE_UNREACHABLE;
CODE_UNREACHABLE; /* LCOV_EXCL_LINE */
}

#include <syscall_dispatch.c>
Expand Down
51 changes: 50 additions & 1 deletion tests/kernel/mem_protect/userspace/src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -1085,6 +1085,52 @@ void test_stack_buffer(void)

}

void z_impl_missing_syscall(void)
{
/* Shouldn't ever get here; no handler function compiled */
k_panic();
}

void test_unimplemented_syscall(void)
{
expect_fault = true;
expected_reason = REASON_KERNEL_OOPS;

missing_syscall();
}

void test_bad_syscall(void)
{
expect_fault = true;
expected_reason = REASON_KERNEL_OOPS;

z_arch_syscall_invoke0(INT_MAX);

}

static struct k_sem recycle_sem;


void test_object_recycle(void)
{
struct _k_object *ko;
int perms_count = 0;

ko = z_object_find(&recycle_sem);
(void)memset(ko->perms, 0xFF, sizeof(ko->perms));

z_object_recycle(&recycle_sem);
zassert_true(ko != NULL, "kernel object not found");
zassert_true(ko->flags & K_OBJ_FLAG_INITIALIZED,
"object wasn't marked as initialized");

for (int i = 0; i < CONFIG_MAX_THREAD_BYTES; i++) {
perms_count += popcount(ko->perms[i]);
}

zassert_true(perms_count == 1, "invalid number of thread permissions");
}

void test_main(void)
{
struct k_mem_partition *parts[] = {&part0, &part1,
Expand Down Expand Up @@ -1135,7 +1181,10 @@ void test_main(void)
ztest_unit_test(domain_add_part_context_switch),
ztest_unit_test(domain_remove_part_context_switch),
ztest_unit_test(domain_remove_thread_context_switch),
ztest_unit_test(test_stack_buffer)
ztest_unit_test(test_stack_buffer),
ztest_user_unit_test(test_unimplemented_syscall),
ztest_user_unit_test(test_bad_syscall),
ztest_unit_test(test_object_recycle)
);
ztest_run_test_suite(userspace);
}
1 change: 1 addition & 0 deletions tests/kernel/mem_protect/userspace/src/test_syscall.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

__syscall void stack_info_get(u32_t *start_addr, u32_t *size);
__syscall int check_perms(void *addr, size_t size, int write);
__syscall void missing_syscall(void);

#include <syscalls/test_syscall.h>

Expand Down
2 changes: 1 addition & 1 deletion tests/kernel/threads/dynamic_thread/prj.conf
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
CONFIG_ZTEST=y
CONFIG_TEST_USERSPACE=y
CONFIG_HEAP_MEM_POOL_SIZE=2048
CONFIG_HEAP_MEM_POOL_SIZE=4096
64 changes: 47 additions & 17 deletions tests/kernel/threads/dynamic_thread/src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,6 @@

#define STACKSIZE (256 + CONFIG_TEST_EXTRA_STACKSIZE)

#if defined(CONFIG_USERSPACE) && defined(CONFIG_DYNAMIC_OBJECTS)

static K_THREAD_STACK_DEFINE(dyn_thread_stack, STACKSIZE);
static K_SEM_DEFINE(start_sem, 0, 1);
static K_SEM_DEFINE(end_sem, 0, 1);
Expand Down Expand Up @@ -106,25 +104,56 @@ static void test_dyn_thread_perms(void)
TC_PRINT("===== must have access denied on k_sem %p\n", &end_sem);
}

#else /* (CONFIG_USERSPACE && CONFIG_DYNAMIC_OBJECTS) */
static struct k_thread *dynamic_threads[CONFIG_MAX_THREAD_BYTES * 8];

static void prep(void)
static void test_thread_index_management(void)
{
}
int i, ctr = 0;

static void create_dynamic_thread(void)
{
TC_PRINT("Test skipped. Userspace and dynamic objects required.\n");
ztest_test_skip();
}
/* Create thread objects until we run out of ids */
while (true) {
struct k_thread *t = k_object_alloc(K_OBJ_THREAD);

static void test_dyn_thread_perms(void)
{
TC_PRINT("Test skipped. Userspace and dynamic objects required.\n");
ztest_test_skip();
}
if (t == NULL) {
break;
}

#endif /* !(CONFIG_USERSPACE && CONFIG_DYNAMIC_OBJECTS) */
dynamic_threads[ctr] = t;
ctr++;
}

zassert_true(ctr != 0, "unable to create any thread objects");

TC_PRINT("created %d thread objects\n", ctr);

/* Show that the above NULL return value wasn't because we ran out of
* heap space/
*/
void *blob = k_malloc(256);
zassert_true(blob != NULL, "out of heap memory");

/* Free one of the threads... */
k_object_free(dynamic_threads[0]);

/* And show that we can now create another one, the freed thread's
* index should have been garbage collected.
*/
dynamic_threads[0] = k_object_alloc(K_OBJ_THREAD);
zassert_true(dynamic_threads[0] != NULL,
"couldn't create thread object\n");

/* TODO: Implement a test that shows that thread IDs are properly
* recycled when a thread object is garbage collected due to references
* dropping to zero. For example, we ought to be able to exit here
* without calling k_object_free() on any of the threads we created
* here; their references would drop to zero and they would be
* automatically freed. However, it is known that the thread IDs are
* not properly recycled when this happens, see #17023.
*/
for (i = 0; i < ctr; i++) {
k_object_free(dynamic_threads[i]);
}
}

/**
* @ingroup kernel_thread_tests
Expand Down Expand Up @@ -160,7 +189,8 @@ void test_main(void)
ztest_test_suite(thread_dynamic,
ztest_unit_test(test_kernel_create_dyn_user_thread),
ztest_user_unit_test(test_user_create_dyn_user_thread),
ztest_unit_test(test_dyn_thread_perms)
ztest_unit_test(test_dyn_thread_perms),
ztest_unit_test(test_thread_index_management)
);
ztest_run_test_suite(thread_dynamic);
}
1 change: 1 addition & 0 deletions tests/kernel/threads/dynamic_thread/testcase.yaml
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
tests:
kernel.threads.dynamic:
tags: kernel threads userspace ignore_faults
filter: CONFIG_ARCH_HAS_USERSPACE