Skip to content

Commit f2039dd

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 5b0eac1 commit f2039dd

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

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

573573
let frame = match PhysFrame::from_start_address(p1_entry.addr()) {
574574
Ok(frame) => frame,
575-
Err(()) => return TranslateResult::InvalidFrameAddress(p1_entry.addr()),
575+
Err(AddressNotAligned) => return TranslateResult::InvalidFrameAddress(p1_entry.addr()),
576576
};
577577
let offset = u64::from(addr.page_offset());
578578
let flags = p1_entry.flags();

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

@@ -815,7 +817,7 @@ impl<'a> MapperAllSizes for RecursivePageTable<'a> {
815817

816818
let frame = match PhysFrame::from_start_address(p1_entry.addr()) {
817819
Ok(frame) => frame,
818-
Err(()) => return TranslateResult::InvalidFrameAddress(p1_entry.addr()),
820+
Err(AddressNotAligned) => return TranslateResult::InvalidFrameAddress(p1_entry.addr()),
819821
};
820822
let offset = u64::from(addr.page_offset());
821823
let flags = p1_entry.flags();
@@ -827,6 +829,33 @@ impl<'a> MapperAllSizes for RecursivePageTable<'a> {
827829
}
828830
}
829831

832+
/// The given page table was not suitable to create a `RecursivePageTable`.
833+
#[derive(Debug)]
834+
pub enum InvalidPageTable {
835+
/// The given page table was not at an recursive address.
836+
///
837+
/// The page table address must be of the form `0o_xxx_xxx_xxx_xxx_0000` where `xxx`
838+
/// is the recursive entry.
839+
NotRecursive,
840+
/// The given page table was not active on the CPU.
841+
///
842+
/// The recursive page table design requires that the given level 4 table is active
843+
/// on the CPU because otherwise it's not possible to access the other page tables
844+
/// through recursive memory addresses.
845+
NotActive,
846+
}
847+
848+
impl fmt::Display for InvalidPageTable {
849+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
850+
match self {
851+
InvalidPageTable::NotRecursive => {
852+
write!(f, "given page table address is not recursive")
853+
}
854+
InvalidPageTable::NotActive => write!(f, "given page table is not active on the CPU"),
855+
}
856+
}
857+
}
858+
830859
#[inline]
831860
fn p3_ptr<S: PageSize>(page: Page<S>, recursive_index: PageTableIndex) -> *mut PageTable {
832861
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)