1 2 #define _SYSTEM 1 3 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> 17 18 #include <errno.h> 19 #include <string.h> 20 #include <env.h> 21 #include <stdio.h> 22 #include <assert.h> 23 24 #include "glo.h" 25 #include "proto.h" 26 #include "util.h" 27 #include "region.h" 28 29 /*===========================================================================* 30 * do_rs_set_priv * 31 *===========================================================================*/ 32 int do_rs_set_priv(message *m) 33 { 34 int r, n, nr; 35 struct vmproc *vmp; 36 bitchunk_t call_mask[VM_CALL_MASK_SIZE], *call_mask_p; 37 38 nr = m->VM_RS_NR; 39 40 if ((r = vm_isokendpt(nr, &n)) != OK) { 41 printf("do_rs_set_priv: bad endpoint %d\n", nr); 42 return EINVAL; 43 } 44 45 vmp = &vmproc[n]; 46 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; 57 } 58 call_mask_p = NULL; 59 } 60 61 acl_set(vmp, call_mask_p, m->VM_RS_SYS); 62 63 return OK; 64 } 65 66 /*===========================================================================* 67 * do_rs_update * 68 *===========================================================================*/ 69 int do_rs_update(message *m_ptr) 70 { 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; 75 76 src_e = m_ptr->m_lsys_vm_update.src; 77 dst_e = m_ptr->m_lsys_vm_update.dst; 78 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; 83 } 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; 88 } 89 dst_vmp = &vmproc[dst_p]; 90 91 /* Let the kernel do the update first. */ 92 r = sys_update(src_e, dst_e); 93 if(r != OK) { 94 return r; 95 } 96 97 /* Do the update in VM now. */ 98 r = swap_proc_slot(src_vmp, dst_vmp); 99 if(r != OK) { 100 return r; 101 } 102 r = swap_proc_dyn_data(src_vmp, dst_vmp); 103 if(r != OK) { 104 return r; 105 } 106 pt_bind(&src_vmp->vm_pt, src_vmp); 107 pt_bind(&dst_vmp->vm_pt, dst_vmp); 108 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"); 117 } 118 119 return SUSPEND; 120 } 121 122 /*===========================================================================* 123 * rs_memctl_make_vm_instance * 124 *===========================================================================*/ 125 static int rs_memctl_make_vm_instance(struct vmproc *new_vm_vmp) 126 { 127 int r; 128 u32_t flags; 129 int verify; 130 struct vmproc *this_vm_vmp; 131 132 this_vm_vmp = &vmproc[VM_PROC_NR]; 133 134 /* Pin memory for the new VM instance. */ 135 r = map_pin_memory(new_vm_vmp); 136 if(r != OK) { 137 return r; 138 } 139 140 /* Preallocate page tables for the entire address space for both 141 * VM and the new VM instance. 142 */ 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; 148 } 149 r = pt_ptalloc_in_range(&new_vm_vmp->vm_pt, 0, 0, flags, verify); 150 if(r != OK) { 151 return r; 152 } 153 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; 158 } 159 r = pt_ptmap(new_vm_vmp, new_vm_vmp); 160 if(r != OK) { 161 return r; 162 } 163 164 return OK; 165 } 166 167 /*===========================================================================* 168 * do_rs_memctl * 169 *===========================================================================*/ 170 int do_rs_memctl(message *m_ptr) 171 { 172 endpoint_t ep; 173 int req, r, proc_nr; 174 struct vmproc *vmp; 175 176 ep = m_ptr->VM_RS_CTL_ENDPT; 177 req = m_ptr->VM_RS_CTL_REQ; 178 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; 183 } 184 vmp = &vmproc[proc_nr]; 185 186 /* Process request. */ 187 switch(req) 188 { 189 case VM_RS_MEM_PIN: 190 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). 195 */ 196 197 #if 0 198 r = map_pin_memory(vmp); 199 return r; 200 #else 201 return OK; 202 #endif 203 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; 210 } 211 } 212 213