Skip to content

Commit

Permalink
move pagetable walker into vm directory
Browse files Browse the repository at this point in the history
  • Loading branch information
yodalee committed May 20, 2022
1 parent ccff44d commit 7253beb
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 38 deletions.
41 changes: 3 additions & 38 deletions src/kvm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +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::addr::{VirtAddr, PhysAddr, align_up, align_down};
use crate::vm::page_flag::PteFlag;
use crate::riscv::{PAGESIZE, MAXVA};
Expand Down Expand Up @@ -80,42 +81,6 @@ fn kvmmap(va: VirtAddr, pa: PhysAddr, size: u64, perm: PteFlag) {
.expect("map_pages_error");
}

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

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

impl<Extra: PageTableVisitor> MapWalkerMut<'_, Extra> {
fn visit_mut(&mut self) -> Extra::Output {
let _ = self.extra.check_va(self.va)?;
let index = self.va.get_index(self.level);
let pte = &mut 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 { &mut *(pte.addr() as *mut PageTable) };
self.page_table = next_table;
self.level = next_level;
self.visit_mut()
}
}
}
}

struct PageMapper {
pa: PhysAddr,
perm: PteFlag
Expand Down Expand Up @@ -196,7 +161,7 @@ fn map_pages(page_table: &mut PageTable, va: VirtAddr, mut pa: PhysAddr, size: u

loop {
let mapper = PageMapper { pa, perm };
let mut walker = MapWalkerMut {
let mut walker = PageTableWalkerMut {
page_table,
va: page_addr,
level: PageTableLevel::Two,
Expand Down Expand Up @@ -287,7 +252,7 @@ fn unmap_pages(page_table: &mut PageTable, va: VirtAddr, npages: u64, do_free: b
let mut addr = va;
while addr < va + npages * PAGESIZE {
let unmapper = PageUnmapper { do_free };
let mut walker = MapWalkerMut {
let mut walker = PageTableWalkerMut {
page_table,
va: addr,
level: PageTableLevel::Two,
Expand Down
1 change: 1 addition & 0 deletions src/vm/mod.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
pub mod addr;
pub mod page_flag;
pub mod page_table;
pub mod page_table_walker;
39 changes: 39 additions & 0 deletions src/vm/page_table_walker.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
use super::addr::VirtAddr;
use super::page_table::{PageTable, PageTableEntry, PageTableLevel};


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

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

impl<Extra: PageTableVisitor> PageTableWalkerMut<'_, Extra> {
pub fn visit_mut(&mut self) -> Extra::Output {
let _ = self.extra.check_va(self.va)?;
let index = self.va.get_index(self.level);
let pte = &mut 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 { &mut *(pte.addr() as *mut PageTable) };
self.page_table = next_table;
self.level = next_level;
self.visit_mut()
}
}
}
}

0 comments on commit 7253beb

Please sign in to comment.