struct mm_context {
size_t ctx_id;
_Atomic size_t tlb_gen;
struct cpu_mask cpus;
};
struct mm {
struct vas *vas;
struct rbit vma_range_tree;
struct rwlock lock;
paddr_t pml4;
vaddr_t mmap_cursor;
refcount_t users;
refcount_t refcount;
};
enum mm_map_flags {
MM_MAP_FIXED = 1 << 0,
MM_MAP_ANON = 1 << 1,
};
enum mm_fault_flags {
MM_FAULT_WRITE = 1 << 0,
MM_FAULT_USER = 1 << 1,
MM_FAULT_INSN = 1 << 2,
};
enum mm_fault_result {
MM_FAULT_OK,
MM_FAULT_RETRY,
MM_FAULT_SIGSEGV,
MM_FAULT_OOM,
};
struct mm * mm_alloc(void);
void mm_free(struct mm *mm);
struct mm * mm_fork(struct mm *src);
void mm_exit(struct mm *mm);
void mm_vma_range_insert(struct mm *mm, struct vma_range *vma_range);
void mm_vma_range_remove(struct mm *mm, struct vma_range *vma_range);
struct vma_range * mm_vma_range_find(struct mm *mm, vaddr_t addr);
struct vma_range * mm_vma_range_find_intersection(struct mm *mm, vaddr_t s, vaddr_t e);
vaddr_t mm_vma_range_find_gap(struct mm *mm, size_t len, size_t align, vaddr_t low, vaddr_t high);
vaddr_t mm_map(struct mm *mm, vaddr_t hint, size_t len, enum vma_range_protection prot, enum mm_map_flags flags);
enum errno mm_unmap(struct mm *mm, vaddr_t start, size_t len);
enum errno mm_protect(struct mm *mm, vaddr_t start, size_t len, enum vma_range_protection prot);
enum errno mm_pgtable_init(struct mm *mm);
void mm_pgtable_free(struct mm *mm);
void mm_activate(struct mm *mm);
enum errno mm_map_page(struct mm *mm, vaddr_t va, paddr_t pa, uint64_t pflags);
void mm_unmap_page(struct mm *mm, vaddr_t va);
paddr_t mm_query(struct mm *mm, vaddr_t va, uint64_t *pflags_out);
enum mm_fault_result mm_fault(struct mm *mm, vaddr_t addr, enum mm_fault_flags flags);
enum mm_fault_result mm_do_anon_fault(struct vma_range *vma_range, vaddr_t addr, enum mm_fault_flags);
enum mm_fault_result mm_do_cow_fault(struct vma_range *vma_range, vaddr_t addr, enum mm_fault_flags);
bool mm_get(struct mm *mm);
void mm_put(struct mm *mm);
bool mm_users_inc(struct mm *mm);
void mm_users_put(struct mm *mm);