Ejemplo n.º 1
0
Archivo: elf.c Proyecto: 8l/sel4-riscv
/*
 * Inject data into the given vspace.
 * TODO: Don't keep these pages mapped in
 */
static int load_segment_into_vspace(seL4_RISCV_PageDirectory 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;

    /* We work a page at a time in the destination vspace. */
    pos = 0;
    while(pos < segment_size) {
        seL4_Word paddr;
        seL4_CPtr sos_cap, tty_cap;
        seL4_Word vpage, kvpage;
        unsigned long kdst;
        int nbytes;
        int err;

        kdst   = dst + PROCESS_SCRATCH;
        vpage  = PAGE_ALIGN(dst);
        kvpage = PAGE_ALIGN(kdst);

        /* First we need to create a frame */
        paddr = ut_alloc(seL4_PageBits);
        conditional_panic(!paddr, "Out of memory - could not allocate frame");
        err = cspace_ut_retype_addr(paddr,
                                    seL4_RISCV_4K,
                                    seL4_PageBits,
                                    cur_cspace,
                                    &tty_cap);
        conditional_panic(err, "Failed to retype to a frame object");

        /* Copy the frame cap as we need to map it into 2 address spaces */
        sos_cap = cspace_copy_cap(cur_cspace, cur_cspace, tty_cap, seL4_AllRights);
        conditional_panic(sos_cap == 0, "Failed to copy frame cap");

        /* Map the frame into tty_test address spaces */
        err = map_page(tty_cap, dest_as, vpage, permissions, 
                       seL4_RISCV_Default_VMAttributes);
        conditional_panic(err, "Failed to map to tty address space");
        /* Map the frame into sos address spaces */
        err = map_page(sos_cap, seL4_CapInitThreadPD, kvpage, seL4_AllRights, 
                       seL4_RISCV_Default_VMAttributes);
        conditional_panic(err, "Failed to map sos address space");

        /* 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_Unify_Instruction(sos_cap, 0, PAGESIZE);

        pos += nbytes;
        dst += nbytes;
        src += nbytes;
    }
    return 0;
}
Ejemplo n.º 2
0
static void
_sos_page_map_5(void* token, seL4_Word kvaddr) {
    dprintf(3, "sos_page_map 5\n");

    sos_page_map_cont_t* cont = (sos_page_map_cont_t*)token;

    seL4_CPtr kframe_cap, frame_cap;

    if (!kvaddr) {
        dprintf(3, "_sos_page_map_5 failed to allocate memory for frame\n");
        cont->callback((void*)(cont->token), ENOMEM);
        free(cont);
        return;
    }

    int err = frame_get_cap(kvaddr, &kframe_cap);
    assert(!err); // There should be no error

    /* Copy the frame cap as we need to map it into 2 address spaces */
    frame_cap = cspace_copy_cap(cur_cspace, cur_cspace, kframe_cap, cont->permissions);
    if (frame_cap == CSPACE_NULL) {
        frame_free(kvaddr);
        cont->callback((void*)(cont->token), EFAULT);
        free(cont);
        return;
    }

    /* Map the frame into application's address space */
    err = _map_sel4_page(cont->as, frame_cap, cont->vpage, cont->permissions,
                         seL4_ARM_Default_VMAttributes);
    if (err) {
        frame_free(kvaddr);
        cspace_delete_cap(cur_cspace, frame_cap);
        cont->callback((void*)(cont->token), err);
        free(cont);
        return;
    }

    //set frame referenced
    frame_set_referenced(kvaddr);

    /* Insert PTE into application's pagetable */
    int x = PT_L1_INDEX(cont->vpage);
    int y = PT_L2_INDEX(cont->vpage);
    cont->as->as_pd_regs[x][y] = (kvaddr | PTE_IN_USE_BIT) & (~PTE_SWAPPED);
    cont->as->as_pd_caps[x][y] = frame_cap;

    dprintf(3, "_sos_page_map_5 called back up\n");
    /* Calling back up */
    cont->callback((void*)(cont->token), 0);
    free(cont);
    return;
}
Ejemplo n.º 3
0
int syscall_bind_async_tcb (struct pawpaw_event* evt) {
	evt->reply = seL4_MessageInfo_new (0, 0, 0, 1);

	seL4_CPtr our_cap = cspace_copy_cap (cur_cspace, current_thread->croot,
		evt->args[0], seL4_AllRights);
	
	if (!our_cap) {
		seL4_SetMR (0, 0);
	} else {
		seL4_SetMR (0, seL4_TCB_BindAEP (current_thread->tcb_cap, our_cap));
	}

	return PAWPAW_EVENT_NEEDS_REPLY;
}
Ejemplo n.º 4
0
Archivo: vm.c Proyecto: gapry/AOS
static int
_set_page_reference(addrspace_t *as, seL4_Word vaddr, uint32_t rights) {

    int err;

    seL4_CPtr kframe_cap, frame_cap;

    seL4_Word vpage = PAGE_ALIGN(vaddr);
    int x = PT_L1_INDEX(vpage);
    int y = PT_L2_INDEX(vpage);

    if (as->as_pd_regs[x] == NULL) {
        return EINVAL;
    }

    seL4_Word kvaddr = (as->as_pd_regs[x][y] & PTE_KVADDR_MASK);
    dprintf(3, "mapping back into kvaddr -> 0x%08x, vaddr = 0x%08x\n", kvaddr, vaddr);

    err = frame_get_cap(kvaddr, &kframe_cap);
    //assert(!err); // This kvaddr is ready to use, there should be no error

    /* Copy the frame cap as we need to map it into 2 address spaces */
    frame_cap = cspace_copy_cap(cur_cspace, cur_cspace, kframe_cap, rights);
    if (frame_cap == CSPACE_NULL) {
        dprintf(3, "vmf: failed copying frame cap\n");
        return EFAULT;
    }

    err = seL4_ARM_Page_Map(frame_cap, as->as_sel4_pd, vpage,
            rights, seL4_ARM_Default_VMAttributes);
    if(err == seL4_FailedLookup){
        dprintf(3, "vmf: failed mapping application frame to sel4\n");
        return EFAULT;
    }

    as->as_pd_caps[x][y] = frame_cap;

    err = frame_set_referenced(kvaddr);
    if(err){
        dprintf(3, "vmf: setting frame referenced error\n");
        return err;
    }

    return 0;
}
Ejemplo n.º 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);
}
Ejemplo n.º 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");
}
Ejemplo n.º 7
0
Archivo: elf.c Proyecto: ahixon/papaya
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;
}