Add missing safety comments in `boot_pt`
This commit is contained in:
parent
c77c2686d8
commit
77f0b0e746
|
|
@ -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) };
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue