1 /* 2 * Copyright (c) 1991, 1993 3 * The Regents of the University of California. All rights reserved. 4 * 5 * This code is derived from software contributed to Berkeley by 6 * The Mach Operating System project at Carnegie-Mellon University. 7 * 8 * %sccs.include.redist.c% 9 * 10 * @(#)vm_user.c 8.1 (Berkeley) 06/11/93 11 * 12 * 13 * Copyright (c) 1987, 1990 Carnegie-Mellon University. 14 * All rights reserved. 15 * 16 * Authors: Avadis Tevanian, Jr., Michael Wayne Young 17 * 18 * Permission to use, copy, modify and distribute this software and 19 * its documentation is hereby granted, provided that both the copyright 20 * notice and this permission notice appear in all copies of the 21 * software, derivative works or modified versions, and any portions 22 * thereof, and that both notices appear in supporting documentation. 23 * 24 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" 25 * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND 26 * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. 27 * 28 * Carnegie Mellon requests users of this software to return to 29 * 30 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU 31 * School of Computer Science 32 * Carnegie Mellon University 33 * Pittsburgh PA 15213-3890 34 * 35 * any improvements or extensions that they make and grant Carnegie the 36 * rights to redistribute these changes. 37 */ 38 39 /* 40 * User-exported virtual memory functions. 41 */ 42 43 #include <sys/param.h> 44 #include <sys/systm.h> 45 #include <sys/proc.h> 46 47 #include <vm/vm.h> 48 49 simple_lock_data_t vm_alloc_lock; /* XXX */ 50 51 #ifdef MACHVMCOMPAT 52 /* 53 * BSD style syscall interfaces to MACH calls 54 * All return MACH return values. 55 */ 56 struct svm_allocate_args { 57 vm_map_t map; 58 vm_offset_t *addr; 59 vm_size_t size; 60 boolean_t anywhere; 61 }; 62 /* ARGSUSED */ 63 int 64 svm_allocate(p, uap, retval) 65 struct proc *p; 66 struct svm_allocate_args *uap; 67 int *retval; 68 { 69 vm_offset_t addr; 70 int rv; 71 72 uap->map = p->p_map; /* XXX */ 73 74 if (copyin((caddr_t)uap->addr, (caddr_t)&addr, sizeof (addr))) 75 rv = KERN_INVALID_ARGUMENT; 76 else 77 rv = vm_allocate(uap->map, &addr, uap->size, uap->anywhere); 78 if (rv == KERN_SUCCESS) { 79 if (copyout((caddr_t)&addr, (caddr_t)uap->addr, sizeof(addr))) 80 rv = KERN_INVALID_ARGUMENT; 81 } 82 return((int)rv); 83 } 84 85 struct svm_deallocate_args { 86 vm_map_t map; 87 vm_offset_t addr; 88 vm_size_t size; 89 }; 90 /* ARGSUSED */ 91 int 92 svm_deallocate(p, uap, retval) 93 struct proc *p; 94 struct svm_deallocate_args *uap; 95 int *retval; 96 { 97 int rv; 98 99 uap->map = p->p_map; /* XXX */ 100 rv = vm_deallocate(uap->map, uap->addr, uap->size); 101 return((int)rv); 102 } 103 104 struct svm_inherit_args { 105 vm_map_t map; 106 vm_offset_t addr; 107 vm_size_t size; 108 vm_inherit_t inherit; 109 }; 110 /* ARGSUSED */ 111 int 112 svm_inherit(p, uap, retval) 113 struct proc *p; 114 struct svm_inherit_args *uap; 115 int *retval; 116 { 117 int rv; 118 119 uap->map = p->p_map; /* XXX */ 120 rv = vm_inherit(uap->map, uap->addr, uap->size, uap->inherit); 121 return((int)rv); 122 } 123 124 struct svm_protect_args { 125 vm_map_t map; 126 vm_offset_t addr; 127 vm_size_t size; 128 boolean_t setmax; 129 vm_prot_t prot; 130 }; 131 /* ARGSUSED */ 132 int 133 svm_protect(p, uap, retval) 134 struct proc *p; 135 struct svm_protect_args *uap; 136 int *retval; 137 { 138 int rv; 139 140 uap->map = p->p_map; /* XXX */ 141 rv = vm_protect(uap->map, uap->addr, uap->size, uap->setmax, uap->prot); 142 return((int)rv); 143 } 144 #endif 145 146 /* 147 * vm_allocate allocates "zero fill" memory in the specfied 148 * map. 149 */ 150 int 151 vm_allocate(map, addr, size, anywhere) 152 register vm_map_t map; 153 register vm_offset_t *addr; 154 register vm_size_t size; 155 boolean_t anywhere; 156 { 157 int result; 158 159 if (map == NULL) 160 return(KERN_INVALID_ARGUMENT); 161 if (size == 0) { 162 *addr = 0; 163 return(KERN_SUCCESS); 164 } 165 166 if (anywhere) 167 *addr = vm_map_min(map); 168 else 169 *addr = trunc_page(*addr); 170 size = round_page(size); 171 172 result = vm_map_find(map, NULL, (vm_offset_t) 0, addr, 173 size, anywhere); 174 175 return(result); 176 } 177 178 /* 179 * vm_deallocate deallocates the specified range of addresses in the 180 * specified address map. 181 */ 182 int 183 vm_deallocate(map, start, size) 184 register vm_map_t map; 185 vm_offset_t start; 186 vm_size_t size; 187 { 188 if (map == NULL) 189 return(KERN_INVALID_ARGUMENT); 190 191 if (size == (vm_offset_t) 0) 192 return(KERN_SUCCESS); 193 194 return(vm_map_remove(map, trunc_page(start), round_page(start+size))); 195 } 196 197 /* 198 * vm_inherit sets the inheritence of the specified range in the 199 * specified map. 200 */ 201 int 202 vm_inherit(map, start, size, new_inheritance) 203 register vm_map_t map; 204 vm_offset_t start; 205 vm_size_t size; 206 vm_inherit_t new_inheritance; 207 { 208 if (map == NULL) 209 return(KERN_INVALID_ARGUMENT); 210 211 return(vm_map_inherit(map, trunc_page(start), round_page(start+size), new_inheritance)); 212 } 213 214 /* 215 * vm_protect sets the protection of the specified range in the 216 * specified map. 217 */ 218 219 int 220 vm_protect(map, start, size, set_maximum, new_protection) 221 register vm_map_t map; 222 vm_offset_t start; 223 vm_size_t size; 224 boolean_t set_maximum; 225 vm_prot_t new_protection; 226 { 227 if (map == NULL) 228 return(KERN_INVALID_ARGUMENT); 229 230 return(vm_map_protect(map, trunc_page(start), round_page(start+size), new_protection, set_maximum)); 231 } 232