Exemplo n.º 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;
}
Exemplo n.º 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;
}