Skip to content

Commit

Permalink
add const visitor for page_table
Browse files Browse the repository at this point in the history
  • Loading branch information
yodalee committed May 20, 2022
1 parent 149ba1e commit d2855b1
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 5 deletions.
6 changes: 3 additions & 3 deletions src/kvm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use rv64::csr::satp::{Satp, SatpMode};
use rv64::asm::sfence_vma;

use crate::vm::page_table::{PageTable, PageTableLevel, PageTableEntry};
use crate::vm::page_table_walker::{PageTableVisitor, PageTableWalkerMut};
use crate::vm::page_table_walker::{PageTableVisitorMut, PageTableWalkerMut};
use crate::vm::addr::{VirtAddr, PhysAddr, align_up, align_down};
use crate::vm::page_flag::PteFlag;
use crate::riscv::{PAGESIZE, MAXVA};
Expand Down Expand Up @@ -86,7 +86,7 @@ struct PageMapper {
perm: PteFlag
}

impl PageTableVisitor for PageMapper {
impl PageTableVisitorMut for PageMapper {
type Output = Result<(), &'static str>;
fn is_valid_va(&self, va: VirtAddr) -> bool {
va < VirtAddr::new(MAXVA)
Expand Down Expand Up @@ -118,7 +118,7 @@ struct PageUnmapper {
do_free: bool
}

impl PageTableVisitor for PageUnmapper {
impl PageTableVisitorMut for PageUnmapper {
type Output = Result<(), &'static str>;
fn is_valid_va(&self, va: VirtAddr) -> bool {
va < VirtAddr::new(MAXVA)
Expand Down
49 changes: 47 additions & 2 deletions src/vm/page_table_walker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,14 @@ pub struct PageTableWalkerMut<'a, Extra> {
pub extra: Extra,
}

pub trait PageTableVisitor {
pub trait PageTableVisitorMut {
type Output : core::ops::Try;
fn is_valid_va(&self, va: VirtAddr) -> bool;
fn leaf(&mut self, pte: &mut PageTableEntry) -> Self::Output;
fn nonleaf(&mut self, pte: &mut PageTableEntry) -> Self::Output;
}

impl<'a, Extra: PageTableVisitor> PageTableWalkerMut<'a, Extra> {
impl<'a, Extra: PageTableVisitorMut> PageTableWalkerMut<'a, Extra> {
pub fn new(page_table: &'a mut PageTable, va: VirtAddr, level: PageTableLevel, extra: Extra) -> Option<Self> {
extra.is_valid_va(va).then(
move || Self {
Expand Down Expand Up @@ -46,3 +46,48 @@ impl<'a, Extra: PageTableVisitor> PageTableWalkerMut<'a, Extra> {
}
}
}

pub struct PageTableWalker<'a, Extra> {
pub page_table: &'a PageTable,
pub va: VirtAddr,
pub level: PageTableLevel,
pub extra: Extra,
}

pub trait PageTableVisitor {
type Output : core::ops::Try;
fn is_valid_va(&self, va: VirtAddr) -> bool;
fn leaf(&self, pte: &PageTableEntry) -> Self::Output;
fn nonleaf(&self, pte: &PageTableEntry) -> Self::Output;
}

impl<'a, Extra: PageTableVisitor> PageTableWalker<'a, Extra> {
pub fn new(page_table: &'a PageTable, va: VirtAddr, level: PageTableLevel, extra: Extra) -> Option<Self> {
extra.is_valid_va(va).then(
move || Self {
page_table,
va,
level,
extra
}
)
}
pub fn visit(&mut self) -> Extra::Output {
let index = self.va.get_index(self.level);
let pte = &self.page_table[index];

match self.level.next_level() {
None => {
self.extra.leaf(pte)
}
Some(next_level) => {
let _ = self.extra.nonleaf(pte)?;

let next_table = unsafe { &*(pte.addr() as *const PageTable) };
self.page_table = next_table;
self.level = next_level;
self.visit()
}
}
}
}

0 comments on commit d2855b1

Please sign in to comment.