AquilaOS documentation
How it works, and its code
Loading...
Searching...
No Matches
vm.h File Reference
#include <core/system.h>
#include <core/printk.h>
#include <ds/queue.h>
#include <fs/vfs.h>
#include <mm/mm.h>
#include <ds/hashmap.h>

Go to the source code of this file.

Data Structures

struct  vm_space
 An address space: its mappings, and its page tables. More...
struct  vm_entry
 A mapping (map entry): a range of an address space, its permissions, and where its pages come from. More...
struct  vm_pager
 A vm object's pager: reads its pages in, and writes them out. More...
struct  vm_aref
 An anon's reference to a page (an aref). More...
struct  vm_anon
 An anon: a mapping's private pages, those the process wrote to. More...
struct  vm_object
 A vm object: what a mapping's pages come from (a file), and its pages that have been read in. More...
struct  vm_page
 A page of physical memory (pages[] has one for every page of RAM). More...

Macros

#define VM_KR   0x0001
 kernel read
#define VM_KW   0x0002
 kernel write
#define VM_KX   0x0004
 kernel execute
#define VM_UR   0x0008
 user read
#define VM_UW   0x0010
 user write
#define VM_UX   0x0020
 user execute
#define VM_PERM   0x003F
 permissions mask
#define VM_NOCACHE   0x0040
 not cached (device memory)
#define VM_SHARED   0x0080
 shared: a fork doesn't copy it
#define VM_COPY   0x0100
 to be copied before it's written to
#define VM_KRW   (VM_KR|VM_KW)
 kernel read/write
#define VM_KRX   (VM_KR|VM_KX)
 kernel read/execute
#define VM_KWX   (VM_KW|VM_KX)
 kernel write/execute
#define VM_KRWX   (VM_KR|VM_KW|VM_KX)
 kernel read/write/execute
#define VM_URW   (VM_UR|VM_UW)
 user read/write
#define VM_URX   (VM_UR|VM_UX)
 user read/execute
#define VM_UWX   (VM_UW|VM_UX)
 user write/execute
#define VM_URWX   (VM_UR|VM_UW|VM_UX)
 user read/write/execute
#define VMOBJ_ZERO   0x0000
 pages of zeros
#define VMOBJ_FILE   0x0001
 a file's pages

Functions

void kvmem_setup (void)
 Sets up the kernel's allocator at boot, once physical memory and the page tables are ready.
void kvmem_selftest (void)
 Runs the allocator's self-test, for the kvmem.test kernel argument, and prints whether it passed.
void kvmem_guardtest (void)
 Writes one byte past the end of an object, for the kvmem.guard kernel argument: the guard page should fault, and the kernel panic.
int vm_map (struct vm_space *vm_space, struct vm_entry *vm_entry)
 Maps a map entry's whole range at once: its physical memory (paddr), or new pages of memory if it has none.
void vm_unmap_full (struct vm_space *vm_space, struct vm_entry *vm_entry)
 Unmaps every page of a map entry's range.
int vm_space_fork (struct vm_space *parent, struct vm_space *child)
 Copies an address space's mappings into another, for fork().
void vm_space_destroy (struct vm_space *vm_space)
 Removes all the mappings of an address space: its entries are released and freed, and its page tables emptied.
struct vm_entry * vm_space_find (struct vm_space *vm_space, vaddr_t vaddr)
 Finds the map entry that an address is in.
int vm_space_insert (struct vm_space *vm_space, struct vm_entry *vm_entry)
 Adds a map entry to an address space, in address order.
struct vm_entry * vm_entry_new (void)
 Makes a new, empty map entry.
void vm_entry_destroy (struct vm_entry *vm_entry)
 Releases what a map entry holds: its references to its anon and its object.
struct vm_anon * vm_anon_new (void)
 Makes a new, empty anon.
struct vm_anon * vm_anon_copy (struct vm_anon *vm_anon)
 Makes a copy of an anon that shares its arefs, and so its pages, when a mapping's shared anon is written to after a fork.
void vm_anon_incref (struct vm_anon *vm_anon)
 Adds a reference to an anon: another mapping shares it (a fork).
void vm_anon_decref (struct vm_anon *vm_anon)
 Drops a reference to an anon, and frees it with the last one.
void vm_anon_destroy (struct vm_anon *vm_anon)
 Releases an anon's arefs, and the pages of those that no other anon shares.
struct vm_object * vm_object_vnode (struct vnode *vnode)
 Gets a vnode's vm object, making it the first time.
void vnode_pages_update (struct vnode *vnode, off_t start, off_t end)
 Reads a file's cached pages again after a write or a truncation changed a range of it.
void vnode_pages_free (struct vnode *vnode)
 Frees a vnode's vm object and its cached pages, when the vnode itself is freed.
int vm_object_page_insert (struct vm_object *vm_object, struct vm_page *vm_page)
 Adds a page to a vm object, at the page's offset (vm_page->off).
void vm_object_incref (struct vm_object *vm_object)
 Adds a reference to a vm object: one more mapping of it.
void vm_object_decref (struct vm_object *vm_object)
 Drops a reference to a vm object: one mapping of it less.

Variables

struct vm_space kvm_space

Macro Definition Documentation

◆ VM_COPY

#define VM_COPY   0x0100

to be copied before it's written to

Definition at line 47 of file vm.h.

Referenced by binfmt_elf_load_segments(), pf_anon(), pf_present(), vm_anon_copy(), and vm_space_fork().

◆ VM_KR

#define VM_KR   0x0001

kernel read

Definition at line 38 of file vm.h.

Referenced by acpi_map().

◆ VM_KRW

#define VM_KRW   (VM_KR|VM_KW)

kernel read/write

Definition at line 49 of file vm.h.

Referenced by arch_mmio_map(), arch_phys_map(), earlycon_fb_init(), fbdev_vesa_prope(), kvmem_alloc(), and slab_page_alloc().

◆ VM_KRWX

#define VM_KRWX   (VM_KR|VM_KW|VM_KX)

kernel read/write/execute

Definition at line 52 of file vm.h.

◆ VM_KRX

#define VM_KRX   (VM_KR|VM_KX)

kernel read/execute

Definition at line 50 of file vm.h.

◆ VM_KW

#define VM_KW   0x0002

kernel write

Definition at line 39 of file vm.h.

Referenced by pf_anon(), pf_zero(), pte_flags(), pte_flags(), pte_flags(), and vm_space_fork().

◆ VM_KWX

#define VM_KWX   (VM_KW|VM_KX)

kernel write/execute

Definition at line 51 of file vm.h.

◆ VM_KX

#define VM_KX   0x0004

kernel execute

Definition at line 40 of file vm.h.

Referenced by pte_flags().

◆ VM_NOCACHE

#define VM_NOCACHE   0x0040

not cached (device memory)

Definition at line 45 of file vm.h.

Referenced by arch_mmio_map(), pte_flags(), pte_flags(), and pte_flags().

◆ VM_PERM

#define VM_PERM   0x003F

permissions mask

Definition at line 44 of file vm.h.

Referenced by pf_anon(), pf_object(), pf_present(), and pf_zero().

◆ VM_SHARED

#define VM_SHARED   0x0080

shared: a fork doesn't copy it

Definition at line 46 of file vm.h.

Referenced by fbdev_vesa_map(), procfs_proc_maps(), procfs_proc_vmstats(), sys_mmap(), and vm_space_fork().

◆ VM_UR

#define VM_UR   0x0008

user read

Definition at line 41 of file vm.h.

Referenced by binfmt_elf_load_segments(), check_violation(), procfs_proc_maps(), procfs_proc_vmstats(), and sys_mmap().

◆ VM_URW

#define VM_URW   (VM_UR|VM_UW)

user read/write

Definition at line 53 of file vm.h.

Referenced by binfmt_fmt_load().

◆ VM_URWX

#define VM_URWX   (VM_UR|VM_UW|VM_UX)

user read/write/execute

Definition at line 56 of file vm.h.

Referenced by pte_flags(), pte_flags(), and pte_flags().

◆ VM_URX

#define VM_URX   (VM_UR|VM_UX)

user read/execute

Definition at line 54 of file vm.h.

Referenced by arch_sigcode_map().

◆ VM_UW

◆ VM_UWX

#define VM_UWX   (VM_UW|VM_UX)

user write/execute

Definition at line 55 of file vm.h.

◆ VM_UX

#define VM_UX   0x0020

user execute

Definition at line 43 of file vm.h.

Referenced by binfmt_elf_load_segments(), check_violation(), procfs_proc_maps(), procfs_proc_vmstats(), pte_flags(), and sys_mmap().

◆ VMOBJ_FILE

#define VMOBJ_FILE   0x0001

a file's pages

Definition at line 60 of file vm.h.

Referenced by procfs_proc_maps(), procfs_proc_vmstats(), vfs_map(), vm_object_decref(), vm_object_incref(), and vm_object_vnode().

◆ VMOBJ_ZERO

#define VMOBJ_ZERO   0x0000

pages of zeros

Definition at line 59 of file vm.h.

Referenced by procfs_proc_vmstats().

Function Documentation

◆ kvmem_guardtest()

void kvmem_guardtest ( void )

Writes one byte past the end of an object, for the kvmem.guard kernel argument: the guard page should fault, and the kernel panic.

Definition at line 278 of file kvmem.c.

References kmalloc(), kvmem_guardtest(), PAGE_ROUND, and printk().

Referenced by kmain(), and kvmem_guardtest().

◆ kvmem_selftest()

void kvmem_selftest ( void )

Runs the allocator's self-test, for the kvmem.test kernel argument, and prints whether it passed.

Definition at line 264 of file kvmem.c.

References kvmem_selftest(), kvmem_selftest_run(), and printk().

Referenced by kmain(), and kvmem_selftest().

◆ kvmem_setup()

void kvmem_setup ( void )

Sets up the kernel's allocator at boot, once physical memory and the page tables are ready.

Definition at line 55 of file kvmem.c.

References ARCH_KVMEM_BASE, ARCH_KVMEM_SIZE, kvmem, kvmem_setup(), malloc_types, PAGE_SIZE, panic, and vmem_init().

Referenced by aarch64_init(), kvmem_setup(), and x86_cpu_init().

◆ vm_anon_copy()

struct vm_anon * vm_anon_copy ( struct vm_anon * vm_anon)

Makes a copy of an anon that shares its arefs, and so its pages, when a mapping's shared anon is written to after a fork.

The pages themselves are copied later, one by one, as they are written to.

Parameters
vm_anonthe anon to copy
Returns
the new anon, with one reference, or NULL if there was no memory for it

Definition at line 174 of file vm_anon.c.

References vm_anon::flags, kfree(), NULL, vm_anon::ref, vm_anon_copy(), vm_anon_copy_arefs(), vm_anon_destroy(), vm_anon_new(), and VM_COPY.

Referenced by pf_anon(), and vm_anon_copy().

◆ vm_anon_decref()

void vm_anon_decref ( struct vm_anon * vm_anon)

Drops a reference to an anon, and frees it with the last one.

Parameters
vm_anonthe anon (NULL does nothing)

Definition at line 130 of file vm_anon.c.

References kfree(), vm_anon::ref, vm_anon_decref(), and vm_anon_destroy().

Referenced by pf_anon(), vm_anon_decref(), and vm_entry_destroy().

◆ vm_anon_destroy()

void vm_anon_destroy ( struct vm_anon * vm_anon)

Releases an anon's arefs, and the pages of those that no other anon shares.

The anon's structure itself is freed by its caller.

Parameters
vm_anonthe anon (NULL does nothing)

Definition at line 85 of file vm_anon.c.

References vm_anon::arefs, hashmap_node::entry, hashmap_for, kfree(), mm_page_dealloc(), vm_page::paddr, vm_aref::ref, qnode::value, vm_anon_destroy(), vm_aref_decref(), and vm_aref::vm_page.

Referenced by vm_anon_copy(), vm_anon_decref(), and vm_anon_destroy().

◆ vm_anon_incref()

void vm_anon_incref ( struct vm_anon * vm_anon)

Adds a reference to an anon: another mapping shares it (a fork).

Parameters
vm_anonthe anon (NULL does nothing)

Definition at line 117 of file vm_anon.c.

References vm_anon::ref, and vm_anon_incref().

Referenced by vm_anon_incref(), and vm_space_fork().

◆ vm_anon_new()

struct vm_anon * vm_anon_new ( void )

Makes a new, empty anon.

Returns
the anon, with no references, or NULL if there was no memory

Definition at line 36 of file vm_anon.c.

References vm_anon::arefs, kfree(), kmalloc(), M_ZERO, NULL, vm_anon_new(), and vm_aref_eq().

Referenced by pf_object(), pf_zero(), vm_anon_copy(), and vm_anon_new().

◆ vm_entry_destroy()

void vm_entry_destroy ( struct vm_entry * vm_entry)

Releases what a map entry holds: its references to its anon and its object.

The entry's structure itself is freed by its caller.

Parameters
vm_entrythe entry (NULL does nothing)

Definition at line 32 of file vm_entry.c.

References vm_entry::vm_anon, vm_anon_decref(), vm_entry_destroy(), vm_entry::vm_object, and vm_object_decref().

Referenced by sys_munmap(), vm_entry_destroy(), and vm_space_destroy().

◆ vm_entry_new()

struct vm_entry * vm_entry_new ( void )

Makes a new, empty map entry.

Returns
the entry, zeroed, or NULL if there was no memory for it

Definition at line 18 of file vm_entry.c.

References kmalloc(), M_ZERO, NULL, and vm_entry_new().

Referenced by binfmt_elf_load_segments(), sys_mmap(), and vm_entry_new().

◆ vm_map()

int vm_map ( struct vm_space * vm_space,
struct vm_entry * vm_entry )

Maps a map entry's whole range at once: its physical memory (paddr), or new pages of memory if it has none.

Entries whose pages come in on page faults aren't mapped this way.

Parameters
vm_spacethe address space
vm_entrythe entry
Returns
0, or -ENOMEM if there was no memory for a page or a page table

Definition at line 29 of file vmm.c.

References vm_entry::base, vm_entry::flags, mm_map(), vm_entry::paddr, vm_space::pmap, vm_entry::size, and vm_map().

Referenced by acpi_map(), earlycon_fb_init(), fbdev_vesa_map(), fbdev_vesa_prope(), and vm_map().

◆ vm_object_decref()

void vm_object_decref ( struct vm_object * vm_object)

Drops a reference to a vm object: one mapping of it less.

A file's object lets go of its vnode with the last one. Its pages stay, cached with the vnode, until the vnode is freed (vnode_pages_free()).

Parameters
vm_objectthe object

Definition at line 38 of file vm_object.c.

References vm_object::p, vm_object::ref, vm_object::type, vfs_close(), vm_object_decref(), and VMOBJ_FILE.

Referenced by sys_mmap(), vm_entry_destroy(), and vm_object_decref().

◆ vm_object_incref()

void vm_object_incref ( struct vm_object * vm_object)

Adds a reference to a vm object: one more mapping of it.

A file's object holds its vnode while it's mapped, because the pages are read from it, and the program file it runs may be removed meanwhile.

Parameters
vm_objectthe object

Definition at line 25 of file vm_object.c.

References vm_object::p, vm_object::ref, vnode::ref, vm_object::type, vm_object_incref(), and VMOBJ_FILE.

Referenced by arch_sigcode_map(), binfmt_elf_load_segments(), sys_mmap(), vm_object_incref(), and vm_space_fork().

◆ vm_object_page_insert()

int vm_object_page_insert ( struct vm_object * vm_object,
struct vm_page * vm_page )

Adds a page to a vm object, at the page's offset (vm_page->off).

Parameters
vm_objectthe object
vm_pagethe page
Returns
0, or -ENOMEM if there was no memory to add it (the object doesn't have the page then)

Definition at line 52 of file vm_object.c.

References vm_page::off, vm_object::pages, and vm_object_page_insert().

Referenced by sigcode_in(), vm_object_page_insert(), and vnode_page_in().

◆ vm_object_vnode()

struct vm_object * vm_object_vnode ( struct vnode * vnode)

Gets a vnode's vm object, making it the first time.

Parameters
vnodethe vnode
Returns
its vm object, or NULL if vnode is NULL or there was no memory

Definition at line 31 of file vm_object.c.

References kfree(), kmalloc(), M_ZERO, NULL, vm_object::p, vm_object::pager, vm_object::pages, vm_object::type, vnode::vm_object, vm_object_vnode(), vm_page_eq(), VMOBJ_FILE, and vnode_pager.

Referenced by binfmt_elf_load_segments(), sys_mmap(), and vm_object_vnode().

◆ vm_space_destroy()

void vm_space_destroy ( struct vm_space * vm_space)

Removes all the mappings of an address space: its entries are released and freed, and its page tables emptied.

Parameters
vm_spacethe address space (NULL does nothing)

Definition at line 124 of file vm_space.c.

References kfree(), NULL, vm_space::pmap, pmap_remove_all(), vm_space::vm_entries, vm_entry_destroy(), and vm_space_destroy().

Referenced by binfmt_fmt_load(), proc_fork(), proc_kill(), and vm_space_destroy().

◆ vm_space_find()

struct vm_entry * vm_space_find ( struct vm_space * vm_space,
vaddr_t vaddr )

Finds the map entry that an address is in.

Parameters
vm_spacethe address space
vaddrthe address
Returns
the entry, or NULL if no mapping covers the address

Definition at line 99 of file vm_space.c.

References vm_entry::base, NULL, PAGE_ALIGN, queue_for, vm_entry::size, vm_space::vm_entries, and vm_space_find().

Referenced by mm_page_fault(), and vm_space_find().

◆ vm_space_fork()

int vm_space_fork ( struct vm_space * src,
struct vm_space * dst )

Copies an address space's mappings into another, for fork().

The two share the pages, copy on write: writable private mappings become read-only in src, and their anons are marked to be copied, so that the first write to a page gives the writer its own copy (mm/fault.c).

Parameters
srcthe parent's address space
dstthe child's address space, empty
Returns
0, -EINVAL if either is NULL, or -ENOMEM if there was no memory for an entry; what was copied stays in dst, for the caller to destroy

Definition at line 152 of file vm_space.c.

References vm_entry::base, vm_anon::flags, vm_entry::flags, kfree(), kmalloc(), memcpy(), vm_space::pmap, pmap_protect(), vm_entry::qnode, queue_for, vm_entry::size, vm_entry::vm_anon, vm_anon_incref(), VM_COPY, vm_space::vm_entries, VM_KW, vm_entry::vm_object, vm_object_incref(), VM_SHARED, vm_space_fork(), and VM_UW.

Referenced by proc_fork(), and vm_space_fork().

◆ vm_space_insert()

int vm_space_insert ( struct vm_space * vm_space,
struct vm_entry * vm_entry )

Adds a map entry to an address space, in address order.

If the entry's base is 0, the entry is placed at the highest free gap between mappings that it fits in. The entry always goes before an existing one (the stack's, at the top of user space): an entry past the last one can't be added.

Parameters
vm_spacethe address space
vm_entrythe entry, with its base (or 0) and size set
Returns
0, -EINVAL if either is NULL, or -ENOMEM if there is no room for it, or no memory for its list node

Definition at line 27 of file vm_space.c.

References vm_entry::base, queue::count, queue::head, kmalloc(), M_ZERO, qnode::next, NULL, qnode::prev, vm_entry::qnode, queue_for, vm_entry::size, qnode::value, vm_space::vm_entries, and vm_space_insert().

Referenced by arch_sigcode_map(), sys_mmap(), and vm_space_insert().

◆ vm_unmap_full()

void vm_unmap_full ( struct vm_space * vm_space,
struct vm_entry * vm_entry )

Unmaps every page of a map entry's range.

The pages themselves stay with what holds them (the anon, the file, the device): only the mappings go.

Parameters
vm_spacethe address space
vm_entrythe entry

Definition at line 42 of file vmm.c.

References vm_entry::base, mm_unmap_full(), vm_space::pmap, vm_entry::size, and vm_unmap_full().

Referenced by sys_munmap(), and vm_unmap_full().

◆ vnode_pages_free()

void vnode_pages_free ( struct vnode * vnode)

Frees a vnode's vm object and its cached pages, when the vnode itself is freed.

Nothing maps them then, since a mapping holds the vnode (vm_object_incref()).

Parameters
vnodethe vnode

Definition at line 172 of file vm_object.c.

References hashmap_node::entry, hashmap_for, kfree(), mm_page_dealloc(), NULL, vm_page::paddr, vm_object::pages, qnode::value, vnode::vm_object, and vnode_pages_free().

Referenced by ext2_close(), procfs_close(), pseudofs_close(), and vnode_pages_free().

◆ vnode_pages_update()

void vnode_pages_update ( struct vnode * vnode,
off_t start,
off_t end )

Reads a file's cached pages again after a write or a truncation changed a range of it.

A page stays where it is, mapped by every process that maps the file, so its contents change but not the page; past the file's end it reads zeros. A private mapping's copies, made when it wrote to a page, are its own and don't change.

Parameters
vnodethe file
startthe start of the range that changed
endits end (exclusive)

Definition at line 128 of file vm_object.c.

References hashmap::count, hashmap_node::entry, hashmap_node::hash, kfree(), kmalloc(), memset(), NULL, vm_page::off, vm_page::paddr, PAGE_ALIGN, PAGE_SIZE, vm_object::pages, pmap_page_write(), printk(), vfs_read(), vnode::vm_object, and vnode_pages_update().

Referenced by vfs_trunc(), vfs_write_io(), and vnode_pages_update().

Variable Documentation

◆ kvm_space