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