summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Braun <rbraun@sceen.net>2016-12-11 16:11:42 +0100
committerRichard Braun <rbraun@sceen.net>2016-12-11 16:17:57 +0100
commitbcc894b69d0d9a1a6f14ad7bd613808cc9f22ef7 (patch)
treef38117cf30496bd613317209dcc02ea818a5f962
parent3973572c6e285de9bdf07cb422c1c95cce4e1370 (diff)
VM: make vm_wire more POSIX-friendly
* doc/mach.texi: Update return codes. * vm/vm_map.c (vm_map_pageable_common): Return KERN_NO_SPACE instead of KERN_FAILURE if some of the specified address range does not correspond to mapped pages. Skip unwired entries instead of failing when unwiring.
-rw-r--r--doc/mach.texi6
-rw-r--r--vm/vm_map.c25
2 files changed, 17 insertions, 14 deletions
diff --git a/doc/mach.texi b/doc/mach.texi
index 99ee8548..d2b88d1f 100644
--- a/doc/mach.texi
+++ b/doc/mach.texi
@@ -3261,10 +3261,8 @@ The function returns @code{KERN_SUCCESS} if the call succeeded,
@code{KERN_INVALID_HOST} if @var{host} was not a valid host
port, @code{KERN_INVALID_TASK} if @var{task} was not a valid task,
@code{KERN_INVALID_VALUE} if @var{access} specified an invalid access
-mode, @code{KERN_FAILURE} if some memory in the specified range is not
-present or has an inappropriate protection value, and
-@code{KERN_INVALID_ARGUMENT} if unwiring (@var{access} is
-@code{VM_PROT_NONE}) and the memory is not already wired.
+mode, and @code{KERN_NO_SPACE} if some memory in the specified range
+is not present or has an inappropriate protection value.
The @code{vm_wire} call is actually an RPC to @var{host}, normally
a send right for a privileged host port, but potentially any send right.
diff --git a/vm/vm_map.c b/vm/vm_map.c
index 003694dd..7db9ceda 100644
--- a/vm/vm_map.c
+++ b/vm/vm_map.c
@@ -1477,7 +1477,7 @@ kern_return_t vm_map_pageable_common(
* Start address is not in map; this is fatal.
*/
vm_map_unlock(map);
- return(KERN_FAILURE);
+ return(KERN_NO_SPACE);
}
/*
@@ -1490,19 +1490,17 @@ kern_return_t vm_map_pageable_common(
vm_map_clip_start(map, entry, start);
/*
- * Unwiring. First ensure that the range to be
- * unwired is really wired down.
+ * Unwiring. First ensure that there are no holes
+ * in the specified range.
*/
while ((entry != vm_map_to_entry(map)) &&
(entry->vme_start < end)) {
- if ((entry->wired_count == 0) ||
- ((entry->vme_end < end) &&
- ((entry->vme_next == vm_map_to_entry(map)) ||
- (entry->vme_next->vme_start > entry->vme_end))) ||
- (user_wire && (entry->user_wired_count == 0))) {
+ if ((entry->vme_end < end) &&
+ ((entry->vme_next == vm_map_to_entry(map)) ||
+ (entry->vme_next->vme_start > entry->vme_end))) {
vm_map_unlock(map);
- return(KERN_INVALID_ARGUMENT);
+ return(KERN_NO_SPACE);
}
entry = entry->vme_next;
}
@@ -1517,6 +1515,13 @@ kern_return_t vm_map_pageable_common(
(entry->vme_start < end)) {
vm_map_clip_end(map, entry, end);
+ /* Skip unwired entries */
+ if (entry->wired_count == 0) {
+ assert(entry->user_wired_count == 0);
+ entry = entry->vme_next;
+ continue;
+ }
+
if (user_wire) {
if (--(entry->user_wired_count) == 0)
{
@@ -1641,7 +1646,7 @@ kern_return_t vm_map_pageable_common(
}
vm_map_unlock(map);
- return(KERN_FAILURE);
+ return(KERN_NO_SPACE);
}
entry = entry->vme_next;
}