mkfs: support indirect blocks in directories
[minix.git] / servers / vm / rs.c
blob5fef8c4470ec9a5c1938a98608e4efa90a1f07e7
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>
24 #include <memory.h>
26 #include "glo.h"
27 #include "proto.h"
28 #include "util.h"
29 #include "region.h"
31 /*===========================================================================*
32 * do_rs_set_priv *
33 *===========================================================================*/
34 int do_rs_set_priv(message *m)
36 int r, n, nr;
37 struct vmproc *vmp;
39 nr = m->VM_RS_NR;
41 if ((r = vm_isokendpt(nr, &n)) != OK) {
42 printf("do_rs_set_priv: bad endpoint %d\n", nr);
43 return EINVAL;
46 vmp = &vmproc[n];
48 if (m->VM_RS_BUF) {
49 r = sys_datacopy(m->m_source, (vir_bytes) m->VM_RS_BUF,
50 SELF, (vir_bytes) vmp->vm_call_mask,
51 sizeof(vmp->vm_call_mask));
52 if (r != OK)
53 return r;
56 return OK;
59 /*===========================================================================*
60 * do_rs_update *
61 *===========================================================================*/
62 int do_rs_update(message *m_ptr)
64 endpoint_t src_e, dst_e, reply_e;
65 int src_p, dst_p;
66 struct vmproc *src_vmp, *dst_vmp;
67 int r;
69 src_e = m_ptr->VM_RS_SRC_ENDPT;
70 dst_e = m_ptr->VM_RS_DST_ENDPT;
72 /* Lookup slots for source and destination process. */
73 if(vm_isokendpt(src_e, &src_p) != OK) {
74 printf("do_rs_update: bad src endpoint %d\n", src_e);
75 return EINVAL;
77 src_vmp = &vmproc[src_p];
78 if(vm_isokendpt(dst_e, &dst_p) != OK) {
79 printf("do_rs_update: bad dst endpoint %d\n", dst_e);
80 return EINVAL;
82 dst_vmp = &vmproc[dst_p];
84 /* Let the kernel do the update first. */
85 r = sys_update(src_e, dst_e);
86 if(r != OK) {
87 return r;
90 /* Do the update in VM now. */
91 r = swap_proc_slot(src_vmp, dst_vmp);
92 if(r != OK) {
93 return r;
95 r = swap_proc_dyn_data(src_vmp, dst_vmp);
96 if(r != OK) {
97 return r;
99 pt_bind(&src_vmp->vm_pt, src_vmp);
100 pt_bind(&dst_vmp->vm_pt, dst_vmp);
102 /* Reply, update-aware. */
103 reply_e = m_ptr->m_source;
104 if(reply_e == src_e) reply_e = dst_e;
105 else if(reply_e == dst_e) reply_e = src_e;
106 m_ptr->m_type = OK;
107 r = send(reply_e, m_ptr);
108 if(r != OK) {
109 panic("send() error");
112 return SUSPEND;
115 /*===========================================================================*
116 * rs_memctl_make_vm_instance *
117 *===========================================================================*/
118 static int rs_memctl_make_vm_instance(struct vmproc *new_vm_vmp)
120 int r;
121 u32_t flags;
122 int verify;
123 struct vmproc *this_vm_vmp;
125 this_vm_vmp = &vmproc[VM_PROC_NR];
127 /* Pin memory for the new VM instance. */
128 r = map_pin_memory(new_vm_vmp);
129 if(r != OK) {
130 return r;
133 /* Preallocate page tables for the entire address space for both
134 * VM and the new VM instance.
136 flags = 0;
137 verify = FALSE;
138 r = pt_ptalloc_in_range(&this_vm_vmp->vm_pt, 0, 0, flags, verify);
139 if(r != OK) {
140 return r;
142 r = pt_ptalloc_in_range(&new_vm_vmp->vm_pt, 0, 0, flags, verify);
143 if(r != OK) {
144 return r;
147 /* Let the new VM instance map VM's page tables and its own. */
148 r = pt_ptmap(this_vm_vmp, new_vm_vmp);
149 if(r != OK) {
150 return r;
152 r = pt_ptmap(new_vm_vmp, new_vm_vmp);
153 if(r != OK) {
154 return r;
157 return OK;
160 /*===========================================================================*
161 * do_rs_memctl *
162 *===========================================================================*/
163 int do_rs_memctl(message *m_ptr)
165 endpoint_t ep;
166 int req, r, proc_nr;
167 struct vmproc *vmp;
169 ep = m_ptr->VM_RS_CTL_ENDPT;
170 req = m_ptr->VM_RS_CTL_REQ;
172 /* Lookup endpoint. */
173 if ((r = vm_isokendpt(ep, &proc_nr)) != OK) {
174 printf("do_rs_memctl: bad endpoint %d\n", ep);
175 return EINVAL;
177 vmp = &vmproc[proc_nr];
179 /* Process request. */
180 switch(req)
182 case VM_RS_MEM_PIN:
184 /* Do not perform VM_RS_MEM_PIN yet - it costs the full
185 * size of the RS stack (64MB by default) in memory,
186 * and it's needed for functionality that isn't complete /
187 * merged in current Minix (surviving VM crashes).
190 #if 0
191 r = map_pin_memory(vmp);
192 return r;
193 #else
194 return OK;
195 #endif
197 case VM_RS_MEM_MAKE_VM:
198 r = rs_memctl_make_vm_instance(vmp);
199 return r;
200 default:
201 printf("do_rs_memctl: bad request %d\n", req);
202 return EINVAL;