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> 25d196e2c3SCristiano 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 222*95cb9397SDavid van Moolenbroek /* 223*95cb9397SDavid van Moolenbroek * Transfer memory mapped regions, using CoW sharing, from 'src_vmp' to 224*95cb9397SDavid van Moolenbroek * 'dst_vmp', for the source process's address range of 'start_addr' 225*95cb9397SDavid van Moolenbroek * (inclusive) to 'end_addr' (exclusive). Return OK or an error code. 226*95cb9397SDavid van Moolenbroek */ 227*95cb9397SDavid van Moolenbroek static int 228*95cb9397SDavid van Moolenbroek transfer_mmap_regions(struct vmproc *dst_vmp, struct vmproc *src_vmp, 229*95cb9397SDavid van Moolenbroek vir_bytes start_addr, vir_bytes end_addr) 230*95cb9397SDavid van Moolenbroek { 231*95cb9397SDavid van Moolenbroek struct vir_region *start_vr, *end_vr; 232*95cb9397SDavid van Moolenbroek 233*95cb9397SDavid van Moolenbroek start_vr = region_search(&src_vmp->vm_regions_avl, start_addr, 234*95cb9397SDavid van Moolenbroek AVL_GREATER_EQUAL); 235*95cb9397SDavid van Moolenbroek 236*95cb9397SDavid van Moolenbroek if (start_vr == NULL || start_vr->vaddr >= end_addr) 237*95cb9397SDavid van Moolenbroek return OK; /* nothing to do */ 238*95cb9397SDavid van Moolenbroek 239*95cb9397SDavid van Moolenbroek end_vr = region_search(&src_vmp->vm_regions_avl, end_addr, AVL_LESS); 240*95cb9397SDavid van Moolenbroek assert(end_vr != NULL); 241*95cb9397SDavid van Moolenbroek assert(start_vr->vaddr <= end_vr->vaddr); 242*95cb9397SDavid van Moolenbroek 243*95cb9397SDavid van Moolenbroek #if LU_DEBUG 244*95cb9397SDavid van Moolenbroek printf("VM: transfer_mmap_regions: transferring memory mapped regions " 245*95cb9397SDavid van Moolenbroek "from %d to %d (0x%lx to 0x%lx)\n", src_vmp->vm_endpoint, 246*95cb9397SDavid van Moolenbroek dst_vmp->vm_endpoint, start_vr->vaddr, end_vr->vaddr); 247*95cb9397SDavid van Moolenbroek #endif 248*95cb9397SDavid van Moolenbroek 249*95cb9397SDavid van Moolenbroek return map_proc_copy_range(dst_vmp, src_vmp, start_vr, end_vr); 250*95cb9397SDavid van Moolenbroek } 251*95cb9397SDavid van Moolenbroek 252433d6423SLionel Sambuc /*===========================================================================* 253433d6423SLionel Sambuc * swap_proc_dyn_data * 254433d6423SLionel Sambuc *===========================================================================*/ 25563483e02SCristiano Giuffrida int swap_proc_dyn_data(struct vmproc *src_vmp, struct vmproc *dst_vmp, 25663483e02SCristiano Giuffrida int sys_upd_flags) 257433d6423SLionel Sambuc { 258433d6423SLionel Sambuc int is_vm; 259433d6423SLionel Sambuc int r; 260433d6423SLionel Sambuc 261433d6423SLionel Sambuc is_vm = (dst_vmp->vm_endpoint == VM_PROC_NR); 262433d6423SLionel Sambuc 26363483e02SCristiano Giuffrida /* For VM, transfer memory mapped regions first. */ 264433d6423SLionel Sambuc if(is_vm) { 265433d6423SLionel Sambuc #if LU_DEBUG 26663483e02SCristiano Giuffrida printf("VM: swap_proc_dyn_data: tranferring memory mapped regions from old (%d) to new VM (%d)\n", 267433d6423SLionel Sambuc src_vmp->vm_endpoint, dst_vmp->vm_endpoint); 268433d6423SLionel Sambuc #endif 26963483e02SCristiano Giuffrida r = pt_map_in_range(src_vmp, dst_vmp, VM_OWN_HEAPBASE, VM_OWN_MMAPTOP); 270433d6423SLionel Sambuc if(r != OK) { 271433d6423SLionel Sambuc printf("swap_proc_dyn_data: pt_map_in_range failed\n"); 272433d6423SLionel Sambuc return r; 273433d6423SLionel Sambuc } 274a6db4d0aSDirk Vogt r = pt_map_in_range(src_vmp, dst_vmp, VM_STACKTOP, VM_DATATOP); 275a6db4d0aSDirk Vogt if(r != OK) { 276a6db4d0aSDirk Vogt printf("swap_proc_dyn_data: pt_map_in_range failed\n"); 277a6db4d0aSDirk Vogt return r; 278a6db4d0aSDirk Vogt } 279a6db4d0aSDirk Vogt 280433d6423SLionel Sambuc } 281433d6423SLionel Sambuc 282433d6423SLionel Sambuc #if LU_DEBUG 283433d6423SLionel Sambuc printf("VM: swap_proc_dyn_data: swapping regions' parents for %d (%d) and %d (%d)\n", 284433d6423SLionel Sambuc src_vmp->vm_endpoint, src_vmp->vm_slot, 285433d6423SLionel Sambuc dst_vmp->vm_endpoint, dst_vmp->vm_slot); 286433d6423SLionel Sambuc #endif 287433d6423SLionel Sambuc 288433d6423SLionel Sambuc /* Swap vir_regions' parents. */ 289433d6423SLionel Sambuc map_setparent(src_vmp); 290433d6423SLionel Sambuc map_setparent(dst_vmp); 291433d6423SLionel Sambuc 29263483e02SCristiano Giuffrida /* Don't transfer mmapped regions if not required. */ 29363483e02SCristiano Giuffrida if(is_vm || (sys_upd_flags & (SF_VM_ROLLBACK|SF_VM_NOMMAP))) { 29463483e02SCristiano Giuffrida return OK; 29563483e02SCristiano Giuffrida } 29663483e02SCristiano Giuffrida 29763483e02SCristiano Giuffrida /* Make sure regions are consistent. */ 29863483e02SCristiano Giuffrida assert(region_search_root(&src_vmp->vm_regions_avl) && region_search_root(&dst_vmp->vm_regions_avl)); 29963483e02SCristiano Giuffrida 30063483e02SCristiano Giuffrida /* Transfer memory mapped regions now. To sandbox the new instance and 30163483e02SCristiano Giuffrida * prevent state corruption on rollback, we share all the regions 302*95cb9397SDavid van Moolenbroek * between the two instances as COW. Source and destination are 303*95cb9397SDavid van Moolenbroek * intentionally swapped in these calls! 304433d6423SLionel Sambuc */ 305*95cb9397SDavid van Moolenbroek r = transfer_mmap_regions(src_vmp, dst_vmp, VM_MMAPBASE, VM_MMAPTOP); 306433d6423SLionel Sambuc 307a6db4d0aSDirk Vogt /* If the stack is not mapped at the VM_DATATOP, there might be some 308a6db4d0aSDirk Vogt * more regions hiding above the stack. We also have to transfer 309a6db4d0aSDirk Vogt * those. 310a6db4d0aSDirk Vogt */ 311*95cb9397SDavid van Moolenbroek if (r == OK && VM_STACKTOP < VM_DATATOP) 312*95cb9397SDavid van Moolenbroek r = transfer_mmap_regions(src_vmp, dst_vmp, VM_STACKTOP, 313*95cb9397SDavid van Moolenbroek VM_DATATOP); 314a6db4d0aSDirk Vogt 315a6db4d0aSDirk Vogt return r; 316a6db4d0aSDirk Vogt } 317433d6423SLionel Sambuc 318433d6423SLionel Sambuc void *mmap(void *addr, size_t len, int f, int f2, int f3, off_t o) 319433d6423SLionel Sambuc { 320433d6423SLionel Sambuc void *ret; 321433d6423SLionel Sambuc phys_bytes p; 322433d6423SLionel Sambuc 323433d6423SLionel Sambuc assert(!addr); 324433d6423SLionel Sambuc assert(!(len % VM_PAGE_SIZE)); 325433d6423SLionel Sambuc 326433d6423SLionel Sambuc ret = vm_allocpages(&p, VMP_SLAB, len/VM_PAGE_SIZE); 327433d6423SLionel Sambuc 328433d6423SLionel Sambuc if(!ret) return MAP_FAILED; 329433d6423SLionel Sambuc memset(ret, 0, len); 330433d6423SLionel Sambuc return ret; 331433d6423SLionel Sambuc } 332433d6423SLionel Sambuc 333433d6423SLionel Sambuc int munmap(void * addr, size_t len) 334433d6423SLionel Sambuc { 335433d6423SLionel Sambuc vm_freepages((vir_bytes) addr, roundup(len, VM_PAGE_SIZE)/VM_PAGE_SIZE); 336433d6423SLionel Sambuc return 0; 337433d6423SLionel Sambuc } 338433d6423SLionel Sambuc 339d196e2c3SCristiano Giuffrida #ifdef __weak_alias 340d196e2c3SCristiano Giuffrida __weak_alias(brk, _brk) 341d196e2c3SCristiano Giuffrida #endif 342d196e2c3SCristiano Giuffrida int _brk(void *addr) 343433d6423SLionel Sambuc { 344433d6423SLionel Sambuc /* brk is a special case function to allow vm itself to 345433d6423SLionel Sambuc allocate memory in it's own (cacheable) HEAP */ 346433d6423SLionel Sambuc vir_bytes target = roundup((vir_bytes)addr, VM_PAGE_SIZE), v; 347433d6423SLionel Sambuc extern char _end; 348433d6423SLionel Sambuc extern char *_brksize; 349433d6423SLionel Sambuc static vir_bytes prevbrk = (vir_bytes) &_end; 350433d6423SLionel Sambuc struct vmproc *vmprocess = &vmproc[VM_PROC_NR]; 351433d6423SLionel Sambuc 352433d6423SLionel Sambuc for(v = roundup(prevbrk, VM_PAGE_SIZE); v < target; 353433d6423SLionel Sambuc v += VM_PAGE_SIZE) { 354433d6423SLionel Sambuc phys_bytes mem, newpage = alloc_mem(1, 0); 355433d6423SLionel Sambuc if(newpage == NO_MEM) return -1; 356433d6423SLionel Sambuc mem = CLICK2ABS(newpage); 357433d6423SLionel Sambuc if(pt_writemap(vmprocess, &vmprocess->vm_pt, 358433d6423SLionel Sambuc v, mem, VM_PAGE_SIZE, 359433d6423SLionel Sambuc ARCH_VM_PTE_PRESENT 360433d6423SLionel Sambuc | ARCH_VM_PTE_USER 361433d6423SLionel Sambuc | ARCH_VM_PTE_RW 362433d6423SLionel Sambuc #if defined(__arm__) 363433d6423SLionel Sambuc | ARM_VM_PTE_CACHED 364433d6423SLionel Sambuc #endif 365433d6423SLionel Sambuc , 0) != OK) { 366433d6423SLionel Sambuc free_mem(newpage, 1); 367433d6423SLionel Sambuc return -1; 368433d6423SLionel Sambuc } 369433d6423SLionel Sambuc prevbrk = v + VM_PAGE_SIZE; 370433d6423SLionel Sambuc } 371433d6423SLionel Sambuc 372433d6423SLionel Sambuc _brksize = (char *) addr; 373433d6423SLionel Sambuc 374433d6423SLionel Sambuc if(sys_vmctl(SELF, VMCTL_FLUSHTLB, 0) != OK) 375433d6423SLionel Sambuc panic("flushtlb failed"); 376433d6423SLionel Sambuc 377433d6423SLionel Sambuc return 0; 378433d6423SLionel Sambuc } 379433d6423SLionel Sambuc 380433d6423SLionel Sambuc /*===========================================================================* 381433d6423SLionel Sambuc * do_getrusage * 382433d6423SLionel Sambuc *===========================================================================*/ 383433d6423SLionel Sambuc int do_getrusage(message *m) 384433d6423SLionel Sambuc { 385433d6423SLionel Sambuc int res, slot; 386433d6423SLionel Sambuc struct vmproc *vmp; 387433d6423SLionel Sambuc struct rusage r_usage; 388433d6423SLionel Sambuc if ((res = vm_isokendpt(m->m_source, &slot)) != OK) 389433d6423SLionel Sambuc return ESRCH; 390433d6423SLionel Sambuc 391433d6423SLionel Sambuc vmp = &vmproc[slot]; 392433d6423SLionel Sambuc 393433d6423SLionel Sambuc if ((res = sys_datacopy(m->m_source, m->m_lc_vm_rusage.addr, 394433d6423SLionel Sambuc SELF, (vir_bytes) &r_usage, (vir_bytes) sizeof(r_usage))) < 0) 395433d6423SLionel Sambuc return res; 396433d6423SLionel Sambuc 397433d6423SLionel Sambuc r_usage.ru_maxrss = vmp->vm_total_max; 398433d6423SLionel Sambuc r_usage.ru_minflt = vmp->vm_minor_page_fault; 399433d6423SLionel Sambuc r_usage.ru_majflt = vmp->vm_major_page_fault; 400433d6423SLionel Sambuc 401433d6423SLionel Sambuc return sys_datacopy(SELF, (vir_bytes) &r_usage, m->m_source, 402433d6423SLionel Sambuc m->m_lc_vm_rusage.addr, (vir_bytes) sizeof(r_usage)); 403433d6423SLionel Sambuc } 40463483e02SCristiano Giuffrida 40563483e02SCristiano Giuffrida /*===========================================================================* 40663483e02SCristiano Giuffrida * adjust_proc_refs * 40763483e02SCristiano Giuffrida *===========================================================================*/ 40863483e02SCristiano Giuffrida void adjust_proc_refs() 40963483e02SCristiano Giuffrida { 41063483e02SCristiano Giuffrida struct vmproc *vmp; 41163483e02SCristiano Giuffrida region_iter iter; 41263483e02SCristiano Giuffrida 41363483e02SCristiano Giuffrida /* Fix up region parents. */ 41463483e02SCristiano Giuffrida for(vmp = vmproc; vmp < &vmproc[VMP_NR]; vmp++) { 41563483e02SCristiano Giuffrida struct vir_region *vr; 41663483e02SCristiano Giuffrida if(!(vmp->vm_flags & VMF_INUSE)) 41763483e02SCristiano Giuffrida continue; 41863483e02SCristiano Giuffrida region_start_iter_least(&vmp->vm_regions_avl, &iter); 41963483e02SCristiano Giuffrida while((vr = region_get_iter(&iter))) { 42063483e02SCristiano Giuffrida USE(vr, vr->parent = vmp;); 42163483e02SCristiano Giuffrida region_incr_iter(&iter); 42263483e02SCristiano Giuffrida } 42363483e02SCristiano Giuffrida } 42463483e02SCristiano Giuffrida } 42563483e02SCristiano Giuffrida 426