diff options
author | Joan Lledó <jlledom@member.fsf.org> | 2021-11-06 09:13:32 +0100 |
---|---|---|
committer | Samuel Thibault <samuel.thibault@ens-lyon.org> | 2021-11-07 17:55:13 +0100 |
commit | 44ca02a46b6fa0a8f1181fdc08efa779c3bdce80 (patch) | |
tree | 140b4a8af5706b6e204bf398baa117a4f62ff615 /vm | |
parent | a0473675b98f51c48ea92c357793c2dbed0d1d85 (diff) | |
download | gnumach-44ca02a46b6fa0a8f1181fdc08efa779c3bdce80.tar.gz gnumach-44ca02a46b6fa0a8f1181fdc08efa779c3bdce80.tar.bz2 gnumach-44ca02a46b6fa0a8f1181fdc08efa779c3bdce80.zip |
vm: vm_region_get_proxy
To get a proxy to the region a given address belongs to,
with protection and range limited to the region ones.
* include/mach/mach4.defs: vm_region_get_proxy RPC declaration
* vm/vm_map.c: vm_region_get_proxy implementation
Message-Id: <20211106081333.10366-2-jlledom@mailfence.com>
Diffstat (limited to 'vm')
-rw-r--r-- | vm/memory_object_proxy.h | 8 | ||||
-rw-r--r-- | vm/vm_map.c | 56 |
2 files changed, 64 insertions, 0 deletions
diff --git a/vm/memory_object_proxy.h b/vm/memory_object_proxy.h index 8b3f2025..97f20b36 100644 --- a/vm/memory_object_proxy.h +++ b/vm/memory_object_proxy.h @@ -36,4 +36,12 @@ extern kern_return_t memory_object_proxy_lookup (ipc_port_t port, vm_offset_t *start, vm_offset_t *len); +extern kern_return_t +memory_object_create_proxy (ipc_space_t space, vm_prot_t max_protection, + ipc_port_t *object, natural_t object_count, + vm_offset_t *offset, natural_t offset_count, + vm_offset_t *start, natural_t start_count, + vm_size_t *len, natural_t len_count, + ipc_port_t *port); + #endif /* _VM_MEMORY_OBJECT_PROXY_H_ */ diff --git a/vm/vm_map.c b/vm/vm_map.c index a687d365..900862d9 100644 --- a/vm/vm_map.c +++ b/vm/vm_map.c @@ -46,6 +46,7 @@ #include <kern/list.h> #include <kern/rbtree.h> #include <kern/slab.h> +#include <kern/mach4.server.h> #include <vm/pmap.h> #include <vm/vm_fault.h> #include <vm/vm_map.h> @@ -53,6 +54,7 @@ #include <vm/vm_page.h> #include <vm/vm_resident.h> #include <vm/vm_kern.h> +#include <vm/memory_object_proxy.h> #include <ipc/ipc_port.h> #include <string.h> @@ -4807,6 +4809,60 @@ kern_return_t vm_region( } /* + * vm_region_get_proxy: + * + * Gets a proxy to the region that ADDRESS belongs to, starting at the + * region start, with MAX_PROTECTION and LEN limited by the region ones, + * and returns it in *PORT. + */ +kern_return_t +vm_region_get_proxy (task_t task, vm_address_t address, + vm_prot_t max_protection, vm_size_t len, + ipc_port_t *port) +{ + kern_return_t ret; + vm_map_entry_t entry, tmp_entry; + vm_offset_t offset, start; + ipc_port_t pager; + + if (task == TASK_NULL) + return(KERN_INVALID_ARGUMENT); + + vm_map_lock_read(task->map); + if (!vm_map_lookup_entry(task->map, address, &tmp_entry)) { + if ((entry = tmp_entry->vme_next) == vm_map_to_entry(task->map)) { + vm_map_unlock_read(task->map); + return(KERN_NO_SPACE); + } + } else { + entry = tmp_entry; + } + + /* 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); + offset = entry->offset; + start = 0; + + vm_map_unlock_read(task->map); + + ret = memory_object_create_proxy(task->itk_space, max_protection, + &pager, 1, + &offset, 1, + &start, 1, + &len, 1, port); + if (ret) + ipc_port_release_send(pager); + + return ret; +} + +/* * Routine: vm_map_simplify * * Description: |