Пример #1
0
Файл: elf.c Проект: KGG814/AOS
void load_segment_into_vspace_cb_continue(int pid
                                         ,seL4_CPtr reply_cap
                                         ,load_segment_args *args
                                         ,int err
                                         ) 
{
    if (TMP_DEBUG) printf("load_segment_into_vspace_cb_continue\n");
    // Get the arguments we use
    if (err) {
        eprintf("Error caught in load_segment_into_vspace_cb_continue\n");
        args->cb(pid, reply_cap, args->cb_args, err);
        free(args);
        return;
    }

    int index                   = args->index;
    seL4_Word vaddr             = args->vaddr;
    unsigned long pos           = args->pos;
    unsigned long file_size     = args->file_size;
    unsigned long dst           = args->dst;
    char *src                   = args->src;
    // Calculate nuber of bytes left to right
    int nbytes = PAGESIZE - (dst & PAGEMASK);
    // Might not be copying to start of page, so add offset from user ptr
    vaddr = vaddr + (dst & OFST_MASK);
    if (pos < file_size){     
        memcpy((void*)vaddr, (void*)src, MIN(nbytes, file_size - args->pos));
    }   
    seL4_ARM_Page_Unify_Instruction(frametable[index].mapping_cap, 0, PAGESIZE);
    args->pos += nbytes;
    args->dst += nbytes;
    args->src += nbytes;
    load_segment_into_vspace(pid, reply_cap, args, err);
    if (TMP_DEBUG) printf("load_segment_into_vspace_cb_continue end\n");
}
Пример #2
0
Файл: vm.c Проект: gapry/AOS
static void
_sos_VMFaultHandler_reply(void* token, int err){
    dprintf(3, "sos_vmf_reply called\n");

    VMF_cont_t *cont= (VMF_cont_t*)token;
    if(err){
        dprintf(3, "sos_vmf received an err\n");
    }
    if (!is_proc_alive(cont->pid)) {
        cspace_free_slot(cur_cspace, cont->reply_cap);
        free(cont);
        return;
    }

    /* Flush the i-cache. Ideally, this should only be done when faulting on text segment */
    //if (cont->is_code) {
    if (!err) {
        seL4_Word vpage = PAGE_ALIGN(cont->vaddr);
        int x = PT_L1_INDEX(vpage);
        int y = PT_L2_INDEX(vpage);

        seL4_Word kvaddr = (cont->as->as_pd_regs[x][y] & PTE_KVADDR_MASK);
        seL4_CPtr kframe_cap;

        err = frame_get_cap(kvaddr, &kframe_cap);
        //assert(!err); // This kvaddr is ready to use, there should be no error
        seL4_ARM_Page_Unify_Instruction(kframe_cap, 0, PAGESIZE);
    }
    //}
    /* If there is an err here, it is not the process's fault
     * It is either the kernel running out of memory or swapping doesn't work
     */
    seL4_MessageInfo_t reply = seL4_MessageInfo_new(0, 0, 0, 0);
    seL4_Send(cont->reply_cap, reply);
    cspace_free_slot(cur_cspace, cont->reply_cap);
    free(cont);
    set_cur_proc(PROC_NULL);
}
Пример #3
0
// Callback for SOS page directory setup
void pd_init_cb(int pid, seL4_CPtr reply_cap, frame_alloc_args *args, int err) {
    if (SOS_DEBUG) printf("pd_init_cb\n");
    // Get the return values from the frame_alloc call
    vm_init_args *vm_args  = (vm_init_args *) args->cb_args;
    int index                   = args->index;
    seL4_Word vaddr             = args->vaddr;

    if (index == FRAMETABLE_ERR || err) {
        eprintf("Error caught in pd_init_cb\n");
        vm_args->cb(pid, reply_cap, vm_args->cb_args, -1);
        free(args);
        free(vm_args);
        return;
    }

    // Set up args for callback
    vm_args->curr_page = 0;
    // Free args from frame_alloc cal
    free(args);
    // Set the page directory to the newly allocated page
    proc_table[pid]->page_directory = (seL4_Word**) vaddr;
    memset((void *)vaddr, 0, PAGE_SIZE);

    if (frametable[index].mapping_cap) {
       seL4_ARM_Page_Unify_Instruction(frametable[index].mapping_cap, 0, PAGESIZE); 
    }
    
    if (TMP_DEBUG) printf("pd addr %p\n",  proc_table[pid]->page_directory[0]);

    // Make sure the page directory isn't swapped out
    printf("Setting index %p to don't swap\n", (void *) index);
    frametable[index].frame_status |= FRAME_DONT_SWAP;

    // Continue initialisation
    pd_caps_init(pid, reply_cap, vm_args);
    if (SOS_DEBUG) printf("pd_init_cb ended\n");
}
Пример #4
0
static int
test_large_page_flush_operation(env_t env)
{
    int num_frame_types = ARRAY_SIZE(frame_types);
    seL4_CPtr frames[num_frame_types];
    int error;
    vka_t *vka = &env->vka;
    bool pt_mapped = false;

    /* Grab some free vspace big enough to hold all the tests. */
    seL4_Word vstart;
    reservation_t reserve = vspace_reserve_range(&env->vspace, 2 * (1 << 25),
                                                  seL4_AllRights, 1, (void **) &vstart);
    test_assert(reserve.res != 0);
    vstart = ALIGN_UP(vstart, (1 << 25));

    /* Create us some frames to play with. */
    for (int i = 0; i < num_frame_types; i++) {
        frames[i] = vka_alloc_frame_leaky(vka, CTZ(frame_types[i].size));
        assert(frames[i]);
    }

    /* Also create a pagetable to map the pages into. */
    seL4_CPtr pt = vka_alloc_page_table_leaky(vka);

    /* Map the pages in. */
    for (int i = 0; i < num_frame_types; i++) {
        if (frame_types[i].need_pt && !pt_mapped) {
            /* Map the pagetable in. */
            error = seL4_ARCH_PageTable_Map(pt, env->page_directory,
                                            vstart + frame_types[i].vaddr_offset,
                                            seL4_ARCH_Default_VMAttributes);
            test_assert(error == 0);

            pt_mapped = true;
        }

        error = seL4_ARCH_Page_Map(frames[i], env->page_directory,
                                   vstart + frame_types[i].vaddr_offset, seL4_AllRights,
                                   seL4_ARCH_Default_VMAttributes);
        test_assert(error == 0);
    }

    /* See if we can invoke page flush on each of them */
    for (int i = 0; i < num_frame_types; i++) {
        error = seL4_ARM_Page_Invalidate_Data(frames[i], 0, frame_types[i].size);
        test_assert(error == 0);
        error = seL4_ARM_Page_Clean_Data(frames[i], 0, frame_types[i].size);
        test_assert(error == 0);
        error = seL4_ARM_Page_CleanInvalidate_Data(frames[i], 0, frame_types[i].size);
        test_assert(error == 0);
        error = seL4_ARM_Page_Unify_Instruction(frames[i], 0, frame_types[i].size);
        test_assert(error == 0);
        error = seL4_ARM_PageDirectory_Invalidate_Data(env->page_directory, vstart + frame_types[i].vaddr_offset, vstart + frame_types[i].vaddr_offset + frame_types[i].size);
        test_assert(error == 0);
        error = seL4_ARM_PageDirectory_Clean_Data(env->page_directory, vstart + frame_types[i].vaddr_offset, vstart + frame_types[i].vaddr_offset + frame_types[i].size);
        test_assert(error == 0);
        error = seL4_ARM_PageDirectory_CleanInvalidate_Data(env->page_directory, vstart + frame_types[i].vaddr_offset, vstart + frame_types[i].vaddr_offset + frame_types[i].size);
        test_assert(error == 0);
        error = seL4_ARM_PageDirectory_Unify_Instruction(env->page_directory, vstart + frame_types[i].vaddr_offset, vstart + frame_types[i].vaddr_offset + frame_types[i].size);
        test_assert(error == 0);
    }

    return sel4test_get_result();
}
Пример #5
0
int map_if_valid(seL4_Word vaddr, int pid, callback_ptr cb, void* args, seL4_CPtr reply_cap) {
    if (SOS_DEBUG) printf("map_if_valid: %p, pid = %d\n", (void * ) vaddr, pid);
    int dir_index = PT_TOP(vaddr);
    int page_index = PT_BOTTOM(vaddr);

    printf("pd addr = %p\n", proc_table[pid]->page_directory);
    if (proc_table[pid]->page_directory == NULL) {
        //assert(0);
        //cb(pid, reply_cap, args, -1);
        eprintf("Error caught in map_if_valid\n");
        return -1;
    }
    
    if (proc_table[pid]->page_directory[dir_index] != NULL) {
        int index = proc_table[pid]->page_directory[dir_index][page_index];
        if (index & SWAPPED) {
            if (SOS_DEBUG) printf("page was swapped\n");
            read_swap_args *swap_args = malloc(sizeof(read_swap_args));
            if (swap_args == NULL) {
                eprintf("Error caught in map_if_valid\n");
                return -1;
            }
            swap_args->cb = cb;
            swap_args->cb_args = args;
            swap_args->vaddr = vaddr;
            swap_args->pid = pid = pid;
            swap_args->reply_cap = reply_cap;
            read_from_swap_slot(pid, reply_cap, swap_args);
            return 0;
        } else if (index != 0 && frametable[index].vaddr == vaddr && 
                   frametable[index].frame_status & FRAME_SWAP_MARKED) {
            // Was temporarily unmapped by clock algo, just map back in
            if (SOS_DEBUG) printf("unmapped by clock, map back in\n");
            seL4_CPtr cap = cspace_copy_cap(cur_cspace
                                   ,cur_cspace
                                   ,frametable[index].frame_cap
                                   ,seL4_AllRights
                                   );
            int err = map_page_user(cap, proc_table[pid]->vroot, vaddr, 
                    seL4_AllRights, seL4_ARM_Default_VMAttributes, proc_table[pid]);
            if (err) {
                eprintf("Error caught in map_if_valid\n");
                return -1;
            }

            frametable[index].frame_status &= ~FRAME_SWAP_MARKED;
            seL4_ARM_Page_Unify_Instruction(cap, 0, PAGESIZE);
            frametable[index].mapping_cap = cap;
            if (cb != NULL) {
                cb(pid, reply_cap, args, 0);
                return 0;
            }
        } else if (index != 0) {
            if (SOS_DEBUG) printf("page should be mapped in\n");
            if (cb != NULL) {
                cb(pid, reply_cap, args, 0);
                return 0;
            }
        }
    }    

    return map_new_frame(vaddr, pid, cb, args, reply_cap);
}
Пример #6
0
void sos_map_page_cb(int pid, seL4_CPtr reply_cap, void *args, int err) {
    // Get arguments we need 
    sos_map_page_args *map_args = (sos_map_page_args *) args;
    int index = map_args->ft_index;

    if (err || index == FRAMETABLE_ERR) {
        eprintf("Error caught in sos_map_page_cb\n");
        map_args->cb(pid, reply_cap, map_args->cb_args, -1);
        free(args);
        return;
    }

    addr_space *as = proc_table[pid];
    seL4_ARM_PageDirectory pd = as->vroot;
    seL4_Word vaddr = map_args->vaddr;
    
    if (SOS_DEBUG) printf("sos_map_page_cb at %p\n", (void *) map_args->vaddr);

    seL4_Word dir_index = PT_TOP(vaddr);
    seL4_Word page_index = PT_BOTTOM(vaddr);

    assert(as->page_directory[dir_index] != NULL);

    if (SOS_DEBUG) printf("dir_index %d, page_index %d\n", dir_index, page_index);

    if ((as->page_directory[dir_index][page_index] & SWAPPED) == SWAPPED) {
        printf("Page was swapped out from under us: %p, pid: %d, value %p\n", (void *) vaddr, pid, 
                (void *) as->page_directory[dir_index][page_index]);
        assert(0);
    } else {
        as->page_directory[dir_index][page_index] = index;
        // Map into the given process page directory //
        if (!frametable[index].mapping_cap) {
            seL4_CPtr cap = cspace_copy_cap(cur_cspace
                                   ,cur_cspace
                                   ,frametable[index].frame_cap
                                   ,seL4_AllRights
                                   );
            err = map_page_user(cap, pd, vaddr, 
                        seL4_AllRights, seL4_ARM_Default_VMAttributes, as);

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

            seL4_ARM_Page_Unify_Instruction(cap, 0, PAGESIZE); 
            frametable[index].mapping_cap = cap; 
            if (SOS_DEBUG) printf("setting mapping cap: %d\n", cap);
            frametable[map_args->ft_index].vaddr = map_args->vaddr;
        }     
    }
    seL4_ARM_Page_Unify_Instruction(frametable[index].mapping_cap, 0, PAGESIZE);
    if (map_args->cb != NULL) {
        map_args->cb(pid, reply_cap, map_args->cb_args, 0);
        free(map_args);
    }
    if (SOS_DEBUG) printf("sos_map_page_cb ended\n");
}