static int test_full_cspace(env_t env) { int error; seL4_CPtr cnode[CONFIG_WORD_SIZE]; seL4_CPtr ep = vka_alloc_endpoint_leaky(&env->vka); seL4_Word ep_pos = 1; /* Create 32 or 64 cnodes, each resolving one bit. */ for (unsigned int i = 0; i < CONFIG_WORD_SIZE; i++) { cnode[i] = vka_alloc_cnode_object_leaky(&env->vka, 1); assert(cnode[i]); } /* Copy cnode i to alternating slots in cnode i-1. */ seL4_Word slot = 0; for (unsigned int i = 1; i < CONFIG_WORD_SIZE; i++) { error = seL4_CNode_Copy( cnode[i - 1], slot, 1, env->cspace_root, cnode[i], seL4_WordBits, seL4_AllRights); test_assert(!error); ep_pos |= (slot << i); slot ^= 1; } /* In the final cnode, put an IPC endpoint in slot 1. */ error = seL4_CNode_Copy( cnode[CONFIG_WORD_SIZE - 1], slot, 1, env->cspace_root, ep, seL4_WordBits, seL4_AllRights); test_assert(!error); /* Start a helper thread in our own cspace, to let it get set up. */ helper_thread_t t; create_helper_thread(env, &t); start_helper(env, &t, ipc_caller, ep, ep_pos, CONFIG_WORD_SIZE, 0); /* Wait for it. */ seL4_MessageInfo_t tag; seL4_Word sender_badge = 0; tag = seL4_Recv(ep, &sender_badge); test_assert(seL4_MessageInfo_get_length(tag) == 1); test_assert(seL4_GetMR(0) == READY_MAGIC); /* Now switch its cspace. */ error = seL4_TCB_SetSpace(t.thread.tcb.cptr, t.fault_endpoint, cnode[0], seL4_NilData, env->page_directory, seL4_NilData); test_assert(!error); /* And now wait for it to do some tests and return to us. */ tag = seL4_Recv(ep, &sender_badge); test_assert(seL4_MessageInfo_get_length(tag) == 1); test_assert(seL4_GetMR(0) == SUCCESS_MAGIC); cleanup_helper(env, &t); return sel4test_get_result(); }
static int test_iopt_map_remap_pt(env_t env) { int error; iopt_cptrs_t pts; seL4_CPtr iospace, frame; error = map_iopt_set(env, &iospace, &pts, &frame); test_eq(error, seL4_NoError); /* unmap the pt */ error = seL4_X86_IOPageTable_Unmap(pts.pts[pts.depth - 1]); test_eq(error, seL4_NoError); /* now map it back in */ error = seL4_X86_IOPageTable_Map(pts.pts[pts.depth - 1], iospace, IOPT_MAP_BASE); test_eq(error, seL4_NoError); /* it should retain its old mappings, and mapping in a new frame should fail */ frame = vka_alloc_frame_leaky(&env->vka, seL4_PageBits); test_assert(frame); error = seL4_X86_Page_MapIO(frame, iospace, seL4_AllRights, IOPT_MAP_BASE); test_assert(error != seL4_NoError); delete_iospace(env, iospace); return sel4test_get_result(); }
static int test_iopt_map_remap_top_pt(env_t env) { int error; iopt_cptrs_t pts; seL4_CPtr iospace, frame, pt; error = map_iopt_set(env, &iospace, &pts, &frame); test_eq(error, seL4_NoError); /* unmap the top PT */ error = seL4_X86_IOPageTable_Unmap(pts.pts[EXPECTED_PT_DEPTH]); test_eq(error, seL4_NoError); /* now map it back in */ error = seL4_X86_IOPageTable_Map(pts.pts[EXPECTED_PT_DEPTH], iospace, IOPT_MAP_BASE); test_eq(error, seL4_NoError); /* it should retain its old mappings, and mapping in a new PT should fail */ pt = vka_alloc_io_page_table_leaky(&env->vka); test_assert(pt); error = seL4_X86_IOPageTable_Map(pt, iospace, IOPT_MAP_BASE); test_assert(error != seL4_NoError); delete_iospace(env, iospace); return sel4test_get_result(); }
static int test_cnode_mutate(env_t env) { int error; seL4_Word src, dest; /* A call that should succeed. */ src = get_cap(&env->vka); dest = get_free_slot(env); error = cnode_mutate(env, src, dest); test_assert(!error); test_assert(is_slot_empty(env, src)); test_assert(!is_slot_empty(env, dest)); /* Mutating to an occupied slot (should fail). */ src = get_cap(&env->vka); dest = get_cap(&env->vka); error = cnode_mutate(env, src, dest); test_assert(error == seL4_DeleteFirst); test_assert(!is_slot_empty(env, src)); test_assert(!is_slot_empty(env, dest)); /* Mutating an empty slot (should fail). */ src = get_free_slot(env); dest = get_free_slot(env); error = cnode_mutate(env, src, dest); test_assert(error == seL4_FailedLookup); test_assert(is_slot_empty(env, src)); test_assert(is_slot_empty(env, dest)); return sel4test_get_result(); }
static int test_iopt_map_remap_pt(env_t env) { int error; int i; seL4_CPtr iospace, pt, frame; seL4_SlotRegion caps = env->io_space_caps; int cap_count = caps.end - caps.start + 1; for (i = 0; i < cap_count; i++) { iospace = caps.start + i; error = map_iopt_set(env, iospace, &pt, &frame); test_eq(error, seL4_NoError); /* unmap the PT */ error = seL4_ARM_IOPageTable_Unmap(pt); test_eq(error, seL4_NoError); /* now map it back in */ error = seL4_ARM_IOPageTable_Map(pt, iospace, IOPT_MAP_BASE); test_eq(error, seL4_NoError); /* it should retain its old mappings, and mapping in a new PT should fail */ pt = vka_alloc_io_page_table_leaky(&env->vka); test_assert(pt); error = seL4_ARM_IOPageTable_Map(pt, iospace, IOPT_MAP_BASE); test_assert(error != seL4_NoError); delete_iospace(env, iospace); } return sel4test_get_result(); }
static int test_iopt_basic_map_unmap(env_t env) { int error; int i; iopt_cptrs_t pts; seL4_CPtr iospace, frame; error = map_iopt_set(env, &iospace, &pts, &frame); test_eq(error, seL4_NoError); error = seL4_X86_Page_Unmap(frame); test_eq(error, seL4_NoError); for (i = pts.depth - 1; i >= 0; i--) { error = seL4_X86_IOPageTable_Unmap(pts.pts[i]); test_eq(error, seL4_NoError); } error = map_iopt_from_iospace(env, iospace, &pts, &frame); test_eq(error, seL4_NoError); for (i = 0; i < pts.depth; i++) { error = seL4_X86_IOPageTable_Unmap(pts.pts[i]); test_eq(error, seL4_NoError); } error = seL4_X86_Page_Unmap(frame); test_eq(error, seL4_NoError); delete_iospace(env, iospace); return sel4test_get_result(); }
static int test_iopt_basic_map_unmap(env_t env) { int error; int i; seL4_CPtr iospace, pt, frame; seL4_SlotRegion caps = env->io_space_caps; int cap_count = caps.end - caps.start + 1; for (i = 0; i < cap_count; i++) { iospace = caps.start + i; error = map_iopt_set(env, iospace, &pt, &frame); test_eq(error, seL4_NoError); error = seL4_ARM_Page_Unmap(frame); test_eq(error, seL4_NoError); error = seL4_ARM_IOPageTable_Unmap(pt); test_eq(error, seL4_NoError); error = map_iopt_from_iospace(env, iospace, &pt, &frame); test_eq(error, seL4_NoError); error = seL4_ARM_IOPageTable_Unmap(pt); test_eq(error, seL4_NoError); error = seL4_ARM_Page_Unmap(frame); test_eq(error, seL4_NoError); delete_iospace(env, iospace); } return sel4test_get_result(); }
static int test_cnode_mint(env_t env) { int error; seL4_Word src, dest; /* A call that should succeed. */ src = get_cap(&env->vka); dest = get_free_slot(env); error = cnode_mint(env, src, dest, seL4_AllRights, seL4_NilData); test_assert(!error); test_assert(!are_tcbs_distinct(src, dest)); /* Mint to an occupied slot (should fail). */ src = get_cap(&env->vka); dest = get_cap(&env->vka); error = cnode_mint(env, src, dest, seL4_AllRights, seL4_NilData); test_assert(error == seL4_DeleteFirst); test_assert(are_tcbs_distinct(src, dest)); /* Mint from an empty slot (should fail). */ src = get_free_slot(env); dest = get_free_slot(env); error = cnode_mint(env, src, dest, seL4_AllRights, seL4_NilData); test_assert(error == seL4_FailedLookup); test_assert(are_tcbs_distinct(src, dest)); return sel4test_get_result(); }
static int ipc_caller(seL4_Word ep0, seL4_Word ep1, seL4_Word word_bits, seL4_Word arg4) { /* Let our parent know we are ready. */ seL4_MessageInfo_t tag = seL4_MessageInfo_new(0, 0, 0, 1); seL4_SetMR(0, READY_MAGIC); seL4_Send(ep0, tag); /* * The parent has changed our cspace on us. Check that it makes sense. * * Basically the entire cspace should be empty except for the cap at ep0. * We should still test that various points in the cspace resolve correctly. */ /* Check that none of the typical endpoints are valid. */ for (unsigned long i = 0; i < word_bits; i++) { seL4_MessageInfo_ptr_new(&tag, 0, 0, 0, 0); tag = seL4_Call(i, tag); test_assert(seL4_MessageInfo_get_label(tag) == seL4_InvalidCapability); } /* Check that changing one bit still gives an invalid cap. */ for (unsigned long i = 0; i < word_bits; i++) { seL4_MessageInfo_ptr_new(&tag, 0, 0, 0, 0); tag = seL4_Call(ep1 ^ BIT(i), tag); test_assert(seL4_MessageInfo_get_label(tag) == seL4_InvalidCapability); } /* And we're done. This should be a valid cap and get us out of here! */ seL4_MessageInfo_ptr_new(&tag, 0, 0, 0, 1); seL4_SetMR(0, SUCCESS_MAGIC); seL4_Send(ep1, tag); return sel4test_get_result(); }
static int suspend_test_helper_2a(seL4_CPtr *t1, seL4_CPtr *t2a, seL4_CPtr *t2b) { /* Helper function that runs at a higher priority. */ /* Start here. */ CHECK_STEP(suspend_test_step, 0); /* Wait for a timer tick to make 2b run. */ while (suspend_test_step == 1) /* spin */{ ; } /* Suspend helper 2b. */ int error = seL4_TCB_Suspend(*t2b); test_check(!error); CHECK_STEP(suspend_test_step, 2); /* Now suspend ourselves, passing control to the low priority process to * resume 2b. */ error = seL4_TCB_Suspend(*t2a); test_check(!error); return sel4test_get_result(); }
/* The enclosed test relies on the current thread being able to create two * threads of unequal priority, both less than the caller's own priority. For * this we need at least 3 priority levels, assuming that the current thread is * running at the highest priority. */ static int test_set_priority(struct env* env) { helper_thread_t thread1; helper_thread_t thread2; ZF_LOGD("test_set_priority starting\n"); create_helper_thread(env, &thread1); set_helper_priority(&thread1, SCHED0005_HIGHEST_PRIO); create_helper_thread(env, &thread2); set_helper_priority(&thread2, SCHED0005_HIGHEST_PRIO - 1); set_priority_step = 0; ZF_LOGD(" "); start_helper(env, &thread1, (helper_fn_t) set_priority_helper_1, (seL4_Word) &thread1.thread.tcb.cptr, (seL4_Word) &thread2.thread.tcb.cptr, 0, 0); start_helper(env, &thread2, (helper_fn_t) set_priority_helper_2, (seL4_Word) &thread1.thread.tcb.cptr, (seL4_Word) &thread2.thread.tcb.cptr, 0, 0); wait_for_helper(&thread1); wait_for_helper(&thread2); test_check(set_priority_step == 4); ZF_LOGD("\n"); cleanup_helper(env, &thread1); cleanup_helper(env, &thread2); return sel4test_get_result(); }
static int test_suspend(struct env* env) { helper_thread_t thread1; helper_thread_t thread2a; helper_thread_t thread2b; ZF_LOGD("Starting test_suspend\n"); create_helper_thread(env, &thread1); ZF_LOGD("Show me\n"); create_helper_thread(env, &thread2a); create_helper_thread(env, &thread2b); /* First set all the helper threads to have unique priorities * and then start them in order of priority. This is so when * the 'start_helper' function does an IPC to the helper * thread, it doesn't allow one of the already started helper * threads to run at all */ set_helper_priority(&thread1, 0); set_helper_priority(&thread2a, 1); set_helper_priority(&thread2b, 2); start_helper(env, &thread1, (helper_fn_t) suspend_test_helper_1, (seL4_Word) &thread1.thread.tcb.cptr, (seL4_Word) &thread2a.thread.tcb.cptr, (seL4_Word) &thread2b.thread.tcb.cptr, 0); start_helper(env, &thread2a, (helper_fn_t) suspend_test_helper_2a, (seL4_Word) &thread1.thread.tcb.cptr, (seL4_Word) &thread2a.thread.tcb.cptr, (seL4_Word) &thread2b.thread.tcb.cptr, 0); start_helper(env, &thread2b, (helper_fn_t) suspend_test_helper_2b, (seL4_Word) &thread1.thread.tcb.cptr, (seL4_Word) &thread2a.thread.tcb.cptr, (seL4_Word) &thread2b.thread.tcb.cptr, 0); /* Now set their priorities to what we want */ set_helper_priority(&thread1, 100); set_helper_priority(&thread2a, 101); set_helper_priority(&thread2b, 101); suspend_test_step = 0; ZF_LOGD(" "); wait_for_helper(&thread1); wait_for_helper(&thread2b); CHECK_STEP(suspend_test_step, 6); ZF_LOGD("\n"); cleanup_helper(env, &thread1); cleanup_helper(env, &thread2a); cleanup_helper(env, &thread2b); return sel4test_get_result(); }
/* * Test that thread suspending works when idling the system. * Note: This test non-deterministically fails. If you find only this test * try re-running the test suite. */ static int test_thread_suspend(env_t env) { helper_thread_t t1; volatile seL4_Word counter; ZF_LOGD("test_thread_suspend\n"); create_helper_thread(env, &t1); set_helper_priority(&t1, 100); start_helper(env, &t1, (helper_fn_t) counter_func, (seL4_Word) &counter, 0, 0, 0); timer_periodic(env->timer->timer, 10 * NS_IN_MS); timer_start(env->timer->timer); sel4_timer_handle_single_irq(env->timer); seL4_Word old_counter; /* Let the counter thread run. We might have a pending interrupt, so * wait twice. */ wait_for_timer_interrupt(env); wait_for_timer_interrupt(env); old_counter = counter; /* Let it run again. */ wait_for_timer_interrupt(env); /* Now, counter should have moved. */ test_check(counter != old_counter); old_counter = counter; /* Suspend the thread, and wait again. */ seL4_TCB_Suspend(t1.thread.tcb.cptr); wait_for_timer_interrupt(env); /* Counter should not have moved. */ test_check(counter == old_counter); old_counter = counter; /* Check once more for good measure. */ wait_for_timer_interrupt(env); /* Counter should not have moved. */ test_check(counter == old_counter); old_counter = counter; /* Resume the thread and check it does move. */ seL4_TCB_Resume(t1.thread.tcb.cptr); wait_for_timer_interrupt(env); test_check(counter != old_counter); /* Done. */ timer_stop(env->timer->timer); sel4_timer_handle_single_irq(env->timer); cleanup_helper(env, &t1); return sel4test_get_result(); }
static int test_cnode_rotate(env_t env) { int error; seL4_Word src, pivot, dest; /* A call that should succeed. */ src = get_cap(&env->vka); pivot = get_cap(&env->vka); dest = get_free_slot(env); error = cnode_rotate(env, src, pivot, dest); test_assert(!error); test_assert(is_slot_empty(env, src)); test_assert(!is_slot_empty(env, pivot)); test_assert(!is_slot_empty(env, dest)); /* Destination occupied (should fail). */ src = get_cap(&env->vka); pivot = get_cap(&env->vka); dest = get_cap(&env->vka); error = cnode_rotate(env, src, pivot, dest); test_assert(error == seL4_DeleteFirst); test_assert(!is_slot_empty(env, src)); test_assert(!is_slot_empty(env, pivot)); test_assert(!is_slot_empty(env, dest)); /* Swapping two caps (should succeed). */ src = get_cap(&env->vka); pivot = get_cap(&env->vka); dest = src; error = cnode_rotate(env, src, pivot, dest); test_assert(!error); test_assert(!are_tcbs_distinct(src, dest)); test_assert(!is_slot_empty(env, pivot)); /* Moving a cap onto itself (should fail). */ src = get_cap(&env->vka); pivot = src; dest = get_free_slot(env); error = cnode_rotate(env, src, pivot, dest); test_assert(error == seL4_IllegalOperation); test_assert(!is_slot_empty(env, src)); test_assert(is_slot_empty(env, dest)); /* Moving empty slots (should fail). */ src = get_free_slot(env); pivot = get_free_slot(env); dest = get_free_slot(env); error = cnode_rotate(env, src, pivot, dest); test_assert(error == seL4_FailedLookup); test_assert(is_slot_empty(env, src)); test_assert(is_slot_empty(env, pivot)); test_assert(is_slot_empty(env, dest)); return sel4test_get_result(); }
/* * Test TCB Resume on self. */ static int test_resume_self(struct env* env) { ZF_LOGD("Starting test_resume_self\n"); /* Ensure nothing bad happens if we resume ourselves. */ int error = seL4_TCB_Resume(env->tcb); test_assert(!error); ZF_LOGD("Ending test_resume_self\n"); return sel4test_get_result(); }
static int test_iopt_basic_iopt(env_t env) { int error; seL4_CPtr iospace, frame; iopt_cptrs_t pts; error = map_iopt_set(env, &iospace, &pts, &frame); test_eq(error, seL4_NoError); delete_iospace(env, iospace); return sel4test_get_result(); }
/* * Test setting priorities. */ static int test_set_priorities(struct env* env) { /* Ensure we can set our priority equal to ourselves. */ int error = seL4_TCB_SetPriority(env->tcb, OUR_PRIO); test_assert(!error); /* Ensure we can set a different thread's priority equal to ourselves. */ seL4_CPtr tcb = vka_alloc_tcb_leaky(&env->vka); error = seL4_TCB_SetPriority(tcb, OUR_PRIO); test_assert(!error); return sel4test_get_result(); }
static int ep_test_func(seL4_CPtr sync_ep, seL4_CPtr test_ep, volatile seL4_Word *status, seL4_Word arg4) { seL4_MessageInfo_t tag = seL4_MessageInfo_new(0, 0, 0, 0); seL4_Word sender_badge; while (1) { seL4_Recv(sync_ep, &sender_badge); /* Hit up the test end point */ seL4_MessageInfo_t reply = seL4_Call(test_ep, tag); /* See what the status was */ *status = !!(seL4_MessageInfo_get_label(reply) != seL4_InvalidCapability); /* Reply */ seL4_Reply(tag); } return sel4test_get_result(); }
int test_allocator(env_t env) { /* Perform a bunch of allocations and frees */ vka_object_t endpoint; int error; for (int i = 0; i < MIN_EXPECTED_ALLOCATIONS; i++) { error = vka_alloc_endpoint(&env->vka, &endpoint); test_assert(error == 0); test_assert(endpoint.cptr != 0); vka_free_object(&env->vka, &endpoint); } return sel4test_get_result(); }
int test_timer(driver_env_t env) { int error = ltimer_set_timeout(&env->timer.ltimer, 1 * NS_IN_S, TIMEOUT_PERIODIC); test_assert_fatal(!error); for (int i = 0; i < 3; i++) { wait_for_timer_interrupt(env); ZF_LOGV("Tick\n"); } error = ltimer_reset(&env->timer.ltimer); test_assert_fatal(!error); return sel4test_get_result(); }
int test_tcb_null_cspace_setspace(env_t env) { helper_thread_t thread; int error; create_helper_thread(env, &thread); /* This should fail because we're passing an invalid CSpace cap. */ error = seL4_TCB_SetSpace(thread.thread.tcb.cptr, 0, seL4_CapNull, seL4_CapData_Guard_new(0, 0), env->page_directory, seL4_CapData_Guard_new(0, 0)); cleanup_helper(env, &thread); return error ? sel4test_get_result() : FAILURE; }
static int test_iopt_no_overlapping_4k(env_t env) { int error; iopt_cptrs_t pts; seL4_CPtr iospace, frame; error = map_iopt_set(env, &iospace, &pts, &frame); test_eq(error, seL4_NoError); frame = vka_alloc_frame_leaky(&env->vka, seL4_PageBits); test_assert(frame); error = seL4_X86_Page_MapIO(frame, iospace, seL4_AllRights, IOPT_MAP_BASE); test_assert(error != seL4_NoError); delete_iospace(env, iospace); return sel4test_get_result(); }
static int test_iopt_basic_iopt(env_t env) { int error; seL4_CPtr pt = 0; seL4_CPtr frame = 0; seL4_SlotRegion caps = env->io_space_caps; int cap_count = caps.end - caps.start + 1; seL4_CPtr cap = caps.start; for (int i = 0; i < cap_count; i++) { error = map_iopt_set(env, cap + i, &pt, &frame); test_eq(error, seL4_NoError); delete_iospace(env, cap + i); } return sel4test_get_result(); }
static int test_all_priorities(struct env* env) { int i; helper_thread_t **threads = (helper_thread_t **) malloc(sizeof(helper_thread_t*) * NUM_PRIOS); assert(threads != NULL); for (i = 0; i < NUM_PRIOS; i++) { threads[i] = (helper_thread_t*) malloc(sizeof(helper_thread_t)); assert(threads[i]); } vka_t *vka = &env->vka; ZF_LOGD("Testing all thread priorities"); volatile seL4_Word last_prio = MAX_PRIO + 1; seL4_CPtr ep = vka_alloc_endpoint_leaky(vka); for (int prio = MIN_PRIO; prio <= MAX_PRIO; prio++) { int idx = prio - MIN_PRIO; test_check(idx >= 0 && idx < NUM_PRIOS); create_helper_thread(env, threads[idx]); set_helper_priority(threads[idx], prio); start_helper(env, threads[idx], (helper_fn_t) prio_test_func, prio, (seL4_Word) &last_prio, ep, 0); } /* Now block. */ seL4_Word sender_badge = 0; seL4_Recv(ep, &sender_badge); /* When we get woken up, last_prio should be MIN_PRIO. */ test_check(last_prio == MIN_PRIO); for (int prio = MIN_PRIO; prio <= MAX_PRIO; prio++) { int idx = prio - MIN_PRIO; cleanup_helper(env, threads[idx]); free(threads[idx]); } free(threads); return sel4test_get_result(); }
static int test_interrupt(env_t env) { int error = timer_periodic(env->timer->timer, 10 * NS_IN_MS); timer_start(env->timer->timer); sel4_timer_handle_single_irq(env->timer); test_check(error == 0); for (int i = 0; i < 3; i++) { wait_for_timer_interrupt(env); } timer_stop(env->timer->timer); sel4_timer_handle_single_irq(env->timer); return sel4test_get_result(); }
static int test_iopt_no_overlapping_pt(env_t env) { int error; iopt_cptrs_t pts; seL4_CPtr iospace, frame, pt; error = map_iopt_set(env, &iospace, &pts, &frame); test_eq(error, seL4_NoError); /* Mapping in a new PT should fail */ pt = vka_alloc_io_page_table_leaky(&env->vka); test_assert(pt); error = seL4_X86_IOPageTable_Map(pt, iospace, IOPT_MAP_BASE); test_assert(error != seL4_NoError); delete_iospace(env, iospace); return sel4test_get_result(); }
static int test_cnode_recycle(env_t env) { int error; seL4_Word slot; /* A call that should succeed. */ slot = get_cap(&env->vka); error = cnode_recycle(env, slot); test_assert(!error); test_assert(!is_slot_empty(env, slot)); /* Recycling an empty slot (should fail). */ slot = get_free_slot(env); error = cnode_recycle(env, slot); test_assert(error == seL4_IllegalOperation); test_assert(is_slot_empty(env, slot)); return sel4test_get_result(); }
static int test_cnode_revoke(env_t env) { int error; seL4_Word slot; /* A call that should succeed. */ slot = get_cap(&env->vka); error = cnode_revoke(env, slot); test_assert(!error); test_assert(!is_slot_empty(env, slot)); /* Revoking a null cap (should fail). */ slot = get_free_slot(env); error = cnode_revoke(env, slot); test_assert(!error); test_assert(is_slot_empty(env, slot)); return sel4test_get_result(); }
static int test_cnode_delete(env_t env) { int error; seL4_Word slot; /* A call that should succeed. */ slot = get_cap(&env->vka); error = cnode_delete(env, slot); test_assert(!error); test_assert(is_slot_empty(env, slot)); /* Deleting a free slot (should succeed). */ slot = get_free_slot(env); error = cnode_delete(env, slot); test_assert(!error); test_assert(is_slot_empty(env, slot)); return sel4test_get_result(); }
static int test_cnode_savecaller(env_t env) { int error; seL4_Word slot; /* A call that should succeed. */ slot = get_free_slot(env); error = cnode_savecaller(env, slot); test_assert(!error); /* Save to an occupied slot (should fail). */ slot = get_cap(&env->vka); error = cnode_savecaller(env, slot); test_assert(error == seL4_DeleteFirst); test_assert(!is_slot_empty(env, slot)); /* TODO: Test saving an actual reply capability. */ return sel4test_get_result(); }