Exemple #1
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;
}
Exemple #2
0
/*! @brief Handles client watching syscalls.

    Most servers would need to call this in order to be notified of client death in order to be able
    to delete any internal book-keeping for the dead client.
 */
refos_err_t
proc_watch_client_handler(void *rpc_userptr , seL4_CPtr rpc_liveness , seL4_CPtr rpc_deathEP ,
                          int32_t* rpc_deathID)
{
    struct proc_pcb *pcb = (struct proc_pcb*) rpc_userptr;
    struct procserv_msg *m = (struct procserv_msg*) pcb->rpcClient.userptr;
    assert(pcb->magic == REFOS_PCB_MAGIC);

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

    /* Retrieve the corresponding client's ASID unwrapped from its liveness cap. */
    if (!dispatcher_badge_liveness(rpc_liveness)) {
        return EINVALIDPARAM;
    }
    
    /* Verify the corresponding client. */
    struct proc_pcb *client = pid_get_pcb(&procServ.PIDList,
                                          rpc_liveness - PID_LIVENESS_BADGE_BASE);
    if (!client) {
        return EINVALIDPARAM; 
    }
    assert(client->magic == REFOS_PCB_MAGIC);

    /* Copy out the death notification endpoint. */
    seL4_CPtr deathNotifyEP = dispatcher_copyout_cptr(rpc_deathEP);
    if (!deathNotifyEP) {
        ROS_ERROR("could not copy out deathNotifyEP.");
        return ENOMEM; 
    }

    /* Add the new client to the watch list of the calling process. */
    int error = client_watch(&pcb->clientWatchList, client->pid, deathNotifyEP);
    if (error) {
        ROS_ERROR("failed to add to watch list. Procserv possibly out of memory.");
        dispatcher_release_copyout_cptr(deathNotifyEP);
        return error;
    }
    if (rpc_deathID) {
        (*rpc_deathID) = client->pid;
    }

    return ESUCCESS;
}
Exemple #3
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;
}