X-Git-Url: https://git.saurik.com/apple/xnu.git/blobdiff_plain/55e303ae13a4cf49d70f2294092726f2fffb9ef2..d190cdc3f5544636abb56dc1874be391d3e1b148:/osfmk/vm/vm_debug.c diff --git a/osfmk/vm/vm_debug.c b/osfmk/vm/vm_debug.c index 87b81f23c..e29eed60f 100644 --- a/osfmk/vm/vm_debug.c +++ b/osfmk/vm/vm_debug.c @@ -1,16 +1,19 @@ /* - * Copyright (c) 2000 Apple Computer, Inc. All rights reserved. + * Copyright (c) 2000-2016 Apple Inc. All rights reserved. * - * @APPLE_LICENSE_HEADER_START@ - * - * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. + * compliance with the License. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this file. * * The Original Code and all software distributed under the License are * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER @@ -20,7 +23,7 @@ * Please see the License for the specific language governing rights and * limitations under the License. * - * @APPLE_LICENSE_HEADER_END@ + * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ */ /* * @OSF_COPYRIGHT@ @@ -62,7 +65,6 @@ #include #include #include -#include #include #include #include @@ -83,6 +85,17 @@ #include #endif +#if !MACH_VM_DEBUG +#define __DEBUG_ONLY __unused +#else /* !MACH_VM_DEBUG */ +#define __DEBUG_ONLY +#endif /* !MACH_VM_DEBUG */ + +#ifdef VM32_SUPPORT + +#include +#include + /* * Routine: mach_vm_region_info [kernel call] * Purpose: @@ -98,18 +111,18 @@ */ kern_return_t -mach_vm_region_info( - vm_map_t map, - vm_offset_t address, - vm_info_region_t *regionp, - vm_info_object_array_t *objectsp, - mach_msg_type_number_t *objectsCntp) +vm32_region_info( + __DEBUG_ONLY vm_map_t map, + __DEBUG_ONLY vm32_offset_t address, + __DEBUG_ONLY vm_info_region_t *regionp, + __DEBUG_ONLY vm_info_object_array_t *objectsp, + __DEBUG_ONLY mach_msg_type_number_t *objectsCntp) { #if !MACH_VM_DEBUG return KERN_FAILURE; #else vm_map_copy_t copy; - vm_offset_t addr; /* memory for OOL data */ + vm_offset_t addr = 0; /* memory for OOL data */ vm_size_t size; /* size of the memory */ unsigned int room; /* room for this many objects */ unsigned int used; /* actually this many objects */ @@ -133,7 +146,9 @@ mach_vm_region_info( for (cmap = map;; cmap = nmap) { /* cmap is read-locked */ - if (!vm_map_lookup_entry(cmap, address, &entry)) { + if (!vm_map_lookup_entry(cmap, + (vm_map_address_t)address, &entry)) { + entry = entry->vme_next; if (entry == vm_map_to_entry(cmap)) { vm_map_unlock_read(cmap); @@ -145,7 +160,7 @@ mach_vm_region_info( } if (entry->is_sub_map) - nmap = entry->object.sub_map; + nmap = VME_SUBMAP(entry); else break; @@ -157,11 +172,11 @@ mach_vm_region_info( /* cmap is read-locked; we have a real entry */ - object = entry->object.vm_object; - region.vir_start = entry->vme_start; - region.vir_end = entry->vme_end; - region.vir_object = (vm_offset_t) object; - region.vir_offset = entry->offset; + object = VME_OBJECT(entry); + region.vir_start = (natural_t) entry->vme_start; + region.vir_end = (natural_t) entry->vme_end; + region.vir_object = (natural_t)(uintptr_t) object; + region.vir_offset = (natural_t) VME_OFFSET(entry); region.vir_needs_copy = entry->needs_copy; region.vir_protection = entry->protection; region.vir_max_protection = entry->max_protection; @@ -170,7 +185,7 @@ mach_vm_region_info( region.vir_user_wired_count = entry->user_wired_count; used = 0; - room = size / sizeof(vm_info_object_t); + room = (unsigned int) (size / sizeof(vm_info_object_t)); if (object == VM_OBJECT_NULL) { vm_map_unlock_read(cmap); @@ -189,29 +204,28 @@ mach_vm_region_info( &((vm_info_object_t *) addr)[used]; vio->vio_object = - (vm_offset_t) cobject; + (natural_t)(uintptr_t) cobject; vio->vio_size = - cobject->size; + (natural_t) cobject->vo_size; vio->vio_ref_count = cobject->ref_count; vio->vio_resident_page_count = cobject->resident_page_count; - vio->vio_absent_count = - cobject->absent_count; vio->vio_copy = - (vm_offset_t) cobject->copy; + (natural_t)(uintptr_t) cobject->copy; vio->vio_shadow = - (vm_offset_t) cobject->shadow; + (natural_t)(uintptr_t) cobject->shadow; vio->vio_shadow_offset = - cobject->shadow_offset; + (natural_t) cobject->vo_shadow_offset; vio->vio_paging_offset = - cobject->paging_offset; + (natural_t) cobject->paging_offset; vio->vio_copy_strategy = cobject->copy_strategy; vio->vio_last_alloc = - cobject->last_alloc; + (vm_offset_t) cobject->last_alloc; vio->vio_paging_in_progress = - cobject->paging_in_progress; + cobject->paging_in_progress + + cobject->activity_in_progress; vio->vio_pager_created = cobject->pager_created; vio->vio_pager_initialized = @@ -226,10 +240,11 @@ mach_vm_region_info( cobject->temporary; vio->vio_alive = cobject->alive; - vio->vio_lock_in_progress = - cobject->lock_in_progress; - vio->vio_lock_restart = - cobject->lock_restart; + vio->vio_purgable = + (cobject->purgable != VM_PURGABLE_DENY); + vio->vio_purgable_volatile = + (cobject->purgable == VM_PURGABLE_VOLATILE || + cobject->purgable == VM_PURGABLE_EMPTY); } used++; @@ -252,14 +267,21 @@ mach_vm_region_info( if (size != 0) kmem_free(ipc_kernel_map, addr, size); - size = round_page_32(2 * used * sizeof(vm_info_object_t)); + size = vm_map_round_page(2 * used * sizeof(vm_info_object_t), + VM_MAP_PAGE_MASK(ipc_kernel_map)); - kr = vm_allocate(ipc_kernel_map, &addr, size, TRUE); + kr = vm_allocate(ipc_kernel_map, &addr, size, VM_FLAGS_ANYWHERE | VM_MAKE_TAG(VM_KERN_MEMORY_IPC)); if (kr != KERN_SUCCESS) return KERN_RESOURCE_SHORTAGE; - kr = vm_map_wire(ipc_kernel_map, addr, addr + size, - VM_PROT_READ|VM_PROT_WRITE, FALSE); + kr = vm_map_wire( + ipc_kernel_map, + vm_map_trunc_page(addr, + VM_MAP_PAGE_MASK(ipc_kernel_map)), + vm_map_round_page(addr + size, + VM_MAP_PAGE_MASK(ipc_kernel_map)), + VM_PROT_READ|VM_PROT_WRITE, + FALSE); assert(kr == KERN_SUCCESS); } @@ -271,19 +293,26 @@ mach_vm_region_info( if (size != 0) kmem_free(ipc_kernel_map, addr, size); } else { - vm_size_t size_used = - round_page_32(used * sizeof(vm_info_object_t)); - - kr = vm_map_unwire(ipc_kernel_map, addr, addr + size_used, FALSE); + vm_size_t size_used = (used * sizeof(vm_info_object_t)); + vm_size_t vmsize_used = vm_map_round_page(size_used, + VM_MAP_PAGE_MASK(ipc_kernel_map)); + + kr = vm_map_unwire( + ipc_kernel_map, + vm_map_trunc_page(addr, + VM_MAP_PAGE_MASK(ipc_kernel_map)), + vm_map_round_page(addr + size_used, + VM_MAP_PAGE_MASK(ipc_kernel_map)), + FALSE); assert(kr == KERN_SUCCESS); - kr = vm_map_copyin(ipc_kernel_map, addr, size_used, - TRUE, ©); + kr = vm_map_copyin(ipc_kernel_map, (vm_map_address_t)addr, + (vm_map_size_t)size_used, TRUE, ©); assert(kr == KERN_SUCCESS); - if (size != size_used) + if (size != vmsize_used) kmem_free(ipc_kernel_map, - addr + size_used, size - size_used); + addr + vmsize_used, size - vmsize_used); } *regionp = region; @@ -292,23 +321,24 @@ mach_vm_region_info( return KERN_SUCCESS; #endif /* MACH_VM_DEBUG */ } + /* * Temporary call for 64 bit data path interface transiotion */ kern_return_t -mach_vm_region_info_64( - vm_map_t map, - vm_offset_t address, - vm_info_region_64_t *regionp, - vm_info_object_array_t *objectsp, - mach_msg_type_number_t *objectsCntp) +vm32_region_info_64( + __DEBUG_ONLY vm_map_t map, + __DEBUG_ONLY vm32_offset_t address, + __DEBUG_ONLY vm_info_region_64_t *regionp, + __DEBUG_ONLY vm_info_object_array_t *objectsp, + __DEBUG_ONLY mach_msg_type_number_t *objectsCntp) { #if !MACH_VM_DEBUG return KERN_FAILURE; #else vm_map_copy_t copy; - vm_offset_t addr; /* memory for OOL data */ + vm_offset_t addr = 0; /* memory for OOL data */ vm_size_t size; /* size of the memory */ unsigned int room; /* room for this many objects */ unsigned int used; /* actually this many objects */ @@ -344,7 +374,7 @@ mach_vm_region_info_64( } if (entry->is_sub_map) - nmap = entry->object.sub_map; + nmap = VME_SUBMAP(entry); else break; @@ -356,11 +386,11 @@ mach_vm_region_info_64( /* cmap is read-locked; we have a real entry */ - object = entry->object.vm_object; - region.vir_start = entry->vme_start; - region.vir_end = entry->vme_end; - region.vir_object = (vm_offset_t) object; - region.vir_offset = entry->offset; + object = VME_OBJECT(entry); + region.vir_start = (natural_t) entry->vme_start; + region.vir_end = (natural_t) entry->vme_end; + region.vir_object = (natural_t)(uintptr_t) object; + region.vir_offset = VME_OFFSET(entry); region.vir_needs_copy = entry->needs_copy; region.vir_protection = entry->protection; region.vir_max_protection = entry->max_protection; @@ -369,7 +399,7 @@ mach_vm_region_info_64( region.vir_user_wired_count = entry->user_wired_count; used = 0; - room = size / sizeof(vm_info_object_t); + room = (unsigned int) (size / sizeof(vm_info_object_t)); if (object == VM_OBJECT_NULL) { vm_map_unlock_read(cmap); @@ -388,29 +418,28 @@ mach_vm_region_info_64( &((vm_info_object_t *) addr)[used]; vio->vio_object = - (vm_offset_t) cobject; + (natural_t)(uintptr_t) cobject; vio->vio_size = - cobject->size; + (natural_t) cobject->vo_size; vio->vio_ref_count = cobject->ref_count; vio->vio_resident_page_count = cobject->resident_page_count; - vio->vio_absent_count = - cobject->absent_count; vio->vio_copy = - (vm_offset_t) cobject->copy; + (natural_t)(uintptr_t) cobject->copy; vio->vio_shadow = - (vm_offset_t) cobject->shadow; + (natural_t)(uintptr_t) cobject->shadow; vio->vio_shadow_offset = - cobject->shadow_offset; + (natural_t) cobject->vo_shadow_offset; vio->vio_paging_offset = - cobject->paging_offset; + (natural_t) cobject->paging_offset; vio->vio_copy_strategy = cobject->copy_strategy; vio->vio_last_alloc = - cobject->last_alloc; + (vm_offset_t) cobject->last_alloc; vio->vio_paging_in_progress = - cobject->paging_in_progress; + cobject->paging_in_progress + + cobject->activity_in_progress; vio->vio_pager_created = cobject->pager_created; vio->vio_pager_initialized = @@ -425,10 +454,11 @@ mach_vm_region_info_64( cobject->temporary; vio->vio_alive = cobject->alive; - vio->vio_lock_in_progress = - cobject->lock_in_progress; - vio->vio_lock_restart = - cobject->lock_restart; + vio->vio_purgable = + (cobject->purgable != VM_PURGABLE_DENY); + vio->vio_purgable_volatile = + (cobject->purgable == VM_PURGABLE_VOLATILE || + cobject->purgable == VM_PURGABLE_EMPTY); } used++; @@ -451,14 +481,21 @@ mach_vm_region_info_64( if (size != 0) kmem_free(ipc_kernel_map, addr, size); - size = round_page_32(2 * used * sizeof(vm_info_object_t)); + size = vm_map_round_page(2 * used * sizeof(vm_info_object_t), + VM_MAP_PAGE_MASK(ipc_kernel_map)); - kr = vm_allocate(ipc_kernel_map, &addr, size, TRUE); + kr = vm_allocate(ipc_kernel_map, &addr, size, VM_FLAGS_ANYWHERE | VM_MAKE_TAG(VM_KERN_MEMORY_IPC)); if (kr != KERN_SUCCESS) return KERN_RESOURCE_SHORTAGE; - kr = vm_map_wire(ipc_kernel_map, addr, addr + size, - VM_PROT_READ|VM_PROT_WRITE, FALSE); + kr = vm_map_wire( + ipc_kernel_map, + vm_map_trunc_page(addr, + VM_MAP_PAGE_MASK(ipc_kernel_map)), + vm_map_round_page(addr + size, + VM_MAP_PAGE_MASK(ipc_kernel_map)), + VM_PROT_READ|VM_PROT_WRITE, + FALSE); assert(kr == KERN_SUCCESS); } @@ -470,19 +507,26 @@ mach_vm_region_info_64( if (size != 0) kmem_free(ipc_kernel_map, addr, size); } else { - vm_size_t size_used = - round_page_32(used * sizeof(vm_info_object_t)); - - kr = vm_map_unwire(ipc_kernel_map, addr, addr + size_used, FALSE); + vm_size_t size_used = (used * sizeof(vm_info_object_t)); + vm_size_t vmsize_used = vm_map_round_page(size_used, + VM_MAP_PAGE_MASK(ipc_kernel_map)); + + kr = vm_map_unwire( + ipc_kernel_map, + vm_map_trunc_page(addr, + VM_MAP_PAGE_MASK(ipc_kernel_map)), + vm_map_round_page(addr + size_used, + VM_MAP_PAGE_MASK(ipc_kernel_map)), + FALSE); assert(kr == KERN_SUCCESS); - kr = vm_map_copyin(ipc_kernel_map, addr, size_used, - TRUE, ©); + kr = vm_map_copyin(ipc_kernel_map, (vm_map_address_t)addr, + (vm_map_size_t)size_used, TRUE, ©); assert(kr == KERN_SUCCESS); - if (size != size_used) + if (size != vmsize_used) kmem_free(ipc_kernel_map, - addr + size_used, size - size_used); + addr + vmsize_used, size - vmsize_used); } *regionp = region; @@ -495,10 +539,10 @@ mach_vm_region_info_64( * Return an array of virtual pages that are mapped to a task. */ kern_return_t -vm_mapped_pages_info( - vm_map_t map, - page_address_array_t *pages, - mach_msg_type_number_t *pages_count) +vm32_mapped_pages_info( + __DEBUG_ONLY vm_map_t map, + __DEBUG_ONLY page_address_array_t *pages, + __DEBUG_ONLY mach_msg_type_number_t *pages_count) { #if !MACH_VM_DEBUG return KERN_FAILURE; @@ -507,21 +551,28 @@ vm_mapped_pages_info( vm_size_t size, size_used; unsigned int actual, space; page_address_array_t list; - vm_offset_t addr; + vm_offset_t addr = 0; if (map == VM_MAP_NULL) return (KERN_INVALID_ARGUMENT); pmap = map->pmap; size = pmap_resident_count(pmap) * sizeof(vm_offset_t); - size = round_page_32(size); + size = vm_map_round_page(size, + VM_MAP_PAGE_MASK(ipc_kernel_map)); for (;;) { - (void) vm_allocate(ipc_kernel_map, &addr, size, TRUE); - (void) vm_map_unwire(ipc_kernel_map, addr, addr + size, FALSE); + (void) vm_allocate(ipc_kernel_map, &addr, size, VM_FLAGS_ANYWHERE | VM_MAKE_TAG(VM_KERN_MEMORY_IPC)); + (void) vm_map_unwire( + ipc_kernel_map, + vm_map_trunc_page(addr, + VM_MAP_PAGE_MASK(ipc_kernel_map)), + vm_map_round_page(addr + size, + VM_MAP_PAGE_MASK(ipc_kernel_map)), + FALSE); list = (page_address_array_t) addr; - space = size / sizeof(vm_offset_t); + space = (unsigned int) (size / sizeof(vm_offset_t)); actual = pmap_list_resident_pages(pmap, list, @@ -537,7 +588,8 @@ vm_mapped_pages_info( /* * Try again, doubling the size */ - size = round_page_32(actual * sizeof(vm_offset_t)); + size = vm_map_round_page(actual * sizeof(vm_offset_t), + VM_MAP_PAGE_MASK(ipc_kernel_map)); } if (actual == 0) { *pages = 0; @@ -545,21 +597,28 @@ vm_mapped_pages_info( (void) kmem_free(ipc_kernel_map, addr, size); } else { + vm_size_t vmsize_used; *pages_count = actual; - size_used = round_page_32(actual * sizeof(vm_offset_t)); - (void) vm_map_wire(ipc_kernel_map, - addr, addr + size, - VM_PROT_READ|VM_PROT_WRITE, FALSE); - (void) vm_map_copyin( - ipc_kernel_map, - addr, - size_used, + size_used = (actual * sizeof(vm_offset_t)); + vmsize_used = vm_map_round_page(size_used, + VM_MAP_PAGE_MASK(ipc_kernel_map)); + (void) vm_map_wire( + ipc_kernel_map, + vm_map_trunc_page(addr, + VM_MAP_PAGE_MASK(ipc_kernel_map)), + vm_map_round_page(addr + size, + VM_MAP_PAGE_MASK(ipc_kernel_map)), + VM_PROT_READ|VM_PROT_WRITE, + FALSE); + (void) vm_map_copyin(ipc_kernel_map, + (vm_map_address_t)addr, + (vm_map_size_t)size_used, TRUE, (vm_map_copy_t *)pages); - if (size_used != size) { + if (vmsize_used != size) { (void) kmem_free(ipc_kernel_map, - addr + size_used, - size - size_used); + addr + vmsize_used, + size - vmsize_used); } } @@ -567,6 +626,8 @@ vm_mapped_pages_info( #endif /* MACH_VM_DEBUG */ } +#endif /* VM32_SUPPORT */ + /* * Routine: host_virtual_physical_table_info * Purpose: @@ -581,15 +642,15 @@ vm_mapped_pages_info( kern_return_t host_virtual_physical_table_info( - host_t host, - hash_info_bucket_array_t *infop, - mach_msg_type_number_t *countp) + __DEBUG_ONLY host_t host, + __DEBUG_ONLY hash_info_bucket_array_t *infop, + __DEBUG_ONLY mach_msg_type_number_t *countp) { #if !MACH_VM_DEBUG return KERN_FAILURE; #else - vm_offset_t addr; - vm_size_t size; + vm_offset_t addr = 0; + vm_size_t size = 0; hash_info_bucket_t *info; unsigned int potential, actual; kern_return_t kr; @@ -612,13 +673,15 @@ host_virtual_physical_table_info( if (info != *infop) kmem_free(ipc_kernel_map, addr, size); - size = round_page_32(actual * sizeof *info); - kr = kmem_alloc_pageable(ipc_kernel_map, &addr, size); + size = vm_map_round_page(actual * sizeof *info, + VM_MAP_PAGE_MASK(ipc_kernel_map)); + kr = vm_allocate(ipc_kernel_map, &addr, size, + VM_FLAGS_ANYWHERE | VM_MAKE_TAG(VM_KERN_MEMORY_IPC)); if (kr != KERN_SUCCESS) return KERN_RESOURCE_SHORTAGE; info = (hash_info_bucket_t *) addr; - potential = size/sizeof *info; + potential = (unsigned int) (size/sizeof (*info)); } if (info == *infop) { @@ -631,15 +694,16 @@ host_virtual_physical_table_info( *countp = 0; } else { vm_map_copy_t copy; - vm_size_t used; + vm_size_t used, vmused; - used = round_page_32(actual * sizeof *info); + used = (actual * sizeof(*info)); + vmused = vm_map_round_page(used, VM_MAP_PAGE_MASK(ipc_kernel_map)); - if (used != size) - kmem_free(ipc_kernel_map, addr + used, size - used); + if (vmused != size) + kmem_free(ipc_kernel_map, addr + vmused, size - vmused); - kr = vm_map_copyin(ipc_kernel_map, addr, used, - TRUE, ©); + kr = vm_map_copyin(ipc_kernel_map, (vm_map_address_t)addr, + (vm_map_size_t)used, TRUE, ©); assert(kr == KERN_SUCCESS); *infop = (hash_info_bucket_t *) copy;