Skip to content

Commit 86d7e31

Browse files
committed
Restructure the TranslateResult type
1 parent c4a51ea commit 86d7e31

File tree

5 files changed

+66
-61
lines changed

5 files changed

+66
-61
lines changed

src/structures/paging/mapper/mapped_page_table.rs

+11-11
Original file line numberDiff line numberDiff line change
@@ -522,42 +522,42 @@ impl<'a, P: PhysToVirt> Mapper<Size4KiB> for MappedPageTable<'a, P> {
522522
}
523523
}
524524

525-
impl<'a, P: PhysToVirt> MapperAllSizes for MappedPageTable<'a, P> {
525+
impl<'a, P: PhysToVirt> Translate for MappedPageTable<'a, P> {
526526
#[allow(clippy::inconsistent_digit_grouping)]
527527
fn translate(&self, addr: VirtAddr) -> TranslateResult {
528528
let p4 = &self.level_4_table;
529529
let p3 = match self.page_table_walker.next_table(&p4[addr.p4_index()]) {
530530
Ok(page_table) => page_table,
531-
Err(PageTableWalkError::NotMapped) => return TranslateResult::PageNotMapped,
531+
Err(PageTableWalkError::NotMapped) => return TranslateResult::NotMapped,
532532
Err(PageTableWalkError::MappedToHugePage) => {
533533
panic!("level 4 entry has huge page bit set")
534534
}
535535
};
536536
let p2 = match self.page_table_walker.next_table(&p3[addr.p3_index()]) {
537537
Ok(page_table) => page_table,
538-
Err(PageTableWalkError::NotMapped) => return TranslateResult::PageNotMapped,
538+
Err(PageTableWalkError::NotMapped) => return TranslateResult::NotMapped,
539539
Err(PageTableWalkError::MappedToHugePage) => {
540540
let entry = &p3[addr.p3_index()];
541541
let frame = PhysFrame::containing_address(entry.addr());
542542
let offset = addr.as_u64() & 0o_777_777_7777;
543543
let flags = entry.flags();
544-
return TranslateResult::Frame1GiB {
545-
frame,
544+
return TranslateResult::Mapped {
545+
frame: MappedFrame::Size1GiB(frame),
546546
offset,
547547
flags,
548548
};
549549
}
550550
};
551551
let p1 = match self.page_table_walker.next_table(&p2[addr.p2_index()]) {
552552
Ok(page_table) => page_table,
553-
Err(PageTableWalkError::NotMapped) => return TranslateResult::PageNotMapped,
553+
Err(PageTableWalkError::NotMapped) => return TranslateResult::NotMapped,
554554
Err(PageTableWalkError::MappedToHugePage) => {
555555
let entry = &p2[addr.p2_index()];
556556
let frame = PhysFrame::containing_address(entry.addr());
557557
let offset = addr.as_u64() & 0o_777_7777;
558558
let flags = entry.flags();
559-
return TranslateResult::Frame2MiB {
560-
frame,
559+
return TranslateResult::Mapped {
560+
frame: MappedFrame::Size2MiB(frame),
561561
offset,
562562
flags,
563563
};
@@ -567,7 +567,7 @@ impl<'a, P: PhysToVirt> MapperAllSizes for MappedPageTable<'a, P> {
567567
let p1_entry = &p1[addr.p1_index()];
568568

569569
if p1_entry.is_unused() {
570-
return TranslateResult::PageNotMapped;
570+
return TranslateResult::NotMapped;
571571
}
572572

573573
let frame = match PhysFrame::from_start_address(p1_entry.addr()) {
@@ -576,8 +576,8 @@ impl<'a, P: PhysToVirt> MapperAllSizes for MappedPageTable<'a, P> {
576576
};
577577
let offset = u64::from(addr.page_offset());
578578
let flags = p1_entry.flags();
579-
TranslateResult::Frame4KiB {
580-
frame,
579+
TranslateResult::Mapped {
580+
frame: MappedFrame::Size4KiB(frame),
581581
offset,
582582
flags,
583583
}

src/structures/paging/mapper/mod.rs

+42-37
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,13 @@ mod offset_page_table;
1717
#[cfg(feature = "instructions")]
1818
mod recursive_page_table;
1919

20-
/// This trait defines page table operations that work for all page sizes of the x86_64
21-
/// architecture.
22-
pub trait MapperAllSizes: Mapper<Size4KiB> + Mapper<Size2MiB> + Mapper<Size1GiB> {
20+
/// An empty convencience trait that requires the `Mapper` trait for all page sizes.
21+
pub trait MapperAllSizes: Mapper<Size4KiB> + Mapper<Size2MiB> + Mapper<Size1GiB> {}
22+
23+
impl<T> MapperAllSizes for T where T: Mapper<Size4KiB> + Mapper<Size2MiB> + Mapper<Size1GiB> {}
24+
25+
/// Provides methods for translating virtual addresses.
26+
pub trait Translate {
2327
/// Return the frame that the given virtual address is mapped to and the offset within that
2428
/// frame.
2529
///
@@ -38,14 +42,8 @@ pub trait MapperAllSizes: Mapper<Size4KiB> + Mapper<Size2MiB> + Mapper<Size1GiB>
3842
#[inline]
3943
fn translate_addr(&self, addr: VirtAddr) -> Option<PhysAddr> {
4044
match self.translate(addr) {
41-
TranslateResult::PageNotMapped | TranslateResult::InvalidFrameAddress(_) => None,
42-
TranslateResult::Frame4KiB { frame, offset, .. } => {
43-
Some(frame.start_address() + offset)
44-
}
45-
TranslateResult::Frame2MiB { frame, offset, .. } => {
46-
Some(frame.start_address() + offset)
47-
}
48-
TranslateResult::Frame1GiB { frame, offset, .. } => {
45+
TranslateResult::NotMapped | TranslateResult::InvalidFrameAddress(_) => None,
46+
TranslateResult::Mapped { frame, offset, .. } => {
4947
Some(frame.start_address() + offset)
5048
}
5149
}
@@ -58,39 +56,46 @@ pub trait MapperAllSizes: Mapper<Size4KiB> + Mapper<Size2MiB> + Mapper<Size1GiB>
5856
/// is returned, depending on the size of the mapped page. The remaining variants indicate errors.
5957
#[derive(Debug)]
6058
pub enum TranslateResult {
61-
/// The page is mapped to a physical frame of size 4KiB.
62-
Frame4KiB {
63-
/// The mapped frame.
64-
frame: PhysFrame<Size4KiB>,
65-
/// The offset whithin the mapped frame.
66-
offset: u64,
67-
/// The flags for the frame.
68-
flags: PageTableFlags,
69-
},
70-
/// The page is mapped to a physical frame of size 2MiB.
71-
Frame2MiB {
72-
/// The mapped frame.
73-
frame: PhysFrame<Size2MiB>,
74-
/// The offset whithin the mapped frame.
75-
offset: u64,
76-
/// The flags for the frame.
77-
flags: PageTableFlags,
78-
},
79-
/// The page is mapped to a physical frame of size 2MiB.
80-
Frame1GiB {
59+
/// The virtual address is mapped to a physical frame.
60+
Mapped {
8161
/// The mapped frame.
82-
frame: PhysFrame<Size1GiB>,
62+
frame: MappedFrame,
8363
/// The offset whithin the mapped frame.
8464
offset: u64,
85-
/// The flags for the frame.
65+
/// The entry flags in the lowest-level page table.
66+
///
67+
/// Flags of higher-level page table entries are not included here, but they can still
68+
/// affect the effective flags for an address, for example when the WRITABLE flag is not
69+
/// set for a level 3 entry.
8670
flags: PageTableFlags,
8771
},
88-
/// The given page is not mapped to a physical frame.
89-
PageNotMapped,
90-
/// The page table entry for the given page points to an invalid physical address.
72+
/// The given virtual address is not mapped to a physical frame.
73+
NotMapped,
74+
/// The page table entry for the given virtual address points to an invalid physical address.
9175
InvalidFrameAddress(PhysAddr),
9276
}
9377

78+
/// Represents a physical frame mapped in a page table.
79+
#[derive(Debug)]
80+
pub enum MappedFrame {
81+
/// The virtual address is mapped to a 4KiB frame.
82+
Size4KiB(PhysFrame<Size4KiB>),
83+
/// The virtual address is mapped to a "large" 2MiB frame.
84+
Size2MiB(PhysFrame<Size2MiB>),
85+
/// The virtual address is mapped to a "huge" 1GiB frame.
86+
Size1GiB(PhysFrame<Size1GiB>),
87+
}
88+
89+
impl MappedFrame {
90+
fn start_address(&self) -> PhysAddr {
91+
match self {
92+
MappedFrame::Size4KiB(frame) => frame.start_address(),
93+
MappedFrame::Size2MiB(frame) => frame.start_address(),
94+
MappedFrame::Size1GiB(frame) => frame.start_address(),
95+
}
96+
}
97+
}
98+
9499
/// A trait for common page table operations on pages of size `S`.
95100
pub trait Mapper<S: PageSize> {
96101
/// Creates a new mapping in the page table.
@@ -460,4 +465,4 @@ pub enum TranslateError {
460465
InvalidFrameAddress(PhysAddr),
461466
}
462467

463-
static _ASSERT_OBJECT_SAFE: Option<&(dyn MapperAllSizes + Sync)> = None;
468+
static _ASSERT_OBJECT_SAFE: Option<&(dyn Translate + Sync)> = None;

src/structures/paging/mapper/offset_page_table.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -260,7 +260,7 @@ impl<'a> Mapper<Size4KiB> for OffsetPageTable<'a> {
260260
}
261261
}
262262

263-
impl<'a> MapperAllSizes for OffsetPageTable<'a> {
263+
impl<'a> Translate for OffsetPageTable<'a> {
264264
#[inline]
265265
fn translate(&self, addr: VirtAddr) -> TranslateResult {
266266
self.inner.translate(addr)

src/structures/paging/mapper/recursive_page_table.rs

+11-11
Original file line numberDiff line numberDiff line change
@@ -758,15 +758,15 @@ impl<'a> Mapper<Size4KiB> for RecursivePageTable<'a> {
758758
}
759759
}
760760

761-
impl<'a> MapperAllSizes for RecursivePageTable<'a> {
761+
impl<'a> Translate for RecursivePageTable<'a> {
762762
#[allow(clippy::inconsistent_digit_grouping)]
763763
fn translate(&self, addr: VirtAddr) -> TranslateResult {
764764
let page = Page::containing_address(addr);
765765

766766
let p4 = &self.p4;
767767
let p4_entry = &p4[addr.p4_index()];
768768
if p4_entry.is_unused() {
769-
return TranslateResult::PageNotMapped;
769+
return TranslateResult::NotMapped;
770770
}
771771
if p4_entry.flags().contains(PageTableFlags::HUGE_PAGE) {
772772
panic!("level 4 entry has huge page bit set")
@@ -775,15 +775,15 @@ impl<'a> MapperAllSizes for RecursivePageTable<'a> {
775775
let p3 = unsafe { &*(p3_ptr(page, self.recursive_index)) };
776776
let p3_entry = &p3[addr.p3_index()];
777777
if p3_entry.is_unused() {
778-
return TranslateResult::PageNotMapped;
778+
return TranslateResult::NotMapped;
779779
}
780780
if p3_entry.flags().contains(PageTableFlags::HUGE_PAGE) {
781781
let entry = &p3[addr.p3_index()];
782782
let frame = PhysFrame::containing_address(entry.addr());
783783
let offset = addr.as_u64() & 0o_777_777_7777;
784784
let flags = entry.flags();
785-
return TranslateResult::Frame1GiB {
786-
frame,
785+
return TranslateResult::Mapped {
786+
frame: MappedFrame::Size1GiB(frame),
787787
offset,
788788
flags,
789789
};
@@ -792,15 +792,15 @@ impl<'a> MapperAllSizes for RecursivePageTable<'a> {
792792
let p2 = unsafe { &*(p2_ptr(page, self.recursive_index)) };
793793
let p2_entry = &p2[addr.p2_index()];
794794
if p2_entry.is_unused() {
795-
return TranslateResult::PageNotMapped;
795+
return TranslateResult::NotMapped;
796796
}
797797
if p2_entry.flags().contains(PageTableFlags::HUGE_PAGE) {
798798
let entry = &p2[addr.p2_index()];
799799
let frame = PhysFrame::containing_address(entry.addr());
800800
let offset = addr.as_u64() & 0o_777_7777;
801801
let flags = entry.flags();
802-
return TranslateResult::Frame2MiB {
803-
frame,
802+
return TranslateResult::Mapped {
803+
frame: MappedFrame::Size2MiB(frame),
804804
offset,
805805
flags,
806806
};
@@ -809,7 +809,7 @@ impl<'a> MapperAllSizes for RecursivePageTable<'a> {
809809
let p1 = unsafe { &*(p1_ptr(page, self.recursive_index)) };
810810
let p1_entry = &p1[addr.p1_index()];
811811
if p1_entry.is_unused() {
812-
return TranslateResult::PageNotMapped;
812+
return TranslateResult::NotMapped;
813813
}
814814
if p1_entry.flags().contains(PageTableFlags::HUGE_PAGE) {
815815
panic!("level 1 entry has huge page bit set")
@@ -821,8 +821,8 @@ impl<'a> MapperAllSizes for RecursivePageTable<'a> {
821821
};
822822
let offset = u64::from(addr.page_offset());
823823
let flags = p1_entry.flags();
824-
TranslateResult::Frame4KiB {
825-
frame,
824+
TranslateResult::Mapped {
825+
frame: MappedFrame::Size4KiB(frame),
826826
offset,
827827
flags,
828828
}

src/structures/paging/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ pub use self::mapper::OffsetPageTable;
1414
#[cfg(feature = "instructions")]
1515
#[doc(no_inline)]
1616
pub use self::mapper::RecursivePageTable;
17-
pub use self::mapper::{Mapper, MapperAllSizes};
17+
pub use self::mapper::{Mapper, Translate};
1818
pub use self::page::{Page, PageSize, Size1GiB, Size2MiB, Size4KiB};
1919
pub use self::page_table::{PageOffset, PageTable, PageTableFlags, PageTableIndex};
2020

0 commit comments

Comments
 (0)