summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lib/libc/sys/mmap.233
-rw-r--r--sys/sys/mman.h1
-rw-r--r--sys/vm/vm_map.c3
-rw-r--r--sys/vm/vm_map.h1
-rw-r--r--sys/vm/vm_mmap.c4
5 files changed, 35 insertions, 7 deletions
diff --git a/lib/libc/sys/mmap.2 b/lib/libc/sys/mmap.2
index 01cde0e..3dd8303 100644
--- a/lib/libc/sys/mmap.2
+++ b/lib/libc/sys/mmap.2
@@ -28,7 +28,7 @@
.\" @(#)mmap.2 8.4 (Berkeley) 5/11/95
.\" $FreeBSD$
.\"
-.Dd September 9, 2013
+.Dd June 19, 2014
.Dt MMAP 2
.Os
.Sh NAME
@@ -141,6 +141,12 @@ argument must be 0.
This flag is identical to
.Dv MAP_ANON
and is provided for compatibility.
+.It Dv MAP_EXCL
+This flag can only be used in combination with
+.Dv MAP_FIXED .
+Please see the definition of
+.Dv MAP_FIXED
+for the description of its effect.
.It Dv MAP_FIXED
Do not permit the system to select a different address than the one
specified.
@@ -152,17 +158,21 @@ If
is specified,
.Fa addr
must be a multiple of the pagesize.
-If a
+If
+.Dv MAP_EXCL
+is not specified, a successfull
.Dv MAP_FIXED
-request is successful, the mapping established by
-.Fn mmap
-replaces any previous mappings for the process' pages in the range from
+request replaces any previous mappings for the process'
+pages in the range from
.Fa addr
to
.Fa addr
+
.Fa len .
-Use of this option is discouraged.
+In contrast, if
+.Dv MAP_EXCL
+is specified, the request will fail if a mapping
+already exists within the range.
.It Dv MAP_HASSEMAPHORE
Notify the kernel that the region may contain semaphores and that special
handling may be necessary.
@@ -393,6 +403,17 @@ argument was not -1.
was specified and the
.Fa offset
argument was not 0.
+.It Bq Er EINVAL
+Both
+.Dv MAP_FIXED
+and
+.Dv MAP_EXCL
+were specified, but the requested region is already used by a mapping.
+.It Bq Er EINVAL
+.Dv MAP_EXCL
+was specified, but
+.Dv MAP_FIXED
+was not.
.It Bq Er ENODEV
.Dv MAP_ANON
has not been specified and
diff --git a/sys/sys/mman.h b/sys/sys/mman.h
index eaea818..e89bee3 100644
--- a/sys/sys/mman.h
+++ b/sys/sys/mman.h
@@ -89,6 +89,7 @@
/*
* Extended flags
*/
+#define MAP_EXCL 0x00004000 /* for MAP_FIXED, fail if address is used */
#define MAP_NOCORE 0x00020000 /* dont include these pages in a coredump */
#define MAP_PREFAULT_READ 0x00040000 /* prefault mapping for reading */
#ifdef __LP64__
diff --git a/sys/vm/vm_map.c b/sys/vm/vm_map.c
index 35f2147..fabc022 100644
--- a/sys/vm/vm_map.c
+++ b/sys/vm/vm_map.c
@@ -1393,7 +1393,8 @@ vm_map_fixed(vm_map_t map, vm_object_t object, vm_ooffset_t offset,
("vm_map_fixed: non-NULL backing object for stack"));
vm_map_lock(map);
VM_MAP_RANGE_CHECK(map, start, end);
- (void) vm_map_delete(map, start, end);
+ if ((cow & MAP_CHECK_EXCL) == 0)
+ vm_map_delete(map, start, end);
if ((cow & (MAP_STACK_GROWS_DOWN | MAP_STACK_GROWS_UP)) != 0) {
result = vm_map_stack_locked(map, start, length, sgrowsiz,
prot, max, cow);
diff --git a/sys/vm/vm_map.h b/sys/vm/vm_map.h
index 850bf25..8cced05 100644
--- a/sys/vm/vm_map.h
+++ b/sys/vm/vm_map.h
@@ -315,6 +315,7 @@ long vmspace_resident_count(struct vmspace *vmspace);
#define MAP_PREFAULT 0x0008
#define MAP_PREFAULT_PARTIAL 0x0010
#define MAP_DISABLE_SYNCER 0x0020
+#define MAP_CHECK_EXCL 0x0040
#define MAP_DISABLE_COREDUMP 0x0100
#define MAP_PREFAULT_MADVISE 0x0200 /* from (user) madvise request */
#define MAP_VN_WRITECOUNT 0x0400
diff --git a/sys/vm/vm_mmap.c b/sys/vm/vm_mmap.c
index 0fc5bb4..a524839 100644
--- a/sys/vm/vm_mmap.c
+++ b/sys/vm/vm_mmap.c
@@ -245,6 +245,8 @@ sys_mmap(td, uap)
flags |= MAP_ANON;
pos = 0;
}
+ if ((flags & (MAP_EXCL | MAP_FIXED)) == MAP_EXCL)
+ return (EINVAL);
/*
* Align the file position to a page boundary,
@@ -1626,6 +1628,8 @@ vm_mmap(vm_map_t map, vm_offset_t *addr, vm_size_t size, vm_prot_t prot,
return (EINVAL);
docow |= MAP_STACK_GROWS_DOWN;
}
+ if ((flags & MAP_EXCL) != 0)
+ docow |= MAP_CHECK_EXCL;
if (fitit) {
if ((flags & MAP_ALIGNMENT_MASK) == MAP_ALIGNED_SUPER)
OpenPOWER on IntegriCloud