summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSamuel Thibault <samuel.thibault@ens-lyon.org>2023-08-28 22:25:59 +0200
committerSamuel Thibault <samuel.thibault@ens-lyon.org>2023-08-28 22:32:18 +0200
commit247031c88d56028d8f6ea888bb28f20a96aafbc2 (patch)
treed18b1e2b7f9729b1f95b4c9da012ee84f6f36e1e
parent8852aa3195cebbbcde50743ce4d8e8c85f32262c (diff)
mach_vm_object_pages: Extend for PAE
-rw-r--r--include/mach_debug/mach_debug.defs9
-rw-r--r--include/mach_debug/mach_debug_types.defs10
-rw-r--r--include/mach_debug/vm_info.h12
-rw-r--r--vm/vm_debug.c89
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, &copy);
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 */
/*