Skip to content

Return the UnusedPhysFrame on MapToError::PageAlreadyMapped #118

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jan 22, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 28 additions & 10 deletions src/structures/paging/mapper/mapped_page_table.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ impl<'a, P: PhysToVirt> MappedPageTable<'a, P> {
frame: UnusedPhysFrame<Size1GiB>,
flags: PageTableFlags,
allocator: &mut A,
) -> Result<MapperFlush<Size1GiB>, MapToError>
) -> Result<MapperFlush<Size1GiB>, MapToError<Size1GiB>>
where
A: FrameAllocator<Size4KiB>,
{
Expand All @@ -52,7 +52,7 @@ impl<'a, P: PhysToVirt> MappedPageTable<'a, P> {
.create_next_table(&mut p4[page.p4_index()], allocator)?;

if !p3[page.p3_index()].is_unused() {
return Err(MapToError::PageAlreadyMapped);
return Err(MapToError::PageAlreadyMapped(frame));
}
p3[page.p3_index()].set_addr(frame.start_address(), flags | PageTableFlags::HUGE_PAGE);

Expand All @@ -67,7 +67,7 @@ impl<'a, P: PhysToVirt> MappedPageTable<'a, P> {
frame: UnusedPhysFrame<Size2MiB>,
flags: PageTableFlags,
allocator: &mut A,
) -> Result<MapperFlush<Size2MiB>, MapToError>
) -> Result<MapperFlush<Size2MiB>, MapToError<Size2MiB>>
where
A: FrameAllocator<Size4KiB>,
{
Expand All @@ -80,7 +80,7 @@ impl<'a, P: PhysToVirt> MappedPageTable<'a, P> {
.create_next_table(&mut p3[page.p3_index()], allocator)?;

if !p2[page.p2_index()].is_unused() {
return Err(MapToError::PageAlreadyMapped);
return Err(MapToError::PageAlreadyMapped(frame));
}
p2[page.p2_index()].set_addr(frame.start_address(), flags | PageTableFlags::HUGE_PAGE);

Expand All @@ -95,7 +95,7 @@ impl<'a, P: PhysToVirt> MappedPageTable<'a, P> {
frame: UnusedPhysFrame<Size4KiB>,
flags: PageTableFlags,
allocator: &mut A,
) -> Result<MapperFlush<Size4KiB>, MapToError>
) -> Result<MapperFlush<Size4KiB>, MapToError<Size4KiB>>
where
A: FrameAllocator<Size4KiB>,
{
Expand All @@ -111,7 +111,7 @@ impl<'a, P: PhysToVirt> MappedPageTable<'a, P> {
.create_next_table(&mut p2[page.p2_index()], allocator)?;

if !p1[page.p1_index()].is_unused() {
return Err(MapToError::PageAlreadyMapped);
return Err(MapToError::PageAlreadyMapped(frame));
}
p1[page.p1_index()].set_frame(frame.frame(), flags);

Expand All @@ -126,7 +126,7 @@ impl<'a, P: PhysToVirt> Mapper<Size1GiB> for MappedPageTable<'a, P> {
frame: UnusedPhysFrame<Size1GiB>,
flags: PageTableFlags,
allocator: &mut A,
) -> Result<MapperFlush<Size1GiB>, MapToError>
) -> Result<MapperFlush<Size1GiB>, MapToError<Size1GiB>>
where
A: FrameAllocator<Size4KiB>,
{
Expand Down Expand Up @@ -199,7 +199,7 @@ impl<'a, P: PhysToVirt> Mapper<Size2MiB> for MappedPageTable<'a, P> {
frame: UnusedPhysFrame<Size2MiB>,
flags: PageTableFlags,
allocator: &mut A,
) -> Result<MapperFlush<Size2MiB>, MapToError>
) -> Result<MapperFlush<Size2MiB>, MapToError<Size2MiB>>
where
A: FrameAllocator<Size4KiB>,
{
Expand Down Expand Up @@ -280,7 +280,7 @@ impl<'a, P: PhysToVirt> Mapper<Size4KiB> for MappedPageTable<'a, P> {
frame: UnusedPhysFrame<Size4KiB>,
flags: PageTableFlags,
allocator: &mut A,
) -> Result<MapperFlush<Size4KiB>, MapToError>
) -> Result<MapperFlush<Size4KiB>, MapToError<Size4KiB>>
where
A: FrameAllocator<Size4KiB>,
{
Expand Down Expand Up @@ -499,7 +499,25 @@ enum PageTableCreateError {
FrameAllocationFailed,
}

impl From<PageTableCreateError> for MapToError {
impl From<PageTableCreateError> for MapToError<Size4KiB> {
fn from(err: PageTableCreateError) -> Self {
match err {
PageTableCreateError::MappedToHugePage => MapToError::ParentEntryHugePage,
PageTableCreateError::FrameAllocationFailed => MapToError::FrameAllocationFailed,
}
}
}

impl From<PageTableCreateError> for MapToError<Size2MiB> {
fn from(err: PageTableCreateError) -> Self {
match err {
PageTableCreateError::MappedToHugePage => MapToError::ParentEntryHugePage,
PageTableCreateError::FrameAllocationFailed => MapToError::FrameAllocationFailed,
}
}
}

impl From<PageTableCreateError> for MapToError<Size1GiB> {
fn from(err: PageTableCreateError) -> Self {
match err {
PageTableCreateError::MappedToHugePage => MapToError::ParentEntryHugePage,
Expand Down
8 changes: 4 additions & 4 deletions src/structures/paging/mapper/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ pub trait Mapper<S: PageSize> {
frame: UnusedPhysFrame<S>,
flags: PageTableFlags,
frame_allocator: &mut A,
) -> Result<MapperFlush<S>, MapToError>
) -> Result<MapperFlush<S>, MapToError<S>>
where
Self: Sized,
A: FrameAllocator<Size4KiB>;
Expand Down Expand Up @@ -117,7 +117,7 @@ pub trait Mapper<S: PageSize> {
frame: UnusedPhysFrame<S>,
flags: PageTableFlags,
frame_allocator: &mut A,
) -> Result<MapperFlush<S>, MapToError>
) -> Result<MapperFlush<S>, MapToError<S>>
where
Self: Sized,
A: FrameAllocator<Size4KiB>,
Expand Down Expand Up @@ -156,15 +156,15 @@ impl<S: PageSize> MapperFlush<S> {

/// This error is returned from `map_to` and similar methods.
#[derive(Debug)]
pub enum MapToError {
pub enum MapToError<S: PageSize> {
/// An additional frame was needed for the mapping process, but the frame allocator
/// returned `None`.
FrameAllocationFailed,
/// An upper level page table entry has the `HUGE_PAGE` flag set, which means that the
/// given page is part of an already mapped huge page.
ParentEntryHugePage,
/// The given page is already mapped to a physical frame.
PageAlreadyMapped,
PageAlreadyMapped(UnusedPhysFrame<S>),
}

/// An error indicating that an `unmap` call failed.
Expand Down
6 changes: 3 additions & 3 deletions src/structures/paging/mapper/offset_page_table.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ impl<'a> Mapper<Size1GiB> for OffsetPageTable<'a> {
frame: UnusedPhysFrame<Size1GiB>,
flags: PageTableFlags,
allocator: &mut A,
) -> Result<MapperFlush<Size1GiB>, MapToError>
) -> Result<MapperFlush<Size1GiB>, MapToError<Size1GiB>>
where
A: FrameAllocator<Size4KiB>,
{
Expand Down Expand Up @@ -89,7 +89,7 @@ impl<'a> Mapper<Size2MiB> for OffsetPageTable<'a> {
frame: UnusedPhysFrame<Size2MiB>,
flags: PageTableFlags,
allocator: &mut A,
) -> Result<MapperFlush<Size2MiB>, MapToError>
) -> Result<MapperFlush<Size2MiB>, MapToError<Size2MiB>>
where
A: FrameAllocator<Size4KiB>,
{
Expand Down Expand Up @@ -123,7 +123,7 @@ impl<'a> Mapper<Size4KiB> for OffsetPageTable<'a> {
frame: UnusedPhysFrame<Size4KiB>,
flags: PageTableFlags,
allocator: &mut A,
) -> Result<MapperFlush<Size4KiB>, MapToError>
) -> Result<MapperFlush<Size4KiB>, MapToError<Size4KiB>>
where
A: FrameAllocator<Size4KiB>,
{
Expand Down
26 changes: 13 additions & 13 deletions src/structures/paging/mapper/recursive_page_table.rs
Original file line number Diff line number Diff line change
Expand Up @@ -85,22 +85,22 @@ impl<'a> RecursivePageTable<'a> {
/// Returns `MapToError::FrameAllocationFailed` if the entry is unused and the allocator
/// returned `None`. Returns `MapToError::ParentEntryHugePage` if the `HUGE_PAGE` flag is set
/// in the passed entry.
unsafe fn create_next_table<'b, A>(
unsafe fn create_next_table<'b, A, S: PageSize>(
entry: &'b mut PageTableEntry,
next_table_page: Page,
allocator: &mut A,
) -> Result<&'b mut PageTable, MapToError>
) -> Result<&'b mut PageTable, MapToError<S>>
where
A: FrameAllocator<Size4KiB>,
{
/// This inner function is used to limit the scope of `unsafe`.
///
/// This is a safe function, so we need to use `unsafe` blocks when we do something unsafe.
fn inner<'b, A>(
fn inner<'b, A, S: PageSize>(
entry: &'b mut PageTableEntry,
next_table_page: Page,
allocator: &mut A,
) -> Result<&'b mut PageTable, MapToError>
) -> Result<&'b mut PageTable, MapToError<S>>
where
A: FrameAllocator<Size4KiB>,
{
Expand Down Expand Up @@ -141,7 +141,7 @@ impl<'a> RecursivePageTable<'a> {
frame: UnusedPhysFrame<Size1GiB>,
flags: PageTableFlags,
allocator: &mut A,
) -> Result<MapperFlush<Size1GiB>, MapToError>
) -> Result<MapperFlush<Size1GiB>, MapToError<Size1GiB>>
where
A: FrameAllocator<Size4KiB>,
{
Expand All @@ -152,7 +152,7 @@ impl<'a> RecursivePageTable<'a> {
let p3 = unsafe { Self::create_next_table(&mut p4[page.p4_index()], p3_page, allocator)? };

if !p3[page.p3_index()].is_unused() {
return Err(MapToError::PageAlreadyMapped);
return Err(MapToError::PageAlreadyMapped(frame));
}
p3[page.p3_index()].set_addr(frame.start_address(), flags | Flags::HUGE_PAGE);

Expand All @@ -167,7 +167,7 @@ impl<'a> RecursivePageTable<'a> {
frame: UnusedPhysFrame<Size2MiB>,
flags: PageTableFlags,
allocator: &mut A,
) -> Result<MapperFlush<Size2MiB>, MapToError>
) -> Result<MapperFlush<Size2MiB>, MapToError<Size2MiB>>
where
A: FrameAllocator<Size4KiB>,
{
Expand All @@ -181,7 +181,7 @@ impl<'a> RecursivePageTable<'a> {
let p2 = unsafe { Self::create_next_table(&mut p3[page.p3_index()], p2_page, allocator)? };

if !p2[page.p2_index()].is_unused() {
return Err(MapToError::PageAlreadyMapped);
return Err(MapToError::PageAlreadyMapped(frame));
}
p2[page.p2_index()].set_addr(frame.start_address(), flags | Flags::HUGE_PAGE);

Expand All @@ -196,7 +196,7 @@ impl<'a> RecursivePageTable<'a> {
frame: UnusedPhysFrame<Size4KiB>,
flags: PageTableFlags,
allocator: &mut A,
) -> Result<MapperFlush<Size4KiB>, MapToError>
) -> Result<MapperFlush<Size4KiB>, MapToError<Size4KiB>>
where
A: FrameAllocator<Size4KiB>,
{
Expand All @@ -212,7 +212,7 @@ impl<'a> RecursivePageTable<'a> {
let p1 = unsafe { Self::create_next_table(&mut p2[page.p2_index()], p1_page, allocator)? };

if !p1[page.p1_index()].is_unused() {
return Err(MapToError::PageAlreadyMapped);
return Err(MapToError::PageAlreadyMapped(frame));
}
p1[page.p1_index()].set_frame(frame.frame(), flags);

Expand All @@ -227,7 +227,7 @@ impl<'a> Mapper<Size1GiB> for RecursivePageTable<'a> {
frame: UnusedPhysFrame<Size1GiB>,
flags: PageTableFlags,
allocator: &mut A,
) -> Result<MapperFlush<Size1GiB>, MapToError>
) -> Result<MapperFlush<Size1GiB>, MapToError<Size1GiB>>
where
A: FrameAllocator<Size4KiB>,
{
Expand Down Expand Up @@ -312,7 +312,7 @@ impl<'a> Mapper<Size2MiB> for RecursivePageTable<'a> {
frame: UnusedPhysFrame<Size2MiB>,
flags: PageTableFlags,
allocator: &mut A,
) -> Result<MapperFlush<Size2MiB>, MapToError>
) -> Result<MapperFlush<Size2MiB>, MapToError<Size2MiB>>
where
A: FrameAllocator<Size4KiB>,
{
Expand Down Expand Up @@ -417,7 +417,7 @@ impl<'a> Mapper<Size4KiB> for RecursivePageTable<'a> {
frame: UnusedPhysFrame<Size4KiB>,
flags: PageTableFlags,
allocator: &mut A,
) -> Result<MapperFlush<Size4KiB>, MapToError>
) -> Result<MapperFlush<Size4KiB>, MapToError<Size4KiB>>
where
A: FrameAllocator<Size4KiB>,
{
Expand Down