# 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)
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,
#include <string.h>
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;
}
|| (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;
}
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;
}
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;
}
}
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);
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);
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;
}
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 *
*===========================================================================*/
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;