1433d6423SLionel Sambuc 2433d6423SLionel Sambuc /* This file contains some utility routines for VM. */ 3433d6423SLionel Sambuc 4433d6423SLionel Sambuc #define _SYSTEM 1 5433d6423SLionel Sambuc 6433d6423SLionel Sambuc #include <minix/callnr.h> 7433d6423SLionel Sambuc #include <minix/com.h> 8433d6423SLionel Sambuc #include <minix/config.h> 9433d6423SLionel Sambuc #include <minix/const.h> 10433d6423SLionel Sambuc #include <minix/ds.h> 11433d6423SLionel Sambuc #include <minix/endpoint.h> 12433d6423SLionel Sambuc #include <minix/minlib.h> 13433d6423SLionel Sambuc #include <minix/type.h> 14433d6423SLionel Sambuc #include <minix/ipc.h> 15433d6423SLionel Sambuc #include <minix/sysutil.h> 16433d6423SLionel Sambuc #include <minix/syslib.h> 17433d6423SLionel Sambuc #include <minix/type.h> 18433d6423SLionel Sambuc #include <minix/bitmap.h> 1963483e02SCristiano Giuffrida #include <minix/rs.h> 20433d6423SLionel Sambuc #include <string.h> 21433d6423SLionel Sambuc #include <errno.h> 22433d6423SLionel Sambuc #include <env.h> 23433d6423SLionel Sambuc #include <unistd.h> 24433d6423SLionel Sambuc #include <assert.h> 25*d196e2c3SCristiano Giuffrida #include <sys/cdefs.h> 26433d6423SLionel Sambuc #include <sys/param.h> 27433d6423SLionel Sambuc #include <sys/mman.h> 28433d6423SLionel Sambuc #include <sys/resource.h> 29433d6423SLionel Sambuc 30433d6423SLionel Sambuc #include "proto.h" 31433d6423SLionel Sambuc #include "glo.h" 32433d6423SLionel Sambuc #include "util.h" 33433d6423SLionel Sambuc #include "region.h" 34433d6423SLionel Sambuc #include "sanitycheck.h" 35433d6423SLionel Sambuc 36433d6423SLionel Sambuc #include <machine/archtypes.h> 37433d6423SLionel Sambuc #include "kernel/const.h" 38433d6423SLionel Sambuc #include "kernel/config.h" 39433d6423SLionel Sambuc #include "kernel/type.h" 40433d6423SLionel Sambuc #include "kernel/proc.h" 41433d6423SLionel Sambuc 42433d6423SLionel Sambuc /*===========================================================================* 43433d6423SLionel Sambuc * get_mem_chunks * 44433d6423SLionel Sambuc *===========================================================================*/ 45433d6423SLionel Sambuc void get_mem_chunks( 46433d6423SLionel Sambuc struct memory *mem_chunks) /* store mem chunks here */ 47433d6423SLionel Sambuc { 48433d6423SLionel Sambuc /* Initialize the free memory list from the kernel-provided memory map. Translate 49433d6423SLionel Sambuc * the byte offsets and sizes in this list to clicks, properly truncated. 50433d6423SLionel Sambuc */ 51433d6423SLionel Sambuc phys_bytes base, size, limit; 52433d6423SLionel Sambuc int i; 53433d6423SLionel Sambuc struct memory *memp; 54433d6423SLionel Sambuc 55433d6423SLionel Sambuc /* Initialize everything to zero. */ 56433d6423SLionel Sambuc memset(mem_chunks, 0, NR_MEMS*sizeof(*mem_chunks)); 57433d6423SLionel Sambuc 58433d6423SLionel Sambuc /* Obtain and parse memory from kernel environment. */ 59433d6423SLionel Sambuc /* XXX Any memory chunk in excess of NR_MEMS is silently ignored. */ 60433d6423SLionel Sambuc for(i = 0; i < MIN(MAXMEMMAP, NR_MEMS); i++) { 61433d6423SLionel Sambuc mem_chunks[i].base = kernel_boot_info.memmap[i].mm_base_addr; 62433d6423SLionel Sambuc mem_chunks[i].size = kernel_boot_info.memmap[i].mm_length; 63433d6423SLionel Sambuc } 64433d6423SLionel Sambuc 65433d6423SLionel Sambuc /* Round physical memory to clicks. Round start up, round end down. */ 66433d6423SLionel Sambuc for (i = 0; i < NR_MEMS; i++) { 67433d6423SLionel Sambuc memp = &mem_chunks[i]; /* next mem chunk is stored here */ 68433d6423SLionel Sambuc base = mem_chunks[i].base; 69433d6423SLionel Sambuc size = mem_chunks[i].size; 70433d6423SLionel Sambuc limit = base + size; 71433d6423SLionel Sambuc base = (phys_bytes) (CLICK_CEIL(base)); 72433d6423SLionel Sambuc limit = (phys_bytes) (CLICK_FLOOR(limit)); 73433d6423SLionel Sambuc if (limit <= base) { 74433d6423SLionel Sambuc memp->base = memp->size = 0; 75433d6423SLionel Sambuc } else { 76433d6423SLionel Sambuc memp->base = base >> CLICK_SHIFT; 77433d6423SLionel Sambuc memp->size = (limit - base) >> CLICK_SHIFT; 78433d6423SLionel Sambuc } 79433d6423SLionel Sambuc } 80433d6423SLionel Sambuc } 81433d6423SLionel Sambuc 82433d6423SLionel Sambuc /*===========================================================================* 83433d6423SLionel Sambuc * vm_isokendpt * 84433d6423SLionel Sambuc *===========================================================================*/ 85433d6423SLionel Sambuc int vm_isokendpt(endpoint_t endpoint, int *procn) 86433d6423SLionel Sambuc { 87433d6423SLionel Sambuc *procn = _ENDPOINT_P(endpoint); 88433d6423SLionel Sambuc if(*procn < 0 || *procn >= NR_PROCS) 89433d6423SLionel Sambuc return EINVAL; 90433d6423SLionel Sambuc if(*procn >= 0 && endpoint != vmproc[*procn].vm_endpoint) 91433d6423SLionel Sambuc return EDEADEPT; 92433d6423SLionel Sambuc if(*procn >= 0 && !(vmproc[*procn].vm_flags & VMF_INUSE)) 93433d6423SLionel Sambuc return EDEADEPT; 94433d6423SLionel Sambuc return OK; 95433d6423SLionel Sambuc } 96433d6423SLionel Sambuc 97433d6423SLionel Sambuc 98433d6423SLionel Sambuc /*===========================================================================* 99433d6423SLionel Sambuc * do_info * 100433d6423SLionel Sambuc *===========================================================================*/ 101433d6423SLionel Sambuc int do_info(message *m) 102433d6423SLionel Sambuc { 103433d6423SLionel Sambuc struct vm_stats_info vsi; 104433d6423SLionel Sambuc struct vm_usage_info vui; 105433d6423SLionel Sambuc static struct vm_region_info vri[MAX_VRI_COUNT]; 106433d6423SLionel Sambuc struct vmproc *vmp; 107433d6423SLionel Sambuc vir_bytes addr, size, next, ptr; 108433d6423SLionel Sambuc int r, pr, dummy, count, free_pages, largest_contig; 109433d6423SLionel Sambuc 110433d6423SLionel Sambuc if (vm_isokendpt(m->m_source, &pr) != OK) 111433d6423SLionel Sambuc return EINVAL; 112433d6423SLionel Sambuc vmp = &vmproc[pr]; 113433d6423SLionel Sambuc 114433d6423SLionel Sambuc ptr = (vir_bytes) m->m_lsys_vm_info.ptr; 115433d6423SLionel Sambuc 116433d6423SLionel Sambuc switch(m->m_lsys_vm_info.what) { 117433d6423SLionel Sambuc case VMIW_STATS: 118433d6423SLionel Sambuc vsi.vsi_pagesize = VM_PAGE_SIZE; 119433d6423SLionel Sambuc vsi.vsi_total = total_pages; 120433d6423SLionel Sambuc memstats(&dummy, &free_pages, &largest_contig); 121433d6423SLionel Sambuc vsi.vsi_free = free_pages; 122433d6423SLionel Sambuc vsi.vsi_largest = largest_contig; 123433d6423SLionel Sambuc 124433d6423SLionel Sambuc get_stats_info(&vsi); 125433d6423SLionel Sambuc 126433d6423SLionel Sambuc addr = (vir_bytes) &vsi; 127433d6423SLionel Sambuc size = sizeof(vsi); 128433d6423SLionel Sambuc 129433d6423SLionel Sambuc break; 130433d6423SLionel Sambuc 131433d6423SLionel Sambuc case VMIW_USAGE: 132433d6423SLionel Sambuc if(m->m_lsys_vm_info.ep < 0) 133433d6423SLionel Sambuc get_usage_info_kernel(&vui); 134433d6423SLionel Sambuc else if (vm_isokendpt(m->m_lsys_vm_info.ep, &pr) != OK) 135433d6423SLionel Sambuc return EINVAL; 136433d6423SLionel Sambuc else get_usage_info(&vmproc[pr], &vui); 137433d6423SLionel Sambuc 138433d6423SLionel Sambuc addr = (vir_bytes) &vui; 139433d6423SLionel Sambuc size = sizeof(vui); 140433d6423SLionel Sambuc 141433d6423SLionel Sambuc break; 142433d6423SLionel Sambuc 143433d6423SLionel Sambuc case VMIW_REGION: 14465b4b952SCristiano Giuffrida if(m->m_lsys_vm_info.ep == SELF) { 14565b4b952SCristiano Giuffrida m->m_lsys_vm_info.ep = m->m_source; 14665b4b952SCristiano Giuffrida } 147433d6423SLionel Sambuc if (vm_isokendpt(m->m_lsys_vm_info.ep, &pr) != OK) 148433d6423SLionel Sambuc return EINVAL; 149433d6423SLionel Sambuc 150433d6423SLionel Sambuc count = MIN(m->m_lsys_vm_info.count, MAX_VRI_COUNT); 151433d6423SLionel Sambuc next = m->m_lsys_vm_info.next; 152433d6423SLionel Sambuc 153433d6423SLionel Sambuc count = get_region_info(&vmproc[pr], vri, count, &next); 154433d6423SLionel Sambuc 155433d6423SLionel Sambuc m->m_lsys_vm_info.count = count; 156433d6423SLionel Sambuc m->m_lsys_vm_info.next = next; 157433d6423SLionel Sambuc 158433d6423SLionel Sambuc addr = (vir_bytes) vri; 159433d6423SLionel Sambuc size = sizeof(vri[0]) * count; 160433d6423SLionel Sambuc 161433d6423SLionel Sambuc break; 162433d6423SLionel Sambuc 163433d6423SLionel Sambuc default: 164433d6423SLionel Sambuc return EINVAL; 165433d6423SLionel Sambuc } 166433d6423SLionel Sambuc 167433d6423SLionel Sambuc if (size == 0) 168433d6423SLionel Sambuc return OK; 169433d6423SLionel Sambuc 170433d6423SLionel Sambuc /* Make sure that no page faults can occur while copying out. A page 171433d6423SLionel Sambuc * fault would cause the kernel to send a notify to us, while we would 172433d6423SLionel Sambuc * be waiting for the result of the copy system call, resulting in a 173433d6423SLionel Sambuc * deadlock. Note that no memory mapping can be undone without the 174433d6423SLionel Sambuc * involvement of VM, so we are safe until we're done. 175433d6423SLionel Sambuc */ 176433d6423SLionel Sambuc r = handle_memory_once(vmp, ptr, size, 1 /*wrflag*/); 177433d6423SLionel Sambuc if (r != OK) return r; 178433d6423SLionel Sambuc 179433d6423SLionel Sambuc /* Now that we know the copy out will succeed, perform the actual copy 180433d6423SLionel Sambuc * operation. 181433d6423SLionel Sambuc */ 182433d6423SLionel Sambuc return sys_datacopy(SELF, addr, 183433d6423SLionel Sambuc (vir_bytes) vmp->vm_endpoint, ptr, size); 184433d6423SLionel Sambuc } 185433d6423SLionel Sambuc 186433d6423SLionel Sambuc /*===========================================================================* 187433d6423SLionel Sambuc * swap_proc_slot * 188433d6423SLionel Sambuc *===========================================================================*/ 189433d6423SLionel Sambuc int swap_proc_slot(struct vmproc *src_vmp, struct vmproc *dst_vmp) 190433d6423SLionel Sambuc { 191433d6423SLionel Sambuc struct vmproc orig_src_vmproc, orig_dst_vmproc; 192433d6423SLionel Sambuc 193433d6423SLionel Sambuc #if LU_DEBUG 194433d6423SLionel Sambuc printf("VM: swap_proc: swapping %d (%d) and %d (%d)\n", 195433d6423SLionel Sambuc src_vmp->vm_endpoint, src_vmp->vm_slot, 196433d6423SLionel Sambuc dst_vmp->vm_endpoint, dst_vmp->vm_slot); 197433d6423SLionel Sambuc #endif 198433d6423SLionel Sambuc 199433d6423SLionel Sambuc /* Save existing data. */ 200433d6423SLionel Sambuc orig_src_vmproc = *src_vmp; 201433d6423SLionel Sambuc orig_dst_vmproc = *dst_vmp; 202433d6423SLionel Sambuc 203433d6423SLionel Sambuc /* Swap slots. */ 204433d6423SLionel Sambuc *src_vmp = orig_dst_vmproc; 205433d6423SLionel Sambuc *dst_vmp = orig_src_vmproc; 206433d6423SLionel Sambuc 207433d6423SLionel Sambuc /* Preserve endpoints and slot numbers. */ 208433d6423SLionel Sambuc src_vmp->vm_endpoint = orig_src_vmproc.vm_endpoint; 209433d6423SLionel Sambuc src_vmp->vm_slot = orig_src_vmproc.vm_slot; 210433d6423SLionel Sambuc dst_vmp->vm_endpoint = orig_dst_vmproc.vm_endpoint; 211433d6423SLionel Sambuc dst_vmp->vm_slot = orig_dst_vmproc.vm_slot; 212433d6423SLionel Sambuc 213433d6423SLionel Sambuc #if LU_DEBUG 214433d6423SLionel Sambuc printf("VM: swap_proc: swapped %d (%d) and %d (%d)\n", 215433d6423SLionel Sambuc src_vmp->vm_endpoint, src_vmp->vm_slot, 216433d6423SLionel Sambuc dst_vmp->vm_endpoint, dst_vmp->vm_slot); 217433d6423SLionel Sambuc #endif 218433d6423SLionel Sambuc 219433d6423SLionel Sambuc return OK; 220433d6423SLionel Sambuc } 221433d6423SLionel Sambuc 222433d6423SLionel Sambuc /*===========================================================================* 223433d6423SLionel Sambuc * swap_proc_dyn_data * 224433d6423SLionel Sambuc *===========================================================================*/ 22563483e02SCristiano Giuffrida int swap_proc_dyn_data(struct vmproc *src_vmp, struct vmproc *dst_vmp, 22663483e02SCristiano Giuffrida int sys_upd_flags) 227433d6423SLionel Sambuc { 228433d6423SLionel Sambuc int is_vm; 229433d6423SLionel Sambuc int r; 23063483e02SCristiano Giuffrida struct vir_region *start_vr, *end_vr; 231433d6423SLionel Sambuc 232433d6423SLionel Sambuc is_vm = (dst_vmp->vm_endpoint == VM_PROC_NR); 233433d6423SLionel Sambuc 23463483e02SCristiano Giuffrida /* For VM, transfer memory mapped regions first. */ 235433d6423SLionel Sambuc if(is_vm) { 236433d6423SLionel Sambuc #if LU_DEBUG 23763483e02SCristiano Giuffrida printf("VM: swap_proc_dyn_data: tranferring memory mapped regions from old (%d) to new VM (%d)\n", 238433d6423SLionel Sambuc src_vmp->vm_endpoint, dst_vmp->vm_endpoint); 239433d6423SLionel Sambuc #endif 24063483e02SCristiano Giuffrida r = pt_map_in_range(src_vmp, dst_vmp, VM_OWN_HEAPBASE, VM_OWN_MMAPTOP); 241433d6423SLionel Sambuc if(r != OK) { 242433d6423SLionel Sambuc printf("swap_proc_dyn_data: pt_map_in_range failed\n"); 243433d6423SLionel Sambuc return r; 244433d6423SLionel Sambuc } 245433d6423SLionel Sambuc } 246433d6423SLionel Sambuc 247433d6423SLionel Sambuc #if LU_DEBUG 248433d6423SLionel Sambuc printf("VM: swap_proc_dyn_data: swapping regions' parents for %d (%d) and %d (%d)\n", 249433d6423SLionel Sambuc src_vmp->vm_endpoint, src_vmp->vm_slot, 250433d6423SLionel Sambuc dst_vmp->vm_endpoint, dst_vmp->vm_slot); 251433d6423SLionel Sambuc #endif 252433d6423SLionel Sambuc 253433d6423SLionel Sambuc /* Swap vir_regions' parents. */ 254433d6423SLionel Sambuc map_setparent(src_vmp); 255433d6423SLionel Sambuc map_setparent(dst_vmp); 256433d6423SLionel Sambuc 25763483e02SCristiano Giuffrida /* Don't transfer mmapped regions if not required. */ 25863483e02SCristiano Giuffrida if(is_vm || (sys_upd_flags & (SF_VM_ROLLBACK|SF_VM_NOMMAP))) { 25963483e02SCristiano Giuffrida return OK; 26063483e02SCristiano Giuffrida } 26163483e02SCristiano Giuffrida 26263483e02SCristiano Giuffrida /* Make sure regions are consistent. */ 26363483e02SCristiano Giuffrida assert(region_search_root(&src_vmp->vm_regions_avl) && region_search_root(&dst_vmp->vm_regions_avl)); 26463483e02SCristiano Giuffrida 26563483e02SCristiano Giuffrida /* Transfer memory mapped regions now. To sandbox the new instance and 26663483e02SCristiano Giuffrida * prevent state corruption on rollback, we share all the regions 26763483e02SCristiano Giuffrida * between the two instances as COW. 268433d6423SLionel Sambuc */ 26963483e02SCristiano Giuffrida start_vr = region_search(&dst_vmp->vm_regions_avl, VM_MMAPBASE, AVL_GREATER_EQUAL); 27063483e02SCristiano Giuffrida end_vr = region_search(&dst_vmp->vm_regions_avl, VM_MMAPTOP, AVL_LESS); 27163483e02SCristiano Giuffrida if(start_vr) { 272433d6423SLionel Sambuc #if LU_DEBUG 27363483e02SCristiano Giuffrida printf("VM: swap_proc_dyn_data: tranferring memory mapped regions from %d to %d\n", 27463483e02SCristiano Giuffrida dst_vmp->vm_endpoint, src_vmp->vm_endpoint); 275433d6423SLionel Sambuc #endif 27663483e02SCristiano Giuffrida assert(end_vr); 27763483e02SCristiano Giuffrida r = map_proc_copy_range(src_vmp, dst_vmp, start_vr, end_vr); 278433d6423SLionel Sambuc if(r != OK) { 279433d6423SLionel Sambuc return r; 280433d6423SLionel Sambuc } 281433d6423SLionel Sambuc } 282433d6423SLionel Sambuc 283433d6423SLionel Sambuc return OK; 284433d6423SLionel Sambuc } 285433d6423SLionel Sambuc 286433d6423SLionel Sambuc void *mmap(void *addr, size_t len, int f, int f2, int f3, off_t o) 287433d6423SLionel Sambuc { 288433d6423SLionel Sambuc void *ret; 289433d6423SLionel Sambuc phys_bytes p; 290433d6423SLionel Sambuc 291433d6423SLionel Sambuc assert(!addr); 292433d6423SLionel Sambuc assert(!(len % VM_PAGE_SIZE)); 293433d6423SLionel Sambuc 294433d6423SLionel Sambuc ret = vm_allocpages(&p, VMP_SLAB, len/VM_PAGE_SIZE); 295433d6423SLionel Sambuc 296433d6423SLionel Sambuc if(!ret) return MAP_FAILED; 297433d6423SLionel Sambuc memset(ret, 0, len); 298433d6423SLionel Sambuc return ret; 299433d6423SLionel Sambuc } 300433d6423SLionel Sambuc 301433d6423SLionel Sambuc int munmap(void * addr, size_t len) 302433d6423SLionel Sambuc { 303433d6423SLionel Sambuc vm_freepages((vir_bytes) addr, roundup(len, VM_PAGE_SIZE)/VM_PAGE_SIZE); 304433d6423SLionel Sambuc return 0; 305433d6423SLionel Sambuc } 306433d6423SLionel Sambuc 307*d196e2c3SCristiano Giuffrida #ifdef __weak_alias 308*d196e2c3SCristiano Giuffrida __weak_alias(brk, _brk) 309*d196e2c3SCristiano Giuffrida #endif 310*d196e2c3SCristiano Giuffrida int _brk(void *addr) 311433d6423SLionel Sambuc { 312433d6423SLionel Sambuc /* brk is a special case function to allow vm itself to 313433d6423SLionel Sambuc allocate memory in it's own (cacheable) HEAP */ 314433d6423SLionel Sambuc vir_bytes target = roundup((vir_bytes)addr, VM_PAGE_SIZE), v; 315433d6423SLionel Sambuc extern char _end; 316433d6423SLionel Sambuc extern char *_brksize; 317433d6423SLionel Sambuc static vir_bytes prevbrk = (vir_bytes) &_end; 318433d6423SLionel Sambuc struct vmproc *vmprocess = &vmproc[VM_PROC_NR]; 319433d6423SLionel Sambuc 320433d6423SLionel Sambuc for(v = roundup(prevbrk, VM_PAGE_SIZE); v < target; 321433d6423SLionel Sambuc v += VM_PAGE_SIZE) { 322433d6423SLionel Sambuc phys_bytes mem, newpage = alloc_mem(1, 0); 323433d6423SLionel Sambuc if(newpage == NO_MEM) return -1; 324433d6423SLionel Sambuc mem = CLICK2ABS(newpage); 325433d6423SLionel Sambuc if(pt_writemap(vmprocess, &vmprocess->vm_pt, 326433d6423SLionel Sambuc v, mem, VM_PAGE_SIZE, 327433d6423SLionel Sambuc ARCH_VM_PTE_PRESENT 328433d6423SLionel Sambuc | ARCH_VM_PTE_USER 329433d6423SLionel Sambuc | ARCH_VM_PTE_RW 330433d6423SLionel Sambuc #if defined(__arm__) 331433d6423SLionel Sambuc | ARM_VM_PTE_CACHED 332433d6423SLionel Sambuc #endif 333433d6423SLionel Sambuc , 0) != OK) { 334433d6423SLionel Sambuc free_mem(newpage, 1); 335433d6423SLionel Sambuc return -1; 336433d6423SLionel Sambuc } 337433d6423SLionel Sambuc prevbrk = v + VM_PAGE_SIZE; 338433d6423SLionel Sambuc } 339433d6423SLionel Sambuc 340433d6423SLionel Sambuc _brksize = (char *) addr; 341433d6423SLionel Sambuc 342433d6423SLionel Sambuc if(sys_vmctl(SELF, VMCTL_FLUSHTLB, 0) != OK) 343433d6423SLionel Sambuc panic("flushtlb failed"); 344433d6423SLionel Sambuc 345433d6423SLionel Sambuc return 0; 346433d6423SLionel Sambuc } 347433d6423SLionel Sambuc 348433d6423SLionel Sambuc /*===========================================================================* 349433d6423SLionel Sambuc * do_getrusage * 350433d6423SLionel Sambuc *===========================================================================*/ 351433d6423SLionel Sambuc int do_getrusage(message *m) 352433d6423SLionel Sambuc { 353433d6423SLionel Sambuc int res, slot; 354433d6423SLionel Sambuc struct vmproc *vmp; 355433d6423SLionel Sambuc struct rusage r_usage; 356433d6423SLionel Sambuc if ((res = vm_isokendpt(m->m_source, &slot)) != OK) 357433d6423SLionel Sambuc return ESRCH; 358433d6423SLionel Sambuc 359433d6423SLionel Sambuc vmp = &vmproc[slot]; 360433d6423SLionel Sambuc 361433d6423SLionel Sambuc if ((res = sys_datacopy(m->m_source, m->m_lc_vm_rusage.addr, 362433d6423SLionel Sambuc SELF, (vir_bytes) &r_usage, (vir_bytes) sizeof(r_usage))) < 0) 363433d6423SLionel Sambuc return res; 364433d6423SLionel Sambuc 365433d6423SLionel Sambuc r_usage.ru_maxrss = vmp->vm_total_max; 366433d6423SLionel Sambuc r_usage.ru_minflt = vmp->vm_minor_page_fault; 367433d6423SLionel Sambuc r_usage.ru_majflt = vmp->vm_major_page_fault; 368433d6423SLionel Sambuc 369433d6423SLionel Sambuc return sys_datacopy(SELF, (vir_bytes) &r_usage, m->m_source, 370433d6423SLionel Sambuc m->m_lc_vm_rusage.addr, (vir_bytes) sizeof(r_usage)); 371433d6423SLionel Sambuc } 37263483e02SCristiano Giuffrida 37363483e02SCristiano Giuffrida /*===========================================================================* 37463483e02SCristiano Giuffrida * adjust_proc_refs * 37563483e02SCristiano Giuffrida *===========================================================================*/ 37663483e02SCristiano Giuffrida void adjust_proc_refs() 37763483e02SCristiano Giuffrida { 37863483e02SCristiano Giuffrida struct vmproc *vmp; 37963483e02SCristiano Giuffrida region_iter iter; 38063483e02SCristiano Giuffrida 38163483e02SCristiano Giuffrida /* Fix up region parents. */ 38263483e02SCristiano Giuffrida for(vmp = vmproc; vmp < &vmproc[VMP_NR]; vmp++) { 38363483e02SCristiano Giuffrida struct vir_region *vr; 38463483e02SCristiano Giuffrida if(!(vmp->vm_flags & VMF_INUSE)) 38563483e02SCristiano Giuffrida continue; 38663483e02SCristiano Giuffrida region_start_iter_least(&vmp->vm_regions_avl, &iter); 38763483e02SCristiano Giuffrida while((vr = region_get_iter(&iter))) { 38863483e02SCristiano Giuffrida USE(vr, vr->parent = vmp;); 38963483e02SCristiano Giuffrida region_incr_iter(&iter); 39063483e02SCristiano Giuffrida } 39163483e02SCristiano Giuffrida } 39263483e02SCristiano Giuffrida } 39363483e02SCristiano Giuffrida 394