Added vm_modify_mapping syscall on pmem capabilities. Also lots of debugging printfs.
authorSimon Gerber <simugerber@student.ethz.ch>
Thu, 22 Nov 2012 14:53:14 +0000 (15:53 +0100)
committerSimon Gerber <simon.gerber@inf.ethz.ch>
Tue, 29 Jan 2013 10:31:00 +0000 (11:31 +0100)
errors/errno.fugu
include/arch/x86_64/barrelfish/invocations_arch.h
include/barrelfish/capabilities.h
include/barrelfish_kpi/capabilities.h
kernel/arch/x86_64/page_mappings_arch.c
kernel/arch/x86_64/syscall.c
kernel/include/paging_generic.h
kernel/include/syscall.h
kernel/syscall.c
lib/barrelfish/target/x86_64/pmap_target.c

index 58dc4de..aeed8a7 100644 (file)
@@ -65,13 +65,16 @@ errors kernel SYS_ERR_ {
     failure TYPE_NOT_CREATABLE  "Specified capability type is not creatable at runtime. Consider retyping it from another capability.",
 
     // errors specific to page mapping
-    failure VNODE_SLOT_INVALID  "Destination slot exceeds size of page table",
-    failure WRONG_MAPPING       "Wrong source/destination mapping type",
-    failure FRAME_OFFSET_INVALID "Specified offset exceeds size of frame",
-    failure VNODE_SLOT_RESERVED        "Destination slot is reserved",
-    failure VNODE_SLOT_INUSE   "Destination slot in use: unmap first",
-    failure VNODE_TYPE          "Encountered non-VNode capability when manipulating page tables",
-    failure VNODE_LOOKUP_NEXT   "Could not find next level page table",
+    failure VNODE_SLOT_INVALID      "Destination slot exceeds size of page table",
+    failure WRONG_MAPPING           "Wrong source/destination mapping type",
+    failure FRAME_OFFSET_INVALID    "Specified offset exceeds size of frame",
+    failure VNODE_SLOT_RESERVED     "Destination slot is reserved",
+    failure VNODE_SLOT_INUSE        "Destination slot in use: unmap first",
+    failure VNODE_TYPE              "Encountered non-VNode capability when manipulating page tables",
+    failure VNODE_LOOKUP_NEXT       "Could not find next level page table",
+    failure VM_MAP_START_UNALIGNED  "Mapping offset not aligned to BASE_PAGE_SIZE",
+    failure VM_MAP_SIZE             "Mapping size too large",
+    failure VM_MAP_OFFSET           "Mapping offset too large",
 
     // errors related to IRQ table
     failure IRQ_LOOKUP          "Specified capability was not found while inserting in IRQ table",
@@ -168,6 +171,7 @@ errors libbarrelfish LIB_ERR_ {
     failure VNODE_MAP           "Failure in vnode_map()",
     failure VNODE_UNMAP         "Failure in vnode_unmap()",
     failure IDC_ENDPOINT_ALLOC  "Failure in idc_endpoint_alloc()",
+    failure VM_MODIFY_MAPPING   "Failure in vm_modify_mapping()",
 
     failure SLOT_ALLOC_INIT     "Failure in slot_alloc_init()",
     failure SLOT_ALLOC_NO_SPACE    "Slot allocator is out of space",
index 86fcfc2..8a38beb 100644 (file)
@@ -201,6 +201,12 @@ static inline errval_t invoke_vnode_unmap(struct capref cap, size_t entry)
     return cap_invoke2(cap, VNodeCmd_Unmap, entry).error;
 }
 
+static inline errval_t
+invoke_vm_modify_mapping(struct capref mem, size_t page_count, uint64_t off)
+{
+    return cap_invoke3(mem, FrameCmd_Modify_Mapping, page_count, off).error;
+}
+
 /**
  * \brief Return the physical address and size of a frame capability
  *
index 3f4bff5..49adb23 100644 (file)
@@ -107,6 +107,12 @@ static inline errval_t vnode_unmap(struct capref pgtl, size_t entry)
     return invoke_vnode_unmap(pgtl, entry);
 }
 
+static inline errval_t
+vm_modify_mapping(struct capref mem, size_t page_count, uint64_t off)
+{
+    return invoke_vm_modify_mapping(mem, page_count, off);
+}
+
 /**
  * \brief Copy a capability between slots in CSpace
  *
index 4a58ef4..1729852 100644 (file)
@@ -157,6 +157,7 @@ enum dispatcher_cmd {
 enum frame_cmd {
     FrameCmd_Identify,   ///< Return physical address of frame
     FrameCmd_SCC_Identify,      ///< Return MC route to frame
+    FrameCmd_Modify_Mapping,    ///< Modify mapping meta data
 };
 
 /**
index 1f0b709..30f839e 100644 (file)
@@ -204,6 +204,26 @@ errval_t caps_copy_to_vnode(struct cte *dest_vnode_cte, cslot_t dest_slot,
 
     assert(handler_func != NULL);
     lvaddr_t pte;
+
+    size_t mapped_pages = src_cte->mapping_info.mapped_pages;
+
+    if (mapped_pages >= src_cte->mapping_info.page_count) {
+        // exceeded allowed page count for this mapping
+        printf("caps_copy_to_vnode: exceeded allowed page count for this mapping\n");
+        printf("                    mapped_pages = %zd, mapping_info.page_count = %zd\n",
+                mapped_pages, src_cte->mapping_info.page_count);
+        return SYS_ERR_VM_MAP_SIZE;
+    }
+
+    if ((param2 - src_cte->mapping_info.offset)/BASE_PAGE_SIZE >= src_cte->mapping_info.page_count) {
+        // requested map offset exceeds mapping region
+        printf("caps_copy_to_vnode: requested map offset exceeds mapping region\n");
+        printf("                    offset = %zd, mapping_info.offset = %zd, page_count = %zd",
+                param2, src_cte->mapping_info.offset,
+                src_cte->mapping_info.page_count);
+        return SYS_ERR_VM_MAP_OFFSET;
+    }
+
     errval_t r = handler_func(dest_cap, dest_slot, src_cap, param1, param2, &pte);
     if (err_is_ok(r)) {
         // update mapping
@@ -211,7 +231,6 @@ errval_t caps_copy_to_vnode(struct cte *dest_vnode_cte, cslot_t dest_slot,
         // or do the base page loop here
         if (src_cte->mapping_info.pte == 0) {
             src_cte->mapping_info.pte = pte;
-            src_cte->mapping_info.mapped_offset = param2;
         }
         src_cte->mapping_info.mapped_pages += 1;
         genvaddr_t vaddr = 0;
@@ -221,8 +240,8 @@ errval_t caps_copy_to_vnode(struct cte *dest_vnode_cte, cslot_t dest_slot,
             printf("error in compile_vaddr: 0x%"PRIxERRV"\n", r2);
         }
         //printf("src_cte->pte = %"PRIxLVADDR"\n", src_cte->mapping_info.pte);
-        printf("full vaddr of new mapping (entry = %"PRIuCSLOT"): 0x%"PRIxGENVADDR"\n",
-               dest_slot, vaddr);
+        //printf("full vaddr of new mapping (entry = %"PRIuCSLOT"): 0x%"PRIxGENVADDR"\n",
+        //       dest_slot, vaddr);
     }
     return r;
 }
index 5403d97..76f7a90 100644 (file)
@@ -138,7 +138,6 @@ static struct sysret handle_copy(struct capability *root,
     return copy_or_mint(root, args, false);
 }
 
-
 static struct sysret handle_delete_common(struct capability *root,
                                    uintptr_t *args,
                                    bool from_monitor)
@@ -410,6 +409,14 @@ static struct sysret handle_frame_identify(struct capability *to,
     };
 }
 
+static struct sysret handle_modify_mapping(struct capability *mem,
+                                           int cmd, uintptr_t *args)
+{
+    size_t page_count = args[0];
+    uint64_t off = args[1];
+    return sys_modify_mapping(mem, page_count, off);
+}
+
 static struct sysret handle_io(struct capability *to, int cmd, uintptr_t *args)
 {
     uint64_t    port = args[0];
@@ -673,10 +680,12 @@ static invocation_handler_t invocations[ObjType_Num][CAP_MAX_CMD] = {
         [DispatcherCmd_SetupGuest] = handle_dispatcher_setup_guest
     },
     [ObjType_Frame] = {
-        [FrameCmd_Identify] = handle_frame_identify
+        [FrameCmd_Identify] = handle_frame_identify,
+        [FrameCmd_Modify_Mapping] = handle_modify_mapping,
     },
     [ObjType_DevFrame] = {
-        [FrameCmd_Identify] = handle_frame_identify
+        [FrameCmd_Identify] = handle_frame_identify,
+        [FrameCmd_Modify_Mapping] = handle_modify_mapping,
     },
     [ObjType_CNode] = {
         [CNodeCmd_Copy]   = handle_copy,
@@ -688,15 +697,19 @@ static invocation_handler_t invocations[ObjType_Num][CAP_MAX_CMD] = {
     },
     [ObjType_VNode_x86_64_pml4] = {
         [VNodeCmd_Unmap] = handle_unmap,
+        [FrameCmd_Modify_Mapping] = handle_modify_mapping,
     },
     [ObjType_VNode_x86_64_pdpt] = {
         [VNodeCmd_Unmap] = handle_unmap,
+        [FrameCmd_Modify_Mapping] = handle_modify_mapping,
     },
     [ObjType_VNode_x86_64_pdir] = {
         [VNodeCmd_Unmap] = handle_unmap,
+        [FrameCmd_Modify_Mapping] = handle_modify_mapping,
     },
     [ObjType_VNode_x86_64_ptable] = {
         [VNodeCmd_Unmap] = handle_unmap,
+        [FrameCmd_Modify_Mapping] = handle_modify_mapping,
     },
     [ObjType_Kernel] = {
         [KernelCmd_Spawn_core]   = monitor_spawn_core,
index 159bdbb..030dd91 100644 (file)
 
 struct mapping_info {
     lvaddr_t pte;           ///< where the capability is mapped
-    size_t mapped_pages;    ///< the amount of mapped pages
-    size_t mapped_offset;   ///< the offset into the physical region identified by the capability where the mapping begins.
+    size_t mapped_pages;    ///< the amount of currently mapped pages
+    // target meta data
+    size_t page_count;      ///< the targeted amount of mapped pages
+    uint64_t offset;        ///< the offset into the physical region identified by the capability where the mapping begins.
 };
 
 struct cte;
index 012c4b5..6b2973f 100644 (file)
@@ -41,6 +41,7 @@ struct sysret
 sys_copy_or_mint(struct capability *root, capaddr_t destcn_cptr, cslot_t dest_slot,
                  capaddr_t source_cptr, int destcn_vbits, int source_vbits,
                  uintptr_t param1, uintptr_t param2, bool mint);
+struct sysret sys_modify_mapping(struct capability *mem, size_t page_count, uint64_t off);
 struct sysret sys_delete(struct capability *root, capaddr_t cptr, uint8_t bits,
                          bool from_monitor);
 struct sysret sys_revoke(struct capability *root, capaddr_t cptr, uint8_t bits,
index d5ee1ae..768fbef 100644 (file)
 #include <syscall.h>
 #include <barrelfish_kpi/syscalls.h>
 #include <capabilities.h>
+#include <cap_predicates.h>
 #include <mdb/mdb.h>
 #include <dispatch.h>
 #include <wakeup.h>
 #include <paging_kernel_helper.h>
+#include <paging_kernel_arch.h>
 #include <exec.h>
 #include <irq.h>
 #include <trace/trace.h>
@@ -331,6 +333,42 @@ sys_copy_or_mint(struct capability *root, capaddr_t destcn_cptr, cslot_t dest_sl
     }
 }
 
+static inline struct cte *cte_for_cap(struct capability *cap)
+{
+    return (struct cte *) (cap - offsetof(struct cte, cap));
+}
+
+struct sysret
+sys_modify_mapping(struct capability *mem, size_t page_count, uint64_t off)
+{
+    /* find cte belonging to cap */
+    struct cte *mem_cap = cte_for_cap(mem);
+    printf("0x%p, 0x%p\n", mem_cap, mem);
+
+    if (!type_is_vnode(mem->type) && mem->type != ObjType_Frame && mem->type != ObjType_DevFrame){
+        // this only works for mappable memory
+        return SYSRET(SYS_ERR_VNODE_TYPE);
+    }
+
+    genpaddr_t map_start = get_address(mem) + off;
+    genpaddr_t frame_end = get_address(mem) + get_size(mem);
+    size_t map_size = page_count*BASE_PAGE_SIZE;
+    if (map_start & BASE_PAGE_MASK) {
+        // return modify error if offset not aligned to base page size
+        return SYSRET(SYS_ERR_VM_MAP_START_UNALIGNED);
+    }
+    if ((map_start + map_size) > frame_end) {
+        // return modify error if offset + map_size after end of memory region
+        printf("map_start = 0x%"PRIxGENPADDR", map_size = %zd, frame_end = 0x%"PRIxGENPADDR"\n",
+                map_start, map_size, frame_end);
+        return SYSRET(SYS_ERR_VM_MAP_SIZE);
+    }
+    mem_cap->mapping_info.page_count = page_count;
+    mem_cap->mapping_info.offset = off;
+
+    return SYSRET(SYS_ERR_OK);
+}
+
 struct sysret sys_delete(struct capability *root, capaddr_t cptr, uint8_t bits,
                          bool from_monitor)
 {
index 23140af..b6570bd 100644 (file)
@@ -123,9 +123,15 @@ static errval_t alloc_vnode(struct pmap_x86 *pmap, struct vnode *root,
         return err_push(err, LIB_ERR_VNODE_CREATE);
     }
 
-    // TODO: setup mapping size
+    // setup mapping size
+    err = vm_modify_mapping(newvnode->u.vnode.cap, 1, 0);
+    if (err_is_fail(err)) {
+        printf("vm_modify_mapping returned an error: %s\n", err_getstring(err));
+        return err_push(err, LIB_ERR_VM_MODIFY_MAPPING);
+    }
 
     // Map it
+    printf("\talloc_vnode calling vnode_map()\n");
     err = vnode_map(root->u.vnode.cap, newvnode->u.vnode.cap, entry,
                     PTABLE_ACCESS_DEFAULT, 0);
     if (err_is_fail(err)) {
@@ -219,7 +225,13 @@ static errval_t do_map(struct pmap_x86 *pmap, genvaddr_t vaddr,
     errval_t err;
     paging_x86_64_flags_t pmap_flags = vregion_to_pmap_flag(flags);
 
-    // TODO: setup mapping info
+    // setup mapping info
+    size_t page_count = ROUND_UP(size, X86_64_BASE_PAGE_SIZE) / X86_64_BASE_PAGE_SIZE;
+    err = vm_modify_mapping(frame, page_count, offset);
+    if (err_is_fail(err)) {
+        printf("vm_modify_mapping returned an error: %s\n", err_getstring(err));
+        return err_push(err, LIB_ERR_VM_MODIFY_MAPPING);
+    }
 
     for (size_t i = offset; i < offset + size; i += X86_64_BASE_PAGE_SIZE) {
 
@@ -247,7 +259,7 @@ static errval_t do_map(struct pmap_x86 *pmap, genvaddr_t vaddr,
 
         // Map entry into the page table in the kernel
         uint32_t entry = X86_64_PTABLE_BASE(vaddr);
-        printf("mapping vaddr = 0x%"PRIxGENVADDR"\n", vaddr);
+        printf("\tdo_map calling vnode_map()\n");
         err = vnode_map(ptable->u.vnode.cap, frame, entry, pmap_flags, i);
         if (err_is_fail(err)) {
             return err_push(err, LIB_ERR_VNODE_MAP);
@@ -483,6 +495,7 @@ static errval_t modify_flags(struct pmap *pmap, genvaddr_t vaddr, size_t size,
 
         // Remap with changed flags
         paging_x86_64_flags_t pmap_flags = vregion_to_pmap_flag(flags);
+        printf("\tmodify_flags calling vnode_map()\n");
         err = vnode_map(ptable->u.vnode.cap, vn->u.frame.cap, vn->entry,
                         pmap_flags, vn->u.frame.offset);
         if (err_is_fail(err)) {