diff -r 8c906f8f22fb lib/barrelfish/target/x86_32/pmap_target.c --- a/lib/barrelfish/target/x86_32/pmap_target.c Fri Nov 11 14:33:00 2011 +0100 +++ b/lib/barrelfish/target/x86_32/pmap_target.c Mon May 21 20:17:03 2012 +0800 @@ -417,7 +417,47 @@ static errval_t modify_flags(struct pmap *pmap, genvaddr_t vaddr, size_t size, vregion_flags_t flags, size_t *retsize) { - USER_PANIC("NYI"); + errval_t err, ret; + struct pmap_x86 *x86 = (struct pmap_x86 *)pmap; + size = ROUND_UP(size, X86_32_BASE_PAGE_SIZE); + + for (size_t i = 0; i < size; i += X86_32_BASE_PAGE_SIZE) { + // Find the page table + struct vnode* ptable; + err = get_ptable(x86, vaddr+i, &ptable); + if (err_is_fail(err) || (ptable == NULL)) { // not mapped + ret = LIB_ERR_PMAP_FIND_VNODE; + continue; + } + + // Find the page + struct vnode *vn = find_vnode(ptable, X86_32_PTABLE_BASE(vaddr + i)); + if (vn == NULL) { // not mapped + ret = LIB_ERR_PMAP_FIND_VNODE; + continue; + } + + // Unmap it in the kernel + err = vnode_unmap(ptable->u.vnode.cap, vn->entry); + if (err_is_fail(err)) { + return err_push(err, LIB_ERR_VNODE_UNMAP); + } + + // Remap with changed flags + paging_x86_32_flags_t pmap_flags = vregion_to_pmap_flag(flags); + err = vnode_map(ptable->u.vnode.cap, vn->u.frame.cap, vn->entry, + pmap_flags, vn->u.frame.offset); + if (err_is_fail(err)) { + return err_push(err, LIB_ERR_VNODE_MAP); + } + + vn->u.frame.flags = flags; + } + + if (retsize) { + *retsize = size; + } + return SYS_ERR_OK; }