Changeset View
Changeset View
Standalone View
Standalone View
sys/vm/vm_mmap.c
Show First 20 Lines • Show All 997 Lines • ▼ Show 20 Lines | kern_mlock(struct proc *proc, struct ucred *cred, uintptr_t addr0, size_t len) | ||||
addr = addr0; | addr = addr0; | ||||
size = len; | size = len; | ||||
last = addr + size; | last = addr + size; | ||||
start = trunc_page(addr); | start = trunc_page(addr); | ||||
end = round_page(last); | end = round_page(last); | ||||
if (last < addr || end < addr) | if (last < addr || end < addr) | ||||
return (EINVAL); | return (EINVAL); | ||||
npages = atop(end - start); | npages = atop(end - start); | ||||
if (npages > vm_page_max_wired) | if (npages > vm_page_max_user_wired) | ||||
return (ENOMEM); | return (ENOMEM); | ||||
map = &proc->p_vmspace->vm_map; | map = &proc->p_vmspace->vm_map; | ||||
PROC_LOCK(proc); | PROC_LOCK(proc); | ||||
nsize = ptoa(npages + pmap_wired_count(map->pmap)); | nsize = ptoa(npages + pmap_wired_count(map->pmap)); | ||||
if (nsize > lim_cur_proc(proc, RLIMIT_MEMLOCK)) { | if (nsize > lim_cur_proc(proc, RLIMIT_MEMLOCK)) { | ||||
PROC_UNLOCK(proc); | PROC_UNLOCK(proc); | ||||
return (ENOMEM); | return (ENOMEM); | ||||
} | } | ||||
PROC_UNLOCK(proc); | PROC_UNLOCK(proc); | ||||
if (npages + vm_wire_count() > vm_page_max_wired) | |||||
return (EAGAIN); | |||||
#ifdef RACCT | #ifdef RACCT | ||||
if (racct_enable) { | if (racct_enable) { | ||||
PROC_LOCK(proc); | PROC_LOCK(proc); | ||||
error = racct_set(proc, RACCT_MEMLOCK, nsize); | error = racct_set(proc, RACCT_MEMLOCK, nsize); | ||||
PROC_UNLOCK(proc); | PROC_UNLOCK(proc); | ||||
if (error != 0) | if (error != 0) | ||||
return (ENOMEM); | return (ENOMEM); | ||||
} | } | ||||
▲ Show 20 Lines • Show All 60 Lines • ▼ Show 20 Lines | if (uap->how & MCL_CURRENT) { | ||||
/* | /* | ||||
* P1003.1-2001 mandates that all currently mapped pages | * P1003.1-2001 mandates that all currently mapped pages | ||||
* will be memory resident and locked (wired) upon return | * will be memory resident and locked (wired) upon return | ||||
* from mlockall(). vm_map_wire() will wire pages, by | * from mlockall(). vm_map_wire() will wire pages, by | ||||
* calling vm_fault_wire() for each page in the region. | * calling vm_fault_wire() for each page in the region. | ||||
*/ | */ | ||||
error = vm_map_wire(map, vm_map_min(map), vm_map_max(map), | error = vm_map_wire(map, vm_map_min(map), vm_map_max(map), | ||||
VM_MAP_WIRE_USER|VM_MAP_WIRE_HOLESOK); | VM_MAP_WIRE_USER|VM_MAP_WIRE_HOLESOK); | ||||
error = (error == KERN_SUCCESS ? 0 : EAGAIN); | if (error == KERN_SUCCESS) | ||||
error = 0; | |||||
else if (error == KERN_RESOURCE_SHORTAGE) | |||||
error = ENOMEM; | |||||
else | |||||
error = EAGAIN; | |||||
} | } | ||||
#ifdef RACCT | #ifdef RACCT | ||||
if (racct_enable && error != KERN_SUCCESS) { | if (racct_enable && error != KERN_SUCCESS) { | ||||
PROC_LOCK(td->td_proc); | PROC_LOCK(td->td_proc); | ||||
racct_set(td->td_proc, RACCT_MEMLOCK, | racct_set(td->td_proc, RACCT_MEMLOCK, | ||||
ptoa(pmap_wired_count(map->pmap))); | ptoa(pmap_wired_count(map->pmap))); | ||||
PROC_UNLOCK(td->td_proc); | PROC_UNLOCK(td->td_proc); | ||||
} | } | ||||
▲ Show 20 Lines • Show All 451 Lines • ▼ Show 20 Lines | rv = vm_map_fixed(map, object, foff, *addr, size, | ||||
prot, maxprot, docow); | prot, maxprot, docow); | ||||
} | } | ||||
if (rv == KERN_SUCCESS) { | if (rv == KERN_SUCCESS) { | ||||
/* | /* | ||||
* If the process has requested that all future mappings | * If the process has requested that all future mappings | ||||
* be wired, then heed this. | * be wired, then heed this. | ||||
*/ | */ | ||||
if (map->flags & MAP_WIREFUTURE) { | if ((map->flags & MAP_WIREFUTURE) != 0) { | ||||
vm_map_wire(map, *addr, *addr + size, | vm_map_lock(map); | ||||
VM_MAP_WIRE_USER | ((flags & MAP_STACK) ? | if ((map->flags & MAP_WIREFUTURE) != 0) | ||||
VM_MAP_WIRE_HOLESOK : VM_MAP_WIRE_NOHOLES)); | rv = vm_map_wire_locked(map, *addr, | ||||
*addr + size, VM_MAP_WIRE_USER | | |||||
((flags & MAP_STACK) ? VM_MAP_WIRE_HOLESOK : | |||||
VM_MAP_WIRE_NOHOLES)); | |||||
if (rv != KERN_SUCCESS) | |||||
(void)vm_map_delete(map, *addr, *addr + size); | |||||
vm_map_unlock(map); | |||||
} | } | ||||
} | } | ||||
return (vm_mmap_to_errno(rv)); | return (vm_mmap_to_errno(rv)); | ||||
} | } | ||||
/* | /* | ||||
* Translate a Mach VM return code to zero on success or the appropriate errno | * Translate a Mach VM return code to zero on success or the appropriate errno | ||||
* on failure. | * on failure. | ||||
Show All 17 Lines |