vm: region: improve locking rules and semantics; implement region killing

the rules around acquiring locks have been strictly defined and
implemented, and general lock usage has been improved, to fix and
prevent several different issues.

a vm-region is now destroyed in two separate steps:
 1. it is "killed": all mappings are unmapped and deleted, the
    region is removed from its parent, and the region and all of
    its sub-regions are marked as "dead", preventing any
    further actions from being performed with the region.
 2. it is "destroyed": the vm-region object is de-allocated when
    the last reference/handle is closed. the references that this
    region holds to any sub-regions are also released, meaning
    these regions may also be de-allocated too.
This commit is contained in:
2026-02-23 18:35:45 +00:00
parent 5690dd5b9c
commit b1ffdcf2bc
2 changed files with 63 additions and 2 deletions

View File

@@ -63,6 +63,7 @@ kern_status_t sys_vm_region_create(
object_ref(obj);
task_unlock_irqrestore(self, flags);
vm_region_lock_irqsave(parent_region, &flags);
struct vm_region *child = NULL;
status = vm_region_create(
@@ -73,6 +74,7 @@ kern_status_t sys_vm_region_create(
region_len,
prot,
&child);
vm_region_unlock_irqrestore(parent_region, flags);
object_unref(obj);
if (status != KERN_OK) {
@@ -92,6 +94,39 @@ kern_status_t sys_vm_region_create(
return KERN_OK;
}
kern_status_t sys_vm_region_kill(kern_handle_t region_handle)
{
struct task *self = current_task();
unsigned long flags;
task_lock_irqsave(self, &flags);
struct object *obj = NULL;
handle_flags_t handle_flags = 0;
kern_status_t status
= task_resolve_handle(self, region_handle, &obj, &handle_flags);
if (status != KERN_OK) {
task_unlock_irqrestore(self, flags);
return status;
}
struct vm_region *region = vm_region_cast(obj);
if (!region) {
task_unlock_irqrestore(self, flags);
return KERN_INVALID_ARGUMENT;
}
object_ref(obj);
task_unlock_irqrestore(self, flags);
vm_region_lock_irqsave(region, &flags);
status = vm_region_kill(region, &flags);
vm_region_unlock_irqrestore(region, flags);
object_unref(obj);
return status;
}
kern_status_t sys_vm_region_read(
kern_handle_t region_handle,
void *dst,