Skip to main content

kernel/mm/vmm/
traits.rs

1// SPDX-License-Identifier: GPL-3.0-only
2//!
3//!
4//! Authors: MarioS271
5
6use crate::lib::addr::{PhysAddr, VirtAddr};
7use crate::lib::types::boot_info::KernelSectionInfo;
8use crate::mm::pmm::Pmm;
9use crate::mm::vmm::boot_mapping::BootMappings;
10use crate::mm::vmm::vma::VmaFlags;
11use crate::mm::vmm::VmmResult;
12
13pub trait VmmPaging {
14    type PageType;
15    type PageTableFlags;
16
17    /// Initialize the kernel page tables and load them
18    ///
19    /// # Panics
20    /// Panics if the PMM cannot allocate memory for the page tables
21    fn setup_kernel_paging(sections: &KernelSectionInfo) -> (VirtAddr, BootMappings);
22
23    /// Map one virtual page to a physical frame. `PRESENT` is forced on regardless of `flags`.
24    ///
25    /// # Safety
26    /// The caller must ensure `virt` is a valid kernel virtual address and `phys` is a
27    /// valid, PMM-allocated frame.
28    unsafe fn map_page(
29        pmm: &mut Pmm,
30        page_ptr: VirtAddr,
31        virt: VirtAddr,
32        phys: PhysAddr,
33        page_type: Self::PageType,
34        flags: Self::PageTableFlags
35    ) -> VmmResult;
36
37    /// Map a certain block of physical memory to virtual pages calculated by the method
38    ///
39    /// # Safety
40    /// The caller must ensure `virt` is a valid kernel virtual address and `phys` is a
41    /// valid, PMM-allocated frame.
42    unsafe fn map_range(
43        pmm: &mut Pmm,
44        page_ptr: VirtAddr,
45        virt: VirtAddr,
46        phys: PhysAddr,
47        size: u64,
48        flags: Self::PageTableFlags,
49        can_overmap: bool
50    ) -> VmmResult;
51
52    /// Unmap one virtual page
53    ///
54    /// # Safety
55    /// The caller must ensure `virt` was previously mapped and that no live code or
56    /// data references the page after this call returns.
57    unsafe fn unmap_page(
58        page_ptr: VirtAddr,
59        virt: VirtAddr
60    ) -> VmmResult;
61
62    /// Change page table flags of an already mapped page
63    ///
64    /// # Safety
65    /// The caller must ensure `virt` was previously mapped and that changing the page's flags
66    /// will not violate anything (example: making a page non-writable while a mutable reference
67    /// is held to it)
68    unsafe fn remap_page(
69        page_ptr: VirtAddr,
70        virt: VirtAddr,
71        new_flags: Self::PageTableFlags
72    ) -> VmmResult;
73
74    /// Walk the page tables and return the phys address mapped at `virt` or `None` if the
75    /// address is not mapped
76    fn translate(
77        page_ptr: VirtAddr,
78        virt: VirtAddr
79    ) -> Option<PhysAddr>;
80
81    /// Walk the page tables and return a tuple of the phys address mapped at `virt` and the size of
82    /// the page `virt` is mapped in, or `None` if the address is not mapped
83    fn translate_with_size(
84        page_ptr: VirtAddr,
85        virt: VirtAddr
86    ) -> Option<(PhysAddr, u64)>;
87
88    /// Translate VMA flags to arch-specific page table flags
89    fn vma_flags_to_page_flags(
90        vma_flags: VmaFlags
91    ) -> Self::PageTableFlags;
92
93    /// Clone the kernel page's mappings into a user page
94    ///
95    /// # Safety
96    /// The caller must ensure that `dst` is a valid, mapped page
97    unsafe fn clone_kernel_mappings(
98        dst: VirtAddr
99    );
100}