From 247031c88d56028d8f6ea888bb28f20a96aafbc2 Mon Sep 17 00:00:00 2001 From: Samuel Thibault Date: Mon, 28 Aug 2023 22:25:59 +0200 Subject: mach_vm_object_pages: Extend for PAE --- include/mach_debug/mach_debug.defs | 9 ++++ include/mach_debug/mach_debug_types.defs | 10 ++++ include/mach_debug/vm_info.h | 12 +++++ vm/vm_debug.c | 89 +++++++++++++++++++++++++------- 4 files changed, 100 insertions(+), 20 deletions(-) diff --git a/include/mach_debug/mach_debug.defs b/include/mach_debug/mach_debug.defs index 8f3456dd..2de7df52 100644 --- a/include/mach_debug/mach_debug.defs +++ b/include/mach_debug/mach_debug.defs @@ -217,3 +217,12 @@ routine host_load_symbol_table( #else /* !defined(MACH_KDB) || MACH_KDB */ skip; /* host_load_symbol_table */ #endif /* !defined(MACH_KDB) || MACH_KDB */ + +#if !defined(MACH_VM_DEBUG) || MACH_VM_DEBUG +routine mach_vm_object_pages_phys( + object : memory_object_name_t; + out pages : vm_page_phys_info_array_t, + CountInOut, Dealloc); +#else /* !defined(MACH_VM_DEBUG) || MACH_VM_DEBUG */ +skip; /* mach_vm_object_pages_phys */ +#endif /* !defined(MACH_VM_DEBUG) || MACH_VM_DEBUG */ diff --git a/include/mach_debug/mach_debug_types.defs b/include/mach_debug/mach_debug_types.defs index 3e38ccae..d897380f 100644 --- a/include/mach_debug/mach_debug_types.defs +++ b/include/mach_debug/mach_debug_types.defs @@ -102,6 +102,16 @@ type vm_page_info_t = struct { }; type vm_page_info_array_t = array[] of vm_page_info_t; +type vm_page_phys_info_t = struct { + rpc_vm_offset_t vpi_offset; + rpc_phys_addr_t vpi_phys_addr; + unsigned vpi_wire_count; + vm_prot_t vpi_page_lock; + vm_prot_t vpi_unlock_request; + vm_page_info_state_t vpi_state; +}; +type vm_page_phys_info_array_t = array[] of vm_page_phys_info_t; + type symtab_name_t = c_string[32]; type kernel_debug_name_t = c_string[*: 64]; diff --git a/include/mach_debug/vm_info.h b/include/mach_debug/vm_info.h index 2c1b019f..cf45a2cc 100644 --- a/include/mach_debug/vm_info.h +++ b/include/mach_debug/vm_info.h @@ -117,6 +117,7 @@ typedef uint32_t vm_page_info_state_t; #define VPI_STATE_PAGER 0x80000000 /* pager has the page */ +/* XXX: This structure holds a 32bit vpi_phys_addr. */ typedef struct vm_page_info { rpc_vm_offset_t vpi_offset; /* offset in object */ rpc_vm_offset_t vpi_phys_addr; /* physical address */ @@ -128,4 +129,15 @@ typedef struct vm_page_info { typedef vm_page_info_t *vm_page_info_array_t; +typedef struct vm_page_phys_info { + rpc_vm_offset_t vpi_offset; /* offset in object */ + rpc_phys_addr_t vpi_phys_addr; /* physical address */ + unsigned int vpi_wire_count; /* number of times wired */ + vm_prot_t vpi_page_lock; /* XP access restrictions */ + vm_prot_t vpi_unlock_request; /* outstanding unlock requests */ + vm_page_info_state_t vpi_state; /* random state bits */ +} vm_page_phys_info_t; + +typedef vm_page_phys_info_t *vm_page_phys_info_array_t; + #endif /* _MACH_DEBUG_VM_INFO_H_ */ diff --git a/vm/vm_debug.c b/vm/vm_debug.c index 0b60611a..b0dace80 100644 --- a/vm/vm_debug.c +++ b/vm/vm_debug.c @@ -265,7 +265,7 @@ mach_vm_object_info( VPI_STATE_PRIVATE|VPI_STATE_ABSENT) /* - * Routine: mach_vm_object_pages [kernel call] + * Routine: mach_vm_object_pages/mach_vm_object_pages_phys/ [kernel call] * Purpose: * Retrieve information about the pages in a VM object. * Conditions: @@ -276,15 +276,16 @@ mach_vm_object_info( * KERN_RESOURCE_SHORTAGE Couldn't allocate memory. */ -kern_return_t -mach_vm_object_pages( +static kern_return_t +_mach_vm_object_pages( vm_object_t object, - vm_page_info_array_t *pagesp, - natural_t *countp) + void* *pagesp, + natural_t *countp, + int phys) { vm_size_t size; vm_offset_t addr; - vm_page_info_t *pages; + void *pages; unsigned int potential, actual, count; vm_page_t p; kern_return_t kr; @@ -307,28 +308,52 @@ mach_vm_object_pages( if (pages != *pagesp) kmem_free(ipc_kernel_map, addr, size); - size = round_page(actual * sizeof *pages); + if (phys) + size = round_page(actual * sizeof(vm_page_phys_info_t)); + else + size = round_page(actual * sizeof(vm_page_info_t)); kr = kmem_alloc(ipc_kernel_map, &addr, size); if (kr != KERN_SUCCESS) return kr; - pages = (vm_page_info_t *) addr; - potential = size/sizeof *pages; + pages = (void *) addr; + if (phys) + potential = size / sizeof(vm_page_phys_info_t); + else + potential = size / sizeof(vm_page_info_t); } /* object is locked, we have enough wired memory */ count = 0; queue_iterate(&object->memq, p, vm_page_t, listq) { - vm_page_info_t *info = &pages[count++]; + vm_page_info_t *info = NULL; + vm_page_phys_info_t *info_phys = NULL; + + if (phys) + info_phys = pages + count * sizeof(*info_phys); + else + info = pages + count * sizeof(*info); + count++; + vm_page_info_state_t state = 0; - info->vpi_offset = p->offset; - if (p->phys_addr != (typeof(info->vpi_phys_addr)) p->phys_addr) - printf("warning: physical address overflow in mach_vm_object_pages!!\n"); - info->vpi_phys_addr = p->phys_addr; - info->vpi_wire_count = p->wire_count; - info->vpi_page_lock = p->page_lock; - info->vpi_unlock_request = p->unlock_request; + if (phys) { + info_phys->vpi_offset = p->offset; + if (p->phys_addr != (typeof(info_phys->vpi_phys_addr)) p->phys_addr) + printf("warning: physical address overflow in mach_vm_object_pages!!\n"); + info_phys->vpi_phys_addr = p->phys_addr; + info_phys->vpi_wire_count = p->wire_count; + info_phys->vpi_page_lock = p->page_lock; + info_phys->vpi_unlock_request = p->unlock_request; + } else { + info->vpi_offset = p->offset; + if (p->phys_addr != (typeof(info->vpi_phys_addr)) p->phys_addr) + printf("warning: physical address overflow in mach_vm_object_pages!!\n"); + info->vpi_phys_addr = p->phys_addr; + info->vpi_wire_count = p->wire_count; + info->vpi_page_lock = p->page_lock; + info->vpi_unlock_request = p->unlock_request; + } if (p->busy) state |= VPI_STATE_BUSY; @@ -376,7 +401,10 @@ mach_vm_object_pages( } vm_page_unlock_queues(); - info->vpi_state = state; + if (phys) + info_phys->vpi_state = state; + else + info->vpi_state = state; } if (object->resident_page_count != count) @@ -397,7 +425,10 @@ mach_vm_object_pages( /* kmem_alloc doesn't zero memory */ - size_used = actual * sizeof *pages; + if (phys) + size_used = actual * sizeof(vm_page_phys_info_t); + else + size_used = actual * sizeof(vm_page_info_t); rsize_used = round_page(size_used); if (rsize_used != size) @@ -412,13 +443,31 @@ mach_vm_object_pages( TRUE, ©); assert(kr == KERN_SUCCESS); - *pagesp = (vm_page_info_t *) copy; + *pagesp = (void *) copy; *countp = actual; } return KERN_SUCCESS; } +kern_return_t +mach_vm_object_pages( + vm_object_t object, + vm_page_info_array_t *pagesp, + natural_t *countp) +{ + return _mach_vm_object_pages(object, (void**) pagesp, countp, 0); +} + +kern_return_t +mach_vm_object_pages_phys( + vm_object_t object, + vm_page_phys_info_array_t *pagesp, + natural_t *countp) +{ + return _mach_vm_object_pages(object, (void**) pagesp, countp, 1); +} + #endif /* MACH_VM_DEBUG */ /* -- cgit v1.2.3