Esempio n. 1
0
static void
init_timer_caps(env_t env)
{
    /* get the timer irq cap */
    seL4_CPtr cap;
    UNUSED int error = vka_cspace_alloc(&env->vka, &cap);
    assert(error == 0);

    vka_cspace_make_path(&env->vka, cap, &env->irq_path);
    error = simple_get_IRQ_control(&env->simple, DEFAULT_TIMER_INTERRUPT, env->irq_path);
    assert(error == 0);

#ifdef CONFIG_ARCH_ARM
    /* get the timer frame cap */
    error = vka_cspace_alloc(&env->vka, &cap);
    assert(error == 0);

    vka_cspace_make_path(&env->vka, cap, &env->frame_path);
    error = simple_get_frame_cap(&env->simple, (void *) DEFAULT_TIMER_PADDR, PAGE_BITS_4K, &env->frame_path);
    assert(error == 0);
#elif CONFIG_ARCH_IA32
    env->io_port_cap = simple_get_IOPort_cap(&env->simple, PIT_IO_PORT_MIN, PIT_IO_PORT_MAX);
    assert(env->io_port_cap != 0);
#else
#error "Unknown architecture"
#endif
}
Esempio n. 2
0
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);
}
Esempio n. 3
0
int
cnode_move(env_t env, seL4_CPtr src, seL4_CPtr dest)
{
    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_move(&dest_path, &src_path);
}
Esempio n. 4
0
int
cnode_mint(env_t env, seL4_CPtr src, seL4_CPtr dest, seL4_Word rights, seL4_CapData_t badge)
{
    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_mint(&dest_path, &src_path, rights, badge);
}
Esempio n. 5
0
int
cnode_rotate(env_t env, seL4_CPtr src, seL4_CPtr pivot, seL4_CPtr dest)
{
    cspacepath_t src_path, dest_path, pivot_path;

    vka_cspace_make_path(&env->vka, src, &src_path);
    vka_cspace_make_path(&env->vka, dest, &dest_path);
    vka_cspace_make_path(&env->vka, pivot, &pivot_path);
    return vka_cnode_rotate(&dest_path, seL4_NilData, &pivot_path, seL4_NilData, &src_path);
}
Esempio n. 6
0
/*! \brief Call from external dataserver asking to be the content initialiser for this dataspace. */
refos_err_t
data_have_data_handler(void *rpc_userptr , seL4_CPtr rpc_dspace_fd , seL4_CPtr rpc_faultNotifyEP ,
                       uint32_t* rpc_dataID)
{
    struct proc_pcb *pcb = (struct proc_pcb*) rpc_userptr;
    struct procserv_msg *m = (struct procserv_msg*) pcb->rpcClient.userptr;
    assert(pcb && pcb->magic == REFOS_PCB_MAGIC);

    if (!(check_dispatch_caps(m, 0x00000001, 2) || check_dispatch_caps(m, 0x00000001, 1))) {
        return EINVALIDPARAM;
    }

    if (rpc_dataID) {
        (*rpc_dataID) = 0;
    }

    /* Verify and find the RAM dataspace. */
    if (!dispatcher_badge_dspace(rpc_dspace_fd)) {
        ROS_ERROR("EINVALIDPARAM: invalid RAM dataspace badge..\n");
        return EINVALIDPARAM;
    }
    struct ram_dspace *dspace = ram_dspace_get_badge(&procServ.dspaceList, rpc_dspace_fd);
    if (!dspace) {
        ROS_ERROR("EINVALIDPARAM: dataspace not found.\n");
        return EINVALIDPARAM;
    }

    /* Special case - no fault notify EP, means unset content-init mode. */
    if (!rpc_faultNotifyEP) {
        cspacepath_t path;
        vka_cspace_make_path(&procServ.vka, 0, &path);
        return ram_dspace_content_init(dspace, path, PID_NULL);
    }

    /* Copyout the content-init fault notify EP. */
    seL4_CPtr faultNotifyEP = dispatcher_copyout_cptr(rpc_faultNotifyEP);
    if (!faultNotifyEP) {
        dvprintf("could not copy out faultNotifyEP.");
        return EINVALIDPARAM; 
    }
    cspacepath_t path;
    vka_cspace_make_path(&procServ.vka, faultNotifyEP, &path);

    /* Initialise the dataspace content with given dataserver EP. */
    int error = ram_dspace_content_init(dspace, path, pcb->pid);
    if (error != ESUCCESS) {
        dispatcher_release_copyout_cptr(faultNotifyEP);
        return error;
    }

    if (rpc_dataID) {
        (*rpc_dataID) = dspace->ID;
    }
    return ESUCCESS;
}
Esempio n. 7
0
/* Binds and IRQ to an endpoint */
static seL4_CPtr
irq_bind(irq_t irq, seL4_CPtr notification_cap, int idx, vka_t* vka, simple_t *simple)
{
    seL4_CPtr irq_cap, bnotification_cap;
    cspacepath_t irq_path, notification_path, bnotification_path;
    seL4_CapData_t badge;
    int err;

    /* Create an IRQ cap */
    err = vka_cspace_alloc(vka, &irq_cap);
    if (err != 0) {
        ZF_LOGE("Failed to allocate cslot for irq\n");
        return seL4_CapNull;
    }
    vka_cspace_make_path(vka, irq_cap, &irq_path);
    err = simple_get_IRQ_control(simple, irq, irq_path);
    if (err != seL4_NoError) {
        ZF_LOGE("Failed to get cap to irq_number %d\n", irq);
        vka_cspace_free(vka, irq_cap);
        return seL4_CapNull;
    }
    /* Badge the provided endpoint. The bit position of the badge tells us the array
     * index of the associated IRQ data. */
    err = vka_cspace_alloc(vka, &bnotification_cap);
    if (err != 0) {
        ZF_LOGE("Failed to allocate cslot for irq\n");
        vka_cspace_free(vka, irq_cap);
        return seL4_CapNull;
    }
    vka_cspace_make_path(vka, notification_cap, &notification_path);
    vka_cspace_make_path(vka, bnotification_cap, &bnotification_path);
    badge = seL4_CapData_Badge_new(BIT(idx));
    err = vka_cnode_mint(&bnotification_path, &notification_path, seL4_AllRights, badge);
    if (err != seL4_NoError) {
        ZF_LOGE("Failed to badge IRQ notification endpoint\n");
        vka_cspace_free(vka, irq_cap);
        vka_cspace_free(vka, bnotification_cap);
        return seL4_CapNull;
    }
    /* bind the IRQ cap to our badged endpoint */
    err = seL4_IRQHandler_SetNotification(irq_cap, bnotification_cap);
    if (err != seL4_NoError) {
        ZF_LOGE("Failed to bind IRQ handler to notification\n");
        vka_cspace_free(vka, irq_cap);
        vka_cspace_free(vka, bnotification_cap);
        return seL4_CapNull;
    }
    /* Finally ACK any pending IRQ and enable the IRQ */
    seL4_IRQHandler_Ack(irq_cap);

    DIRQSERVER("Registered IRQ %d with badge 0x%lx\n", irq, BIT(idx));
    return irq_cap;
}
Esempio n. 8
0
static void make_proxy_vka(vka_t *vka, allocman_t *allocman) {
    int num = ram_num_untypeds();
    int error UNUSED;

    proxy_vka_t *proxy = &proxy_vka;
    memset(proxy, 0, sizeof(*proxy));
    proxy->allocman = allocman;
    allocman_make_vka(&proxy->regular_vka, allocman);

    utspace_trickle_create(&proxy->ram_ut_manager);
    for (int i = 0; i < num; i++) {
        cspacepath_t path;
        seL4_CPtr cap;
        uintptr_t paddr;
        int size_bits;
        ram_get_untyped(i, &paddr, &size_bits, &cap);
        vka_cspace_make_path(&proxy->regular_vka, cap, &path);
        error = _utspace_trickle_add_uts(allocman, &proxy->ram_ut_manager, 1, &path, (uint32_t*)&size_bits, &paddr);
        assert(!error);
    }
    if (num > 0) {
        proxy->have_mem = 1;
    }
    *vka = (vka_t) {
        proxy,
        proxy_vka_cspace_alloc,
        proxy_vka_cspace_make_path,
        proxy_vka_utspace_alloc,
        proxy_vka_cspace_free,
        proxy_vka_utspace_free,
        proxy_vka_utspace_paddr
    };
}
Esempio n. 9
0
File: iopt.c Progetto: seL4/sel4test
static void
delete_iospace(env_t env, seL4_CPtr iospace)
{
    cspacepath_t path;
    vka_cspace_make_path(&env->vka, iospace, &path);
    vka_cnode_delete(&path);
}
Esempio n. 10
0
File: vmm.c Progetto: seL4/seL4_libs
seL4_CPtr vmm_create_async_event_notification_cap(vmm_t *vmm, seL4_Word badge) {

    if (!(badge & BIT(27))) {
        ZF_LOGE("Invalid badge");
        return seL4_CapNull;
    }

    // notification cap
    seL4_CPtr ntfn = vmm->plat_callbacks.get_async_event_notification();

    // path to notification cap slot
    cspacepath_t ntfn_path = {};
    vka_cspace_make_path(&vmm->vka, ntfn, &ntfn_path);

    // allocate slot to store copy
    cspacepath_t minted_ntfn_path = {};
    vka_cspace_alloc_path(&vmm->vka, &minted_ntfn_path);

    // mint the notification cap
    seL4_CapData_t badge_data = seL4_CapData_Badge_new(badge);
    int error = vka_cnode_mint(&minted_ntfn_path, &ntfn_path, seL4_AllRights, badge_data);

    if (error != seL4_NoError) {
        ZF_LOGE("Failed to mint notification cap");
        return seL4_CapNull;
    }

    return minted_ntfn_path.capPtr;
}
Esempio n. 11
0
int
cnode_delete(env_t env, seL4_CPtr slot)
{
    cspacepath_t path;
    vka_cspace_make_path(&env->vka, slot, &path);
    return vka_cnode_delete(&path);
}
Esempio n. 12
0
int
cnode_savecaller(env_t env, seL4_CPtr cap)
{
    cspacepath_t path;
    vka_cspace_make_path(&env->vka, cap, &path);
    return vka_cnode_saveCaller(&path);
}
Esempio n. 13
0
int
cnode_revoke(env_t env, seL4_CPtr cap)
{
    cspacepath_t path;
    vka_cspace_make_path(&env->vka, cap, &path);
    return vka_cnode_revoke(&path);
}
Esempio n. 14
0
/* 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, &copy_path);
    if (error != seL4_NoError) {
        return NULL;
    }
    vka_cspace_make_path(vka, page, &page_path);
    error = vka_cnode_copy(&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, &copy_path.capPtr, NULL,  seL4_AllRights, 1, size_bits, 1);
    if (!mapping) {
        vka_cnode_delete(&copy_path);
        vka_cspace_free(vka, copy_path.capPtr);
        return NULL;
    }
    return mapping;
}
Esempio n. 15
0
/**
 * Start a thrd
 */
void thrd_start(thrd_env_t *env, thrd_t *thread, thrd_fn_t entry_point,
             seL4_Word arg0, seL4_Word arg1, seL4_Word arg2, seL4_Word arg3) {

    UNUSED int error;

    seL4_CPtr local_endpoint;

    if (thread->is_process) {
        /* copy the local endpoint */
        cspacepath_t path;
        vka_cspace_make_path(&env->vka, thread->local_endpoint.cptr, &path);
        local_endpoint = sel4utils_copy_cap_to_process(&thread->process, path);
    } else {
        local_endpoint = thread->local_endpoint.cptr;
    }

    /* If we are starting a process then the first two args are to get us
     * through the standard 'main' function and end up in invoke_thrd
     * if we are starting a regular thread then these will be ignored */
    create_args(thread->args_strings, thread->args, THRDS_TOTAL_ARGS,
        0, invoke_thrd, (seL4_Word) entry_point, local_endpoint,
        arg0, arg1, arg2, arg3);

    if (thread->is_process) {
        thread->process.entry_point = (void*)_start;
        thread->process.sysinfo = (uintptr_t)sel4_vsyscall;
        error = sel4utils_spawn_process_v(&thread->process, &env->vka, &env->vspace,
                                        THRDS_TOTAL_ARGS, thread->args, 1);
        assert(error == 0);
    } else {
        error = sel4utils_start_thread(&thread->thread, invoke_thrd,
                                       (void *) THRDS_TOTAL_ARGS, (void *) thread->args, 1);
        assert(error == 0);
    }
}
Esempio n. 16
0
File: main.c Progetto: BwRy/sel4test
static void
init_allocator(env_t env, test_init_data_t *init_data)
{
    UNUSED int error;
    UNUSED reservation_t virtual_reservation;

    /* initialise allocator */
    allocman_t *allocator = bootstrap_use_current_1level(init_data->root_cnode,
                                                         init_data->cspace_size_bits, init_data->free_slots.start,
                                                         init_data->free_slots.end, ALLOCATOR_STATIC_POOL_SIZE,
                                                         allocator_mem_pool);
    if (allocator == NULL) {
        ZF_LOGF("Failed to bootstrap allocator");
    }
    allocman_make_vka(&env->vka, allocator);

    /* fill the allocator with untypeds */
    seL4_CPtr slot;
    unsigned int size_bits_index;
    for (slot = init_data->untypeds.start, size_bits_index = 0;
            slot <= init_data->untypeds.end;
            slot++, size_bits_index++) {

        cspacepath_t path;
        vka_cspace_make_path(&env->vka, slot, &path);
        /* allocman doesn't require the paddr unless we need to ask for phys addresses,
         * which we don't. */
        uintptr_t fake_paddr = 0;
        size_t size_bits = init_data->untyped_size_bits_list[size_bits_index];
        error = allocman_utspace_add_uts(allocator, 1, &path, &size_bits, &fake_paddr);
        if (error) {
            ZF_LOGF("Failed to add untyped objects to allocator");
        }
    }

    /* create a vspace */
    void *existing_frames[init_data->stack_pages + 2];
    existing_frames[0] = (void *) init_data;
    existing_frames[1] = seL4_GetIPCBuffer();
    assert(init_data->stack_pages > 0);
    for (int i = 0; i < init_data->stack_pages; i++) {
        existing_frames[i + 2] = init_data->stack + (i * PAGE_SIZE_4K);
    }

    error = sel4utils_bootstrap_vspace(&env->vspace, &alloc_data, init_data->page_directory, &env->vka,                 NULL, NULL, existing_frames);

    /* switch the allocator to a virtual memory pool */
    void *vaddr;
    virtual_reservation = vspace_reserve_range(&env->vspace, ALLOCATOR_VIRTUAL_POOL_SIZE,
                                               seL4_AllRights, 1, &vaddr);
    if (virtual_reservation.res == 0) {
        ZF_LOGF("Failed to switch allocator to virtual memory pool");
    }

    bootstrap_configure_virtual_pool(allocator, vaddr, ALLOCATOR_VIRTUAL_POOL_SIZE,
                                     env->page_directory);

}
Esempio n. 17
0
static seL4_Error simple_frame_cap_wrapper(void *data, void *paddr, int size_bits, cspacepath_t *path) {
    seL4_CPtr cap = pci_devices_get_device_mem_frame((uintptr_t)paddr);
    if (cap != 0) {
        vka_cspace_make_path(&vka, cap, path);
        return 0;
    }

    /* Check whether it is a guest mapped region. */
    cap = guest_mappings_get_mapping_mem_frame((uintptr_t)paddr);
    if (cap != 0) {
        printf("Guest map found at 0x%x\n", paddr);
        vka_cspace_make_path(&vka, cap, path);
        return 0;
    }

    /* Else */
    return -1;
}
Esempio n. 18
0
File: iopt.c Progetto: seL4/sel4test
static int
map_iopt_set(env_t env, seL4_CPtr *iospace, iopt_cptrs_t *pts, seL4_CPtr *frame)
{
    int error;
    cspacepath_t master_path, iospace_path;

    /* Allocate a random device ID that hopefully doesn't exist have any
     * RMRR regions */
    error = vka_cspace_alloc(&env->vka, iospace);
    test_assert(!error);
    vka_cspace_make_path(&env->vka, *iospace, &iospace_path);
    vka_cspace_make_path(&env->vka, env->io_space, &master_path);
    error = vka_cnode_mint(&iospace_path, &master_path, seL4_AllRights,(DOMAIN_ID << 16) | FAKE_PCI_DEVICE);
    test_eq(error, seL4_NoError);

    error = map_iopt_from_iospace(env, *iospace, pts, frame);

    return error;
}
Esempio n. 19
0
static inline void
parent_ep_obj_to_cspath(cspacepath_t *result)
{
    if (result == NULL) {
        return;
    }
    vka_cspace_make_path(get_serial_server()->server_vka,
                         get_serial_server()->server_ep_obj.cptr,
                         result);
}
Esempio n. 20
0
File: thread.c Progetto: Zolok/refos
void
thread_release(struct proc_tcb *thread)
{
    assert(thread);
    assert(thread->vspaceRef);
    cspacepath_t path;
    vka_cspace_make_path(&procServ.vka, thread_tcb_obj(thread), &path);
    vka_cnode_revoke(&path);
    sel4utils_clean_up_thread(&procServ.vka, &thread->vspaceRef->vspace, &thread->sel4utilsThread);
    vs_unref(thread->vspaceRef);
    memset(thread, 0, sizeof(struct proc_tcb));
}
Esempio n. 21
0
/* copy a cap to a process, returning the cptr in the process' cspace */
static seL4_CPtr
copy_cap_to_process(sel4utils_process_t *process, seL4_CPtr cap)
{
    seL4_CPtr copied_cap;
    cspacepath_t path;

    vka_cspace_make_path(&env.vka, cap, &path);
    copied_cap = sel4utils_copy_cap_to_process(process, path);
    assert(copied_cap != 0);

    return copied_cap;
}
Esempio n. 22
0
void
sel4utils_unmap_pages(vspace_t *vspace, void *vaddr, size_t num_pages, size_t size_bits, vka_t *vka)
{
    uintptr_t v = (uintptr_t) vaddr;
    sel4utils_alloc_data_t *data = get_alloc_data(vspace);
    sel4utils_res_t *reserve = find_reserve(data, v);

    if (!sel4_valid_size_bits(size_bits)) {
        ZF_LOGE("Invalid size_bits %zu", size_bits);
        return;
    }

    if (vka == VSPACE_FREE) {
        vka = data->vka;
    }

    for (int i = 0; i < num_pages; i++) {
        seL4_CPtr cap = get_cap(data->top_level, v);

        /* unmap */
        if (cap != 0) {
            int error = seL4_ARCH_Page_Unmap(cap);
            if (error != seL4_NoError) {
                ZF_LOGE("Failed to unmap page at vaddr %p", vaddr);
            }
        }

        if (vka) {
            cspacepath_t path;
            vka_cspace_make_path(vka, cap, &path);
            vka_cnode_delete(&path);
            vka_cspace_free(vka, cap);
            if (sel4utils_get_cookie(vspace, vaddr)) {
                vka_utspace_free(vka, kobject_get_type(KOBJECT_FRAME, size_bits),
                                     size_bits, sel4utils_get_cookie(vspace, vaddr));
            }
        }

        if (reserve == NULL) {
            clear_entries(vspace, v, size_bits);
        } else {
            reserve_entries(vspace, v, size_bits);
        }
        assert(get_cap(data->top_level, v) != cap);
        assert(get_cookie(data->top_level, v) == 0);

        v += (1 << size_bits);
        vaddr = (void *) v;
    }
}
Esempio n. 23
0
int
vm_install_service(vm_t* vm, seL4_CPtr service, int index, uint32_t b)
{
    cspacepath_t src, dst;
    seL4_CapData_t badge;
    int err;
    badge = seL4_CapData_Badge_new(b);
    vka_cspace_make_path(vm->vka, service, &src);
    dst.root = vm->cspace.cptr;
    dst.capPtr = index;
    dst.capDepth = VM_CSPACE_SIZE_BITS;
    err =  vka_cnode_mint(&dst, &src, seL4_AllRights, badge);
    return err;
}
Esempio n. 24
0
void
sel4utils_unmap_dup(vka_t *vka, vspace_t *vspace, void *mapping, size_t size_bits)
{
    /* Grap a copy of the cap */
    seL4_CPtr copy = vspace_get_cap(vspace, mapping);
    cspacepath_t copy_path;
    assert(copy);
    /* now free the mapping */
    vspace_unmap_pages(vspace, mapping, 1, size_bits, VSPACE_PRESERVE);
    /* delete and free the cap */
    vka_cspace_make_path(vka, copy, &copy_path);
    vka_cnode_delete(&copy_path);
    vka_cspace_free(vka, copy);
}
Esempio n. 25
0
// creates IRQHandler cap "handler" for IRQ "irq"
static void
get_irqhandler_cap(int irq, cspacepath_t* handler)
{
    seL4_CPtr cap;
    // get a cspace slot
    UNUSED int err = vka_cspace_alloc(&vka, &cap);
    assert(err == 0);

    // convert allocated cptr to a cspacepath, for use in
    // operations such as Untyped_Retype
    vka_cspace_make_path(&vka, cap, handler);

    // exec seL4_IRQControl_Get(seL4_CapIRQControl, irq, ...)
    // to get an IRQHandler cap for IRQ "irq"
    err = simple_get_IRQ_control(&simple, irq, *handler);
    assert(err == 0);
}
Esempio n. 26
0
/*! @brief Handles server pager setup syscalls.

    A dataserver calls the process server with this call in order to set up to be the pager of
    one of its client processes for a particular window. The client process is identified by the
    passing of its liveliness cap. All faults for the client's process which happen at that window
    will then be delegated to the dataserver to be handled.
*/
refos_err_t
proc_register_as_pager_handler(void *rpc_userptr , seL4_CPtr rpc_window ,
                               seL4_CPtr rpc_faultNotifyEP , seL4_Word* rpc_winID) 
{
    struct proc_pcb *pcb = (struct proc_pcb*) rpc_userptr;
    struct procserv_msg *m = (struct procserv_msg*) pcb->rpcClient.userptr;
    assert(pcb && pcb->magic == REFOS_PCB_MAGIC);

    if (!check_dispatch_caps(m, 0x00000001, 2)) {
        return EINVALIDPARAM;
    }

    /* Retrieve and verify the window cap. */
    if (!dispatcher_badge_window(rpc_window)) {
        ROS_WARNING("Invalid window badge.");
        return EINVALIDPARAM;
    }
    struct w_window *win = w_get_window(&procServ.windowList, rpc_window - W_BADGE_BASE);
    if (!win) {
        ROS_ERROR("invalid window ID.");
        return EINVALIDPARAM;
    }
    assert(win->magic == W_MAGIC);

    /* Copy out the fault endpoint. */
    seL4_CPtr faultNotifyEP = dispatcher_copyout_cptr(rpc_faultNotifyEP);
    if (!faultNotifyEP) {
        dvprintf("could not copy out faultNotifyEP.");
        return EINVALIDPARAM; 
    }

    /* Set the pager endpoint. If there was anything else mapped to this window, it will be
       unmapped. */
    cspacepath_t faultNotifyEPPath;
    vka_cspace_make_path(&procServ.vka, faultNotifyEP, &faultNotifyEPPath);
    w_set_pager_endpoint(win, faultNotifyEPPath, pcb->pid);

    if (rpc_winID) {
        (*rpc_winID) = win->wID;
    }
    return ESUCCESS;
}
Esempio n. 27
0
int
serial_server_client_connect(seL4_CPtr badged_server_ep_cap,
                             vka_t *client_vka, vspace_t *client_vspace,
                             serial_client_context_t *conn)
{
    seL4_Error error;
    int shmem_n_pages;
    uintptr_t shmem_tmp_vaddr;
    seL4_MessageInfo_t tag;
    cspacepath_t frame_cspath;

    if (badged_server_ep_cap == 0 || client_vka == NULL || client_vspace == NULL
            || conn == NULL) {
        return seL4_InvalidArgument;
    }

    memset(conn, 0, sizeof(serial_client_context_t));

    shmem_n_pages = BYTES_TO_4K_PAGES(SERIAL_SERVER_SHMEM_MAX_SIZE);
    if (shmem_n_pages > seL4_MsgMaxExtraCaps) {
        ZF_LOGE(SERSERVC"connect: Currently unsupported shared memory size: "
                "IPC cap transfer capability is inadequate.");
        return seL4_RangeError;
    }
    conn->shmem = vspace_new_pages(client_vspace,
                                   seL4_AllRights,
                                   shmem_n_pages,
                                   seL4_PageBits);
    if (conn->shmem == NULL) {
        ZF_LOGE(SERSERVC"connect: Failed to alloc shmem.");
        return seL4_NotEnoughMemory;
    }
    assert(IS_ALIGNED((uintptr_t)conn->shmem, seL4_PageBits));

    /* Look up the Frame cap behind each page in the shmem range, and marshal
     * all of those Frame caps to the parent. The parent will then map those
     * Frames into its VSpace and establish a shmem link.
     */
    shmem_tmp_vaddr = (uintptr_t)conn->shmem;
    for (int i = 0; i < shmem_n_pages; i++) {
        vka_cspace_make_path(client_vka,
                             vspace_get_cap(client_vspace,
                                            (void *)shmem_tmp_vaddr),
                             &frame_cspath);

        seL4_SetCap(i, frame_cspath.capPtr);
        shmem_tmp_vaddr += BIT(seL4_PageBits);
    }

    /* Call the server asking it to establish the shmem mapping with us, and
     * get us connected up.
     */
    seL4_SetMR(SSMSGREG_FUNC, FUNC_CONNECT_REQ);
    seL4_SetMR(SSMSGREG_CONNECT_REQ_SHMEM_SIZE,
               SERIAL_SERVER_SHMEM_MAX_SIZE);
    /* extraCaps doubles up as the number of shmem pages. */
    tag = seL4_MessageInfo_new(0, 0,
                               shmem_n_pages,
                               SSMSGREG_CONNECT_REQ_END);

    tag = seL4_Call(badged_server_ep_cap, tag);

    /* It makes sense to verify that the message we're getting back is an
     * ACK response to our request message.
     */
    if (seL4_GetMR(SSMSGREG_FUNC) != FUNC_CONNECT_ACK) {
        error = seL4_IllegalOperation;
        ZF_LOGE(SERSERVC"connect: Reply message was not a CONNECT_ACK as "
                "expected.");
        goto out;
    }
    /* When the parent replies, we check to see if it was successful, etc. */
    error = seL4_MessageInfo_get_label(tag);
    if (error != (int)SERIAL_SERVER_NOERROR) {
        ZF_LOGE(SERSERVC"connect ERR %d: Failed to connect to the server.",
                error);

        if (error == (int)SERIAL_SERVER_ERROR_SHMEM_TOO_LARGE) {
            ZF_LOGE(SERSERVC"connect: Your requested shmem mapping size is too "
                    "large.\n\tServer's max shmem size is %luB.",
                    (long)seL4_GetMR(SSMSGREG_CONNECT_ACK_MAX_SHMEM_SIZE));
        }
        goto out;
    }

    conn->shmem_size = SERIAL_SERVER_SHMEM_MAX_SIZE;
    vka_cspace_make_path(client_vka, badged_server_ep_cap,
                         &conn->badged_server_ep_cspath);

    return seL4_NoError;

out:
    if (conn->shmem != NULL) {
        vspace_unmap_pages(client_vspace, (void *)conn->shmem, shmem_n_pages,
                           seL4_PageBits, VSPACE_FREE);
    }
    return error;
}
Esempio n. 28
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. 29
0
/* Run a single test.
 * Each test is launched as its own process. */
int
run_test(struct testcase *test)
{
    UNUSED int error;
    sel4utils_process_t test_process;

    /* Test intro banner. */
    printf("  %s\n", test->name);

    error = sel4utils_configure_process(&test_process, &env.vka, &env.vspace,
                                        env.init->priority, TESTS_APP);
    assert(error == 0);

    /* set up caps about the process */
    env.init->page_directory = copy_cap_to_process(&test_process, test_process.pd.cptr);
    env.init->root_cnode = SEL4UTILS_CNODE_SLOT;
    env.init->tcb = copy_cap_to_process(&test_process, test_process.thread.tcb.cptr);
    env.init->domain = copy_cap_to_process(&test_process, simple_get_init_cap(&env.simple, seL4_CapDomain));
#ifndef CONFIG_KERNEL_STABLE
    env.init->asid_pool = copy_cap_to_process(&test_process, simple_get_init_cap(&env.simple, seL4_CapInitThreadASIDPool));
#endif /* CONFIG_KERNEL_STABLE */
#ifdef CONFIG_IOMMU
    env.init->io_space = copy_cap_to_process(&test_process, simple_get_init_cap(&env.simple, seL4_CapIOSpace));
#endif /* CONFIG_IOMMU */
    /* setup data about untypeds */
    env.init->untypeds = copy_untypeds_to_process(&test_process, untypeds, num_untypeds);
    copy_timer_caps(env.init, &env, &test_process);
    /* copy the fault endpoint - we wait on the endpoint for a message
     * or a fault to see when the test finishes */
    seL4_CPtr endpoint = copy_cap_to_process(&test_process, test_process.fault_endpoint.cptr);

    /* WARNING: DO NOT COPY MORE CAPS TO THE PROCESS BEYOND THIS POINT,
     * AS THE SLOTS WILL BE CONSIDERED FREE AND OVERRIDDEN BY THE TEST PROCESS. */
    /* set up free slot range */
    env.init->cspace_size_bits = CONFIG_SEL4UTILS_CSPACE_SIZE_BITS;
    env.init->free_slots.start = endpoint + 1;
    env.init->free_slots.end = (1u << CONFIG_SEL4UTILS_CSPACE_SIZE_BITS);
    assert(env.init->free_slots.start < env.init->free_slots.end);
    /* copy test name */
    strncpy(env.init->name, test->name + strlen("TEST_"), TEST_NAME_MAX);
#ifdef SEL4_DEBUG_KERNEL
    seL4_DebugNameThread(test_process.thread.tcb.cptr, env.init->name);
#endif

    /* set up args for the test process */
    char endpoint_string[10];
    char sel4test_name[] = { TESTS_APP };
    char zero_string[] = {"0"};
    char *argv[] = {sel4test_name, zero_string, endpoint_string};
    argv[0] = endpoint_string;
    snprintf(endpoint_string, 10, "%d", endpoint);
    /* spawn the process */
    error = sel4utils_spawn_process_v(&test_process, &env.vka, &env.vspace,
                            ARRAY_SIZE(argv), argv, 1);
    assert(error == 0);

    /* send env.init_data to the new process */
    void *remote_vaddr = send_init_data(&env, test_process.fault_endpoint.cptr, &test_process);

    /* wait on it to finish or fault, report result */
    seL4_Word badge;
    seL4_MessageInfo_t info = seL4_Wait(test_process.fault_endpoint.cptr, &badge);

    int result = seL4_GetMR(0);
    if (seL4_MessageInfo_get_label(info) != seL4_NoFault) {
        sel4utils_print_fault_message(info, test->name);
        result = FAILURE;
    }

    /* unmap the env.init data frame */
    vspace_unmap_pages(&test_process.vspace, remote_vaddr, 1, PAGE_BITS_4K, NULL);

    /* reset all the untypeds for the next test */
    for (int i = 0; i < num_untypeds; i++) {
        cspacepath_t path;
        vka_cspace_make_path(&env.vka, untypeds[i].cptr, &path);
        vka_cnode_revoke(&path);
    }

    /* destroy the process */
    sel4utils_destroy_process(&test_process, &env.vka);

    test_assert(result == SUCCESS);
    return result;
}
Esempio n. 30
0
void proxy_vka_cspace_make_path(void *data, seL4_CPtr slot, cspacepath_t *res) {
    proxy_vka_t *vka = (proxy_vka_t*)data;
    vka_cspace_make_path(&vka->regular_vka, slot, res);
}