From 1449fe6719917de29e1651c89a3d81d91bbedd3c Mon Sep 17 00:00:00 2001 From: Harald Hoyer Date: Tue, 8 Dec 2020 08:46:31 +0100 Subject: [PATCH] feat(paging): Also return flags for `MapperAllSizes::translate()` Extend `TranslateResult` returned by `MapperAllSizes::translate()` with the page flags. This way, there is a method to get the flags for the page of a `VirtAddr`. --- .../paging/mapper/mapped_page_table.rs | 27 +++++++++++++++---- src/structures/paging/mapper/mod.rs | 18 ++++++++++--- .../paging/mapper/recursive_page_table.rs | 27 +++++++++++++++---- 3 files changed, 59 insertions(+), 13 deletions(-) diff --git a/src/structures/paging/mapper/mapped_page_table.rs b/src/structures/paging/mapper/mapped_page_table.rs index e68221fed..55b884bbd 100644 --- a/src/structures/paging/mapper/mapped_page_table.rs +++ b/src/structures/paging/mapper/mapped_page_table.rs @@ -537,18 +537,30 @@ impl<'a, P: PhysToVirt> MapperAllSizes for MappedPageTable<'a, P> { Ok(page_table) => page_table, Err(PageTableWalkError::NotMapped) => return TranslateResult::PageNotMapped, Err(PageTableWalkError::MappedToHugePage) => { - let frame = PhysFrame::containing_address(p3[addr.p3_index()].addr()); + let entry = &p3[addr.p3_index()]; + let frame = PhysFrame::containing_address(entry.addr()); let offset = addr.as_u64() & 0o_777_777_7777; - return TranslateResult::Frame1GiB { frame, offset }; + let flags = entry.flags(); + return TranslateResult::Frame1GiB { + frame, + offset, + flags, + }; } }; let p1 = match self.page_table_walker.next_table(&p2[addr.p2_index()]) { Ok(page_table) => page_table, Err(PageTableWalkError::NotMapped) => return TranslateResult::PageNotMapped, Err(PageTableWalkError::MappedToHugePage) => { - let frame = PhysFrame::containing_address(p2[addr.p2_index()].addr()); + let entry = &p2[addr.p2_index()]; + let frame = PhysFrame::containing_address(entry.addr()); let offset = addr.as_u64() & 0o_777_7777; - return TranslateResult::Frame2MiB { frame, offset }; + let flags = entry.flags(); + return TranslateResult::Frame2MiB { + frame, + offset, + flags, + }; } }; @@ -563,7 +575,12 @@ impl<'a, P: PhysToVirt> MapperAllSizes for MappedPageTable<'a, P> { Err(()) => return TranslateResult::InvalidFrameAddress(p1_entry.addr()), }; let offset = u64::from(addr.page_offset()); - TranslateResult::Frame4KiB { frame, offset } + let flags = p1_entry.flags(); + TranslateResult::Frame4KiB { + frame, + offset, + flags, + } } } diff --git a/src/structures/paging/mapper/mod.rs b/src/structures/paging/mapper/mod.rs index d1c73898c..9cc8e233a 100644 --- a/src/structures/paging/mapper/mod.rs +++ b/src/structures/paging/mapper/mod.rs @@ -39,9 +39,15 @@ pub trait MapperAllSizes: Mapper + Mapper + Mapper fn translate_addr(&self, addr: VirtAddr) -> Option { match self.translate(addr) { TranslateResult::PageNotMapped | TranslateResult::InvalidFrameAddress(_) => None, - TranslateResult::Frame4KiB { frame, offset } => Some(frame.start_address() + offset), - TranslateResult::Frame2MiB { frame, offset } => Some(frame.start_address() + offset), - TranslateResult::Frame1GiB { frame, offset } => Some(frame.start_address() + offset), + TranslateResult::Frame4KiB { frame, offset, .. } => { + Some(frame.start_address() + offset) + } + TranslateResult::Frame2MiB { frame, offset, .. } => { + Some(frame.start_address() + offset) + } + TranslateResult::Frame1GiB { frame, offset, .. } => { + Some(frame.start_address() + offset) + } } } } @@ -58,6 +64,8 @@ pub enum TranslateResult { frame: PhysFrame, /// The offset whithin the mapped frame. offset: u64, + /// The flags for the frame. + flags: PageTableFlags, }, /// The page is mapped to a physical frame of size 2MiB. Frame2MiB { @@ -65,6 +73,8 @@ pub enum TranslateResult { frame: PhysFrame, /// The offset whithin the mapped frame. offset: u64, + /// The flags for the frame. + flags: PageTableFlags, }, /// The page is mapped to a physical frame of size 2MiB. Frame1GiB { @@ -72,6 +82,8 @@ pub enum TranslateResult { frame: PhysFrame, /// The offset whithin the mapped frame. offset: u64, + /// The flags for the frame. + flags: PageTableFlags, }, /// The given page is not mapped to a physical frame. PageNotMapped, diff --git a/src/structures/paging/mapper/recursive_page_table.rs b/src/structures/paging/mapper/recursive_page_table.rs index e57aed0b8..9c99afb62 100644 --- a/src/structures/paging/mapper/recursive_page_table.rs +++ b/src/structures/paging/mapper/recursive_page_table.rs @@ -776,9 +776,15 @@ impl<'a> MapperAllSizes for RecursivePageTable<'a> { return TranslateResult::PageNotMapped; } if p3_entry.flags().contains(PageTableFlags::HUGE_PAGE) { - let frame = PhysFrame::containing_address(p3[addr.p3_index()].addr()); + let entry = &p3[addr.p3_index()]; + let frame = PhysFrame::containing_address(entry.addr()); let offset = addr.as_u64() & 0o_777_777_7777; - return TranslateResult::Frame1GiB { frame, offset }; + let flags = entry.flags(); + return TranslateResult::Frame1GiB { + frame, + offset, + flags, + }; } let p2 = unsafe { &*(p2_ptr(page, self.recursive_index)) }; @@ -787,9 +793,15 @@ impl<'a> MapperAllSizes for RecursivePageTable<'a> { return TranslateResult::PageNotMapped; } if p2_entry.flags().contains(PageTableFlags::HUGE_PAGE) { - let frame = PhysFrame::containing_address(p2[addr.p2_index()].addr()); + let entry = &p2[addr.p2_index()]; + let frame = PhysFrame::containing_address(entry.addr()); let offset = addr.as_u64() & 0o_777_7777; - return TranslateResult::Frame2MiB { frame, offset }; + let flags = entry.flags(); + return TranslateResult::Frame2MiB { + frame, + offset, + flags, + }; } let p1 = unsafe { &*(p1_ptr(page, self.recursive_index)) }; @@ -806,7 +818,12 @@ impl<'a> MapperAllSizes for RecursivePageTable<'a> { Err(()) => return TranslateResult::InvalidFrameAddress(p1_entry.addr()), }; let offset = u64::from(addr.page_offset()); - TranslateResult::Frame4KiB { frame, offset } + let flags = p1_entry.flags(); + TranslateResult::Frame4KiB { + frame, + offset, + flags, + } } }