1433d6423SLionel Sambuc 2433d6423SLionel Sambuc #define _SYSTEM 1 3433d6423SLionel Sambuc 4433d6423SLionel Sambuc #include <minix/callnr.h> 5433d6423SLionel Sambuc #include <minix/com.h> 6433d6423SLionel Sambuc #include <minix/config.h> 7433d6423SLionel Sambuc #include <minix/const.h> 8433d6423SLionel Sambuc #include <minix/ds.h> 9433d6423SLionel Sambuc #include <minix/endpoint.h> 10433d6423SLionel Sambuc #include <minix/minlib.h> 11433d6423SLionel Sambuc #include <minix/type.h> 12433d6423SLionel Sambuc #include <minix/ipc.h> 13433d6423SLionel Sambuc #include <minix/sysutil.h> 14433d6423SLionel Sambuc #include <minix/syslib.h> 15433d6423SLionel Sambuc #include <minix/bitmap.h> 16433d6423SLionel Sambuc 17433d6423SLionel Sambuc #include <errno.h> 18433d6423SLionel Sambuc #include <assert.h> 19433d6423SLionel Sambuc #include <env.h> 20433d6423SLionel Sambuc 21433d6423SLionel Sambuc #include "glo.h" 22433d6423SLionel Sambuc #include "proto.h" 23433d6423SLionel Sambuc #include "util.h" 24433d6423SLionel Sambuc #include "sanitycheck.h" 25433d6423SLionel Sambuc 26433d6423SLionel Sambuc static void reset_vm_rusage(struct vmproc *vmp) 27433d6423SLionel Sambuc { 28433d6423SLionel Sambuc vmp->vm_total = 0; 29433d6423SLionel Sambuc vmp->vm_total_max = 0; 30433d6423SLionel Sambuc vmp->vm_minor_page_fault = 0; 31433d6423SLionel Sambuc vmp->vm_major_page_fault = 0; 32433d6423SLionel Sambuc } 33433d6423SLionel Sambuc 34433d6423SLionel Sambuc void free_proc(struct vmproc *vmp) 35433d6423SLionel Sambuc { 36433d6423SLionel Sambuc map_free_proc(vmp); 37433d6423SLionel Sambuc pt_free(&vmp->vm_pt); 38433d6423SLionel Sambuc region_init(&vmp->vm_regions_avl); 39433d6423SLionel Sambuc #if VMSTATS 40433d6423SLionel Sambuc vmp->vm_bytecopies = 0; 41433d6423SLionel Sambuc #endif 42433d6423SLionel Sambuc vmp->vm_region_top = 0; 43433d6423SLionel Sambuc reset_vm_rusage(vmp); 44433d6423SLionel Sambuc } 45433d6423SLionel Sambuc 46433d6423SLionel Sambuc void clear_proc(struct vmproc *vmp) 47433d6423SLionel Sambuc { 48433d6423SLionel Sambuc region_init(&vmp->vm_regions_avl); 49433d6423SLionel Sambuc acl_clear(vmp); 50433d6423SLionel Sambuc vmp->vm_flags = 0; /* Clear INUSE, so slot is free. */ 51433d6423SLionel Sambuc #if VMSTATS 52433d6423SLionel Sambuc vmp->vm_bytecopies = 0; 53433d6423SLionel Sambuc #endif 54433d6423SLionel Sambuc vmp->vm_region_top = 0; 55433d6423SLionel Sambuc reset_vm_rusage(vmp); 56433d6423SLionel Sambuc } 57433d6423SLionel Sambuc 58433d6423SLionel Sambuc /*===========================================================================* 59433d6423SLionel Sambuc * do_exit * 60433d6423SLionel Sambuc *===========================================================================*/ 61433d6423SLionel Sambuc int do_exit(message *msg) 62433d6423SLionel Sambuc { 63433d6423SLionel Sambuc int proc; 64433d6423SLionel Sambuc struct vmproc *vmp; 65433d6423SLionel Sambuc 66433d6423SLionel Sambuc SANITYCHECK(SCL_FUNCTIONS); 67433d6423SLionel Sambuc 68433d6423SLionel Sambuc if(vm_isokendpt(msg->VME_ENDPOINT, &proc) != OK) { 69433d6423SLionel Sambuc printf("VM: bogus endpoint VM_EXIT %d\n", msg->VME_ENDPOINT); 70433d6423SLionel Sambuc return EINVAL; 71433d6423SLionel Sambuc } 72433d6423SLionel Sambuc vmp = &vmproc[proc]; 73433d6423SLionel Sambuc 74433d6423SLionel Sambuc if(!(vmp->vm_flags & VMF_EXITING)) { 75433d6423SLionel Sambuc printf("VM: unannounced VM_EXIT %d\n", msg->VME_ENDPOINT); 76433d6423SLionel Sambuc return EINVAL; 77433d6423SLionel Sambuc } 78*63483e02SCristiano Giuffrida if(vmp->vm_flags & VMF_VM_INSTANCE) { 79*63483e02SCristiano Giuffrida vmp->vm_flags &= ~VMF_VM_INSTANCE; 80*63483e02SCristiano Giuffrida num_vm_instances--; 81*63483e02SCristiano Giuffrida } 82433d6423SLionel Sambuc 83433d6423SLionel Sambuc { 84433d6423SLionel Sambuc /* Free pagetable and pages allocated by pt code. */ 85433d6423SLionel Sambuc SANITYCHECK(SCL_DETAIL); 86433d6423SLionel Sambuc free_proc(vmp); 87433d6423SLionel Sambuc SANITYCHECK(SCL_DETAIL); 88433d6423SLionel Sambuc } 89433d6423SLionel Sambuc SANITYCHECK(SCL_DETAIL); 90433d6423SLionel Sambuc 91433d6423SLionel Sambuc /* Reset process slot fields. */ 92433d6423SLionel Sambuc clear_proc(vmp); 93433d6423SLionel Sambuc 94433d6423SLionel Sambuc SANITYCHECK(SCL_FUNCTIONS); 95433d6423SLionel Sambuc return OK; 96433d6423SLionel Sambuc } 97433d6423SLionel Sambuc 98433d6423SLionel Sambuc /*===========================================================================* 99433d6423SLionel Sambuc * do_willexit * 100433d6423SLionel Sambuc *===========================================================================*/ 101433d6423SLionel Sambuc int do_willexit(message *msg) 102433d6423SLionel Sambuc { 103433d6423SLionel Sambuc int proc; 104433d6423SLionel Sambuc struct vmproc *vmp; 105433d6423SLionel Sambuc 106433d6423SLionel Sambuc if(vm_isokendpt(msg->VMWE_ENDPOINT, &proc) != OK) { 107433d6423SLionel Sambuc printf("VM: bogus endpoint VM_EXITING %d\n", 108433d6423SLionel Sambuc msg->VMWE_ENDPOINT); 109433d6423SLionel Sambuc return EINVAL; 110433d6423SLionel Sambuc } 111433d6423SLionel Sambuc vmp = &vmproc[proc]; 112433d6423SLionel Sambuc 113433d6423SLionel Sambuc vmp->vm_flags |= VMF_EXITING; 114433d6423SLionel Sambuc 115433d6423SLionel Sambuc return OK; 116433d6423SLionel Sambuc } 117433d6423SLionel Sambuc 118433d6423SLionel Sambuc int do_procctl(message *msg, int transid) 119433d6423SLionel Sambuc { 120433d6423SLionel Sambuc endpoint_t proc; 121433d6423SLionel Sambuc struct vmproc *vmp; 122433d6423SLionel Sambuc 123433d6423SLionel Sambuc if(vm_isokendpt(msg->VMPCTL_WHO, &proc) != OK) { 124433d6423SLionel Sambuc printf("VM: bogus endpoint VM_PROCCTL %ld\n", 125433d6423SLionel Sambuc msg->VMPCTL_WHO); 126433d6423SLionel Sambuc return EINVAL; 127433d6423SLionel Sambuc } 128433d6423SLionel Sambuc vmp = &vmproc[proc]; 129433d6423SLionel Sambuc 130433d6423SLionel Sambuc switch(msg->VMPCTL_PARAM) { 131433d6423SLionel Sambuc case VMPPARAM_CLEAR: 132433d6423SLionel Sambuc if(msg->m_source != RS_PROC_NR 133433d6423SLionel Sambuc && msg->m_source != VFS_PROC_NR) 134433d6423SLionel Sambuc return EPERM; 135433d6423SLionel Sambuc free_proc(vmp); 136433d6423SLionel Sambuc if(pt_new(&vmp->vm_pt) != OK) 137433d6423SLionel Sambuc panic("VMPPARAM_CLEAR: pt_new failed"); 138433d6423SLionel Sambuc pt_bind(&vmp->vm_pt, vmp); 139433d6423SLionel Sambuc return OK; 140433d6423SLionel Sambuc case VMPPARAM_HANDLEMEM: 141433d6423SLionel Sambuc { 142433d6423SLionel Sambuc if(msg->m_source != VFS_PROC_NR) 143433d6423SLionel Sambuc return EPERM; 144433d6423SLionel Sambuc 145433d6423SLionel Sambuc handle_memory_start(vmp, msg->VMPCTL_M1, 146433d6423SLionel Sambuc msg->VMPCTL_LEN, msg->VMPCTL_FLAGS, 147433d6423SLionel Sambuc VFS_PROC_NR, VFS_PROC_NR, transid, 1); 148433d6423SLionel Sambuc 149433d6423SLionel Sambuc return SUSPEND; 150433d6423SLionel Sambuc } 151433d6423SLionel Sambuc default: 152433d6423SLionel Sambuc return EINVAL; 153433d6423SLionel Sambuc } 154433d6423SLionel Sambuc 155433d6423SLionel Sambuc return OK; 156433d6423SLionel Sambuc } 157433d6423SLionel Sambuc 158