x86: Added mapped capability in unmap syscall arguments.
authorSimon Gerber <simugerber@student.ethz.ch>
Thu, 22 Nov 2012 14:53:29 +0000 (15:53 +0100)
committerSimon Gerber <simon.gerber@inf.ethz.ch>
Tue, 29 Jan 2013 10:31:06 +0000 (11:31 +0100)
12 files changed:
include/arch/x86_32/barrelfish/invocations_arch.h
include/arch/x86_64/barrelfish/invocations_arch.h
include/barrelfish/capabilities.h
kernel/arch/x86_32/page_mappings_arch.c
kernel/arch/x86_32/syscall.c
kernel/arch/x86_64/page_mappings_arch.c
kernel/arch/x86_64/syscall.c
kernel/include/capabilities.h
kernel/paging_generic.c
lib/barrelfish/target/x86_32/pmap_target.c
lib/barrelfish/target/x86_64/pmap_target.c
usr/bench/mem_bench/membench.c

index bb75c09..6032073 100644 (file)
@@ -246,13 +246,19 @@ static inline errval_t invoke_vnode_map(struct capref ptable, capaddr_t slot,
 }
 
 
-static inline errval_t invoke_vnode_unmap(struct capref cap, size_t entry, size_t pte_count)
+static inline errval_t invoke_vnode_unmap(struct capref cap, capaddr_t mapping_cptr, int mapping_bits, size_t entry, size_t pte_count)
 {
     uint8_t invoke_bits = get_cap_valid_bits(cap);
     capaddr_t invoke_cptr = get_cap_addr(cap) >> (CPTR_BITS - invoke_bits);
 
+    pte_count -= 1;
+
+    assert(entry < 1024);
+    assert(pte_count < 1024);
+    assert(mapping_bits <= 0xff);
+
     return syscall4((invoke_bits << 16) | (VNodeCmd_Unmap << 8) | SYSCALL_INVOKE,
-                    invoke_cptr, entry, pte_count).error;
+                    invoke_cptr, mapping_cptr, ((mapping_bits & 0xff)<<20) | ((pte_count & 0x3ff)<<10) | (entry & 0x3ff)).error;
 }
 
 /**
index 8ee7bde..850d387 100644 (file)
@@ -203,9 +203,10 @@ static inline errval_t invoke_vnode_map(struct capref ptable, capaddr_t slot,
     return cap_invoke7(ptable, VNodeCmd_Map, slot, src, frombits, flags, offset, pte_count).error;
 }
 
-static inline errval_t invoke_vnode_unmap(struct capref cap, size_t entry, size_t num_pages)
+static inline errval_t invoke_vnode_unmap(struct capref cap, capaddr_t mapping_addr,
+                                          int bits, size_t entry, size_t num_pages)
 {
-    return cap_invoke3(cap, VNodeCmd_Unmap, entry, num_pages).error;
+    return cap_invoke5(cap, VNodeCmd_Unmap, mapping_addr, bits, entry, num_pages).error;
 }
 
 /**
index e7bfa80..4638960 100644 (file)
@@ -99,9 +99,12 @@ vnode_map(struct capref dest, struct capref src, capaddr_t slot,
     return invoke_vnode_map(dest, slot, saddr, svbits, attr, off, pte_count);
 }
 
-static inline errval_t vnode_unmap(struct capref pgtl, size_t entry, size_t num_pages)
+static inline errval_t vnode_unmap(struct capref pgtl, struct capref mapping, size_t entry, size_t num_pages)
 {
-    return invoke_vnode_unmap(pgtl, entry, num_pages);
+    uint8_t bits = get_cap_valid_bits(mapping);
+    capaddr_t mapping_addr = get_cap_addr(mapping) >> (CPTR_BITS - bits);
+
+    return invoke_vnode_unmap(pgtl, mapping_addr, bits, entry, num_pages);
 }
 
 /**
index e86f18c..06e9f89 100644 (file)
@@ -318,15 +318,15 @@ static inline void read_pt_entry(struct capability *pgtable, size_t slot,
     }
 }
 
-errval_t page_mappings_unmap(struct capability *pgtable, size_t slot, size_t num_pages)
+errval_t page_mappings_unmap(struct capability *pgtable, struct cte *mapping, size_t slot, size_t num_pages)
 {
     assert(type_is_vnode(pgtable->type));
     //printf("page_mappings_unmap(%zd pages, slot = %zd)\n", num_pages, slot);
 
     // get page table entry data
     genpaddr_t paddr;
-    lpaddr_t pte;
-    read_pt_entry(pgtable, slot, &paddr, &pte, NULL);
+    //lpaddr_t pte;
+    read_pt_entry(pgtable, slot, &paddr, NULL, NULL);
     lvaddr_t pt = local_phys_to_mem(gen_phys_to_local_phys(get_address(pgtable)));
 
     // get virtual address of first page
@@ -338,16 +338,18 @@ errval_t page_mappings_unmap(struct capability *pgtable, size_t slot, size_t num
     // printf("num_pages = %zu\n", num_pages);
 
     // get cap for mapping
+    /*
     struct cte *mem;
     errval_t err = lookup_cap_for_mapping(paddr, pte, &mem);
     if (err_is_fail(err)) {
         printf("page_mappings_unmap: %ld\n", err);
         return err;
     }
+    */
     //printf("state before unmap: mapped_pages = %zd\n", mem->mapping_info.mapped_pages);
     //printf("state before unmap: num_pages    = %zd\n", num_pages);
 
-    if (num_pages != mem->mapping_info.pte_count) {
+    if (num_pages != mapping->mapping_info.pte_count) {
         // want to unmap a different amount of pages than was mapped
         return SYS_ERR_VM_MAP_SIZE;
     }
@@ -355,7 +357,7 @@ errval_t page_mappings_unmap(struct capability *pgtable, size_t slot, size_t num
     do_unmap(pt, slot, vaddr, num_pages);
 
     // update mapping info
-    memset(&mem->mapping_info, 0, sizeof(struct mapping_info));
+    memset(&mapping->mapping_info, 0, sizeof(struct mapping_info));
 
     do_tlb_flush();
 
index 175b2f1..538d192 100644 (file)
@@ -231,9 +231,21 @@ static struct sysret handle_map(struct capability *pgtable,
 static struct sysret handle_unmap(struct capability *pgtable,
                                   int cmd, uintptr_t *args)
 {
-    size_t entry = args[0];
-    size_t pte_count = args[1];
-    errval_t err = page_mappings_unmap(pgtable, entry, pte_count);
+    size_t mapping_caddr = args[0];
+    size_t entry = args[1] & 0x3ff;
+    size_t pte_count = (args[1]>>10) & 0x3ff;
+    pte_count += 1;
+    int mapping_bits = (args[1]>>20) & 0xff;
+
+    errval_t err;
+    struct cte *mapping = NULL;
+    err = caps_lookup_slot(&dcb_current->cspace.cap, mapping_caddr, mapping_bits,
+                           &mapping, CAPRIGHTS_READ_WRITE);
+    if (err_is_fail(err)) {
+        return SYSRET(err_push(err, SYS_ERR_CAP_NOT_FOUND));
+    }
+
+    err = page_mappings_unmap(pgtable, mapping, entry, pte_count);
     return SYSRET(err);
 }
 
index 8c87fde..6e9cf2f 100644 (file)
@@ -344,15 +344,17 @@ size_t do_unmap(lvaddr_t pt, cslot_t slot, genvaddr_t vaddr, size_t num_pages)
     return unmapped_pages;
 }
 
-errval_t page_mappings_unmap(struct capability *pgtable, size_t slot, size_t num_pages)
+errval_t page_mappings_unmap(struct capability *pgtable, struct cte *mapping, size_t slot, size_t num_pages)
 {
     assert(type_is_vnode(pgtable->type));
     //printf("page_mappings_unmap(%zd pages)\n", num_pages);
 
     // get page table entry data
     genpaddr_t paddr;
-    lvaddr_t pte;
-    read_pt_entry(pgtable, slot, &paddr, &pte, NULL);
+    /* lpaddr_t pte_ = mapping_cte->mapping_info.pte;
+    lvaddr_t pte = local_phys_to_mem(pte_); */
+
+    read_pt_entry(pgtable, slot, &paddr, NULL, NULL);
     lvaddr_t pt = local_phys_to_mem(gen_phys_to_local_phys(get_address(pgtable)));
 
     // get virtual address of first page
@@ -364,16 +366,16 @@ errval_t page_mappings_unmap(struct capability *pgtable, size_t slot, size_t num
     // printf("num_pages = %zu\n", num_pages);
 
     // get cap for mapping
-    struct cte *mem;
+    /* struct cte *mem;
     errval_t err = lookup_cap_for_mapping(paddr, pte, &mem);
     if (err_is_fail(err)) {
         printf("page_mappings_unmap: %ld\n", err);
         return err;
-    }
+    } */
     //printf("state before unmap: mapped_pages = %zd\n", mem->mapping_info.mapped_pages);
     //printf("state before unmap: num_pages    = %zd\n", num_pages);
 
-    if (num_pages != mem->mapping_info.pte_count) {
+    if (num_pages != mapping->mapping_info.pte_count) {
         // want to unmap a different amount of pages than was mapped
         return SYS_ERR_VM_MAP_SIZE;
     }
@@ -381,7 +383,7 @@ errval_t page_mappings_unmap(struct capability *pgtable, size_t slot, size_t num
     do_unmap(pt, slot, vaddr, num_pages);
 
     // update mapping info
-    memset(&mem->mapping_info, 0, sizeof(struct mapping_info));
+    memset(&mapping->mapping_info, 0, sizeof(struct mapping_info));
 
     // XXX: FIXME: Going to reload cr3 to flush the entire TLB.
     // This is inefficient.
index d796f7c..8bd216b 100644 (file)
@@ -189,9 +189,20 @@ static struct sysret handle_revoke(struct capability *root,
 static struct sysret handle_unmap(struct capability *pgtable,
                                   int cmd, uintptr_t *args)
 {
-    size_t entry = args[0];
-    size_t pages = args[1];
-    errval_t err = page_mappings_unmap(pgtable, entry, pages);
+    capaddr_t cptr = args[0];
+    int bits       = args[1];
+    size_t entry   = args[2];
+    size_t pages   = args[3];
+
+    errval_t err;
+    struct cte *mapping;
+    err = caps_lookup_slot(&dcb_current->cspace.cap, cptr, bits,
+                                    &mapping, CAPRIGHTS_READ_WRITE);
+    if (err_is_fail(err)) {
+        return SYSRET(err_push(err, SYS_ERR_CAP_NOT_FOUND));
+    }
+
+    err = page_mappings_unmap(pgtable, mapping, entry, pages);
     return SYSRET(err);
 }
 
index 7adb474..e47ecbd 100644 (file)
@@ -60,7 +60,7 @@ errval_t caps_copy_to_vnode(struct cte *dest_vnode_cte, cslot_t dest_slot,
                             struct cte *src_cte, uintptr_t flags,
                             uintptr_t offset, uintptr_t pte_count);
 size_t do_unmap(lvaddr_t pt, cslot_t slot, genvaddr_t vaddr, size_t num_pages);
-errval_t page_mappings_unmap(struct capability *pgtable, size_t entry, size_t num_pages);
+errval_t page_mappings_unmap(struct capability *pgtable, struct cte *mapping, size_t entry, size_t num_pages);
 void dump_hw_page_tables(struct dcb *dispatcher);
 
 errval_t caps_retype(enum objtype type, size_t objbits,
index 10667b9..09e8b61 100644 (file)
 
 static inline errval_t find_next_ptable(struct cte *old, struct cte **next)
 {
-    int result;
     errval_t err;
     if (old->mapping_info.pte) {
         err = mdb_find_cap_for_address(local_phys_to_gen_phys((lpaddr_t)old->mapping_info.pte), next);
         if (err_no(err) == CAPS_ERR_CAP_NOT_FOUND) {
-            printf("could not find cap associated with 0x%"PRIxLVADDR"\n", result, old->mapping_info.pte);
+            printf("could not find cap associated with 0x%"PRIxLPADDR"\n", old->mapping_info.pte);
             return SYS_ERR_VNODE_LOOKUP_NEXT;
         }
         if (err_is_fail(err)) {
index 2f758e0..b34b7fe 100644 (file)
@@ -489,7 +489,7 @@ static errval_t do_single_unmap(struct pmap_x86 *pmap, genvaddr_t vaddr, size_t
     if (pt) {
         struct vnode *page = find_vnode(pt, X86_32_PTABLE_BASE(vaddr));
         if (page && page->u.frame.pte_count == pte_count) {
-            err = vnode_unmap(pt->u.vnode.cap, page->entry, page->u.frame.pte_count);
+            err = vnode_unmap(pt->u.vnode.cap, page->u.frame.cap, page->entry, page->u.frame.pte_count);
             if (err_is_fail(err)) {
                 printf("vnode_unmap returned error: %s (%d)\n", err_getstring(err), err_no(err));
                 return err_push(err, LIB_ERR_VNODE_UNMAP);
index 096045c..ceee7bd 100644 (file)
@@ -495,7 +495,7 @@ static errval_t do_single_unmap(struct pmap_x86 *pmap, genvaddr_t vaddr, size_t
     if (pt) {
         struct vnode *page = find_vnode(pt, X86_64_PTABLE_BASE(vaddr));
         if (page && page->u.frame.pte_count == pte_count) {
-            err = vnode_unmap(pt->u.vnode.cap, page->entry, page->u.frame.pte_count);
+            err = vnode_unmap(pt->u.vnode.cap, page->u.frame.cap, page->entry, page->u.frame.pte_count);
             if (err_is_fail(err)) {
                 printf("vnode_unmap returned error: %s (%d)\n", err_getstring(err), err_no(err));
                 return err_push(err, LIB_ERR_VNODE_UNMAP);
@@ -604,7 +604,7 @@ static errval_t modify_flags(struct pmap *pmap, genvaddr_t vaddr, size_t size,
     if (pt) {
         struct vnode *page = find_vnode(pt, X86_64_PTABLE_BASE(vaddr));
         if (page) {
-            err = vnode_unmap(pt->u.vnode.cap, page->entry, pages);
+            err = vnode_unmap(pt->u.vnode.cap, page->u.frame.cap, page->entry, pages);
             if (err_is_fail(err)) {
                 printf("vnode_unmap returned error: %s (%"PRIuERRV")\n", err_getstring(err), err);
                 ret = err_push(err, LIB_ERR_VNODE_UNMAP);
index 993b4c3..287dc5a 100644 (file)
@@ -60,7 +60,7 @@ int main(int argc, char *argv[])
         if (runs[i] > THRESH) {
             runs[i] = BENCH_IGNORE_WATERMARK;
         }
-        err = vnode_unmap(pagetable,(cslot_t)(i%512),1);
+        err = vnode_unmap(pagetable,frame,(cslot_t)(i%512),1);
         assert(err_is_ok(err));
     }