Skip to content

Commit 15ce8dd

Browse files
authored
feat(paging): Also return flags for MapperAllSizes::translate() (#207)
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`.
1 parent 38f1c7d commit 15ce8dd

File tree

3 files changed

+59
-13
lines changed

3 files changed

+59
-13
lines changed

src/structures/paging/mapper/mapped_page_table.rs

+22-5
Original file line numberDiff line numberDiff line change
@@ -537,18 +537,30 @@ impl<'a, P: PhysToVirt> MapperAllSizes for MappedPageTable<'a, P> {
537537
Ok(page_table) => page_table,
538538
Err(PageTableWalkError::NotMapped) => return TranslateResult::PageNotMapped,
539539
Err(PageTableWalkError::MappedToHugePage) => {
540-
let frame = PhysFrame::containing_address(p3[addr.p3_index()].addr());
540+
let entry = &p3[addr.p3_index()];
541+
let frame = PhysFrame::containing_address(entry.addr());
541542
let offset = addr.as_u64() & 0o_777_777_7777;
542-
return TranslateResult::Frame1GiB { frame, offset };
543+
let flags = entry.flags();
544+
return TranslateResult::Frame1GiB {
545+
frame,
546+
offset,
547+
flags,
548+
};
543549
}
544550
};
545551
let p1 = match self.page_table_walker.next_table(&p2[addr.p2_index()]) {
546552
Ok(page_table) => page_table,
547553
Err(PageTableWalkError::NotMapped) => return TranslateResult::PageNotMapped,
548554
Err(PageTableWalkError::MappedToHugePage) => {
549-
let frame = PhysFrame::containing_address(p2[addr.p2_index()].addr());
555+
let entry = &p2[addr.p2_index()];
556+
let frame = PhysFrame::containing_address(entry.addr());
550557
let offset = addr.as_u64() & 0o_777_7777;
551-
return TranslateResult::Frame2MiB { frame, offset };
558+
let flags = entry.flags();
559+
return TranslateResult::Frame2MiB {
560+
frame,
561+
offset,
562+
flags,
563+
};
552564
}
553565
};
554566

@@ -563,7 +575,12 @@ impl<'a, P: PhysToVirt> MapperAllSizes for MappedPageTable<'a, P> {
563575
Err(()) => return TranslateResult::InvalidFrameAddress(p1_entry.addr()),
564576
};
565577
let offset = u64::from(addr.page_offset());
566-
TranslateResult::Frame4KiB { frame, offset }
578+
let flags = p1_entry.flags();
579+
TranslateResult::Frame4KiB {
580+
frame,
581+
offset,
582+
flags,
583+
}
567584
}
568585
}
569586

src/structures/paging/mapper/mod.rs

+15-3
Original file line numberDiff line numberDiff line change
@@ -39,9 +39,15 @@ pub trait MapperAllSizes: Mapper<Size4KiB> + Mapper<Size2MiB> + Mapper<Size1GiB>
3939
fn translate_addr(&self, addr: VirtAddr) -> Option<PhysAddr> {
4040
match self.translate(addr) {
4141
TranslateResult::PageNotMapped | TranslateResult::InvalidFrameAddress(_) => None,
42-
TranslateResult::Frame4KiB { frame, offset } => Some(frame.start_address() + offset),
43-
TranslateResult::Frame2MiB { frame, offset } => Some(frame.start_address() + offset),
44-
TranslateResult::Frame1GiB { frame, offset } => Some(frame.start_address() + offset),
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, .. } => {
49+
Some(frame.start_address() + offset)
50+
}
4551
}
4652
}
4753
}
@@ -58,20 +64,26 @@ pub enum TranslateResult {
5864
frame: PhysFrame<Size4KiB>,
5965
/// The offset whithin the mapped frame.
6066
offset: u64,
67+
/// The flags for the frame.
68+
flags: PageTableFlags,
6169
},
6270
/// The page is mapped to a physical frame of size 2MiB.
6371
Frame2MiB {
6472
/// The mapped frame.
6573
frame: PhysFrame<Size2MiB>,
6674
/// The offset whithin the mapped frame.
6775
offset: u64,
76+
/// The flags for the frame.
77+
flags: PageTableFlags,
6878
},
6979
/// The page is mapped to a physical frame of size 2MiB.
7080
Frame1GiB {
7181
/// The mapped frame.
7282
frame: PhysFrame<Size1GiB>,
7383
/// The offset whithin the mapped frame.
7484
offset: u64,
85+
/// The flags for the frame.
86+
flags: PageTableFlags,
7587
},
7688
/// The given page is not mapped to a physical frame.
7789
PageNotMapped,

src/structures/paging/mapper/recursive_page_table.rs

+22-5
Original file line numberDiff line numberDiff line change
@@ -776,9 +776,15 @@ impl<'a> MapperAllSizes for RecursivePageTable<'a> {
776776
return TranslateResult::PageNotMapped;
777777
}
778778
if p3_entry.flags().contains(PageTableFlags::HUGE_PAGE) {
779-
let frame = PhysFrame::containing_address(p3[addr.p3_index()].addr());
779+
let entry = &p3[addr.p3_index()];
780+
let frame = PhysFrame::containing_address(entry.addr());
780781
let offset = addr.as_u64() & 0o_777_777_7777;
781-
return TranslateResult::Frame1GiB { frame, offset };
782+
let flags = entry.flags();
783+
return TranslateResult::Frame1GiB {
784+
frame,
785+
offset,
786+
flags,
787+
};
782788
}
783789

784790
let p2 = unsafe { &*(p2_ptr(page, self.recursive_index)) };
@@ -787,9 +793,15 @@ impl<'a> MapperAllSizes for RecursivePageTable<'a> {
787793
return TranslateResult::PageNotMapped;
788794
}
789795
if p2_entry.flags().contains(PageTableFlags::HUGE_PAGE) {
790-
let frame = PhysFrame::containing_address(p2[addr.p2_index()].addr());
796+
let entry = &p2[addr.p2_index()];
797+
let frame = PhysFrame::containing_address(entry.addr());
791798
let offset = addr.as_u64() & 0o_777_7777;
792-
return TranslateResult::Frame2MiB { frame, offset };
799+
let flags = entry.flags();
800+
return TranslateResult::Frame2MiB {
801+
frame,
802+
offset,
803+
flags,
804+
};
793805
}
794806

795807
let p1 = unsafe { &*(p1_ptr(page, self.recursive_index)) };
@@ -806,7 +818,12 @@ impl<'a> MapperAllSizes for RecursivePageTable<'a> {
806818
Err(()) => return TranslateResult::InvalidFrameAddress(p1_entry.addr()),
807819
};
808820
let offset = u64::from(addr.page_offset());
809-
TranslateResult::Frame4KiB { frame, offset }
821+
let flags = p1_entry.flags();
822+
TranslateResult::Frame4KiB {
823+
frame,
824+
offset,
825+
flags,
826+
}
810827
}
811828
}
812829

0 commit comments

Comments
 (0)