From: Cristiano Giuffrida Date: Tue, 11 Mar 2014 22:22:55 +0000 (+0100) Subject: vm: Extend the vm_memctl() interface. X-Git-Url: http://zhaoyanbai.com/repos/%22http:/www.isc.org/icons/zpipe.c?a=commitdiff_plain;h=refs%2Fchanges%2F89%2F3089%2F2;p=minix.git vm: Extend the vm_memctl() interface. Change-Id: I87b7c188bd1fc54a3ec943e7ff1d05c6f4c8a56a --- diff --git a/minix/include/minix/com.h b/minix/include/minix/com.h index 5010cb3af..7cacd8cdf 100644 --- a/minix/include/minix/com.h +++ b/minix/include/minix/com.h @@ -713,6 +713,11 @@ # define VM_RS_CTL_REQ m1_i2 # define VM_RS_MEM_PIN 0 /* pin memory */ # define VM_RS_MEM_MAKE_VM 1 /* make VM instance */ +# define VM_RS_MEM_HEAP_PREALLOC 2 /* preallocate heap regions */ +# define VM_RS_MEM_MAP_PREALLOC 3 /* preallocate mmaped regions */ +# define VM_RS_MEM_GET_PREALLOC_MAP 4 /* get preallocated mmaped regions */ +# define VM_RS_CTL_ADDR m2_p1 +# define VM_RS_CTL_LEN m2_i3 #define VM_WATCH_EXIT (VM_RQ_BASE+43) diff --git a/minix/include/minix/vm.h b/minix/include/minix/vm.h index 9761502a5..f1b75259a 100644 --- a/minix/include/minix/vm.h +++ b/minix/include/minix/vm.h @@ -18,7 +18,7 @@ int vm_unmap_phys(endpoint_t who, void *vaddr, size_t len); int vm_notify_sig(endpoint_t ep, endpoint_t ipc_ep); int vm_set_priv(endpoint_t ep, void *buf, int sys_proc); int vm_update(endpoint_t src_e, endpoint_t dst_e, int flags); -int vm_memctl(endpoint_t ep, int req); +int vm_memctl(endpoint_t ep, int req, void** addr, size_t *len); int vm_query_exit(endpoint_t *endpt); int vm_watch_exit(endpoint_t ep); int minix_vfs_mmap(endpoint_t who, off_t offset, size_t len, diff --git a/minix/lib/libsys/vm_memctl.c b/minix/lib/libsys/vm_memctl.c index 1a4bea877..0637476cc 100644 --- a/minix/lib/libsys/vm_memctl.c +++ b/minix/lib/libsys/vm_memctl.c @@ -3,13 +3,27 @@ #include int -vm_memctl(endpoint_t ep, int req) +vm_memctl(endpoint_t ep, int req, void** addr, size_t *len) { message m; + int r; memset(&m, 0, sizeof(m)); m.VM_RS_CTL_ENDPT = ep; m.VM_RS_CTL_REQ = req; + m.VM_RS_CTL_ADDR = addr ? *addr : 0; + m.VM_RS_CTL_LEN = len ? *len : 0; - return _taskcall(VM_PROC_NR, VM_RS_MEMCTL, &m); + r = _taskcall(VM_PROC_NR, VM_RS_MEMCTL, &m); + if(r != OK) { + return r; + } + if(addr) { + *addr = m.VM_RS_CTL_ADDR; + } + if(addr) { + *len = m.VM_RS_CTL_LEN; + } + + return OK; } diff --git a/minix/servers/rs/manager.c b/minix/servers/rs/manager.c index 9fb6e2702..8c3f027cb 100644 --- a/minix/servers/rs/manager.c +++ b/minix/servers/rs/manager.c @@ -487,7 +487,7 @@ struct rproc *rp; || (s = sys_getpriv(&rp->r_priv, child_proc_nr_e)) != OK) { printf("RS: unable to set privilege structure: %d\n", s); cleanup_service(rp); - vm_memctl(RS_PROC_NR, VM_RS_MEM_PIN); + vm_memctl(RS_PROC_NR, VM_RS_MEM_PIN, 0, 0); return ENOMEM; } @@ -495,7 +495,7 @@ struct rproc *rp; if ((s = sched_init_proc(rp)) != OK) { printf("RS: unable to start scheduling: %d\n", s); cleanup_service(rp); - vm_memctl(RS_PROC_NR, VM_RS_MEM_PIN); + vm_memctl(RS_PROC_NR, VM_RS_MEM_PIN,0,0); return s; } @@ -511,7 +511,7 @@ struct rproc *rp; if ((s = read_exec(rp)) != OK) { printf("RS: read_exec failed: %d\n", s); cleanup_service(rp); - vm_memctl(RS_PROC_NR, VM_RS_MEM_PIN); + vm_memctl(RS_PROC_NR, VM_RS_MEM_PIN, 0, 0); return s; } } @@ -519,7 +519,7 @@ struct rproc *rp; printf("RS: execing child with srv_execve()...\n"); s = srv_execve(child_proc_nr_e, rp->r_exec, rp->r_exec_len, rp->r_argv, environ); - vm_memctl(RS_PROC_NR, VM_RS_MEM_PIN); + vm_memctl(RS_PROC_NR, VM_RS_MEM_PIN, 0, 0); if (s != OK) { printf("RS: srv_execve failed: %d\n", s); cleanup_service(rp); @@ -534,7 +534,7 @@ struct rproc *rp; if(rs_verbose) printf("RS: informing VM of instance %s\n", srv_to_string(rp)); - s = vm_memctl(rpub->endpoint, VM_RS_MEM_MAKE_VM); + s = vm_memctl(rpub->endpoint, VM_RS_MEM_MAKE_VM, 0, 0); if(s != OK) { printf("vm_memctl failed: %d\n", s); cleanup_service(rp); @@ -1129,7 +1129,7 @@ static int run_script(struct rproc *rp) return kill_service(rp,"can't let the script run",r); } /* Pin RS memory again after fork()ing. */ - vm_memctl(RS_PROC_NR, VM_RS_MEM_PIN); + vm_memctl(RS_PROC_NR, VM_RS_MEM_PIN, 0, 0); } return OK; } diff --git a/minix/servers/vm/rs.c b/minix/servers/vm/rs.c index 064f8de87..3587e8617 100644 --- a/minix/servers/vm/rs.c +++ b/minix/servers/vm/rs.c @@ -167,6 +167,65 @@ static int rs_memctl_make_vm_instance(struct vmproc *new_vm_vmp) return OK; } +/*===========================================================================* + * rs_memctl_heap_prealloc * + *===========================================================================*/ +static int rs_memctl_heap_prealloc(struct vmproc *vmp, + vir_bytes *addr, size_t *len) +{ + + /* + * XXX: Is this still needed? + */ + + return OK; +} + +/*===========================================================================* + * rs_memctl_map_prealloc * + *===========================================================================*/ +static int rs_memctl_map_prealloc(struct vmproc *vmp, + vir_bytes *addr, size_t *len) +{ +#if 0 + struct vir_region *vr; + if(*len <= 0) { + return EINVAL; + } + *len = CLICK_CEIL(*len); + + if(!(vr = map_page_region(vmp, VM_DATATOP - *len, VM_DATATOP, *len, + MAP_NONE, VR_ANON|VR_WRITABLE|VR_CONTIG, MF_PREALLOC))) { + return ENOMEM; + } + map_region_set_tag(vr, VRT_PREALLOC_MAP); + *addr = arch_map2vir(vmp, vr->vaddr); +#endif + return OK; +} + +/*===========================================================================* + * rs_memctl_get_prealloc_map * + *===========================================================================*/ +static int rs_memctl_get_prealloc_map(struct vmproc *vmp, + vir_bytes *addr, size_t *len) +{ +#if 0 + struct vir_region *vr; + + vr = map_region_lookup_tag(vmp, VRT_PREALLOC_MAP); + if(!vr) { + *addr = 0; + *len = 0; + } + else { + *addr = arch_map2vir(vmp, vr->vaddr); + *len = vr->length; + } +#endif + return OK; +} + /*===========================================================================* * do_rs_memctl * *===========================================================================*/ @@ -207,6 +266,15 @@ int do_rs_memctl(message *m_ptr) case VM_RS_MEM_MAKE_VM: r = rs_memctl_make_vm_instance(vmp); return r; + case VM_RS_MEM_HEAP_PREALLOC: + r = rs_memctl_heap_prealloc(vmp, (vir_bytes*) &m_ptr->VM_RS_CTL_ADDR, (size_t*) &m_ptr->VM_RS_CTL_LEN); + return r; + case VM_RS_MEM_MAP_PREALLOC: + r = rs_memctl_map_prealloc(vmp, (vir_bytes*) &m_ptr->VM_RS_CTL_ADDR, (size_t*) &m_ptr->VM_RS_CTL_LEN); + return r; + case VM_RS_MEM_GET_PREALLOC_MAP: + r = rs_memctl_get_prealloc_map(vmp, (vir_bytes*) &m_ptr->VM_RS_CTL_ADDR, (size_t*) &m_ptr->VM_RS_CTL_LEN); + return r; default: printf("do_rs_memctl: bad request %d\n", req); return EINVAL;