Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

mm/pgtable: minor cleanups #147

Merged
merged 4 commits into from
Nov 20, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/cpu/percpu.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ use crate::cpu::vmsa::init_guest_vmsa;
use crate::error::SvsmError;
use crate::locking::{LockGuard, RWLock, SpinLock};
use crate::mm::alloc::{allocate_page, allocate_zeroed_page};
use crate::mm::pagetable::{get_init_pgtable_locked, PTEntryFlags, PageTable, PageTableRef};
use crate::mm::pagetable::{get_init_pgtable_locked, PTEntryFlags, PageTableRef};
use crate::mm::virtualrange::VirtualRange;
use crate::mm::vm::{Mapping, VMKernelStack, VMPhysMem, VMRMapping, VMReserved, VMR};
use crate::mm::{
Expand Down Expand Up @@ -304,7 +304,7 @@ impl PerCpu {
pub fn map_self_stage2(&mut self) -> Result<(), SvsmError> {
let vaddr = VirtAddr::from(self as *const PerCpu);
let paddr = virt_to_phys(vaddr);
let flags = PageTable::data_flags();
let flags = PTEntryFlags::data();

self.get_pgtable().map_4k(SVSM_PERCPU_BASE, paddr, flags)
}
Expand Down
100 changes: 43 additions & 57 deletions src/mm/pagetable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ use crate::error::SvsmError;
use crate::locking::{LockGuard, SpinLock};
use crate::mm::alloc::{allocate_zeroed_page, free_page};
use crate::mm::{phys_to_virt, virt_to_phys, PGTABLE_LVL3_IDX_SHARED};
use crate::types::{PAGE_SIZE, PAGE_SIZE_2M};
use crate::types::{PageSize, PAGE_SIZE, PAGE_SIZE_2M};
use crate::utils::immut_after_init::ImmutAfterInitCell;
use bitflags::bitflags;
use core::ops::{Deref, DerefMut, Index, IndexMut};
Expand Down Expand Up @@ -115,6 +115,32 @@ bitflags! {
}
}

impl PTEntryFlags {
pub fn exec() -> Self {
Self::PRESENT | Self::GLOBAL | Self::ACCESSED | Self::DIRTY
}

pub fn data() -> Self {
Self::PRESENT | Self::GLOBAL | Self::WRITABLE | Self::NX | Self::ACCESSED | Self::DIRTY
}

pub fn data_ro() -> Self {
Self::PRESENT | Self::GLOBAL | Self::NX | Self::ACCESSED | Self::DIRTY
}

pub fn task_exec() -> Self {
Self::PRESENT | Self::ACCESSED | Self::DIRTY
}

pub fn task_data() -> Self {
Self::PRESENT | Self::WRITABLE | Self::NX | Self::ACCESSED | Self::DIRTY
}

pub fn task_data_ro() -> Self {
Self::PRESENT | Self::NX | Self::ACCESSED | Self::DIRTY
}
}

#[repr(C)]
#[derive(Copy, Clone, Debug, Default)]
pub struct PTEntry(PhysAddr);
Expand Down Expand Up @@ -221,43 +247,6 @@ impl PageTable {
self.root.entries[entry] = other.root.entries[entry];
}

pub fn exec_flags() -> PTEntryFlags {
PTEntryFlags::PRESENT | PTEntryFlags::GLOBAL | PTEntryFlags::ACCESSED | PTEntryFlags::DIRTY
}

pub fn data_flags() -> PTEntryFlags {
PTEntryFlags::PRESENT
| PTEntryFlags::GLOBAL
| PTEntryFlags::WRITABLE
| PTEntryFlags::NX
| PTEntryFlags::ACCESSED
| PTEntryFlags::DIRTY
}

pub fn data_ro_flags() -> PTEntryFlags {
PTEntryFlags::PRESENT
| PTEntryFlags::GLOBAL
| PTEntryFlags::NX
| PTEntryFlags::ACCESSED
| PTEntryFlags::DIRTY
}

pub fn task_data_flags() -> PTEntryFlags {
PTEntryFlags::PRESENT
| PTEntryFlags::WRITABLE
| PTEntryFlags::NX
| PTEntryFlags::ACCESSED
| PTEntryFlags::DIRTY
}

pub fn task_data_ro_flags() -> PTEntryFlags {
PTEntryFlags::PRESENT | PTEntryFlags::NX | PTEntryFlags::ACCESSED | PTEntryFlags::DIRTY
}

pub fn task_exec_flags() -> PTEntryFlags {
PTEntryFlags::PRESENT | PTEntryFlags::ACCESSED | PTEntryFlags::DIRTY
}

fn allocate_page_table() -> Result<*mut PTPage, SvsmError> {
let ptr = allocate_zeroed_page()?;
Ok(ptr.as_mut_ptr::<PTPage>())
Expand Down Expand Up @@ -320,7 +309,7 @@ impl PageTable {
PageTable::walk_addr_lvl3(&mut self.root, vaddr)
}

fn alloc_pte_lvl3(entry: &mut PTEntry, vaddr: VirtAddr, pgsize: usize) -> Mapping {
fn alloc_pte_lvl3(entry: &mut PTEntry, vaddr: VirtAddr, size: PageSize) -> Mapping {
let flags = entry.flags();

if flags.contains(PTEntryFlags::PRESENT) {
Expand All @@ -337,15 +326,14 @@ impl PageTable {
| PTEntryFlags::WRITABLE
| PTEntryFlags::USER
| PTEntryFlags::ACCESSED;
entry.clear();
entry.set(set_c_bit(paddr), flags);

let idx = PageTable::index::<2>(vaddr);

unsafe { PageTable::alloc_pte_lvl2(&mut (*page)[idx], vaddr, pgsize) }
unsafe { PageTable::alloc_pte_lvl2(&mut (*page)[idx], vaddr, size) }
}

fn alloc_pte_lvl2(entry: &mut PTEntry, vaddr: VirtAddr, pgsize: usize) -> Mapping {
fn alloc_pte_lvl2(entry: &mut PTEntry, vaddr: VirtAddr, size: PageSize) -> Mapping {
let flags = entry.flags();

if flags.contains(PTEntryFlags::PRESENT) {
Expand All @@ -362,18 +350,17 @@ impl PageTable {
| PTEntryFlags::WRITABLE
| PTEntryFlags::USER
| PTEntryFlags::ACCESSED;
entry.clear();
entry.set(set_c_bit(paddr), flags);

let idx = PageTable::index::<1>(vaddr);

unsafe { PageTable::alloc_pte_lvl1(&mut (*page)[idx], vaddr, pgsize) }
unsafe { PageTable::alloc_pte_lvl1(&mut (*page)[idx], vaddr, size) }
}

fn alloc_pte_lvl1(entry: &mut PTEntry, vaddr: VirtAddr, pgsize: usize) -> Mapping {
fn alloc_pte_lvl1(entry: &mut PTEntry, vaddr: VirtAddr, size: PageSize) -> Mapping {
let flags = entry.flags();

if pgsize == PAGE_SIZE_2M || flags.contains(PTEntryFlags::PRESENT) {
if size == PageSize::Huge || flags.contains(PTEntryFlags::PRESENT) {
return Mapping::Level1(entry);
}

Expand All @@ -387,7 +374,6 @@ impl PageTable {
| PTEntryFlags::WRITABLE
| PTEntryFlags::USER
| PTEntryFlags::ACCESSED;
entry.clear();
entry.set(set_c_bit(paddr), flags);

let idx = PageTable::index::<0>(vaddr);
Expand All @@ -400,9 +386,9 @@ impl PageTable {

match m {
Mapping::Level0(entry) => Mapping::Level0(entry),
Mapping::Level1(entry) => PageTable::alloc_pte_lvl1(entry, vaddr, PAGE_SIZE),
Mapping::Level2(entry) => PageTable::alloc_pte_lvl2(entry, vaddr, PAGE_SIZE),
Mapping::Level3(entry) => PageTable::alloc_pte_lvl3(entry, vaddr, PAGE_SIZE),
Mapping::Level1(entry) => PageTable::alloc_pte_lvl1(entry, vaddr, PageSize::Regular),
Mapping::Level2(entry) => PageTable::alloc_pte_lvl2(entry, vaddr, PageSize::Regular),
Mapping::Level3(entry) => PageTable::alloc_pte_lvl3(entry, vaddr, PageSize::Regular),
}
}

Expand All @@ -412,8 +398,8 @@ impl PageTable {
match m {
Mapping::Level0(entry) => Mapping::Level0(entry),
Mapping::Level1(entry) => Mapping::Level1(entry),
Mapping::Level2(entry) => PageTable::alloc_pte_lvl2(entry, vaddr, PAGE_SIZE_2M),
Mapping::Level3(entry) => PageTable::alloc_pte_lvl3(entry, vaddr, PAGE_SIZE_2M),
Mapping::Level2(entry) => PageTable::alloc_pte_lvl2(entry, vaddr, PageSize::Huge),
Mapping::Level3(entry) => PageTable::alloc_pte_lvl3(entry, vaddr, PageSize::Huge),
}
}

Expand Down Expand Up @@ -682,7 +668,7 @@ impl PageTable {
vaddr = vaddr + PAGE_SIZE_2M;
}
_ => {
log::debug!("Can't unmap - address not mapped {:#x}", vaddr);
log::error!("Can't unmap - address not mapped {:#x}", vaddr);
}
}
}
Expand Down Expand Up @@ -811,8 +797,8 @@ impl RawPageTablePart {

match m {
Mapping::Level0(entry) => Mapping::Level0(entry),
Mapping::Level1(entry) => PageTable::alloc_pte_lvl1(entry, vaddr, PAGE_SIZE),
Mapping::Level2(entry) => PageTable::alloc_pte_lvl2(entry, vaddr, PAGE_SIZE),
Mapping::Level1(entry) => PageTable::alloc_pte_lvl1(entry, vaddr, PageSize::Regular),
Mapping::Level2(entry) => PageTable::alloc_pte_lvl2(entry, vaddr, PageSize::Regular),
Mapping::Level3(_) => panic!("PT level 3 not possible in PageTablePart"),
}
}
Expand All @@ -823,8 +809,8 @@ impl RawPageTablePart {
match m {
Mapping::Level0(entry) => Mapping::Level0(entry),
Mapping::Level1(entry) => Mapping::Level1(entry),
Mapping::Level2(entry) => PageTable::alloc_pte_lvl2(entry, vaddr, PAGE_SIZE_2M),
Mapping::Level3(entry) => PageTable::alloc_pte_lvl3(entry, vaddr, PAGE_SIZE_2M),
Mapping::Level2(entry) => PageTable::alloc_pte_lvl2(entry, vaddr, PageSize::Huge),
Mapping::Level3(entry) => PageTable::alloc_pte_lvl3(entry, vaddr, PageSize::Huge),
}
}

Expand Down
4 changes: 2 additions & 2 deletions src/mm/ptguards.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
//
// Author: Joerg Roedel <[email protected]>

use super::pagetable::PageTable;
use super::pagetable::PTEntryFlags;
use crate::address::{Address, PhysAddr, VirtAddr};
use crate::cpu::percpu::this_cpu_mut;
use crate::cpu::tlb::flush_address_sync;
Expand Down Expand Up @@ -43,7 +43,7 @@ impl PerCPUPageMappingGuard {
assert!((paddr_start.bits() & align_mask) == 0);
assert!((paddr_end.bits() & align_mask) == 0);

let flags = PageTable::data_flags();
let flags = PTEntryFlags::data();
let huge = ((paddr_start.bits() & (PAGE_SIZE_2M - 1)) == 0)
&& ((paddr_end.bits() & (PAGE_SIZE_2M - 1)) == 0);
let vaddr = if huge {
Expand Down
4 changes: 2 additions & 2 deletions src/mm/stack.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use crate::cpu::flush_tlb_global_sync;
use crate::error::SvsmError;
use crate::locking::SpinLock;
use crate::mm::alloc::{allocate_zeroed_page, free_page};
use crate::mm::pagetable::{get_init_pgtable_locked, PageTable, PageTableRef};
use crate::mm::pagetable::{get_init_pgtable_locked, PTEntryFlags, PageTableRef};
use crate::mm::{phys_to_virt, virt_to_phys};
use crate::mm::{
STACK_PAGES, STACK_SIZE, STACK_TOTAL_SIZE, SVSM_SHARED_STACK_BASE, SVSM_SHARED_STACK_END,
Expand Down Expand Up @@ -80,7 +80,7 @@ static STACK_ALLOC: SpinLock<StackRange> = SpinLock::new(StackRange::new(
));

pub fn allocate_stack_addr(stack: VirtAddr, pgtable: &mut PageTableRef) -> Result<(), SvsmError> {
let flags = PageTable::data_flags();
let flags = PTEntryFlags::data();
for i in 0..STACK_PAGES {
let page = allocate_zeroed_page()?;
let paddr = virt_to_phys(page);
Expand Down
10 changes: 5 additions & 5 deletions src/svsm_paging.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use crate::elf;
use crate::error::SvsmError;
use crate::kernel_launch::KernelLaunchInfo;
use crate::mm;
use crate::mm::pagetable::{set_init_pgtable, PageTable, PageTableRef};
use crate::mm::pagetable::{set_init_pgtable, PTEntryFlags, PageTable, PageTableRef};
use crate::mm::PerCPUPageMappingGuard;
use crate::sev::ghcb::PageStateChangeOp;
use crate::sev::{pvalidate, PvalidateOp};
Expand All @@ -30,11 +30,11 @@ pub fn init_page_table(launch_info: &KernelLaunchInfo, kernel_elf: &elf::Elf64Fi
let aligned_vaddr_end = vaddr_end.page_align_up();
let segment_len = aligned_vaddr_end - vaddr_start;
let flags = if segment.flags.contains(elf::Elf64PhdrFlags::EXECUTE) {
PageTable::exec_flags()
PTEntryFlags::exec()
} else if segment.flags.contains(elf::Elf64PhdrFlags::WRITE) {
PageTable::data_flags()
PTEntryFlags::data()
} else {
PageTable::data_ro_flags()
PTEntryFlags::data_ro()
};

pgtable
Expand All @@ -50,7 +50,7 @@ pub fn init_page_table(launch_info: &KernelLaunchInfo, kernel_elf: &elf::Elf64Fi
VirtAddr::from(launch_info.heap_area_virt_start),
VirtAddr::from(launch_info.heap_area_virt_end()),
PhysAddr::from(launch_info.heap_area_phys_start),
PageTable::data_flags(),
PTEntryFlags::data(),
)
.expect("Failed to map heap");

Expand Down