tests: dynamic_thread_stack: Check thread stack permission
Check if a user thread is capable of free another thread stack. Signed-off-by: Flavio Ceolin <flavio.ceolin@intel.com>
This commit is contained in:
parent
c12f0507b6
commit
95dde52b1e
1 changed files with 98 additions and 1 deletions
|
@ -9,7 +9,7 @@
|
||||||
|
|
||||||
#define TIMEOUT_MS 500
|
#define TIMEOUT_MS 500
|
||||||
|
|
||||||
#define POOL_SIZE 20480
|
#define POOL_SIZE 28672
|
||||||
|
|
||||||
#ifdef CONFIG_USERSPACE
|
#ifdef CONFIG_USERSPACE
|
||||||
#define STACK_OBJ_SIZE K_THREAD_STACK_LEN(CONFIG_DYNAMIC_THREAD_STACK_SIZE)
|
#define STACK_OBJ_SIZE K_THREAD_STACK_LEN(CONFIG_DYNAMIC_THREAD_STACK_SIZE)
|
||||||
|
@ -168,6 +168,103 @@ ZTEST(dynamic_thread_stack, test_dynamic_thread_stack_alloc)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
K_SEM_DEFINE(perm_sem, 0, 1);
|
||||||
|
ZTEST_BMEM static volatile bool expect_fault;
|
||||||
|
ZTEST_BMEM static volatile unsigned int expected_reason;
|
||||||
|
|
||||||
|
static void set_fault(unsigned int reason)
|
||||||
|
{
|
||||||
|
expect_fault = true;
|
||||||
|
expected_reason = reason;
|
||||||
|
compiler_barrier();
|
||||||
|
}
|
||||||
|
|
||||||
|
void k_sys_fatal_error_handler(unsigned int reason, const z_arch_esf_t *pEsf)
|
||||||
|
{
|
||||||
|
if (expect_fault) {
|
||||||
|
if (expected_reason == reason) {
|
||||||
|
printk("System error was expected\n");
|
||||||
|
expect_fault = false;
|
||||||
|
} else {
|
||||||
|
printk("Wrong fault reason, expecting %d\n",
|
||||||
|
expected_reason);
|
||||||
|
TC_END_REPORT(TC_FAIL);
|
||||||
|
k_fatal_halt(reason);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
printk("Unexpected fault during test\n");
|
||||||
|
TC_END_REPORT(TC_FAIL);
|
||||||
|
k_fatal_halt(reason);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void perm_func(void *arg1, void *arg2, void *arg3)
|
||||||
|
{
|
||||||
|
k_sem_take((struct k_sem *)arg1, K_FOREVER);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void perm_func_violator(void *arg1, void *arg2, void *arg3)
|
||||||
|
{
|
||||||
|
(void)k_thread_stack_free((k_thread_stack_t *)arg2);
|
||||||
|
|
||||||
|
zassert_unreachable("should not reach here");
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @brief Exercise stack permissions */
|
||||||
|
ZTEST(dynamic_thread_stack, test_dynamic_thread_stack_permission)
|
||||||
|
{
|
||||||
|
static k_tid_t tid[2];
|
||||||
|
static struct k_thread th[2];
|
||||||
|
static k_thread_stack_t *stack[2];
|
||||||
|
|
||||||
|
if (!IS_ENABLED(CONFIG_DYNAMIC_THREAD_PREFER_ALLOC)) {
|
||||||
|
ztest_test_skip();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!IS_ENABLED(CONFIG_DYNAMIC_THREAD_ALLOC)) {
|
||||||
|
ztest_test_skip();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!IS_ENABLED(CONFIG_USERSPACE)) {
|
||||||
|
ztest_test_skip();
|
||||||
|
}
|
||||||
|
|
||||||
|
stack[0] = k_thread_stack_alloc(CONFIG_DYNAMIC_THREAD_STACK_SIZE, K_USER);
|
||||||
|
zassert_not_null(stack[0]);
|
||||||
|
|
||||||
|
stack[1] = k_thread_stack_alloc(CONFIG_DYNAMIC_THREAD_STACK_SIZE, K_USER);
|
||||||
|
zassert_not_null(stack[1]);
|
||||||
|
|
||||||
|
k_thread_access_grant(k_current_get(), &perm_sem);
|
||||||
|
|
||||||
|
/* First thread inherit permissions */
|
||||||
|
tid[0] = k_thread_create(&th[0], stack[0], CONFIG_DYNAMIC_THREAD_STACK_SIZE, perm_func,
|
||||||
|
&perm_sem, NULL, NULL, 0, K_USER | K_INHERIT_PERMS, K_NO_WAIT);
|
||||||
|
zassert_not_null(tid[0]);
|
||||||
|
|
||||||
|
/* Second thread will have access to specific kobjects only */
|
||||||
|
tid[1] = k_thread_create(&th[1], stack[1], CONFIG_DYNAMIC_THREAD_STACK_SIZE,
|
||||||
|
perm_func_violator, &perm_sem, stack[0], NULL, 0, K_USER,
|
||||||
|
K_FOREVER);
|
||||||
|
zassert_not_null(tid[1]);
|
||||||
|
k_thread_access_grant(tid[1], &perm_sem);
|
||||||
|
k_thread_access_grant(tid[1], &stack[1]);
|
||||||
|
|
||||||
|
set_fault(K_ERR_KERNEL_OOPS);
|
||||||
|
|
||||||
|
k_thread_start(tid[1]);
|
||||||
|
|
||||||
|
/* join all threads and check that flags have been set */
|
||||||
|
zassert_ok(k_thread_join(tid[1], K_MSEC(TIMEOUT_MS)));
|
||||||
|
|
||||||
|
k_sem_give(&perm_sem);
|
||||||
|
zassert_ok(k_thread_join(tid[0], K_MSEC(TIMEOUT_MS)));
|
||||||
|
|
||||||
|
/* clean up stacks allocated from the heap */
|
||||||
|
zassert_ok(k_thread_stack_free(stack[0]));
|
||||||
|
zassert_ok(k_thread_stack_free(stack[1]));
|
||||||
|
}
|
||||||
|
|
||||||
static void *dynamic_thread_stack_setup(void)
|
static void *dynamic_thread_stack_setup(void)
|
||||||
{
|
{
|
||||||
k_thread_heap_assign(k_current_get(), &stack_heap);
|
k_thread_heap_assign(k_current_get(), &stack_heap);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue