/* Some more generic routines for helping with mapping */ void * sel4utils_dup_and_map(vka_t *vka, vspace_t *vspace, seL4_CPtr page, size_t size_bits) { int error; cspacepath_t page_path; cspacepath_t copy_path; void *mapping; /* First need to copy the cap */ error = vka_cspace_alloc_path(vka, ©_path); if (error != seL4_NoError) { return NULL; } vka_cspace_make_path(vka, page, &page_path); error = vka_cnode_copy(©_path, &page_path, seL4_AllRights); if (error != seL4_NoError) { vka_cspace_free(vka, copy_path.capPtr); return NULL; } /* Now map it in */ mapping = vspace_map_pages(vspace, ©_path.capPtr, NULL, seL4_AllRights, 1, size_bits, 1); if (!mapping) { vka_cnode_delete(©_path); vka_cspace_free(vka, copy_path.capPtr); return NULL; } return mapping; }
int cnode_copy(env_t env, seL4_CPtr src, seL4_CPtr dest, seL4_Word rights) { cspacepath_t src_path, dest_path; vka_cspace_make_path(&env->vka, src, &src_path); vka_cspace_make_path(&env->vka, dest, &dest_path); return vka_cnode_copy(&dest_path, &src_path, rights); }
int vm_create(const char* name, int priority, seL4_CPtr vmm_endpoint, seL4_Word vm_badge, vka_t *vka, simple_t *simple, vspace_t *vmm_vspace, ps_io_ops_t* io_ops, vm_t* vm) { seL4_CapData_t null_cap_data = {{0}}; seL4_CapData_t cspace_root_data; cspacepath_t src, dst; int err; vm->name = name; vm->ndevices = 0; vm->onode_head = NULL; vm->entry_point = NULL; vm->vka = vka; vm->simple = simple; vm->vmm_vspace = vmm_vspace; vm->io_ops = io_ops; vm->vchan_num_cons = 0; vm->vchan_cons = NULL; /* Create a cspace */ err = vka_alloc_cnode_object(vka, VM_CSPACE_SIZE_BITS, &vm->cspace); assert(!err); vka_cspace_make_path(vka, vm->cspace.cptr, &src); cspace_root_data = seL4_CapData_Guard_new(0, 32 - VM_CSPACE_SIZE_BITS); dst.root = vm->cspace.cptr; dst.capPtr = VM_CSPACE_SLOT; dst.capDepth = VM_CSPACE_SIZE_BITS; err = vka_cnode_mint(&dst, &src, seL4_AllRights, cspace_root_data); assert(!err); /* Create a vspace */ err = vka_alloc_page_directory(vka, &vm->pd); assert(!err); err = simple_ASIDPool_assign(simple, vm->pd.cptr); assert(err == seL4_NoError); err = sel4utils_get_vspace(vmm_vspace, &vm->vm_vspace, &vm->data, vka, vm->pd.cptr, &vm_object_allocation_cb, (void*)vm); assert(!err); /* Badge the endpoint */ vka_cspace_make_path(vka, vmm_endpoint, &src); err = vka_cspace_alloc_path(vka, &dst); assert(!err); err = vka_cnode_mint(&dst, &src, seL4_AllRights, seL4_CapData_Badge_new(vm_badge)); assert(!err); /* Copy it to the cspace of the VM for fault IPC */ src = dst; dst.root = vm->cspace.cptr; dst.capPtr = VM_FAULT_EP_SLOT; dst.capDepth = VM_CSPACE_SIZE_BITS; err = vka_cnode_copy(&dst, &src, seL4_AllRights); assert(!err); /* Create TCB */ err = vka_alloc_tcb(vka, &vm->tcb); assert(!err); err = seL4_TCB_Configure(vm_get_tcb(vm), VM_FAULT_EP_SLOT, priority - 1, vm->cspace.cptr, cspace_root_data, vm->pd.cptr, null_cap_data, 0, seL4_CapNull); assert(!err); /* Create VCPU */ err = vka_alloc_vcpu(vka, &vm->vcpu); assert(!err); err = seL4_ARM_VCPU_SetTCB(vm->vcpu.cptr, vm_get_tcb(vm)); assert(!err); /* Initialise fault system */ vm->fault = fault_init(vm); assert(vm->fault); return err; }
/* allocate lots of untyped memory for tests to use */ num_untypeds = populate_untypeds(untypeds); /* create a frame that will act as the init data, we can then map that * in to target processes */ env.init = (test_init_data_t *) vspace_new_pages(&env.vspace, seL4_AllRights, 1, PAGE_BITS_4K); assert(env.init != NULL); /* copy the cap to map into the remote process */ cspacepath_t src, dest; vka_cspace_make_path(&env.vka, vspace_get_cap(&env.vspace, env.init), &src); UNUSED int error = vka_cspace_alloc(&env.vka, &env.init_frame_cap_copy); assert(error == 0); vka_cspace_make_path(&env.vka, env.init_frame_cap_copy, &dest); error = vka_cnode_copy(&dest, &src, seL4_AllRights); assert(error == 0); /* copy the untyped size bits list across to the init frame */ memcpy(env.init->untyped_size_bits_list, untyped_size_bits_list, sizeof(uint8_t) * num_untypeds); /* parse elf region data about the test image to pass to the tests app */ num_elf_regions = sel4utils_elf_num_regions(TESTS_APP); assert(num_elf_regions < MAX_REGIONS); sel4utils_elf_reserve(NULL, TESTS_APP, elf_regions); /* copy the region list for the process to clone itself */ memcpy(env.init->elf_regions, elf_regions, sizeof(sel4utils_elf_region_t) * num_elf_regions); env.init->num_elf_regions = num_elf_regions; /* get the caps we need to send to tests to set up a timer */