Exemple #1
0
refos_err_t
proc_unregister_as_pager_handler(void *rpc_userptr , seL4_CPtr rpc_window)
{
    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, 1)) {
        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);

    /* Unset the pager endpoint. If there was anything else mapped to this window, it will be
       unmapped. */
    cspacepath_t emptyPath;
    memset(&emptyPath, 0, sizeof(cspacepath_t));
    w_set_pager_endpoint(win, emptyPath, PID_NULL);
    return ESUCCESS;
}
Exemple #2
0
seL4_CPtr
proc_get_mem_window_dspace_handler(void *rpc_userptr , seL4_CPtr rpc_window ,
                                   refos_err_t* rpc_errno)
{
    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, 1)) {
        SET_ERRNO_PTR(rpc_errno, EINVALIDWINDOW);
        return 0;
    }

    if (!dispatcher_badge_window(rpc_window)) {
        SET_ERRNO_PTR(rpc_errno, EINVALIDWINDOW);
        return 0;
    }
    
    /* Retrieve the window from global window list. */
    struct w_window *window = w_get_window(&procServ.windowList, rpc_window - W_BADGE_BASE);
    if (!window) {
        ROS_ERROR("Failed to find associated window in global list. Procserv book-keeping bug.");
        SET_ERRNO_PTR(rpc_errno, EINVALIDWINDOW);
        return 0;
    }

    if (window->mode != W_MODE_ANONYMOUS) {
        SET_ERRNO_PTR(rpc_errno, ESUCCESS);
        return 0;
    }
    assert(window->ramDataspace && window->ramDataspace->magic == RAM_DATASPACE_MAGIC);

    SET_ERRNO_PTR(rpc_errno, ESUCCESS);
    return window->ramDataspace->capability.capPtr;
}
Exemple #3
0
refos_err_t
data_dataunmap_handler(void *rpc_userptr , seL4_CPtr rpc_memoryWindow)
{
    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, 1)) {
        return EINVALIDPARAM;
    }

    /* Retrieve and validate window badge. */
    if (!dispatcher_badge_window(rpc_memoryWindow)) { 
        return EINVALIDWINDOW;
    }
    struct w_window *window = w_get_window(&procServ.windowList, rpc_memoryWindow - W_BADGE_BASE);
    if (!window) {
        return EINVALIDWINDOW;
    }
    
    /* If window is already empty, then there's nothing to do here. */
    if (window->mode == W_MODE_EMPTY) {
        return ESUCCESS;
    }

    /* If window is mapped to something else, the un-do operation should not be data_unmap. */
    if (window->mode != W_MODE_ANONYMOUS) {
        return EINVALIDPARAM;
    }

    /* Reset the window back to empty. */
    w_set_anon_dspace(window, NULL, 0);
    return ESUCCESS;
}
Exemple #4
0
/*! @brief Handles memory window deletion syscalls. */
refos_err_t
proc_delete_mem_window_handler(void *rpc_userptr , seL4_CPtr rpc_window)
{
    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, 1)) {
        return EINVALIDWINDOW;
    }

    if (!dispatcher_badge_window(rpc_window)) {
        return EINVALIDWINDOW;
    }

    /* Perform the actual window deletion. Also unmaps the window. */
    vs_delete_window(&pcb->vspace, rpc_window - W_BADGE_BASE);
    return ESUCCESS;
}
Exemple #5
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;
}
Exemple #6
0
/*! \brief Maps the given dataspace to the given memory window. */
refos_err_t
data_datamap_handler(void *rpc_userptr , seL4_CPtr rpc_dspace_fd , seL4_CPtr rpc_memoryWindow,
                     uint32_t rpc_offset)
{
    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, 0x00000003, 2)) {
        return EINVALIDPARAM;
    }

    /* Retrieve and validate window badge. */
    if (!dispatcher_badge_window(rpc_memoryWindow)) { 
        return EINVALIDWINDOW;
    }
    struct w_window *window = w_get_window(&procServ.windowList, rpc_memoryWindow - W_BADGE_BASE);
    if (!window) {
        return EINVALIDWINDOW;
    }

    /* 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;
    }

    /* Check that the offset is sane. */
    if (rpc_offset > (dspace->npages * REFOS_PAGE_SIZE)) {
        return EINVALIDPARAM;
    }

    /* Associate the dataspace with the window. This will release whatever the window was associated
       with beforehand. */
    w_set_anon_dspace(window, dspace, rpc_offset);
    return ESUCCESS;
}
Exemple #7
0
/*! @brief Handles memory window resize syscalls. */
refos_err_t
proc_resize_mem_window_handler(void *rpc_userptr , seL4_CPtr rpc_window , uint32_t rpc_size)
{
    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, 1)) {
        dvprintf("Warning: proc_resize_mem_window invalid window cap.\n");
        return EINVALIDWINDOW;
    }

    if (!dispatcher_badge_window(rpc_window)) {
        dvprintf("Warning: proc_resize_mem_window invalid window badge.\n");
        return EINVALIDWINDOW;
    }

    /* Perform the actual window resize operation. */
    return vs_resize_window(&pcb->vspace, rpc_window - W_BADGE_BASE, rpc_size);
}
Exemple #8
0
/*! @brief Handles server window map syscalls.

    A server calls this on the process server in response to a prior fault delegation notification
    made by the process server, in order to map the given frame in the dataserver's VSpace into
    the faulting address frame, resolving the fault.
 */
refos_err_t
proc_window_map_handler(void *rpc_userptr , seL4_CPtr rpc_window , uint32_t rpc_windowOffset ,
                        uint32_t rpc_srcAddr)
{
    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, 1)) {
        return EINVALIDPARAM;
    }

    /* Retrieve and verify the window cap. */
    if (!dispatcher_badge_window(rpc_window)) {
        return EINVALIDPARAM;
    }
    struct w_window *window = w_get_window(&procServ.windowList, rpc_window - W_BADGE_BASE);
    if (!window) {
        ROS_ERROR("window does not exist!\n");
        return EINVALIDWINDOW;
    }
    
    /* Map the frame from src vspace to dest vspace. */
    struct proc_pcb *clientPCB = NULL;
    int error = vs_map_across_vspace(&pcb->vspace, rpc_srcAddr, window, rpc_windowOffset,
                                    &clientPCB);
    if (error) {
        return error;
    }
    assert(clientPCB != NULL && clientPCB->magic == REFOS_PCB_MAGIC);

    /* Resume the blocked faulting thread if there is one. */
    assert(procServ.unblockClientFaultPID == PID_NULL);
    procServ.unblockClientFaultPID = clientPCB->pid;
    return ESUCCESS;
}