Пример #1
0
static int
test_iopt_basic_map_unmap(env_t env)
{
    int error;
    int i;
    seL4_CPtr iospace, pt, frame;
    seL4_SlotRegion caps = env->io_space_caps;
    int cap_count = caps.end - caps.start + 1;

    for (i = 0; i < cap_count; i++) {
        iospace = caps.start + i;
        error = map_iopt_set(env, iospace, &pt, &frame);
        test_eq(error, seL4_NoError);

        error = seL4_ARM_Page_Unmap(frame);
        test_eq(error, seL4_NoError);

        error = seL4_ARM_IOPageTable_Unmap(pt);
        test_eq(error, seL4_NoError);

        error = map_iopt_from_iospace(env, iospace, &pt, &frame);
        test_eq(error, seL4_NoError);

        error = seL4_ARM_IOPageTable_Unmap(pt);
        test_eq(error, seL4_NoError);
        error = seL4_ARM_Page_Unmap(frame);
        test_eq(error, seL4_NoError);
        delete_iospace(env, iospace);
    }
    return sel4test_get_result();
}
Пример #2
0
/***********************************************************************
 * sos_page_unmap
 ***********************************************************************/
int
sos_page_unmap(addrspace_t *as, seL4_Word vaddr) {
    dprintf(3, "sos_page_unmap entered\n");
    seL4_Word vpage = PAGE_ALIGN(vaddr);
    int x = PT_L1_INDEX(vpage);
    int y = PT_L2_INDEX(vpage);

    if(as == NULL ||
            (as->as_pd_caps == NULL || as->as_pd_caps[x] == NULL) ||
            (as->as_pd_regs == NULL || as->as_pd_regs[x] == NULL)) {
        dprintf(3, "sos_page_unmap err 1\n");
        return EINVAL;
    }

    assert(as->as_pd_caps[x][y] != 0);
    int err;
    err = seL4_ARM_Page_Unmap(as->as_pd_caps[x][y]);
    if (err) {
        dprintf(3, "sos_page_unmap err 2\n");
        return EFAULT;
    }
    cspace_delete_cap(cur_cspace, as->as_pd_caps[x][y]);

    return 0;
}
Пример #3
0
void sos_map_page_dir_cb(int pid, seL4_CPtr reply_cap, void *args, int err) {
    if (SOS_DEBUG) printf("sos_map_page_dir_cb\n");

    frame_alloc_args *alloc_args = (frame_alloc_args *) args;
    sos_map_page_args *map_args = alloc_args->cb_args;

    if (err || !alloc_args->index) {
        eprintf("Error caught in sos_map_page_dir_cb\n");
        free(alloc_args);
        map_args->cb(pid, reply_cap, map_args->cb_args, -1);
        free(map_args);
        return;
    }

    seL4_Word dir_index = PT_TOP(map_args->vaddr);

    printf("directory index %p, pagetable addr %p\n",(void *)dir_index, (void *)alloc_args->vaddr);
    printf("index %d\n", alloc_args->index);

    proc_table[pid]->page_directory[dir_index] = (seL4_Word *) alloc_args->vaddr;

    seL4_ARM_Page_Unmap(frametable[alloc_args->index].frame_cap);
    err = map_page(frametable[alloc_args->index].frame_cap
                  ,seL4_CapInitThreadPD
                  ,alloc_args->vaddr
                  ,seL4_AllRights
                  ,seL4_ARM_Default_VMAttributes
                  );

    if (err) {
        eprintf("Error caught in sos_map_page_dir_cb\n");
        free(alloc_args);
        map_args->cb(pid, reply_cap, map_args->cb_args, -1);
        free(map_args);
        return;
    }

    memset((void *)alloc_args->vaddr, 0, PAGE_SIZE);

    frametable[alloc_args->index].vaddr = -1;
    printf("Setting index %p to don't swap\n", (void *)alloc_args->index);
    frametable[alloc_args->index].frame_status |= FRAME_DONT_SWAP;
    free(alloc_args);

    sos_map_page_cb(pid, reply_cap, map_args, 0);

    if (SOS_DEBUG) printf("sos_map_page_dir_cb ended\n");
}
Пример #4
0
void pt_cleanup(int pid) {
    assert(pid > 0 && pid <= MAX_PROCESSES);
    //free all the pages + revoke/delete the corresponding cap 
    //9242_TODO unmark swapped out pages
    printf("Starting pt_cleanup\n");
    seL4_Word** pd = proc_table[pid]->page_directory;
    seL4_ARM_PageTable **ct = proc_table[pid]->cap_table;
    if (pd) {
        for (int i = 0; i < PD_MAX_ENTRIES; i++) {
            if (pd[i]) {
                for (int j = 0; j < PT_MAX_ENTRIES; j++) {
                    if (pd[i][j]) {
                        if (pd[i][j] & SWAPPED) {
                            printf("freeing a swap slot: %d\n", pd[i][j] & SWAP_SLOT_MASK);
                            free_swap_slot(pd[i][j] & SWAP_SLOT_MASK); 
                        } else {
                            int index = pd[i][j] & FRAME_INDEX_MASK;
                            int page_pid = (frametable[index].frame_status & PROCESS_MASK) >> PROCESS_BIT_SHIFT;
                            //if (page_pid == pid) {
                            printf("page_pid = %d, pid = %d\n", page_pid, pid);
                            frame_free(index);
                            //} 
                        }
                    }
                }
                frame_free(vaddr_to_index((seL4_Word) pd[i]));
            }
        }
        frame_free(vaddr_to_index((seL4_Word) pd));
    }

    //free the cap table 
    if (ct) {
        for (int i = 0; i < CAP_TABLE_PAGES; i++) {
            for (int j = 0; j < CT_MAX_ENTRIES; j++) {
                if ((seL4_Word) ct[i][j]) {
                    seL4_ARM_Page_Unmap(ct[i][j]);
                }
            }
            frame_free(vaddr_to_index((seL4_Word) ct[i])); 
        }
    }
    printf("pt cleanup ended\n");
} 
Пример #5
0
static int load_segment_directly_into_vspace(addrspace_t dest_as,
                                    char *src, unsigned long segment_size,
                                    unsigned long file_size, unsigned long dst,
                                    unsigned long permissions) {
    assert(file_size <= segment_size);

    unsigned long pos;

    struct as_region* reg = as_define_region (dest_as, dst, segment_size,
        permissions, REGION_GENERIC);

    if (!reg) {
        return 1;
    }

    /* We work a page at a time in the destination vspace. */
    pos = 0;
    while(pos < segment_size) {
        seL4_CPtr sos_cap, frame_cap;
        seL4_Word vpage, kvpage;

        unsigned long kdst;
        int nbytes;
        int err;

        kdst   = dst + PROCESS_SCRATCH_START;
        vpage  = PAGE_ALIGN(dst);
        kvpage = PAGE_ALIGN(kdst);
        //kvpage = PROCESS_SCRATCH + 0x1000;

        /* Map the page into the destination address space */
        int status = PAGE_FAILED;
        struct pt_entry* page = page_map (dest_as, reg, vpage, &status,
            NULL, NULL);

        if (!page || status != PAGE_SUCCESS) {
            /* we should really only be using this function at boot time.
             * load_segment_into_vspace will handle lazy loading/swap events
             * for you - early on in the boot we can assume that swapping is NOT
             * an option */
            return 1;
        }

        /* Map the frame into SOS as well so we can copy into it */
        /* FIXME: WOULD BE MUCH NICER(!) if we just used cur_addrspace - 
         * you will need to create a region in main's init function */
        sos_cap = page->cap;
        assert (sos_cap);

        frame_cap = cspace_copy_cap (cur_cspace, cur_cspace, sos_cap,
            seL4_AllRights);

        if (!frame_cap) {
            return 1;
        }
        
        err = map_page (frame_cap, seL4_CapInitThreadPD, kvpage, seL4_AllRights,
            seL4_ARM_Default_VMAttributes);

        if (err) {
            return 1;
        }

        /* Now copy our data into the destination vspace */
        nbytes = PAGESIZE - (dst & PAGEMASK);
        if (pos < file_size){
            memcpy((void*)kdst, (void*)src, MIN(nbytes, file_size - pos));
        }

        /* Not observable to I-cache yet so flush the frame */
        seL4_ARM_Page_FlushCaches(frame_cap);

        /* unmap page + delete cap copy */
        err = seL4_ARM_Page_Unmap (frame_cap);
        if (err) {
            return 1;
        }

        cspace_delete_cap (cur_cspace, frame_cap);

        pos += nbytes;
        dst += nbytes;
        src += nbytes;
    }

    return 0;
}