From 65b4b95259c5be80f21ebbfbf258aa91c6ee12c5 Mon Sep 17 00:00:00 2001 From: Cristiano Giuffrida Date: Wed, 12 Mar 2014 00:23:01 +0100 Subject: [PATCH] vm: Allow VM to make self calls when needed. Change-Id: I7aada24adad3dc6bfe5b0bd4a50b5005c79ff887 --- minix/servers/vm/acl.c | 5 +++++ minix/servers/vm/mmap.c | 43 +++++++++++++++++++++++++++++++++++++- minix/servers/vm/utility.c | 3 +++ 3 files changed, 50 insertions(+), 1 deletion(-) diff --git a/minix/servers/vm/acl.c b/minix/servers/vm/acl.c index a31b22cf9..d7e11bde0 100644 --- a/minix/servers/vm/acl.c +++ b/minix/servers/vm/acl.c @@ -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", diff --git a/minix/servers/vm/mmap.c b/minix/servers/vm/mmap.c index 727914482..8c472a141 100644 --- a/minix/servers/vm/mmap.c +++ b/minix/servers/vm/mmap.c @@ -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) { diff --git a/minix/servers/vm/utility.c b/minix/servers/vm/utility.c index 63a6217ec..81417870c 100644 --- a/minix/servers/vm/utility.c +++ b/minix/servers/vm/utility.c @@ -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;