diff options
author | Diego Nieto Cid <dnietoc@gmail.com> | 2025-09-21 21:23:42 +0100 |
---|---|---|
committer | Samuel Thibault <samuel.thibault@ens-lyon.org> | 2025-09-22 00:51:29 +0200 |
commit | 9ae4d99c1d1e7c9c0977cebb4df9b86fa92cca94 (patch) | |
tree | 62e1baaaefde974b943755eb8771ad0a2ca182f4 /vm/vm_user.c | |
parent | 1269629d90b28a23ef9742645cfaf657ea3165bb (diff) |
* doc/mach.texi: add a "Memory Limitations" section to document the new interfaces.
* include/mach/gnumach.defs: (vm_set_size_limit) new routine
(vm_get_size_limit) likewise
* kern/task.c: (task_create_kernel) if parent_task is not null copy virtual memory limit
* tests/test-vm.c: (test_vm_limit) add test for the new routines
* vm/vm_map.h: (struct vm_map) new fields size_none, size_cur_limit and size_max_limit
(vm_map_find_entry) add new parameters cur_protection and max_protection
* vm/vm_map.c: (vm_map_setup) initialize new fields
(vm_map_enforce_limit) new function
(vm_map_copy_limits) new function
(vm_map_find_entry) add protection and max_protection parameters.
call limit enforcer function
(vm_map_enter) likewise
(vm_map_copyout) likewise
(vm_map_copyout_page_list) likewise
(vm_map_fork) copy parent limit to the new map and compute and set size_none of the new map
* vm/vm_user.c: (vm_set_size_limit) new function
(vm_get_size_limit) likewise
* xen/grant.c: update call to vm_map_find_entry to pass protection parameters
Message-ID: <0b71f4f89b7cc2b159893a805480d7493d522d60.1758485757.git.dnietoc@gmail.com>
Diffstat (limited to 'vm/vm_user.c')
-rw-r--r-- | vm/vm_user.c | 69 |
1 files changed, 69 insertions, 0 deletions
diff --git a/vm/vm_user.c b/vm/vm_user.c index c6dbda68..ef2c39d7 100644 --- a/vm/vm_user.c +++ b/vm/vm_user.c @@ -813,3 +813,72 @@ kern_return_t vm_pages_phys( return KERN_SUCCESS; } + +/* + * vm_set_size_limit + * + * Sets the current/maximum virtual adress space limits + * of the `target_task`. + * + * The host privileged port must be provided to increase + * the max limit. + */ +kern_return_t +vm_set_size_limit( + const ipc_port_t host_port, + vm_map_t map, + vm_size_t current_limit, + vm_size_t max_limit) +{ + ipc_kobject_type_t ikot_host = IKOT_NONE; + + if (current_limit > max_limit) + return KERN_INVALID_ARGUMENT; + if (map == VM_MAP_NULL) + return KERN_INVALID_TASK; + + if (!IP_VALID(host_port)) + return KERN_INVALID_HOST; + ip_lock(host_port); + if (ip_active(host_port)) + ikot_host = ip_kotype(host_port); + ip_unlock(host_port); + + if (ikot_host != IKOT_HOST && ikot_host != IKOT_HOST_PRIV) + return KERN_INVALID_HOST; + + vm_map_lock(map); + if (max_limit > map->size_max_limit && ikot_host != IKOT_HOST_PRIV) { + vm_map_unlock(map); + return KERN_NO_ACCESS; + } + + map->size_cur_limit = current_limit; + map->size_max_limit = max_limit; + vm_map_unlock(map); + + return KERN_SUCCESS; +} + +/* + * vm_get_size_limit + * + * Gets the current/maximum virtual adress space limits + * of the provided `map`. + */ +kern_return_t +vm_get_size_limit( + vm_map_t map, + vm_size_t *current_limit, + vm_size_t *max_limit) +{ + if (map == VM_MAP_NULL) + return KERN_INVALID_TASK; + + vm_map_lock_read(map); + *current_limit = map->size_cur_limit; + *max_limit = map->size_max_limit; + vm_map_unlock_read(map); + + return KERN_SUCCESS; +} |