|
9 | 9 |
|
10 | 10 | #define TIMEOUT_MS 500
|
11 | 11 |
|
12 |
| -#define POOL_SIZE 20480 |
| 12 | +#define POOL_SIZE 28672 |
13 | 13 |
|
14 | 14 | #ifdef CONFIG_USERSPACE
|
15 | 15 | #define STACK_OBJ_SIZE Z_THREAD_STACK_SIZE_ADJUST(CONFIG_DYNAMIC_THREAD_STACK_SIZE)
|
@@ -132,6 +132,103 @@ ZTEST(dynamic_thread_stack, test_dynamic_thread_stack_alloc)
|
132 | 132 | }
|
133 | 133 | }
|
134 | 134 |
|
| 135 | +K_SEM_DEFINE(perm_sem, 0, 1); |
| 136 | +ZTEST_BMEM static volatile bool expect_fault; |
| 137 | +ZTEST_BMEM static volatile unsigned int expected_reason; |
| 138 | + |
| 139 | +static void set_fault(unsigned int reason) |
| 140 | +{ |
| 141 | + expect_fault = true; |
| 142 | + expected_reason = reason; |
| 143 | + compiler_barrier(); |
| 144 | +} |
| 145 | + |
| 146 | +void k_sys_fatal_error_handler(unsigned int reason, const z_arch_esf_t *pEsf) |
| 147 | +{ |
| 148 | + if (expect_fault) { |
| 149 | + if (expected_reason == reason) { |
| 150 | + printk("System error was expected\n"); |
| 151 | + expect_fault = false; |
| 152 | + } else { |
| 153 | + printk("Wrong fault reason, expecting %d\n", |
| 154 | + expected_reason); |
| 155 | + TC_END_REPORT(TC_FAIL); |
| 156 | + k_fatal_halt(reason); |
| 157 | + } |
| 158 | + } else { |
| 159 | + printk("Unexpected fault during test\n"); |
| 160 | + TC_END_REPORT(TC_FAIL); |
| 161 | + k_fatal_halt(reason); |
| 162 | + } |
| 163 | +} |
| 164 | + |
| 165 | +static void perm_func(void *arg1, void *arg2, void *arg3) |
| 166 | +{ |
| 167 | + k_sem_take((struct k_sem *)arg1, K_FOREVER); |
| 168 | +} |
| 169 | + |
| 170 | +static void perm_func_violator(void *arg1, void *arg2, void *arg3) |
| 171 | +{ |
| 172 | + (void)k_thread_stack_free((k_thread_stack_t *)arg2); |
| 173 | + |
| 174 | + zassert_unreachable("should not reach here"); |
| 175 | +} |
| 176 | + |
| 177 | +/** @brief Exercise stack permissions */ |
| 178 | +ZTEST(dynamic_thread_stack, test_dynamic_thread_stack_permission) |
| 179 | +{ |
| 180 | + static k_tid_t tid[2]; |
| 181 | + static struct k_thread th[2]; |
| 182 | + static k_thread_stack_t *stack[2]; |
| 183 | + |
| 184 | + if (!IS_ENABLED(CONFIG_DYNAMIC_THREAD_PREFER_ALLOC)) { |
| 185 | + ztest_test_skip(); |
| 186 | + } |
| 187 | + |
| 188 | + if (!IS_ENABLED(CONFIG_DYNAMIC_THREAD_ALLOC)) { |
| 189 | + ztest_test_skip(); |
| 190 | + } |
| 191 | + |
| 192 | + if (!IS_ENABLED(CONFIG_USERSPACE)) { |
| 193 | + ztest_test_skip(); |
| 194 | + } |
| 195 | + |
| 196 | + stack[0] = k_thread_stack_alloc(CONFIG_DYNAMIC_THREAD_STACK_SIZE, K_USER); |
| 197 | + zassert_not_null(stack[0]); |
| 198 | + |
| 199 | + stack[1] = k_thread_stack_alloc(CONFIG_DYNAMIC_THREAD_STACK_SIZE, K_USER); |
| 200 | + zassert_not_null(stack[1]); |
| 201 | + |
| 202 | + k_thread_access_grant(k_current_get(), &perm_sem); |
| 203 | + |
| 204 | + /* First thread inherit permissions */ |
| 205 | + tid[0] = k_thread_create(&th[0], stack[0], CONFIG_DYNAMIC_THREAD_STACK_SIZE, perm_func, |
| 206 | + &perm_sem, NULL, NULL, 0, K_USER | K_INHERIT_PERMS, K_NO_WAIT); |
| 207 | + zassert_not_null(tid[0]); |
| 208 | + |
| 209 | + /* Second thread will have access to specific kobjects only */ |
| 210 | + tid[1] = k_thread_create(&th[1], stack[1], CONFIG_DYNAMIC_THREAD_STACK_SIZE, |
| 211 | + perm_func_violator, &perm_sem, stack[0], NULL, 0, K_USER, |
| 212 | + K_FOREVER); |
| 213 | + zassert_not_null(tid[1]); |
| 214 | + k_thread_access_grant(tid[1], &perm_sem); |
| 215 | + k_thread_access_grant(tid[1], &stack[1]); |
| 216 | + |
| 217 | + set_fault(K_ERR_KERNEL_OOPS); |
| 218 | + |
| 219 | + k_thread_start(tid[1]); |
| 220 | + |
| 221 | + /* join all threads and check that flags have been set */ |
| 222 | + zassert_ok(k_thread_join(tid[1], K_MSEC(TIMEOUT_MS))); |
| 223 | + |
| 224 | + k_sem_give(&perm_sem); |
| 225 | + zassert_ok(k_thread_join(tid[0], K_MSEC(TIMEOUT_MS))); |
| 226 | + |
| 227 | + /* clean up stacks allocated from the heap */ |
| 228 | + zassert_ok(k_thread_stack_free(stack[0])); |
| 229 | + zassert_ok(k_thread_stack_free(stack[1])); |
| 230 | +} |
| 231 | + |
135 | 232 | static void *dynamic_thread_stack_setup(void)
|
136 | 233 | {
|
137 | 234 | k_thread_heap_assign(k_current_get(), &stack_heap);
|
|
0 commit comments