1*45748Smckusick /* 2*45748Smckusick * Copyright (c) 1985, Avadis Tevanian, Jr., Michael Wayne Young 3*45748Smckusick * Copyright (c) 1987 Carnegie-Mellon University 4*45748Smckusick * Copyright (c) 1991 Regents of the University of California. 5*45748Smckusick * All rights reserved. 6*45748Smckusick * 7*45748Smckusick * This code is derived from software contributed to Berkeley by 8*45748Smckusick * The Mach Operating System project at Carnegie-Mellon University. 9*45748Smckusick * 10*45748Smckusick * The CMU software License Agreement specifies the terms and conditions 11*45748Smckusick * for use and redistribution. 12*45748Smckusick * 13*45748Smckusick * @(#)vm_user.c 7.1 (Berkeley) 12/05/90 14*45748Smckusick */ 15*45748Smckusick 16*45748Smckusick /* 17*45748Smckusick * User-exported virtual memory functions. 18*45748Smckusick */ 19*45748Smckusick 20*45748Smckusick #include "param.h" 21*45748Smckusick #include "systm.h" 22*45748Smckusick #include "user.h" 23*45748Smckusick #include "proc.h" 24*45748Smckusick 25*45748Smckusick #include "../vm/vm_param.h" 26*45748Smckusick #include "../vm/vm_object.h" 27*45748Smckusick #include "../vm/vm_map.h" 28*45748Smckusick #include "../vm/vm_page.h" 29*45748Smckusick #include "../vm/vm_statistics.h" 30*45748Smckusick 31*45748Smckusick #include "lock.h" /* XXX */ 32*45748Smckusick simple_lock_data_t vm_alloc_lock; /* XXX */ 33*45748Smckusick 34*45748Smckusick #ifdef MACHVMCOMPAT 35*45748Smckusick /* 36*45748Smckusick * BSD style syscall interfaces to MACH calls 37*45748Smckusick * All return MACH return values. 38*45748Smckusick */ 39*45748Smckusick /* ARGSUSED */ 40*45748Smckusick svm_allocate(p, uap, retval) 41*45748Smckusick struct proc *p; 42*45748Smckusick struct args { 43*45748Smckusick vm_map_t map; 44*45748Smckusick vm_offset_t *addr; 45*45748Smckusick vm_size_t size; 46*45748Smckusick boolean_t anywhere; 47*45748Smckusick } *uap; 48*45748Smckusick int *retval; 49*45748Smckusick { 50*45748Smckusick vm_offset_t addr; 51*45748Smckusick int rv; 52*45748Smckusick 53*45748Smckusick uap->map = p->p_map; /* XXX */ 54*45748Smckusick 55*45748Smckusick if (copyin((caddr_t)uap->addr, (caddr_t)&addr, sizeof (addr))) 56*45748Smckusick rv = KERN_INVALID_ARGUMENT; 57*45748Smckusick else 58*45748Smckusick rv = vm_allocate(uap->map, &addr, uap->size, uap->anywhere); 59*45748Smckusick if (rv == KERN_SUCCESS) { 60*45748Smckusick if (copyout((caddr_t)&addr, (caddr_t)uap->addr, sizeof(addr))) 61*45748Smckusick rv = KERN_INVALID_ARGUMENT; 62*45748Smckusick } 63*45748Smckusick return((int)rv); 64*45748Smckusick } 65*45748Smckusick 66*45748Smckusick /* ARGSUSED */ 67*45748Smckusick svm_deallocate(p, uap, retval) 68*45748Smckusick struct proc *p; 69*45748Smckusick struct args { 70*45748Smckusick vm_map_t map; 71*45748Smckusick vm_offset_t addr; 72*45748Smckusick vm_size_t size; 73*45748Smckusick } *uap; 74*45748Smckusick int *retval; 75*45748Smckusick { 76*45748Smckusick int rv; 77*45748Smckusick 78*45748Smckusick uap->map = p->p_map; /* XXX */ 79*45748Smckusick rv = vm_deallocate(uap->map, uap->addr, uap->size); 80*45748Smckusick return((int)rv); 81*45748Smckusick } 82*45748Smckusick 83*45748Smckusick /* ARGSUSED */ 84*45748Smckusick svm_inherit(p, uap, retval) 85*45748Smckusick struct proc *p; 86*45748Smckusick struct args { 87*45748Smckusick vm_map_t map; 88*45748Smckusick vm_offset_t addr; 89*45748Smckusick vm_size_t size; 90*45748Smckusick vm_inherit_t inherit; 91*45748Smckusick } *uap; 92*45748Smckusick int *retval; 93*45748Smckusick { 94*45748Smckusick int rv; 95*45748Smckusick 96*45748Smckusick uap->map = p->p_map; /* XXX */ 97*45748Smckusick rv = vm_inherit(uap->map, uap->addr, uap->size, uap->inherit); 98*45748Smckusick return((int)rv); 99*45748Smckusick } 100*45748Smckusick 101*45748Smckusick /* ARGSUSED */ 102*45748Smckusick svm_protect(p, uap, retval) 103*45748Smckusick struct proc *p; 104*45748Smckusick struct args { 105*45748Smckusick vm_map_t map; 106*45748Smckusick vm_offset_t addr; 107*45748Smckusick vm_size_t size; 108*45748Smckusick boolean_t setmax; 109*45748Smckusick vm_prot_t prot; 110*45748Smckusick } *uap; 111*45748Smckusick int *retval; 112*45748Smckusick { 113*45748Smckusick int rv; 114*45748Smckusick 115*45748Smckusick uap->map = p->p_map; /* XXX */ 116*45748Smckusick rv = vm_protect(uap->map, uap->addr, uap->size, uap->setmax, uap->prot); 117*45748Smckusick return((int)rv); 118*45748Smckusick } 119*45748Smckusick #endif 120*45748Smckusick 121*45748Smckusick /* 122*45748Smckusick * vm_allocate allocates "zero fill" memory in the specfied 123*45748Smckusick * map. 124*45748Smckusick */ 125*45748Smckusick vm_allocate(map, addr, size, anywhere) 126*45748Smckusick register vm_map_t map; 127*45748Smckusick register vm_offset_t *addr; 128*45748Smckusick register vm_size_t size; 129*45748Smckusick boolean_t anywhere; 130*45748Smckusick { 131*45748Smckusick int result; 132*45748Smckusick 133*45748Smckusick if (map == VM_MAP_NULL) 134*45748Smckusick return(KERN_INVALID_ARGUMENT); 135*45748Smckusick if (size == 0) { 136*45748Smckusick *addr = 0; 137*45748Smckusick return(KERN_SUCCESS); 138*45748Smckusick } 139*45748Smckusick 140*45748Smckusick if (anywhere) 141*45748Smckusick *addr = vm_map_min(map); 142*45748Smckusick else 143*45748Smckusick *addr = trunc_page(*addr); 144*45748Smckusick size = round_page(size); 145*45748Smckusick 146*45748Smckusick result = vm_map_find(map, VM_OBJECT_NULL, (vm_offset_t) 0, addr, 147*45748Smckusick size, anywhere); 148*45748Smckusick 149*45748Smckusick return(result); 150*45748Smckusick } 151*45748Smckusick 152*45748Smckusick /* 153*45748Smckusick * vm_deallocate deallocates the specified range of addresses in the 154*45748Smckusick * specified address map. 155*45748Smckusick */ 156*45748Smckusick vm_deallocate(map, start, size) 157*45748Smckusick register vm_map_t map; 158*45748Smckusick vm_offset_t start; 159*45748Smckusick vm_size_t size; 160*45748Smckusick { 161*45748Smckusick if (map == VM_MAP_NULL) 162*45748Smckusick return(KERN_INVALID_ARGUMENT); 163*45748Smckusick 164*45748Smckusick if (size == (vm_offset_t) 0) 165*45748Smckusick return(KERN_SUCCESS); 166*45748Smckusick 167*45748Smckusick return(vm_map_remove(map, trunc_page(start), round_page(start+size))); 168*45748Smckusick } 169*45748Smckusick 170*45748Smckusick /* 171*45748Smckusick * vm_inherit sets the inheritence of the specified range in the 172*45748Smckusick * specified map. 173*45748Smckusick */ 174*45748Smckusick vm_inherit(map, start, size, new_inheritance) 175*45748Smckusick register vm_map_t map; 176*45748Smckusick vm_offset_t start; 177*45748Smckusick vm_size_t size; 178*45748Smckusick vm_inherit_t new_inheritance; 179*45748Smckusick { 180*45748Smckusick if (map == VM_MAP_NULL) 181*45748Smckusick return(KERN_INVALID_ARGUMENT); 182*45748Smckusick 183*45748Smckusick return(vm_map_inherit(map, trunc_page(start), round_page(start+size), new_inheritance)); 184*45748Smckusick } 185*45748Smckusick 186*45748Smckusick /* 187*45748Smckusick * vm_protect sets the protection of the specified range in the 188*45748Smckusick * specified map. 189*45748Smckusick */ 190*45748Smckusick 191*45748Smckusick vm_protect(map, start, size, set_maximum, new_protection) 192*45748Smckusick register vm_map_t map; 193*45748Smckusick vm_offset_t start; 194*45748Smckusick vm_size_t size; 195*45748Smckusick boolean_t set_maximum; 196*45748Smckusick vm_prot_t new_protection; 197*45748Smckusick { 198*45748Smckusick if (map == VM_MAP_NULL) 199*45748Smckusick return(KERN_INVALID_ARGUMENT); 200*45748Smckusick 201*45748Smckusick return(vm_map_protect(map, trunc_page(start), round_page(start+size), new_protection, set_maximum)); 202*45748Smckusick } 203