Add unsafe with explained comments

This commit is contained in:
Ruihan Li 2025-02-17 09:47:37 +08:00 committed by Junyang Zhang
parent 619814e652
commit 3bc4424a5b
3 changed files with 34 additions and 16 deletions

View File

@ -105,5 +105,7 @@ pub(crate) unsafe fn send_ipi(hw_cpu_id: HwCpuId, irq_num: u8, guard: &dyn PinCu
); );
let apic = apic::get_or_init(guard); let apic = apic::get_or_init(guard);
apic.send_ipi(icr); // SAFETY: The ICR is valid to generate the request IPI. Generating the request IPI is safe
// as guaranteed by the caller.
unsafe { apic.send_ipi(icr) };
} }

View File

@ -77,15 +77,19 @@ impl super::Apic for X2Apic {
unsafe fn send_ipi(&self, icr: super::Icr) { unsafe fn send_ipi(&self, icr: super::Icr) {
let _guard = crate::trap::disable_local(); let _guard = crate::trap::disable_local();
wrmsr(IA32_X2APIC_ESR, 0); // SAFETY: These `rdmsr` and `wrmsr` instructions write the interrupt command to APIC and
wrmsr(IA32_X2APIC_ICR, icr.0); // wait for results. The caller guarantees it's safe to execute this interrupt command.
loop { unsafe {
let icr = rdmsr(IA32_X2APIC_ICR); wrmsr(IA32_X2APIC_ESR, 0);
if ((icr >> 12) & 0x1) == 0 { wrmsr(IA32_X2APIC_ICR, icr.0);
break; loop {
} let icr = rdmsr(IA32_X2APIC_ICR);
if rdmsr(IA32_X2APIC_ESR) > 0 { if ((icr >> 12) & 0x1) == 0 {
break; break;
}
if rdmsr(IA32_X2APIC_ESR) > 0 {
break;
}
} }
} }
} }

View File

@ -57,13 +57,18 @@ pub unsafe fn unprotect_gpa_range(gpa: Paddr, page_num: usize) -> Result<(), Pag
let _ = boot_pt::with_borrow(|boot_pt| { let _ = boot_pt::with_borrow(|boot_pt| {
for i in 0..page_num { for i in 0..page_num {
let vaddr = paddr_to_vaddr(gpa + i * PAGE_SIZE); let vaddr = paddr_to_vaddr(gpa + i * PAGE_SIZE);
boot_pt.protect_base_page(vaddr, protect_op); // SAFETY: The caller ensures that the address range exists in the linear mapping and
// can be mapped as shared pages.
unsafe { boot_pt.protect_base_page(vaddr, protect_op) };
} }
}); });
// Protect the page in the kernel page table. // Protect the page in the kernel page table.
let pt = KERNEL_PAGE_TABLE.get().unwrap(); let pt = KERNEL_PAGE_TABLE.get().unwrap();
let vaddr = paddr_to_vaddr(gpa); let vaddr = paddr_to_vaddr(gpa);
pt.protect_flush_tlb(&(vaddr..vaddr + page_num * PAGE_SIZE), protect_op) // SAFETY: The caller ensures that the address range exists in the linear mapping and can be
// mapped as shared pages.
unsafe { pt.protect_flush_tlb(&(vaddr..vaddr + page_num * PAGE_SIZE), protect_op) }
.map_err(|_| PageConvertError::PageTable)?; .map_err(|_| PageConvertError::PageTable)?;
map_gpa( map_gpa(
@ -106,21 +111,28 @@ pub unsafe fn protect_gpa_range(gpa: Paddr, page_num: usize) -> Result<(), PageC
let _ = boot_pt::with_borrow(|boot_pt| { let _ = boot_pt::with_borrow(|boot_pt| {
for i in 0..page_num { for i in 0..page_num {
let vaddr = paddr_to_vaddr(gpa + i * PAGE_SIZE); let vaddr = paddr_to_vaddr(gpa + i * PAGE_SIZE);
boot_pt.protect_base_page(vaddr, protect_op); // SAFETY: The caller ensures that the address range exists in the linear mapping and
// can be mapped as non-shared pages.
unsafe { boot_pt.protect_base_page(vaddr, protect_op) };
} }
}); });
// Protect the page in the kernel page table. // Protect the page in the kernel page table.
let pt = KERNEL_PAGE_TABLE.get().unwrap(); let pt = KERNEL_PAGE_TABLE.get().unwrap();
let vaddr = paddr_to_vaddr(gpa); let vaddr = paddr_to_vaddr(gpa);
pt.protect_flush_tlb(&(vaddr..vaddr + page_num * PAGE_SIZE), protect_op) // SAFETY: The caller ensures that the address range exists in the linear mapping and can be
// mapped as non-shared pages.
unsafe { pt.protect_flush_tlb(&(vaddr..vaddr + page_num * PAGE_SIZE), protect_op) }
.map_err(|_| PageConvertError::PageTable)?; .map_err(|_| PageConvertError::PageTable)?;
map_gpa((gpa & PAGE_MASK) as u64, (page_num * PAGE_SIZE) as u64) map_gpa((gpa & PAGE_MASK) as u64, (page_num * PAGE_SIZE) as u64)
.map_err(|_| PageConvertError::TdVmcall)?; .map_err(|_| PageConvertError::TdVmcall)?;
for i in 0..page_num { for i in 0..page_num {
// SAFETY: The caller ensures that the address range represents physical memory so the
// memory can be accepted.
unsafe { unsafe {
accept_page(0, (gpa + i * PAGE_SIZE) as u64).map_err(|_| PageConvertError::TdCall)?; accept_page(0, (gpa + i * PAGE_SIZE) as u64).map_err(|_| PageConvertError::TdCall)?
} };
} }
Ok(()) Ok(())
} }