Add missing safety comments in `boot_pt`

This commit is contained in:
Zhang Junyang 2025-11-18 11:27:37 +08:00 committed by Ruihan Li
parent c77c2686d8
commit 77f0b0e746
1 changed files with 24 additions and 3 deletions

View File

@ -168,11 +168,14 @@ impl<E: PteTrait, C: PagingConstsTrait> BootPageTable<E, C> {
// Walk to the last level of the page table.
while level > 1 {
let index = pte_index::<C>(from, level);
// SAFETY: The result pointer is within the PT frame.
let pte_ptr = unsafe { (paddr_to_vaddr(pt) as *mut E).add(index) };
// SAFETY: The pointer to the entry is valid to read.
let pte = unsafe { pte_ptr.read() };
match pte.to_repr(level) {
PteScalar::Absent => {
let (pte, child_pt) = self.alloc_child(level);
// SAFETY: The pointer to the entry is valid to write.
unsafe { pte_ptr.write(pte) };
pt = child_pt;
}
@ -187,11 +190,14 @@ impl<E: PteTrait, C: PagingConstsTrait> BootPageTable<E, C> {
}
// Map the page in the last level page table.
let index = pte_index::<C>(from, 1);
// SAFETY: The result pointer is within the PT frame.
let pte_ptr = unsafe { (paddr_to_vaddr(pt) as *mut E).add(index) };
// SAFETY: The pointer to the entry is valid to read.
let pte = unsafe { pte_ptr.read() };
if matches!(pte.to_repr(1), PteScalar::Mapped(_, _)) {
panic!("mapping an already mapped page in the boot page table");
}
// SAFETY: The pointer to the entry is valid to write.
unsafe { pte_ptr.write(E::from_repr(&PteScalar::Mapped(to, prop), 1)) };
}
@ -219,7 +225,9 @@ impl<E: PteTrait, C: PagingConstsTrait> BootPageTable<E, C> {
// Walk to the last level of the page table.
while level > 1 {
let index = pte_index::<C>(virt_addr, level);
// SAFETY: The result pointer is within the PT frame.
let pte_ptr = unsafe { (paddr_to_vaddr(pt) as *mut E).add(index) };
// SAFETY: The pointer to the entry is valid to read.
let pte = unsafe { pte_ptr.read() };
match pte.to_repr(level) {
PteScalar::Absent => {
@ -232,7 +240,9 @@ impl<E: PteTrait, C: PagingConstsTrait> BootPageTable<E, C> {
// Split the huge page.
let (child_pte, child_frame_pa) = self.alloc_child(level);
for i in 0..nr_subpage_per_huge::<C>() {
// SAFETY: The result pointer is within the new PT frame.
let nxt_ptr = unsafe { (paddr_to_vaddr(child_frame_pa) as *mut E).add(i) };
// SAFETY: The pointer to the entry is valid to write.
unsafe {
nxt_ptr.write(E::from_repr(
&PteScalar::Mapped(huge_pa + i * C::BASE_PAGE_SIZE, prop),
@ -240,6 +250,7 @@ impl<E: PteTrait, C: PagingConstsTrait> BootPageTable<E, C> {
))
};
}
// SAFETY: The pointer to the entry is valid to write.
unsafe { pte_ptr.write(child_pte) };
pt = child_frame_pa;
}
@ -248,12 +259,15 @@ impl<E: PteTrait, C: PagingConstsTrait> BootPageTable<E, C> {
}
// Do protection in the last level page table.
let index = pte_index::<C>(virt_addr, 1);
// SAFETY: The result pointer is within the PT frame.
let pte_ptr = unsafe { (paddr_to_vaddr(pt) as *mut E).add(index) };
// SAFETY: The pointer to the entry is valid to read.
let pte = unsafe { pte_ptr.read() };
let PteScalar::Mapped(pa, mut prop) = pte.to_repr(1) else {
panic!("protecting an unmapped page in the boot page table");
};
op(&mut prop);
// SAFETY: The pointer to the entry is valid to write.
unsafe { pte_ptr.write(E::from_repr(&PteScalar::Mapped(pa, prop), 1)) };
}
@ -273,6 +287,7 @@ impl<E: PteTrait, C: PagingConstsTrait> BootPageTable<E, C> {
// Zero it out.
let vaddr = paddr_to_vaddr(frame_paddr) as *mut u8;
// SAFETY: The allocated frame is valid to write.
unsafe { core::ptr::write_bytes(vaddr, 0, PAGE_SIZE) };
(
@ -304,11 +319,17 @@ fn dfs_walk_on_leave<E: PteTrait, C: PagingConstsTrait>(
) {
if level >= 2 {
let pt_vaddr = paddr_to_vaddr(pt) as *mut E;
let pt = unsafe { core::slice::from_raw_parts_mut(pt_vaddr, nr_subpage_per_huge::<C>()) };
for pte in pt {
for offset in 0..nr_subpage_per_huge::<C>() {
// SAFETY: The result pointer is within the PT frame.
let pte_ptr = unsafe { pt_vaddr.add(offset) };
// SAFETY: The pointer to the entry is valid to read.
let mut pte = unsafe { pte_ptr.read() };
if let PteScalar::PageTable(child_pt, flags) = pte.to_repr(level) {
dfs_walk_on_leave::<E, C>(child_pt, level - 1, op);
op(pte, child_pt, level, flags);
op(&mut pte, child_pt, level, flags);
// SAFETY: The pointer to the entry is valid to write.
unsafe { pte_ptr.write(pte) };
}
}
}