page_walker/walkers/
protector.rs1use core::marker::PhantomData;
5use core::ops::Range;
6use crate::address_space::PageTableMapper;
7use crate::{PageFormat, PteType};
8use num_traits::{FromPrimitive, PrimInt, Unsigned};
9
10pub struct PteProtector<'a, PTE, Mapper, Error>
16where
17 PTE: FromPrimitive + PrimInt + Unsigned,
18 Mapper: PageTableMapper<PTE, Error>,
19{
20 pub mapper: &'a mut Mapper,
22 pub mask: (PTE, PTE),
25 pub format: &'a PageFormat<'a, PTE>,
27 pub error: PhantomData<Error>,
29}
30
31impl<'a, PTE, Mapper, Error> crate::PageWalkerMut<PTE, Error> for PteProtector<'a, PTE, Mapper, Error>
32where
33 PTE: FromPrimitive + PrimInt + Unsigned,
34 Mapper: PageTableMapper<PTE, Error>,
35{
36 fn read_pte(&self, phys_addr: PTE) -> Result<PTE, Error> {
38 self.mapper.read_pte(phys_addr)
39 }
40
41 fn write_pte(&mut self, phys_addr: PTE, value: PTE) -> Result<(), Error> {
43 self.mapper.write_pte(phys_addr, value)
44 }
45
46 fn handle_pte(&mut self, pte_type: PteType, _range: Range<usize>, pte: &mut PTE) -> Result<(), Error> {
48 let physical_mask = self.format.physical_mask;
49
50 if let PteType::Page(level) = pte_type {
51 let level = &self.format.levels[level];
52
53 if level.is_present(*pte) {
54 let clear_mask = self.mask.0 &
57 !(physical_mask | level.huge_page_bit.0 | level.present_bit.0);
58 let set_mask = self.mask.1 &
59 !(physical_mask | level.huge_page_bit.0 | level.present_bit.0);
60
61 *pte = (*pte & !clear_mask) | set_mask;
62 }
63 }
64
65 Ok(())
66 }
67}