diff options
author | Samuel Thibault <samuel.thibault@ens-lyon.org> | 2016-10-02 19:44:46 +0200 |
---|---|---|
committer | Samuel Thibault <samuel.thibault@ens-lyon.org> | 2016-10-02 19:44:46 +0200 |
commit | ae25754394cd7ecc771eba37324ff49996e96e3a (patch) | |
tree | e5b2f0ad3e17827a9b19a9fe930a443158753c27 /vm/vm_user.c | |
parent | 4ce5f4c5b064c1a252cb6142706b83d69aa1aca4 (diff) | |
parent | 1443986a08b4cd564172875c07551681314014da (diff) |
Merge branch 'master' into HEAD
Diffstat (limited to 'vm/vm_user.c')
-rw-r--r-- | vm/vm_user.c | 176 |
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), |