diff options
Diffstat (limited to 'sys/vm/vm_mmap.c')
-rw-r--r-- | sys/vm/vm_mmap.c | 34 |
1 files changed, 27 insertions, 7 deletions
diff --git a/sys/vm/vm_mmap.c b/sys/vm/vm_mmap.c index 68c2108..17631f9 100644 --- a/sys/vm/vm_mmap.c +++ b/sys/vm/vm_mmap.c @@ -226,7 +226,7 @@ kern_mmap(struct thread *td, uintptr_t addr0, size_t size, int prot, int flags, } if ((flags & ~(MAP_SHARED | MAP_PRIVATE | MAP_FIXED | MAP_HASSEMAPHORE | MAP_STACK | MAP_NOSYNC | MAP_ANON | MAP_EXCL | MAP_NOCORE | - MAP_PREFAULT_READ | + MAP_PREFAULT_READ | MAP_GUARD | #ifdef MAP_32BIT MAP_32BIT | #endif @@ -239,6 +239,10 @@ kern_mmap(struct thread *td, uintptr_t addr0, size_t size, int prot, int flags, if (prot != PROT_NONE && (prot & ~(PROT_READ | PROT_WRITE | PROT_EXEC)) != 0) return (EINVAL); + if ((flags & MAP_GUARD) != 0 && (prot != PROT_NONE || fd != -1 || + pos != 0 || (flags & (MAP_SHARED | MAP_PRIVATE | MAP_PREFAULT | + MAP_PREFAULT_READ | MAP_ANON | MAP_STACK)) != 0)) + return (EINVAL); /* * Align the file position to a page boundary, @@ -314,7 +318,10 @@ kern_mmap(struct thread *td, uintptr_t addr0, size_t size, int prot, int flags, * returns an error earlier. */ error = 0; - } else if (flags & MAP_ANON) { + } else if ((flags & MAP_GUARD) != 0) { + error = vm_mmap_object(&vms->vm_map, &addr, size, VM_PROT_NONE, + VM_PROT_NONE, flags, NULL, pos, FALSE, td); + } else if ((flags & MAP_ANON) != 0) { /* * Mapping blank space is trivial. * @@ -1431,10 +1438,12 @@ vm_mmap_object(vm_map_t map, vm_offset_t *addr, vm_size_t size, vm_prot_t prot, vm_prot_t maxprot, int flags, vm_object_t object, vm_ooffset_t foff, boolean_t writecounted, struct thread *td) { - boolean_t fitit; + boolean_t curmap, fitit; + vm_offset_t max_addr; int docow, error, findspace, rv; - if (map == &td->td_proc->p_vmspace->vm_map) { + curmap = map == &td->td_proc->p_vmspace->vm_map; + if (curmap) { PROC_LOCK(td->td_proc); if (map->size + size > lim_cur_proc(td->td_proc, RLIMIT_VMEM)) { PROC_UNLOCK(td->td_proc); @@ -1511,6 +1520,8 @@ vm_mmap_object(vm_map_t map, vm_offset_t *addr, vm_size_t size, vm_prot_t prot, } if ((flags & MAP_EXCL) != 0) docow |= MAP_CHECK_EXCL; + if ((flags & MAP_GUARD) != 0) + docow |= MAP_CREATE_GUARD; if (fitit) { if ((flags & MAP_ALIGNMENT_MASK) == MAP_ALIGNED_SUPER) @@ -1520,11 +1531,20 @@ vm_mmap_object(vm_map_t map, vm_offset_t *addr, vm_size_t size, vm_prot_t prot, MAP_ALIGNMENT_SHIFT); else findspace = VMFS_OPTIMAL_SPACE; - rv = vm_map_find(map, object, foff, addr, size, + max_addr = 0; #ifdef MAP_32BIT - flags & MAP_32BIT ? MAP_32BIT_MAX_ADDR : + if ((flags & MAP_32BIT) != 0) + max_addr = MAP_32BIT_MAX_ADDR; #endif - 0, findspace, prot, maxprot, docow); + if (curmap) { + rv = vm_map_find_min(map, object, foff, addr, size, + round_page((vm_offset_t)td->td_proc->p_vmspace-> + vm_daddr + lim_max(td, RLIMIT_DATA)), max_addr, + findspace, prot, maxprot, docow); + } else { + rv = vm_map_find(map, object, foff, addr, size, + max_addr, findspace, prot, maxprot, docow); + } } else { rv = vm_map_fixed(map, object, foff, *addr, size, prot, maxprot, docow); |