Skip to content

Commit 8752e3c

Browse files
committed
Use custom error types instead of ()
This fixes the clippy warnings we currently see on CI. Since this changes the signature of public functions, this is a **breaking change**. However, I don't expect that much code is broken by this.
1 parent 710cfa2 commit 8752e3c

File tree

5 files changed

+62
-22
lines changed

5 files changed

+62
-22
lines changed

src/structures/paging/frame.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
//! Abstractions for default-sized and huge physical memory frames.
22
3+
use super::page::AddressNotAligned;
34
use crate::structures::paging::page::{PageSize, Size4KiB};
45
use crate::PhysAddr;
56
use core::fmt;
@@ -19,9 +20,9 @@ impl<S: PageSize> PhysFrame<S> {
1920
///
2021
/// Returns an error if the address is not correctly aligned (i.e. is not a valid frame start).
2122
#[inline]
22-
pub fn from_start_address(address: PhysAddr) -> Result<Self, ()> {
23+
pub fn from_start_address(address: PhysAddr) -> Result<Self, AddressNotAligned> {
2324
if !address.is_aligned(S::SIZE) {
24-
return Err(());
25+
return Err(AddressNotAligned);
2526
}
2627
Ok(PhysFrame::containing_address(address))
2728
}

src/structures/paging/mapper/mapped_page_table.rs

+7-7
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use crate::structures::paging::{
22
frame::PhysFrame,
33
frame_alloc::FrameAllocator,
44
mapper::*,
5-
page::{Page, Size1GiB, Size2MiB, Size4KiB},
5+
page::{AddressNotAligned, Page, Size1GiB, Size2MiB, Size4KiB},
66
page_table::{FrameError, PageTable, PageTableEntry, PageTableFlags},
77
};
88

@@ -178,7 +178,7 @@ impl<'a, P: PhysToVirt> Mapper<Size1GiB> for MappedPageTable<'a, P> {
178178
}
179179

180180
let frame = PhysFrame::from_start_address(p3_entry.addr())
181-
.map_err(|()| UnmapError::InvalidFrameAddress(p3_entry.addr()))?;
181+
.map_err(|AddressNotAligned| UnmapError::InvalidFrameAddress(p3_entry.addr()))?;
182182

183183
p3_entry.set_unused();
184184
Ok((frame, MapperFlush::new(page)))
@@ -246,7 +246,7 @@ impl<'a, P: PhysToVirt> Mapper<Size1GiB> for MappedPageTable<'a, P> {
246246
}
247247

248248
PhysFrame::from_start_address(p3_entry.addr())
249-
.map_err(|()| TranslateError::InvalidFrameAddress(p3_entry.addr()))
249+
.map_err(|AddressNotAligned| TranslateError::InvalidFrameAddress(p3_entry.addr()))
250250
}
251251
}
252252

@@ -289,7 +289,7 @@ impl<'a, P: PhysToVirt> Mapper<Size2MiB> for MappedPageTable<'a, P> {
289289
}
290290

291291
let frame = PhysFrame::from_start_address(p2_entry.addr())
292-
.map_err(|()| UnmapError::InvalidFrameAddress(p2_entry.addr()))?;
292+
.map_err(|AddressNotAligned| UnmapError::InvalidFrameAddress(p2_entry.addr()))?;
293293

294294
p2_entry.set_unused();
295295
Ok((frame, MapperFlush::new(page)))
@@ -374,7 +374,7 @@ impl<'a, P: PhysToVirt> Mapper<Size2MiB> for MappedPageTable<'a, P> {
374374
}
375375

376376
PhysFrame::from_start_address(p2_entry.addr())
377-
.map_err(|()| TranslateError::InvalidFrameAddress(p2_entry.addr()))
377+
.map_err(|AddressNotAligned| TranslateError::InvalidFrameAddress(p2_entry.addr()))
378378
}
379379
}
380380

@@ -518,7 +518,7 @@ impl<'a, P: PhysToVirt> Mapper<Size4KiB> for MappedPageTable<'a, P> {
518518
}
519519

520520
PhysFrame::from_start_address(p1_entry.addr())
521-
.map_err(|()| TranslateError::InvalidFrameAddress(p1_entry.addr()))
521+
.map_err(|AddressNotAligned| TranslateError::InvalidFrameAddress(p1_entry.addr()))
522522
}
523523
}
524524

@@ -560,7 +560,7 @@ impl<'a, P: PhysToVirt> MapperAllSizes for MappedPageTable<'a, P> {
560560

561561
let frame = match PhysFrame::from_start_address(p1_entry.addr()) {
562562
Ok(frame) => frame,
563-
Err(()) => return TranslateResult::InvalidFrameAddress(p1_entry.addr()),
563+
Err(AddressNotAligned) => return TranslateResult::InvalidFrameAddress(p1_entry.addr()),
564564
};
565565
let offset = u64::from(addr.page_offset());
566566
TranslateResult::Frame4KiB { frame, offset }

src/structures/paging/mapper/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ pub use self::mapped_page_table::{MappedPageTable, PhysToVirt};
44
#[cfg(target_pointer_width = "64")]
55
pub use self::offset_page_table::OffsetPageTable;
66
#[cfg(feature = "instructions")]
7-
pub use self::recursive_page_table::RecursivePageTable;
7+
pub use self::recursive_page_table::{InvalidPageTable, RecursivePageTable};
88

99
use crate::structures::paging::{
1010
frame_alloc::FrameAllocator, page_table::PageTableFlags, Page, PageSize, PhysFrame, Size1GiB,

src/structures/paging/mapper/recursive_page_table.rs

+39-10
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
11
//! Access the page tables through a recursively mapped level 4 table.
22
3+
use core::fmt;
4+
35
use super::*;
46
use crate::registers::control::Cr3;
57
use crate::structures::paging::PageTableIndex;
68
use crate::structures::paging::{
79
frame_alloc::FrameAllocator,
8-
page::NotGiantPageSize,
10+
page::{AddressNotAligned, NotGiantPageSize},
911
page_table::{FrameError, PageTable, PageTableEntry, PageTableFlags},
1012
Page, PageSize, PhysFrame, Size1GiB, Size2MiB, Size4KiB,
1113
};
@@ -46,18 +48,18 @@ impl<'a> RecursivePageTable<'a> {
4648
///
4749
/// Otherwise `Err(())` is returned.
4850
#[inline]
49-
pub fn new(table: &'a mut PageTable) -> Result<Self, ()> {
51+
pub fn new(table: &'a mut PageTable) -> Result<Self, InvalidPageTable> {
5052
let page = Page::containing_address(VirtAddr::new(table as *const _ as u64));
5153
let recursive_index = page.p4_index();
5254

5355
if page.p3_index() != recursive_index
5456
|| page.p2_index() != recursive_index
5557
|| page.p1_index() != recursive_index
5658
{
57-
return Err(());
59+
return Err(InvalidPageTable::NotRecursive);
5860
}
5961
if Ok(Cr3::read().0) != table[recursive_index].frame() {
60-
return Err(());
62+
return Err(InvalidPageTable::NotActive);
6163
}
6264

6365
Ok(RecursivePageTable {
@@ -326,7 +328,7 @@ impl<'a> Mapper<Size1GiB> for RecursivePageTable<'a> {
326328
}
327329

328330
let frame = PhysFrame::from_start_address(p3_entry.addr())
329-
.map_err(|()| UnmapError::InvalidFrameAddress(p3_entry.addr()))?;
331+
.map_err(|AddressNotAligned| UnmapError::InvalidFrameAddress(p3_entry.addr()))?;
330332

331333
p3_entry.set_unused();
332334
Ok((frame, MapperFlush::new(page)))
@@ -404,7 +406,7 @@ impl<'a> Mapper<Size1GiB> for RecursivePageTable<'a> {
404406
}
405407

406408
PhysFrame::from_start_address(p3_entry.addr())
407-
.map_err(|()| TranslateError::InvalidFrameAddress(p3_entry.addr()))
409+
.map_err(|AddressNotAligned| TranslateError::InvalidFrameAddress(p3_entry.addr()))
408410
}
409411
}
410412

@@ -454,7 +456,7 @@ impl<'a> Mapper<Size2MiB> for RecursivePageTable<'a> {
454456
}
455457

456458
let frame = PhysFrame::from_start_address(p2_entry.addr())
457-
.map_err(|()| UnmapError::InvalidFrameAddress(p2_entry.addr()))?;
459+
.map_err(|AddressNotAligned| UnmapError::InvalidFrameAddress(p2_entry.addr()))?;
458460

459461
p2_entry.set_unused();
460462
Ok((frame, MapperFlush::new(page)))
@@ -561,7 +563,7 @@ impl<'a> Mapper<Size2MiB> for RecursivePageTable<'a> {
561563
}
562564

563565
PhysFrame::from_start_address(p2_entry.addr())
564-
.map_err(|()| TranslateError::InvalidFrameAddress(p2_entry.addr()))
566+
.map_err(|AddressNotAligned| TranslateError::InvalidFrameAddress(p2_entry.addr()))
565567
}
566568
}
567569

@@ -752,7 +754,7 @@ impl<'a> Mapper<Size4KiB> for RecursivePageTable<'a> {
752754
}
753755

754756
PhysFrame::from_start_address(p1_entry.addr())
755-
.map_err(|()| TranslateError::InvalidFrameAddress(p1_entry.addr()))
757+
.map_err(|AddressNotAligned| TranslateError::InvalidFrameAddress(p1_entry.addr()))
756758
}
757759
}
758760

@@ -803,13 +805,40 @@ impl<'a> MapperAllSizes for RecursivePageTable<'a> {
803805

804806
let frame = match PhysFrame::from_start_address(p1_entry.addr()) {
805807
Ok(frame) => frame,
806-
Err(()) => return TranslateResult::InvalidFrameAddress(p1_entry.addr()),
808+
Err(AddressNotAligned) => return TranslateResult::InvalidFrameAddress(p1_entry.addr()),
807809
};
808810
let offset = u64::from(addr.page_offset());
809811
TranslateResult::Frame4KiB { frame, offset }
810812
}
811813
}
812814

815+
/// The given page table was not suitable to create a `RecursivePageTable`.
816+
#[derive(Debug)]
817+
pub enum InvalidPageTable {
818+
/// The given page table was not at an recursive address.
819+
///
820+
/// The page table address must be of the form `0o_xxx_xxx_xxx_xxx_0000` where `xxx`
821+
/// is the recursive entry.
822+
NotRecursive,
823+
/// The given page table was not active on the CPU.
824+
///
825+
/// The recursive page table design requires that the given level 4 table is active
826+
/// on the CPU because otherwise it's not possible to access the other page tables
827+
/// through recursive memory addresses.
828+
NotActive,
829+
}
830+
831+
impl fmt::Display for InvalidPageTable {
832+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
833+
match self {
834+
InvalidPageTable::NotRecursive => {
835+
write!(f, "given page table address is not recursive")
836+
}
837+
InvalidPageTable::NotActive => write!(f, "given page table is not active on the CPU"),
838+
}
839+
}
840+
}
841+
813842
#[inline]
814843
fn p3_ptr<S: PageSize>(page: Page<S>, recursive_index: PageTableIndex) -> *mut PageTable {
815844
p3_page(page, recursive_index).start_address().as_mut_ptr()

src/structures/paging/page.rs

+12-2
Original file line numberDiff line numberDiff line change
@@ -67,9 +67,9 @@ impl<S: PageSize> Page<S> {
6767
///
6868
/// Returns an error if the address is not correctly aligned (i.e. is not a valid page start).
6969
#[inline]
70-
pub fn from_start_address(address: VirtAddr) -> Result<Self, ()> {
70+
pub fn from_start_address(address: VirtAddr) -> Result<Self, AddressNotAligned> {
7171
if !address.is_aligned(S::SIZE) {
72-
return Err(());
72+
return Err(AddressNotAligned);
7373
}
7474
Ok(Page::containing_address(address))
7575
}
@@ -362,6 +362,16 @@ impl<S: PageSize> fmt::Debug for PageRangeInclusive<S> {
362362
}
363363
}
364364

365+
/// The given address was not sufficiently aligned.
366+
#[derive(Debug)]
367+
pub struct AddressNotAligned;
368+
369+
impl fmt::Display for AddressNotAligned {
370+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
371+
write!(f, "the given address was not sufficiently aligned")
372+
}
373+
}
374+
365375
#[cfg(test)]
366376
mod tests {
367377
use super::*;

0 commit comments

Comments
 (0)