Skip to content

Commit

Permalink
feat(paging): Also return flags for MapperAllSizes::translate()
Browse files Browse the repository at this point in the history
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`.
  • Loading branch information
haraldh committed Dec 16, 2020
1 parent e824cf6 commit 1449fe6
Show file tree
Hide file tree
Showing 3 changed files with 59 additions and 13 deletions.
27 changes: 22 additions & 5 deletions src/structures/paging/mapper/mapped_page_table.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
};
}
};

Expand All @@ -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,
}
}
}

Expand Down
18 changes: 15 additions & 3 deletions src/structures/paging/mapper/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,15 @@ pub trait MapperAllSizes: Mapper<Size4KiB> + Mapper<Size2MiB> + Mapper<Size1GiB>
fn translate_addr(&self, addr: VirtAddr) -> Option<PhysAddr> {
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)
}
}
}
}
Expand All @@ -58,20 +64,26 @@ pub enum TranslateResult {
frame: PhysFrame<Size4KiB>,
/// 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 {
/// The mapped frame.
frame: PhysFrame<Size2MiB>,
/// 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 {
/// The mapped frame.
frame: PhysFrame<Size1GiB>,
/// 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,
Expand Down
27 changes: 22 additions & 5 deletions src/structures/paging/mapper/recursive_page_table.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)) };
Expand All @@ -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)) };
Expand All @@ -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,
}
}
}

Expand Down

0 comments on commit 1449fe6

Please sign in to comment.