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