vm: merge i386 and arm pagetable code
[minix.git] / servers / vm / rs.c
blobe932f6b14a6acc487f296bcb338108111138b0f2
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/keymap.h>
11 #include <minix/minlib.h>
12 #include <minix/type.h>
13 #include <minix/ipc.h>
14 #include <minix/sysutil.h>
15 #include <minix/syslib.h>
16 #include <minix/safecopies.h>
17 #include <minix/bitmap.h>
19 #include <errno.h>
20 #include <string.h>
21 #include <env.h>
22 #include <stdio.h>
23 #include <assert.h>
25 #include "glo.h"
26 #include "proto.h"
27 #include "util.h"
28 #include "region.h"
30 /*===========================================================================*
31 * do_rs_set_priv *
32 *===========================================================================*/
33 int do_rs_set_priv(message *m)
35 int r, n, nr;
36 struct vmproc *vmp;
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,
49 SELF, (vir_bytes) vmp->vm_call_mask,
50 sizeof(vmp->vm_call_mask));
51 if (r != OK)
52 return r;
55 return OK;
58 /*===========================================================================*
59 * do_rs_update *
60 *===========================================================================*/
61 int do_rs_update(message *m_ptr)
63 endpoint_t src_e, dst_e, reply_e;
64 int src_p, dst_p;
65 struct vmproc *src_vmp, *dst_vmp;
66 int r;
68 src_e = m_ptr->VM_RS_SRC_ENDPT;
69 dst_e = m_ptr->VM_RS_DST_ENDPT;
71 /* Lookup slots for source and destination process. */
72 if(vm_isokendpt(src_e, &src_p) != OK) {
73 printf("do_rs_update: bad src endpoint %d\n", src_e);
74 return EINVAL;
76 src_vmp = &vmproc[src_p];
77 if(vm_isokendpt(dst_e, &dst_p) != OK) {
78 printf("do_rs_update: bad dst endpoint %d\n", dst_e);
79 return EINVAL;
81 dst_vmp = &vmproc[dst_p];
83 /* Let the kernel do the update first. */
84 r = sys_update(src_e, dst_e);
85 if(r != OK) {
86 return r;
89 /* Do the update in VM now. */
90 r = swap_proc_slot(src_vmp, dst_vmp);
91 if(r != OK) {
92 return r;
94 r = swap_proc_dyn_data(src_vmp, dst_vmp);
95 if(r != OK) {
96 return r;
98 pt_bind(&src_vmp->vm_pt, src_vmp);
99 pt_bind(&dst_vmp->vm_pt, dst_vmp);
101 /* Reply, update-aware. */
102 reply_e = m_ptr->m_source;
103 if(reply_e == src_e) reply_e = dst_e;
104 else if(reply_e == dst_e) reply_e = src_e;
105 m_ptr->m_type = OK;
106 r = send(reply_e, m_ptr);
107 if(r != OK) {
108 panic("send() error");
111 return SUSPEND;
114 /*===========================================================================*
115 * rs_memctl_make_vm_instance *
116 *===========================================================================*/
117 static int rs_memctl_make_vm_instance(struct vmproc *new_vm_vmp)
119 int r;
120 u32_t flags;
121 int verify;
122 struct vmproc *this_vm_vmp;
124 this_vm_vmp = &vmproc[VM_PROC_NR];
126 /* Pin memory for the new VM instance. */
127 r = map_pin_memory(new_vm_vmp);
128 if(r != OK) {
129 return r;
132 /* Preallocate page tables for the entire address space for both
133 * VM and the new VM instance.
135 flags = 0;
136 verify = FALSE;
137 r = pt_ptalloc_in_range(&this_vm_vmp->vm_pt, 0, 0, flags, verify);
138 if(r != OK) {
139 return r;
141 r = pt_ptalloc_in_range(&new_vm_vmp->vm_pt, 0, 0, flags, verify);
142 if(r != OK) {
143 return r;
146 /* Let the new VM instance map VM's page tables and its own. */
147 r = pt_ptmap(this_vm_vmp, new_vm_vmp);
148 if(r != OK) {
149 return r;
151 r = pt_ptmap(new_vm_vmp, new_vm_vmp);
152 if(r != OK) {
153 return r;
156 return OK;
159 /*===========================================================================*
160 * do_rs_memctl *
161 *===========================================================================*/
162 int do_rs_memctl(message *m_ptr)
164 endpoint_t ep;
165 int req, r, proc_nr;
166 struct vmproc *vmp;
168 ep = m_ptr->VM_RS_CTL_ENDPT;
169 req = m_ptr->VM_RS_CTL_REQ;
171 /* Lookup endpoint. */
172 if ((r = vm_isokendpt(ep, &proc_nr)) != OK) {
173 printf("do_rs_memctl: bad endpoint %d\n", ep);
174 return EINVAL;
176 vmp = &vmproc[proc_nr];
178 /* Process request. */
179 switch(req)
181 case VM_RS_MEM_PIN:
183 /* Do not perform VM_RS_MEM_PIN yet - it costs the full
184 * size of the RS stack (64MB by default) in memory,
185 * and it's needed for functionality that isn't complete /
186 * merged in current Minix (surviving VM crashes).
189 #if 0
190 r = map_pin_memory(vmp);
191 return r;
192 #else
193 return OK;
194 #endif
196 case VM_RS_MEM_MAKE_VM:
197 r = rs_memctl_make_vm_instance(vmp);
198 return r;
199 default:
200 printf("do_rs_memctl: bad request %d\n", req);
201 return EINVAL;