summaryrefslogtreecommitdiff
path: root/vm/vm_user.c
diff options
context:
space:
mode:
authorSamuel Thibault <samuel.thibault@ens-lyon.org>2016-10-02 19:44:46 +0200
committerSamuel Thibault <samuel.thibault@ens-lyon.org>2016-10-02 19:44:46 +0200
commitae25754394cd7ecc771eba37324ff49996e96e3a (patch)
treee5b2f0ad3e17827a9b19a9fe930a443158753c27 /vm/vm_user.c
parent4ce5f4c5b064c1a252cb6142706b83d69aa1aca4 (diff)
parent1443986a08b4cd564172875c07551681314014da (diff)
Merge branch 'master' into HEAD
Diffstat (limited to 'vm/vm_user.c')
-rw-r--r--vm/vm_user.c176
1 files changed, 106 insertions, 70 deletions
diff --git a/vm/vm_user.c b/vm/vm_user.c
index 6cd9d775..ae95798c 100644
--- a/vm/vm_user.c
+++ b/vm/vm_user.c
@@ -38,6 +38,7 @@
#include <mach/vm_attributes.h>
#include <mach/vm_param.h>
#include <mach/vm_statistics.h>
+#include <mach/vm_cache_statistics.h>
#include <kern/host.h>
#include <kern/task.h>
#include <vm/vm_fault.h>
@@ -55,11 +56,11 @@ vm_statistics_data_t vm_stat;
* vm_allocate allocates "zero fill" memory in the specfied
* map.
*/
-kern_return_t vm_allocate(map, addr, size, anywhere)
- register vm_map_t map;
- register vm_offset_t *addr;
- register vm_size_t size;
- boolean_t anywhere;
+kern_return_t vm_allocate(
+ vm_map_t map,
+ vm_offset_t *addr,
+ vm_size_t size,
+ boolean_t anywhere)
{
kern_return_t result;
@@ -96,10 +97,10 @@ kern_return_t vm_allocate(map, addr, size, anywhere)
* vm_deallocate deallocates the specified range of addresses in the
* specified address map.
*/
-kern_return_t vm_deallocate(map, start, size)
- register vm_map_t map;
- vm_offset_t start;
- vm_size_t size;
+kern_return_t vm_deallocate(
+ vm_map_t map,
+ vm_offset_t start,
+ vm_size_t size)
{
if (map == VM_MAP_NULL)
return(KERN_INVALID_ARGUMENT);
@@ -114,11 +115,11 @@ kern_return_t vm_deallocate(map, start, size)
* vm_inherit sets the inheritance of the specified range in the
* specified map.
*/
-kern_return_t vm_inherit(map, start, size, new_inheritance)
- register vm_map_t map;
- vm_offset_t start;
- vm_size_t size;
- vm_inherit_t new_inheritance;
+kern_return_t vm_inherit(
+ vm_map_t map,
+ vm_offset_t start,
+ vm_size_t size,
+ vm_inherit_t new_inheritance)
{
if (map == VM_MAP_NULL)
return(KERN_INVALID_ARGUMENT);
@@ -148,12 +149,12 @@ kern_return_t vm_inherit(map, start, size, new_inheritance)
* specified map.
*/
-kern_return_t vm_protect(map, start, size, set_maximum, new_protection)
- register vm_map_t map;
- vm_offset_t start;
- vm_size_t size;
- boolean_t set_maximum;
- vm_prot_t new_protection;
+kern_return_t vm_protect(
+ vm_map_t map,
+ vm_offset_t start,
+ vm_size_t size,
+ boolean_t set_maximum,
+ vm_prot_t new_protection)
{
if ((map == VM_MAP_NULL) ||
(new_protection & ~(VM_PROT_ALL|VM_PROT_NOTIFY)))
@@ -171,9 +172,9 @@ kern_return_t vm_protect(map, start, size, set_maximum, new_protection)
set_maximum));
}
-kern_return_t vm_statistics(map, stat)
- vm_map_t map;
- vm_statistics_data_t *stat;
+kern_return_t vm_statistics(
+ vm_map_t map,
+ vm_statistics_data_t *stat)
{
if (map == VM_MAP_NULL)
return(KERN_INVALID_ARGUMENT);
@@ -181,7 +182,7 @@ kern_return_t vm_statistics(map, stat)
*stat = vm_stat;
stat->pagesize = PAGE_SIZE;
- stat->free_count = vm_page_free_count;
+ stat->free_count = vm_page_mem_free();
stat->active_count = vm_page_active_count;
stat->inactive_count = vm_page_inactive_count;
stat->wire_count = vm_page_wire_count;
@@ -189,19 +190,40 @@ kern_return_t vm_statistics(map, stat)
return(KERN_SUCCESS);
}
+kern_return_t vm_cache_statistics(
+ vm_map_t map,
+ vm_cache_statistics_data_t *stats)
+{
+ if (map == VM_MAP_NULL)
+ return KERN_INVALID_ARGUMENT;
+
+ stats->cache_object_count = vm_object_external_count;
+ stats->cache_count = vm_object_external_pages;
+
+ /* XXX Not implemented yet */
+ stats->active_tmp_count = 0;
+ stats->inactive_tmp_count = 0;
+ stats->active_perm_count = 0;
+ stats->inactive_perm_count = 0;
+ stats->dirty_count = 0;
+ stats->laundry_count = 0;
+ stats->writeback_count = 0;
+ stats->slab_count = 0;
+ stats->slab_reclaim_count = 0;
+ return KERN_SUCCESS;
+}
+
/*
* Handle machine-specific attributes for a mapping, such
* as cachability, migrability, etc.
*/
-kern_return_t vm_machine_attribute(map, address, size, attribute, value)
- vm_map_t map;
- vm_address_t address;
- vm_size_t size;
- vm_machine_attribute_t attribute;
- vm_machine_attribute_val_t* value; /* IN/OUT */
+kern_return_t vm_machine_attribute(
+ vm_map_t map,
+ vm_address_t address,
+ vm_size_t size,
+ vm_machine_attribute_t attribute,
+ vm_machine_attribute_val_t* value) /* IN/OUT */
{
- extern kern_return_t vm_map_machine_attribute();
-
if (map == VM_MAP_NULL)
return(KERN_INVALID_ARGUMENT);
@@ -213,12 +235,12 @@ kern_return_t vm_machine_attribute(map, address, size, attribute, value)
return vm_map_machine_attribute(map, address, size, attribute, value);
}
-kern_return_t vm_read(map, address, size, data, data_size)
- vm_map_t map;
- vm_address_t address;
- vm_size_t size;
- pointer_t *data;
- vm_size_t *data_size;
+kern_return_t vm_read(
+ vm_map_t map,
+ vm_address_t address,
+ vm_size_t size,
+ pointer_t *data,
+ vm_size_t *data_size)
{
kern_return_t error;
vm_map_copy_t ipc_address;
@@ -237,11 +259,11 @@ kern_return_t vm_read(map, address, size, data, data_size)
return(error);
}
-kern_return_t vm_write(map, address, data, size)
- vm_map_t map;
- vm_address_t address;
- pointer_t data;
- vm_size_t size;
+kern_return_t vm_write(
+ vm_map_t map,
+ vm_address_t address,
+ pointer_t data,
+ vm_size_t size)
{
if (map == VM_MAP_NULL)
return KERN_INVALID_ARGUMENT;
@@ -250,11 +272,11 @@ kern_return_t vm_write(map, address, data, size)
FALSE /* interruptible XXX */);
}
-kern_return_t vm_copy(map, source_address, size, dest_address)
- vm_map_t map;
- vm_address_t source_address;
- vm_size_t size;
- vm_address_t dest_address;
+kern_return_t vm_copy(
+ vm_map_t map,
+ vm_address_t source_address,
+ vm_size_t size,
+ vm_address_t dest_address)
{
vm_map_copy_t copy;
kern_return_t kr;
@@ -282,26 +304,19 @@ kern_return_t vm_copy(map, source_address, size, dest_address)
* Routine: vm_map
*/
kern_return_t vm_map(
- target_map,
- address, size, mask, anywhere,
- memory_object, offset,
- copy,
- cur_protection, max_protection, inheritance)
- vm_map_t target_map;
- vm_offset_t *address;
- vm_size_t size;
- vm_offset_t mask;
- boolean_t anywhere;
- ipc_port_t memory_object;
- vm_offset_t offset;
- boolean_t copy;
- vm_prot_t cur_protection;
- vm_prot_t max_protection;
- vm_inherit_t inheritance;
+ vm_map_t target_map,
+ vm_offset_t *address,
+ vm_size_t size,
+ vm_offset_t mask,
+ boolean_t anywhere,
+ ipc_port_t memory_object,
+ vm_offset_t offset,
+ boolean_t copy,
+ vm_prot_t cur_protection,
+ vm_prot_t max_protection,
+ vm_inherit_t inheritance)
{
- register
vm_object_t object;
- register
kern_return_t result;
if ((target_map == VM_MAP_NULL) ||
@@ -318,6 +333,9 @@ kern_return_t vm_map(
return(KERN_INVALID_ARGUMENT);
}
+ if (size == 0)
+ return KERN_INVALID_ARGUMENT;
+
*address = trunc_page(*address);
size = round_page(size);
@@ -387,16 +405,30 @@ kern_return_t vm_map(
*
* [ To unwire the pages, specify VM_PROT_NONE. ]
*/
-kern_return_t vm_wire(host, map, start, size, access)
- host_t host;
- register vm_map_t map;
+kern_return_t vm_wire(port, map, start, size, access)
+ const ipc_port_t port;
+ vm_map_t map;
vm_offset_t start;
vm_size_t size;
vm_prot_t access;
{
- if (host == HOST_NULL)
+ boolean_t priv;
+
+ if (!IP_VALID(port))
return KERN_INVALID_HOST;
+ ip_lock(port);
+ if (!ip_active(port) ||
+ (ip_kotype(port) != IKOT_HOST_PRIV
+ && ip_kotype(port) != IKOT_HOST))
+ {
+ ip_unlock(port);
+ return KERN_INVALID_HOST;
+ }
+
+ priv = ip_kotype(port) == IKOT_HOST_PRIV;
+ ip_unlock(port);
+
if (map == VM_MAP_NULL)
return KERN_INVALID_TASK;
@@ -408,6 +440,10 @@ kern_return_t vm_wire(host, map, start, size, access)
if (projected_buffer_in_range(map, start, start+size))
return(KERN_INVALID_ARGUMENT);
+ /* TODO: make it tunable */
+ if (!priv && access != VM_PROT_NONE && map->user_wired + size > 65536)
+ return KERN_NO_ACCESS;
+
return vm_map_pageable_user(map,
trunc_page(start),
round_page(start+size),