Skip to content

Commit

Permalink
Merge pull request #147 from 00xc/mm/pgtable
Browse files Browse the repository at this point in the history
mm/pgtable: minor cleanups
  • Loading branch information
joergroedel authored Nov 20, 2023
2 parents 62eca0f + 371ca45 commit 641952b
Show file tree
Hide file tree
Showing 5 changed files with 54 additions and 68 deletions.
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 @@ -222,43 +248,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 @@ -321,7 +310,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 @@ -338,15 +327,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 @@ -363,18 +351,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 @@ -388,7 +375,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 @@ -401,9 +387,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 @@ -413,8 +399,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 @@ -683,7 +669,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 @@ -812,8 +798,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 @@ -824,8 +810,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 @@ -45,7 +45,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

0 comments on commit 641952b

Please sign in to comment.