vm: add vm-region to manage userspace virtual memory address spaces
vm-region supports creating nested regions of virtual memory, each with their own memory protection restrictions. vm-objects can be mapped into a vm-region, making the underlying memory accessible. all mappings are lazy: page tables are not updated until the mapped memory is accessed.
This commit is contained in:
126
include/mango/vm-region.h
Normal file
126
include/mango/vm-region.h
Normal file
@@ -0,0 +1,126 @@
|
||||
#ifndef MANGO_VM_REGION_H_
|
||||
#define MANGO_VM_REGION_H_
|
||||
|
||||
#include <mango/object.h>
|
||||
#include <mango/pmap.h>
|
||||
#include <mango/vm.h>
|
||||
|
||||
#define VM_REGION_NAME_MAX 64
|
||||
|
||||
#define VM_REGION_ANY_MAP_ADDRESS ((virt_addr_t) - 1)
|
||||
|
||||
struct vm_region;
|
||||
struct vm_object;
|
||||
|
||||
enum vm_region_entry_type {
|
||||
VM_REGION_ENTRY_NONE = 0,
|
||||
VM_REGION_ENTRY_REGION,
|
||||
VM_REGION_ENTRY_MAPPING,
|
||||
};
|
||||
|
||||
struct vm_region_entry {
|
||||
struct btree_node e_node;
|
||||
struct vm_region_entry *e_parent;
|
||||
enum vm_region_entry_type e_type;
|
||||
/* absolute virtual address of the entry */
|
||||
virt_addr_t e_base_address;
|
||||
/* size of the entry in bytes */
|
||||
size_t e_size;
|
||||
};
|
||||
|
||||
struct vm_region_mapping {
|
||||
struct vm_region_entry m_entry;
|
||||
struct vm_object *m_object;
|
||||
|
||||
/* used to link to vm_object->vo_mappings */
|
||||
struct queue_entry m_object_entry;
|
||||
|
||||
enum vm_prot m_prot;
|
||||
/* offset in bytes to the start of the object data that was mapped */
|
||||
off_t m_object_offset;
|
||||
};
|
||||
|
||||
struct vm_region {
|
||||
struct object vr_base;
|
||||
struct vm_region_entry vr_entry;
|
||||
|
||||
char vr_name[VM_REGION_NAME_MAX];
|
||||
|
||||
/* btree of struct vm_region_entry.
|
||||
* sibling entries cannot overlap each other, and child entries must
|
||||
* be entirely contained within their immediate parent entry. */
|
||||
struct btree vr_entries;
|
||||
|
||||
/* memory protection restriction mask.
|
||||
* any mapping in this region, or any of its children, cannot use
|
||||
* protection flags that are not set in this mask.
|
||||
* for example, if VM_PROT_EXEC is /not/ set here, no mapping
|
||||
* can be created in this region or any child region with VM_PROT_EXEC
|
||||
* set. */
|
||||
enum vm_prot vr_prot;
|
||||
|
||||
/* the physical address space in which mappings in this region (and
|
||||
* its children) are created */
|
||||
pmap_t vr_pmap;
|
||||
};
|
||||
|
||||
extern kern_status_t vm_region_type_init(void);
|
||||
|
||||
extern kern_status_t vm_region_create(
|
||||
struct vm_region *parent,
|
||||
const char *name,
|
||||
virt_addr_t base,
|
||||
size_t len,
|
||||
enum vm_prot prot,
|
||||
struct vm_region **out);
|
||||
|
||||
/* find the child region that has jurisdiction over the specified virtual
|
||||
* address. returns the lowest-nested region that covers the specified virtual
|
||||
* address. */
|
||||
extern struct vm_region *vm_region_find_child(
|
||||
struct vm_region *region,
|
||||
virt_addr_t addr);
|
||||
|
||||
/* find the child region that has jurisdiction over the specified virtual
|
||||
* address area. returns the lowest-nested region that covers the specified
|
||||
* virtual address area. the area must be fully contained within a region, with
|
||||
* no partial overlaps. if an area is covered by multiple regions, or is only
|
||||
* partially within a region, returns NULL. */
|
||||
extern struct vm_region *vm_region_find_child_for_area(
|
||||
struct vm_region *region,
|
||||
virt_addr_t addr,
|
||||
size_t len);
|
||||
extern struct vm_region_mapping *vm_region_find_mapping(
|
||||
struct vm_region *region,
|
||||
virt_addr_t addr);
|
||||
|
||||
extern kern_status_t vm_region_map_object(
|
||||
struct vm_region *region,
|
||||
virt_addr_t map_address,
|
||||
struct vm_object *object,
|
||||
off_t object_offset,
|
||||
size_t length,
|
||||
enum vm_prot prot,
|
||||
virt_addr_t *out);
|
||||
|
||||
/* returns true if the memory area defined by [base, base+len] contains:
|
||||
* - no child regions
|
||||
* - no vm_object mappings
|
||||
* if any child regions or mappings exist in the memory area, returns false.
|
||||
* if the memory area exceeds the bounds of the region, returns false.
|
||||
*/
|
||||
extern bool vm_region_is_area_free(
|
||||
const struct vm_region *region,
|
||||
virt_addr_t base,
|
||||
size_t len);
|
||||
|
||||
extern kern_status_t vm_region_demand_map(
|
||||
struct vm_region *region,
|
||||
virt_addr_t addr,
|
||||
enum pmap_fault_flags flags);
|
||||
|
||||
extern void vm_region_dump(struct vm_region *region, int depth);
|
||||
|
||||
DEFINE_OBJECT_LOCK_FUNCTION(vm_region, vr_base)
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user