make vfs & filesystems use failable copying
[minix3.git] / servers / vm / rs.c
blob493148f3dbd55e9396991ea2dda2d81f3f798534
2 #define _SYSTEM 1
4 #include <minix/callnr.h>
5 #include <minix/com.h>
6 #include <minix/config.h>
7 #include <minix/const.h>
8 #include <minix/ds.h>
9 #include <minix/endpoint.h>
10 #include <minix/minlib.h>
11 #include <minix/type.h>
12 #include <minix/ipc.h>
13 #include <minix/sysutil.h>
14 #include <minix/syslib.h>
15 #include <minix/safecopies.h>
16 #include <minix/bitmap.h>
18 #include <errno.h>
19 #include <string.h>
20 #include <env.h>
21 #include <stdio.h>
22 #include <assert.h>
24 #include "glo.h"
25 #include "proto.h"
26 #include "util.h"
27 #include "region.h"
29 /*===========================================================================*
30 * do_rs_set_priv *
31 *===========================================================================*/
32 int do_rs_set_priv(message *m)
34 int r, n, nr;
35 struct vmproc *vmp;
36 bitchunk_t call_mask[VM_CALL_MASK_SIZE], *call_mask_p;
38 nr = m->VM_RS_NR;
40 if ((r = vm_isokendpt(nr, &n)) != OK) {
41 printf("do_rs_set_priv: bad endpoint %d\n", nr);
42 return EINVAL;
45 vmp = &vmproc[n];
47 if (m->VM_RS_BUF) {
48 r = sys_datacopy(m->m_source, (vir_bytes) m->VM_RS_BUF, SELF,
49 (vir_bytes) call_mask, sizeof(call_mask));
50 if (r != OK)
51 return r;
52 call_mask_p = call_mask;
53 } else {
54 if (m->VM_RS_SYS) {
55 printf("VM: do_rs_set_priv: sys procs don't share!\n");
56 return EINVAL;
58 call_mask_p = NULL;
61 acl_set(vmp, call_mask_p, m->VM_RS_SYS);
63 return OK;
66 /*===========================================================================*
67 * do_rs_update *
68 *===========================================================================*/
69 int do_rs_update(message *m_ptr)
71 endpoint_t src_e, dst_e, reply_e;
72 int src_p, dst_p;
73 struct vmproc *src_vmp, *dst_vmp;
74 int r;
76 src_e = m_ptr->VM_RS_SRC_ENDPT;
77 dst_e = m_ptr->VM_RS_DST_ENDPT;
79 /* Lookup slots for source and destination process. */
80 if(vm_isokendpt(src_e, &src_p) != OK) {
81 printf("do_rs_update: bad src endpoint %d\n", src_e);
82 return EINVAL;
84 src_vmp = &vmproc[src_p];
85 if(vm_isokendpt(dst_e, &dst_p) != OK) {
86 printf("do_rs_update: bad dst endpoint %d\n", dst_e);
87 return EINVAL;
89 dst_vmp = &vmproc[dst_p];
91 /* Let the kernel do the update first. */
92 r = sys_update(src_e, dst_e);
93 if(r != OK) {
94 return r;
97 /* Do the update in VM now. */
98 r = swap_proc_slot(src_vmp, dst_vmp);
99 if(r != OK) {
100 return r;
102 r = swap_proc_dyn_data(src_vmp, dst_vmp);
103 if(r != OK) {
104 return r;
106 pt_bind(&src_vmp->vm_pt, src_vmp);
107 pt_bind(&dst_vmp->vm_pt, dst_vmp);
109 /* Reply, update-aware. */
110 reply_e = m_ptr->m_source;
111 if(reply_e == src_e) reply_e = dst_e;
112 else if(reply_e == dst_e) reply_e = src_e;
113 m_ptr->m_type = OK;
114 r = ipc_send(reply_e, m_ptr);
115 if(r != OK) {
116 panic("ipc_send() error");
119 return SUSPEND;
122 /*===========================================================================*
123 * rs_memctl_make_vm_instance *
124 *===========================================================================*/
125 static int rs_memctl_make_vm_instance(struct vmproc *new_vm_vmp)
127 int r;
128 u32_t flags;
129 int verify;
130 struct vmproc *this_vm_vmp;
132 this_vm_vmp = &vmproc[VM_PROC_NR];
134 /* Pin memory for the new VM instance. */
135 r = map_pin_memory(new_vm_vmp);
136 if(r != OK) {
137 return r;
140 /* Preallocate page tables for the entire address space for both
141 * VM and the new VM instance.
143 flags = 0;
144 verify = FALSE;
145 r = pt_ptalloc_in_range(&this_vm_vmp->vm_pt, 0, 0, flags, verify);
146 if(r != OK) {
147 return r;
149 r = pt_ptalloc_in_range(&new_vm_vmp->vm_pt, 0, 0, flags, verify);
150 if(r != OK) {
151 return r;
154 /* Let the new VM instance map VM's page tables and its own. */
155 r = pt_ptmap(this_vm_vmp, new_vm_vmp);
156 if(r != OK) {
157 return r;
159 r = pt_ptmap(new_vm_vmp, new_vm_vmp);
160 if(r != OK) {
161 return r;
164 return OK;
167 /*===========================================================================*
168 * do_rs_memctl *
169 *===========================================================================*/
170 int do_rs_memctl(message *m_ptr)
172 endpoint_t ep;
173 int req, r, proc_nr;
174 struct vmproc *vmp;
176 ep = m_ptr->VM_RS_CTL_ENDPT;
177 req = m_ptr->VM_RS_CTL_REQ;
179 /* Lookup endpoint. */
180 if ((r = vm_isokendpt(ep, &proc_nr)) != OK) {
181 printf("do_rs_memctl: bad endpoint %d\n", ep);
182 return EINVAL;
184 vmp = &vmproc[proc_nr];
186 /* Process request. */
187 switch(req)
189 case VM_RS_MEM_PIN:
191 /* Do not perform VM_RS_MEM_PIN yet - it costs the full
192 * size of the RS stack (64MB by default) in memory,
193 * and it's needed for functionality that isn't complete /
194 * merged in current Minix (surviving VM crashes).
197 #if 0
198 r = map_pin_memory(vmp);
199 return r;
200 #else
201 return OK;
202 #endif
204 case VM_RS_MEM_MAKE_VM:
205 r = rs_memctl_make_vm_instance(vmp);
206 return r;
207 default:
208 printf("do_rs_memctl: bad request %d\n", req);
209 return EINVAL;