]> Zhao Yanbai Git Server - minix.git/commitdiff
vm: Allow VM to make self calls when needed. 92/3092/2
authorCristiano Giuffrida <giuffrida@cs.vu.nl>
Tue, 11 Mar 2014 23:23:01 +0000 (00:23 +0100)
committerDavid van Moolenbroek <david@minix3.org>
Wed, 16 Sep 2015 11:06:51 +0000 (11:06 +0000)
Change-Id: I7aada24adad3dc6bfe5b0bd4a50b5005c79ff887

minix/servers/vm/acl.c
minix/servers/vm/mmap.c
minix/servers/vm/utility.c

index a31b22cf9c4fb4968802d2800d2f83b2b963679d..d7e11bde0a3582124d5e1d08d9374c32cc637b04 100644 (file)
@@ -36,6 +36,11 @@ acl_init(void)
 int
 acl_check(struct vmproc *vmp, int call)
 {
+
+       /* VM makes asynchronous calls to itself.  Always allow those. */
+       if (vmp->vm_endpoint == VM_PROC_NR)
+               return OK;
+
        /* If the process has no ACL, all calls are allowed.. for now. */
        if (vmp->vm_acl == NO_ACL) {
                printf("VM: calling process %u has no ACL!\n",
index 7279144826af862658c21e25d3a48d7d86b4a455..8c472a141b4321edf8075216cce6358f216eac3a 100644 (file)
@@ -483,6 +483,30 @@ int do_get_refcount(message *m)
        return r;
 }
 
+/*===========================================================================*
+ *                             munmap_vm_lin                                 *
+ *===========================================================================*/
+int munmap_vm_lin(vir_bytes addr, size_t len)
+{
+       if(addr % VM_PAGE_SIZE) {
+               printf("munmap_vm_lin: offset not page aligned\n");
+               return EFAULT;
+       }
+
+       if(len % VM_PAGE_SIZE) {
+               printf("munmap_vm_lin: len not page aligned\n");
+               return EFAULT;
+       }
+
+       if(pt_writemap(NULL, &vmproc[VM_PROC_NR].vm_pt, addr, MAP_NONE, len, 0,
+               WMF_OVERWRITE | WMF_FREE) != OK) {
+               printf("munmap_vm_lin: pt_writemap failed\n");
+               return EFAULT;
+       }
+
+       return OK;
+}
+
 /*===========================================================================*
  *                              do_munmap                                    *
  *===========================================================================*/
@@ -490,6 +514,7 @@ int do_munmap(message *m)
 {
         int r, n;
         struct vmproc *vmp;
+       struct vir_region *vr;
         vir_bytes addr, len;
        endpoint_t target = SELF;
 
@@ -505,9 +530,25 @@ int do_munmap(message *m)
         if((r=vm_isokendpt(target, &n)) != OK) {
                 panic("do_mmap: message from strange source: %d", m->m_source);
         }
+
         vmp = &vmproc[n];
 
+       if(m->m_source == VM_PROC_NR) {
+               /* VM munmap is a special case, the region we want to
+                * munmap may or may not be there in our data structures,
+                * depending on whether this is an updated VM instance or not.
+                */
+               if(!region_search_root(&vmp->vm_regions_avl)) {
+                       munmap_vm_lin(addr, m->VMUM_LEN);
+               }
+               else if((vr = map_lookup(vmp, addr, NULL))) {
+                       if(map_unmap_region(vmp, vr, 0, m->VMUM_LEN) != OK) {
+                               printf("VM: self map_unmap_region failed\n");
+                       }
+               }
+               return SUSPEND;
+       }
+
        if(m->m_type == VM_UNMAP_PHYS) {
                addr = (vir_bytes) m->m_lsys_vm_unmap_phys.vaddr;
        } else if(m->m_type == VM_SHM_UNMAP) {
index 63a6217ec615ce70a6f4a4f19f60cb9adc66ed55..81417870c1666ff66e943e7bc91b6681cc3b5bd6 100644 (file)
@@ -142,6 +142,9 @@ int do_info(message *m)
                break;
 
        case VMIW_REGION:
+               if(m->m_lsys_vm_info.ep == SELF) {
+                       m->m_lsys_vm_info.ep = m->m_source;
+               }
                if (vm_isokendpt(m->m_lsys_vm_info.ep, &pr) != OK)
                        return EINVAL;