Exemplo n.º 1
0
/*! @brief Handles memory window creation syscalls.

    The window must not be overlapping with an existing window in the client's VSpace, or
    EINVALIDPARAM will be the returned.
    
    When mapping a dataspace to a non-page aligned window, the dataspace will actually be mapped to
    the page-aligned address of the window base due to technical restrictions. Thus, the first B -
    PAGE_ALIGN(B) bytes of the mapped dataspace is unaccessible. This can have unintended effects
    when two processes map the same dataspace for sharing purposes. In other words, when sharing
    dataspaces, it's easiest for the window bases for BOTH processes to be page-aligned.
 */
seL4_CPtr
proc_create_mem_window_internal_handler(void *rpc_userptr , uint32_t rpc_vaddr , uint32_t rpc_size ,
                                        uint32_t rpc_permissions, uint32_t flags,
                                        refos_err_t* rpc_errno)
{
    struct proc_pcb *pcb = (struct proc_pcb*) rpc_userptr;
    assert(pcb && pcb->magic == REFOS_PCB_MAGIC);

    /* Check that this window does not override protected kernel memory. */
    if (rpc_vaddr >= PROCESS_KERNEL_RESERVED || PROCESS_KERNEL_RESERVED < (rpc_size + rpc_vaddr)) {
        dvprintf("memory window out of bounds, overlaps kernel reserved.\n");
        SET_ERRNO_PTR(rpc_errno, EINVALIDPARAM);
        return 0;
    }

    /* Create the window. */
    int windowID = W_INVALID_WINID;
    bool cached = (flags & W_FLAGS_UNCACHED) ? false : true;
    int error = vs_create_window(&pcb->vspace, rpc_vaddr, rpc_size, rpc_permissions, cached,
            &windowID);
    if (error != ESUCCESS || windowID == W_INVALID_WINID) {
        dvprintf("Could not create window.\n");
        SET_ERRNO_PTR(rpc_errno, error);
        return 0;
    }

    /* Find the window and return the window capability. */
    struct w_window* window = w_get_window(&procServ.windowList, windowID);
    if (!window) {
        assert(!"Successfully allocated window failed to be found. Process server bug.");
        /* Cannot recover from this situation cleanly. Shouldn't ever happen. */
        SET_ERRNO_PTR(rpc_errno, EINVALID);
        return 0;
    }

    assert(window->magic == W_MAGIC);
    assert(window->capability.capPtr);
    SET_ERRNO_PTR(rpc_errno, ESUCCESS);
    return window->capability.capPtr;
}
Exemplo n.º 2
0
int
test_vspace_mapping(void)
{
    test_start("vspace mapping");

    /* Create a vspace for testing mapping. */
    struct vs_vspace vs;
    int error = vs_initialise(&vs, 31337);
    test_assert(error == ESUCCESS);
    test_assert(vs.magic == REFOS_VSPACE_MAGIC);

    /* Create a memory segment window. */
    const vaddr_t window = 0x10000;
    const vaddr_t windowSize = 0x8000;
    int windowID;
    error = vs_create_window(&vs, window, windowSize, W_PERMISSION_WRITE | W_PERMISSION_READ,
            true, &windowID);
    test_assert(error == ESUCCESS);
    test_assert(windowID != W_INVALID_WINID);

    /* Allocate a frame to map. */
    vka_object_t frame;
    error = vka_alloc_frame(&procServ.vka, seL4_PageBits, &frame);
    test_assert(error == ESUCCESS);
    test_assert(frame.cptr != 0);

    /* Try to map in some invalid spots. */
    tvprintf("trying mapping into invalid spots...\n");
    error = vs_map(&vs, 0x9A0, &frame.cptr, 1);
    test_assert(error == EINVALIDWINDOW);
    error = vs_map(&vs, window - 0x9A0, &frame.cptr, 1);
    test_assert(error == EINVALIDWINDOW);
    error = vs_map(&vs, window + windowSize + 0x1, &frame.cptr, 1);
    test_assert(error == EINVALIDWINDOW);
    error = vs_map(&vs, window + windowSize + 0x5123, &frame.cptr, 1);
    test_assert(error == EINVALIDWINDOW);

    /* Try to unmap from some invalid spots. */
    tvprintf("trying unmapping from invalid spots...\n");
    error = vs_unmap(&vs, window - 0x9A0, 1);
    test_assert(error == EINVALIDWINDOW);
    error = vs_unmap(&vs, window + windowSize + 0x423, 5);
    test_assert(error == EINVALIDWINDOW);
    error = vs_unmap(&vs, window, windowSize + 1);
    test_assert(error == EINVALIDWINDOW);

    /* Map the frame many times in all the valid spots. */
    for (vaddr_t waddr = window; waddr < window + windowSize; waddr += (1 << seL4_PageBits)) {
        tvprintf("trying mapping into valid spot 0x%x...\n", (uint32_t) waddr);
        /* Map the frame. */
        error = vs_map(&vs, waddr, &frame.cptr, 1);
        test_assert(error == ESUCCESS);
        /* Try to map frame here again. Should complain. */
        error = vs_map(&vs, waddr, &frame.cptr, 1);
        test_assert(error == EUNMAPFIRST);
    }

    /* Unmap and remap the frame many times in all the valid spots. */
    for (vaddr_t waddr = window; waddr < window + windowSize; waddr += (1 << seL4_PageBits)) {
        tvprintf("trying remapping into valid spot 0x%x...\n", (uint32_t) waddr);
        /* Unmap the frame. */
        error = vs_unmap(&vs, waddr, 1);
        test_assert(error == ESUCCESS);
        /* Remap the frame. */
        error = vs_map(&vs, waddr, &frame.cptr, 1);
        test_assert(error == ESUCCESS);
    }

    /* Clean up. Note that deleting the vspace should delete the created window. */
    tvprintf("cleaning up everything in vspace...\n");
    vs_unref(&vs);
    test_assert(vs.magic != REFOS_VSPACE_MAGIC);
    vka_free_object(&procServ.vka, &frame);

    return test_success();
}