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

@@ -11,6 +11,11 @@
struct vm_region;
struct vm_object;
enum vm_region_status {
VM_REGION_DEAD = 0,
VM_REGION_ONLINE,
};
enum vm_region_entry_type {
VM_REGION_ENTRY_NONE = 0,
VM_REGION_ENTRY_REGION,
@@ -18,9 +23,16 @@ enum vm_region_entry_type {
};
struct vm_region_entry {
struct btree_node e_node;
union {
struct btree_node e_node;
/* this entry is only used to queue vm-region objects for
* recursive cleanup */
struct queue_entry e_entry;
};
struct vm_region_entry *e_parent;
enum vm_region_entry_type e_type;
/* absolute address of this entry */
virt_addr_t e_address;
/* offset in bytes of this entry within its immediate parent. */
off_t e_offset;
/* size of the entry in bytes */
@@ -31,7 +43,7 @@ struct vm_region_mapping {
struct vm_region_entry m_entry;
struct vm_object *m_object;
/* used to link to vm_object->vo_mappings */
/* used to link to vm_object->vo_mappings */
struct queue_entry m_object_entry;
vm_prot_t m_prot;
@@ -41,6 +53,7 @@ struct vm_region_mapping {
struct vm_region {
struct object vr_base;
enum vm_region_status vr_status;
struct vm_region_entry vr_entry;
char vr_name[VM_REGION_NAME_MAX];
@@ -81,6 +94,19 @@ extern kern_status_t vm_region_create(
vm_prot_t prot,
struct vm_region **out);
/* recursively kills a given region and all of its sub-regions.
* when a region is killed, all of its mappings are unmapped, and any further
* operations on the region are denied. however, all handles and references to
* the region (any any sub-region) remain valid, and no kernel memory is
* de-allocated.
* the memory used by the vm-region object itself is de-allocated when the last
* handle/reference to the object is released.
* this function should be called with `region` locked.
*/
extern kern_status_t vm_region_kill(
struct vm_region *region,
unsigned long *lock_flags);
/* map a vm-object into a vm-region.
* [region_offset,length] must fall within exactly one region, and cannot span
* multiple sibling regions.