Esempio n. 1
0
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;
}
Esempio n. 2
0
int
sel4utils_map_page(vka_t *vka, seL4_CPtr pd, seL4_CPtr frame, void *vaddr,
                   seL4_CapRights rights, int cacheable, vka_object_t *objects, int *num_objects)
{
    assert(vka != NULL);
    assert(pd != 0);
    assert(frame != 0);
    assert(vaddr != 0);
    assert(rights != 0);
    assert(num_objects);

    seL4_ARCH_VMAttributes attr = 0;
    int num = 0;

#ifdef CONFIG_ARCH_IA32
    if (!cacheable) {
        attr = seL4_IA32_CacheDisabled;
    }
#elif CONFIG_ARCH_ARM /* CONFIG_ARCH_IA32 */
    if (cacheable) {
        attr = seL4_ARM_PageCacheable;
    }
#endif /* CONFIG_ARCH_ARM */
    int error = seL4_ARCH_Page_Map(frame, pd, (seL4_Word) vaddr, rights, attr);

#ifdef CONFIG_X86_64

page_map_retry:

    if (error == seL4_FailedLookupPDPT) {
        error = vka_alloc_page_directory_pointer_table(vka, pagetable);
        if (!error) {
            error = seL4_ARCH_PageDirectoryPointerTable_Map(pagetable->cptr, pd, (seL4_Word)vaddr,
                                                            seL4_ARCH_Default_VMAttributes);
        } else {
            LOG_ERROR("Page directory pointer table allocation failed %d", error);
        }

        if (!error) {
            error = seL4_ARCH_Page_Map(frame, pd, (seL4_Word)vaddr, rights, attr);
            if (error != seL4_NoError) {
                goto page_map_retry;
            }
        } else {
            LOG_ERROR("Page directory pointer table mapping failed %d\n", error);
        }
    }

    if (error == seL4_FailedLookupPD) {
        error = vka_alloc_page_directory(vka, pagetable);
        if (!error) {
            error = seL4_ARCH_PageDirectory_Map(pagetable->cptr, pd, (seL4_Word)vaddr,
                                                seL4_ARCH_Default_VMAttributes);
        } else {
            LOG_ERROR("Page direcotry allocation failed %d\n", error);
        }

        if (!error) {
            error = seL4_ARCH_Page_Map(frame, pd, (seL4_Word)vaddr, rights, attr);
            if (error != seL4_NoError) {
                goto page_map_retry;
            }

        } else {
            LOG_ERROR("Page directory mapping failed %d\n", error);
        }
    }

#endif

    if (error == seL4_FailedLookup) {
        /* need a page table, allocate one */
        assert(objects != NULL);
        assert(*num_objects > 0);
        error = vka_alloc_page_table(vka, &objects[0]);

        /* map in the page table */
        if (!error) {
            error = seL4_ARCH_PageTable_Map(objects[0].cptr, pd, (seL4_Word) vaddr,
                                            seL4_ARCH_Default_VMAttributes);
        } else {
            LOG_ERROR("Page table allocation failed, %d", error);
        }

        if (error == seL4_DeleteFirst) {
            /* It's possible that in allocated the page table, we needed to allocate/map
             * in some memory, which caused a page table to get mapped in at the
             * same location we are wanting one. If this has happened then we can just
             * delete this page table and try the frame mapping again */
            vka_free_object(vka, &objects[0]);
            error = seL4_NoError;
        } else {
            num = 1;
        }
#ifdef CONFIG_PAE_PAGING
        if (error == seL4_FailedLookup) {
            /* need a page directory, allocate one */
            assert(*num_objects > 1);
            error = vka_alloc_page_directory(vka, &objects[1]);
            if (!error) {
                error = seL4_IA32_PageDirectory_Map(objects[1].cptr, pd, (seL4_Word) vaddr,
                                                    seL4_ARCH_Default_VMAttributes);
            } else {
                LOG_ERROR("Page directory allocation failed, %d", error);
            }
            if (error == seL4_DeleteFirst) {
                vka_free_object(vka, &objects[1]);
                error = seL4_NoError;
            } else {
                num = 2;
            }
            if (!error) {
                error = seL4_ARCH_PageTable_Map(objects[0].cptr, pd, (seL4_Word) vaddr,
                                                seL4_ARCH_Default_VMAttributes);
            } else {
                LOG_ERROR("Page directory mapping failed, %d", error);
            }
        }
#endif
        /* now try mapping the frame in again if nothing else went wrong */
        if (!error) {
            error = seL4_ARCH_Page_Map(frame, pd, (seL4_Word) vaddr, rights, attr);
        } else {
            LOG_ERROR("Page table mapping failed, %d", error);
        }
    }

    if (error != seL4_NoError) {
        LOG_ERROR("Failed to map page at address %p with cap %"PRIuPTR", error: %d", vaddr, frame, error);
    }
    *num_objects = num;

    return error;
}