145748Smckusick /* 245748Smckusick * Copyright (c) 1991 Regents of the University of California. 345748Smckusick * All rights reserved. 445748Smckusick * 545748Smckusick * This code is derived from software contributed to Berkeley by 645748Smckusick * The Mach Operating System project at Carnegie-Mellon University. 745748Smckusick * 8*48493Smckusick * %sccs.include.redist.c% 945748Smckusick * 10*48493Smckusick * @(#)vm_user.c 7.3 (Berkeley) 04/21/91 11*48493Smckusick * 12*48493Smckusick * 13*48493Smckusick * Copyright (c) 1987, 1990 Carnegie-Mellon University. 14*48493Smckusick * All rights reserved. 15*48493Smckusick * 16*48493Smckusick * Authors: Avadis Tevanian, Jr., Michael Wayne Young 17*48493Smckusick * 18*48493Smckusick * Permission to use, copy, modify and distribute this software and 19*48493Smckusick * its documentation is hereby granted, provided that both the copyright 20*48493Smckusick * notice and this permission notice appear in all copies of the 21*48493Smckusick * software, derivative works or modified versions, and any portions 22*48493Smckusick * thereof, and that both notices appear in supporting documentation. 23*48493Smckusick * 24*48493Smckusick * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" 25*48493Smckusick * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND 26*48493Smckusick * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. 27*48493Smckusick * 28*48493Smckusick * Carnegie Mellon requests users of this software to return to 29*48493Smckusick * 30*48493Smckusick * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU 31*48493Smckusick * School of Computer Science 32*48493Smckusick * Carnegie Mellon University 33*48493Smckusick * Pittsburgh PA 15213-3890 34*48493Smckusick * 35*48493Smckusick * any improvements or extensions that they make and grant Carnegie the 36*48493Smckusick * rights to redistribute these changes. 3745748Smckusick */ 3845748Smckusick 3945748Smckusick /* 4045748Smckusick * User-exported virtual memory functions. 4145748Smckusick */ 4245748Smckusick 4345748Smckusick #include "param.h" 4445748Smckusick #include "systm.h" 4545748Smckusick #include "proc.h" 4645748Smckusick 4748386Skarels #include "vm.h" 4848386Skarels #include "vm_page.h" 4945748Smckusick 5045748Smckusick simple_lock_data_t vm_alloc_lock; /* XXX */ 5145748Smckusick 5245748Smckusick #ifdef MACHVMCOMPAT 5345748Smckusick /* 5445748Smckusick * BSD style syscall interfaces to MACH calls 5545748Smckusick * All return MACH return values. 5645748Smckusick */ 5745748Smckusick /* ARGSUSED */ 5845748Smckusick svm_allocate(p, uap, retval) 5945748Smckusick struct proc *p; 6045748Smckusick struct args { 6145748Smckusick vm_map_t map; 6245748Smckusick vm_offset_t *addr; 6345748Smckusick vm_size_t size; 6445748Smckusick boolean_t anywhere; 6545748Smckusick } *uap; 6645748Smckusick int *retval; 6745748Smckusick { 6845748Smckusick vm_offset_t addr; 6945748Smckusick int rv; 7045748Smckusick 7145748Smckusick uap->map = p->p_map; /* XXX */ 7245748Smckusick 7345748Smckusick if (copyin((caddr_t)uap->addr, (caddr_t)&addr, sizeof (addr))) 7445748Smckusick rv = KERN_INVALID_ARGUMENT; 7545748Smckusick else 7645748Smckusick rv = vm_allocate(uap->map, &addr, uap->size, uap->anywhere); 7745748Smckusick if (rv == KERN_SUCCESS) { 7845748Smckusick if (copyout((caddr_t)&addr, (caddr_t)uap->addr, sizeof(addr))) 7945748Smckusick rv = KERN_INVALID_ARGUMENT; 8045748Smckusick } 8145748Smckusick return((int)rv); 8245748Smckusick } 8345748Smckusick 8445748Smckusick /* ARGSUSED */ 8545748Smckusick svm_deallocate(p, uap, retval) 8645748Smckusick struct proc *p; 8745748Smckusick struct args { 8845748Smckusick vm_map_t map; 8945748Smckusick vm_offset_t addr; 9045748Smckusick vm_size_t size; 9145748Smckusick } *uap; 9245748Smckusick int *retval; 9345748Smckusick { 9445748Smckusick int rv; 9545748Smckusick 9645748Smckusick uap->map = p->p_map; /* XXX */ 9745748Smckusick rv = vm_deallocate(uap->map, uap->addr, uap->size); 9845748Smckusick return((int)rv); 9945748Smckusick } 10045748Smckusick 10145748Smckusick /* ARGSUSED */ 10245748Smckusick svm_inherit(p, uap, retval) 10345748Smckusick struct proc *p; 10445748Smckusick struct args { 10545748Smckusick vm_map_t map; 10645748Smckusick vm_offset_t addr; 10745748Smckusick vm_size_t size; 10845748Smckusick vm_inherit_t inherit; 10945748Smckusick } *uap; 11045748Smckusick int *retval; 11145748Smckusick { 11245748Smckusick int rv; 11345748Smckusick 11445748Smckusick uap->map = p->p_map; /* XXX */ 11545748Smckusick rv = vm_inherit(uap->map, uap->addr, uap->size, uap->inherit); 11645748Smckusick return((int)rv); 11745748Smckusick } 11845748Smckusick 11945748Smckusick /* ARGSUSED */ 12045748Smckusick svm_protect(p, uap, retval) 12145748Smckusick struct proc *p; 12245748Smckusick struct args { 12345748Smckusick vm_map_t map; 12445748Smckusick vm_offset_t addr; 12545748Smckusick vm_size_t size; 12645748Smckusick boolean_t setmax; 12745748Smckusick vm_prot_t prot; 12845748Smckusick } *uap; 12945748Smckusick int *retval; 13045748Smckusick { 13145748Smckusick int rv; 13245748Smckusick 13345748Smckusick uap->map = p->p_map; /* XXX */ 13445748Smckusick rv = vm_protect(uap->map, uap->addr, uap->size, uap->setmax, uap->prot); 13545748Smckusick return((int)rv); 13645748Smckusick } 13745748Smckusick #endif 13845748Smckusick 13945748Smckusick /* 14045748Smckusick * vm_allocate allocates "zero fill" memory in the specfied 14145748Smckusick * map. 14245748Smckusick */ 14345748Smckusick vm_allocate(map, addr, size, anywhere) 14445748Smckusick register vm_map_t map; 14545748Smckusick register vm_offset_t *addr; 14645748Smckusick register vm_size_t size; 14745748Smckusick boolean_t anywhere; 14845748Smckusick { 14945748Smckusick int result; 15045748Smckusick 15148386Skarels if (map == NULL) 15245748Smckusick return(KERN_INVALID_ARGUMENT); 15345748Smckusick if (size == 0) { 15445748Smckusick *addr = 0; 15545748Smckusick return(KERN_SUCCESS); 15645748Smckusick } 15745748Smckusick 15845748Smckusick if (anywhere) 15945748Smckusick *addr = vm_map_min(map); 16045748Smckusick else 16145748Smckusick *addr = trunc_page(*addr); 16245748Smckusick size = round_page(size); 16345748Smckusick 16448386Skarels result = vm_map_find(map, NULL, (vm_offset_t) 0, addr, 16545748Smckusick size, anywhere); 16645748Smckusick 16745748Smckusick return(result); 16845748Smckusick } 16945748Smckusick 17045748Smckusick /* 17145748Smckusick * vm_deallocate deallocates the specified range of addresses in the 17245748Smckusick * specified address map. 17345748Smckusick */ 17445748Smckusick vm_deallocate(map, start, size) 17545748Smckusick register vm_map_t map; 17645748Smckusick vm_offset_t start; 17745748Smckusick vm_size_t size; 17845748Smckusick { 17948386Skarels if (map == NULL) 18045748Smckusick return(KERN_INVALID_ARGUMENT); 18145748Smckusick 18245748Smckusick if (size == (vm_offset_t) 0) 18345748Smckusick return(KERN_SUCCESS); 18445748Smckusick 18545748Smckusick return(vm_map_remove(map, trunc_page(start), round_page(start+size))); 18645748Smckusick } 18745748Smckusick 18845748Smckusick /* 18945748Smckusick * vm_inherit sets the inheritence of the specified range in the 19045748Smckusick * specified map. 19145748Smckusick */ 19245748Smckusick vm_inherit(map, start, size, new_inheritance) 19345748Smckusick register vm_map_t map; 19445748Smckusick vm_offset_t start; 19545748Smckusick vm_size_t size; 19645748Smckusick vm_inherit_t new_inheritance; 19745748Smckusick { 19848386Skarels if (map == NULL) 19945748Smckusick return(KERN_INVALID_ARGUMENT); 20045748Smckusick 20145748Smckusick return(vm_map_inherit(map, trunc_page(start), round_page(start+size), new_inheritance)); 20245748Smckusick } 20345748Smckusick 20445748Smckusick /* 20545748Smckusick * vm_protect sets the protection of the specified range in the 20645748Smckusick * specified map. 20745748Smckusick */ 20845748Smckusick 20945748Smckusick vm_protect(map, start, size, set_maximum, new_protection) 21045748Smckusick register vm_map_t map; 21145748Smckusick vm_offset_t start; 21245748Smckusick vm_size_t size; 21345748Smckusick boolean_t set_maximum; 21445748Smckusick vm_prot_t new_protection; 21545748Smckusick { 21648386Skarels if (map == NULL) 21745748Smckusick return(KERN_INVALID_ARGUMENT); 21845748Smckusick 21945748Smckusick return(vm_map_protect(map, trunc_page(start), round_page(start+size), new_protection, set_maximum)); 22045748Smckusick } 221