xref: /minix3/minix/servers/vm/exit.c (revision 63483e02e6a5924979f1c177070e18c56323a45c)
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