So I've applied the patch and have tried to actually exercise the new functionality.
And unfortunately, I'm reminded (by a kernel panic and a corrupted filesystem) of the two important cases that we have forgot: * Submaps * "Anonymous" mappings (created with a null memory object) Submaps could be doable by recursing down through them — or really, we can just explicitly not support submaps, they only seem to be relevant for the kernel's own memory map. Anonymous mappings are exactly what we're interested in for realloc/mremap, so it's important that we support them. After reading up on how memory objects (pagers) and vm_object's and pages and whatnot work within the kernel, I believe a call to vm_object_pager_create () should be sufficient to "realize" a previously-anonymous mapping. I've applied these changes to your patch: --- a/vm/memory_object_proxy.c +++ b/vm/memory_object_proxy.c @@ -201,6 +201,7 @@ memory_object_get_proxy (task_t task, const vm_offset_t address, { kern_return_t ret; vm_map_entry_t entry, tmp_entry; + vm_object_t object; vm_offset_t offset, start; ipc_port_t pager; @@ -217,14 +218,26 @@ memory_object_get_proxy (task_t task, const vm_offset_t address, entry = tmp_entry; } + if (entry->is_sub_map) { + vm_map_unlock_read(task->map); + return(KERN_INVALID_ARGUMENT); + } + /* Limit the allowed protection and range to the entry ones */ if (len > entry->vme_end - entry->vme_start) { vm_map_unlock_read(task->map); return(KERN_INVALID_ARGUMENT); } - max_protection &= entry->max_protection; - pager = ipc_port_copy_send(entry->object.vm_object->pager); + + object = entry->object.vm_object; + vm_object_lock(object); + /* Create a pager in case this is an internal object that does + not yet have one. */ + vm_object_pager_create(object); + pager = ipc_port_copy_send(object->pager); + vm_object_unlock(object); + offset = entry->offset; start = 0; And now the kernel at least no longer crashes, even after multiple iterations of this (good!). I am able to successfully create a proxy and map it, and it does find the same underlying vm_object_t. vm_region () also shows the same name and offset between the old and the new mappings, so all is good in theory. The only problem is when I try to actually read data from the new mapping, I get complete garbage :( Sergey