Unify headers of safety comments

This commit is contained in:
Ruihan Li
2024-05-21 20:07:26 +08:00
committed by Tate, Hongliang Tian
parent 07fbbcfd8c
commit 83b88229a3
36 changed files with 102 additions and 102 deletions

View File

@ -24,7 +24,7 @@ fn init_bootloader_name(bootloader_name: &'static Once<String>) {
let mut name = ""; let mut name = "";
let info = MB1_INFO.get().unwrap(); let info = MB1_INFO.get().unwrap();
if info.boot_loader_name != 0 { if info.boot_loader_name != 0 {
// Safety: the bootloader name is C-style zero-terminated string. // SAFETY: the bootloader name is C-style zero-terminated string.
unsafe { unsafe {
let cstr = paddr_to_vaddr(info.boot_loader_name as usize) as *const u8; let cstr = paddr_to_vaddr(info.boot_loader_name as usize) as *const u8;
let mut len = 0; let mut len = 0;
@ -45,7 +45,7 @@ fn init_kernel_commandline(kernel_cmdline: &'static Once<KCmdlineArg>) {
let mut cmdline = ""; let mut cmdline = "";
let info = MB1_INFO.get().unwrap(); let info = MB1_INFO.get().unwrap();
if info.cmdline != 0 { if info.cmdline != 0 {
// Safety: the command line is C-style zero-terminated string. // SAFETY: the command line is C-style zero-terminated string.
unsafe { unsafe {
let cstr = paddr_to_vaddr(info.cmdline as usize) as *const u8; let cstr = paddr_to_vaddr(info.cmdline as usize) as *const u8;
let mut len = 0; let mut len = 0;

View File

@ -56,7 +56,7 @@ impl RemappingRegisters {
}; };
let vaddr: usize = paddr_to_vaddr(base_address as usize); let vaddr: usize = paddr_to_vaddr(base_address as usize);
// Safety: All offsets and sizes are strictly adhered to in the manual, and the base address is obtained from Drhd. // SAFETY: All offsets and sizes are strictly adhered to in the manual, and the base address is obtained from Drhd.
let mut remapping_reg = unsafe { let mut remapping_reg = unsafe {
fault::init(vaddr); fault::init(vaddr);
let version = Volatile::new_read_only(&*(vaddr as *const u32)); let version = Volatile::new_read_only(&*(vaddr as *const u32));

View File

@ -68,7 +68,7 @@ impl Dmar {
return None; return None;
} }
let acpi_table_lock = super::ACPI_TABLES.get().unwrap().lock(); let acpi_table_lock = super::ACPI_TABLES.get().unwrap().lock();
// Safety: The DmarHeader is the header for the DMAR structure, it fits all the field described in Intel manual. // SAFETY: The DmarHeader is the header for the DMAR structure, it fits all the field described in Intel manual.
let dmar_mapping = unsafe { let dmar_mapping = unsafe {
acpi_table_lock acpi_table_lock
.get_sdt::<DmarHeader>(Signature::DMAR) .get_sdt::<DmarHeader>(Signature::DMAR)
@ -77,7 +77,7 @@ impl Dmar {
let physical_address = dmar_mapping.physical_start(); let physical_address = dmar_mapping.physical_start();
let len = dmar_mapping.mapped_length(); let len = dmar_mapping.mapped_length();
// Safety: The target address is the start of the remapping structures, // SAFETY: The target address is the start of the remapping structures,
// and the length is valid since the value is read from the length field in SDTHeader minus the size of DMAR header. // and the length is valid since the value is read from the length field in SDTHeader minus the size of DMAR header.
let dmar_slice = unsafe { let dmar_slice = unsafe {
core::slice::from_raw_parts_mut( core::slice::from_raw_parts_mut(
@ -89,7 +89,7 @@ impl Dmar {
let mut remapping_structures = Vec::new(); let mut remapping_structures = Vec::new();
let mut index = 0; let mut index = 0;
let mut remain_length = len - size_of::<DmarHeader>(); let mut remain_length = len - size_of::<DmarHeader>();
// Safety: Indexes and offsets are strictly followed by the manual. // SAFETY: Indexes and offsets are strictly followed by the manual.
unsafe { unsafe {
while remain_length > 0 { while remain_length > 0 {
// Common header: type: u16, length: u16 // Common header: type: u16, length: u16

View File

@ -110,7 +110,7 @@ impl IoApicAccess {
} }
pub fn read(&mut self, register: u8) -> u32 { pub fn read(&mut self, register: u8) -> u32 {
// Safety: Since the base address is valid, the read/write should be safe. // SAFETY: Since the base address is valid, the read/write should be safe.
unsafe { unsafe {
self.register.write_volatile(register as u32); self.register.write_volatile(register as u32);
self.data.read_volatile() self.data.read_volatile()
@ -118,7 +118,7 @@ impl IoApicAccess {
} }
pub fn write(&mut self, register: u8, data: u32) { pub fn write(&mut self, register: u8, data: u32) {
// Safety: Since the base address is valid, the read/write should be safe. // SAFETY: Since the base address is valid, the read/write should be safe.
unsafe { unsafe {
self.register.write_volatile(register as u32); self.register.write_volatile(register as u32);
self.data.write_volatile(data); self.data.write_volatile(data);
@ -156,7 +156,7 @@ pub fn init() {
// Need to find a way to determine if it is a valid address or not. // Need to find a way to determine if it is a valid address or not.
const IO_APIC_DEFAULT_ADDRESS: usize = 0xFEC0_0000; const IO_APIC_DEFAULT_ADDRESS: usize = 0xFEC0_0000;
#[cfg(feature = "intel_tdx")] #[cfg(feature = "intel_tdx")]
// Safety: // SAFETY:
// This is safe because we are ensuring that the `IO_APIC_DEFAULT_ADDRESS` is a valid MMIO address before this operation. // This is safe because we are ensuring that the `IO_APIC_DEFAULT_ADDRESS` is a valid MMIO address before this operation.
// The `IO_APIC_DEFAULT_ADDRESS` is a well-known address used for IO APICs in x86 systems, and it is page-aligned, which is a requirement for the `unprotect_gpa_range` function. // The `IO_APIC_DEFAULT_ADDRESS` is a well-known address used for IO APICs in x86 systems, and it is page-aligned, which is a requirement for the `unprotect_gpa_range` function.
// We are also ensuring that we are only unprotecting a single page. // We are also ensuring that we are only unprotecting a single page.

View File

@ -32,7 +32,7 @@ impl X2Apic {
const EXTD_BIT_IDX: u8 = 10; const EXTD_BIT_IDX: u8 = 10;
(1 << EN_BIT_IDX) | (1 << EXTD_BIT_IDX) (1 << EN_BIT_IDX) | (1 << EXTD_BIT_IDX)
}; };
// Safety: // SAFETY:
// This is safe because we are ensuring that the operations are performed on valid MSRs. // This is safe because we are ensuring that the operations are performed on valid MSRs.
// We are using them to read and write to the `IA32_APIC_BASE` and `IA32_X2APIC_SIVR` MSRs, which are well-defined and valid MSRs in x86 systems. // We are using them to read and write to the `IA32_APIC_BASE` and `IA32_X2APIC_SIVR` MSRs, which are well-defined and valid MSRs in x86 systems.
// Therefore, we are not causing any undefined behavior or violating any of the requirements of the `rdmsr` and `wrmsr` functions. // Therefore, we are not causing any undefined behavior or violating any of the requirements of the `rdmsr` and `wrmsr` functions.

View File

@ -64,7 +64,7 @@ pub fn tlb_flush(vaddr: Vaddr) {
} }
pub fn tlb_flush_all_including_global() { pub fn tlb_flush_all_including_global() {
// Safety: updates to CR4 here only change the global-page bit, the side effect // SAFETY: updates to CR4 here only change the global-page bit, the side effect
// is only to invalidate the TLB, which doesn't affect the memory safety. // is only to invalidate the TLB, which doesn't affect the memory safety.
unsafe { unsafe {
// To invalidate all entries, including global-page // To invalidate all entries, including global-page

View File

@ -70,7 +70,7 @@ pub fn tsc_freq() -> u64 {
/// Reads the current value of the processors time-stamp counter (TSC). /// Reads the current value of the processors time-stamp counter (TSC).
pub fn read_tsc() -> u64 { pub fn read_tsc() -> u64 {
// Safety: It is safe to read a time-related counter. // SAFETY: It is safe to read a time-related counter.
unsafe { _rdtsc() } unsafe { _rdtsc() }
} }

View File

@ -23,7 +23,7 @@ pub fn exit_qemu(exit_code: QemuExitCode) -> ! {
use x86_64::instructions::port::Port; use x86_64::instructions::port::Port;
let mut port = Port::new(0xf4); let mut port = Port::new(0xf4);
// Safety: The write to the ISA debug exit port is safe and `0xf4` should // SAFETY: The write to the ISA debug exit port is safe and `0xf4` should
// be the port number. // be the port number.
unsafe { unsafe {
port.write(exit_code as u32); port.write(exit_code as u32);

View File

@ -184,7 +184,7 @@ fn handle_mmio(trapframe: &mut dyn TdxTrapFrame, ve_info: &TdgVeInfo) -> Result<
Register::CL => (trapframe.rcx() & 0xFF) as u64, Register::CL => (trapframe.rcx() & 0xFF) as u64,
_ => todo!(), _ => todo!(),
}; };
// Safety: The mmio_gpa obtained from `ve_info` is valid, and the value and size parsed from the instruction are valid. // SAFETY: The mmio_gpa obtained from `ve_info` is valid, and the value and size parsed from the instruction are valid.
unsafe { unsafe {
write_mmio(size, ve_info.guest_physical_address, value) write_mmio(size, ve_info.guest_physical_address, value)
.map_err(MmioError::TdVmcallError)? .map_err(MmioError::TdVmcallError)?
@ -192,14 +192,14 @@ fn handle_mmio(trapframe: &mut dyn TdxTrapFrame, ve_info: &TdgVeInfo) -> Result<
} }
InstrMmioType::WriteImm => { InstrMmioType::WriteImm => {
let value = instr.immediate(0); let value = instr.immediate(0);
// Safety: The mmio_gpa obtained from `ve_info` is valid, and the value and size parsed from the instruction are valid. // SAFETY: The mmio_gpa obtained from `ve_info` is valid, and the value and size parsed from the instruction are valid.
unsafe { unsafe {
write_mmio(size, ve_info.guest_physical_address, value) write_mmio(size, ve_info.guest_physical_address, value)
.map_err(MmioError::TdVmcallError)? .map_err(MmioError::TdVmcallError)?
} }
} }
InstrMmioType::Read => InstrMmioType::Read =>
// Safety: The mmio_gpa obtained from `ve_info` is valid, and the size parsed from the instruction is valid. // SAFETY: The mmio_gpa obtained from `ve_info` is valid, and the size parsed from the instruction is valid.
unsafe { unsafe {
let read_res = read_mmio(size, ve_info.guest_physical_address) let read_res = read_mmio(size, ve_info.guest_physical_address)
.map_err(MmioError::TdVmcallError)? .map_err(MmioError::TdVmcallError)?
@ -294,7 +294,7 @@ fn handle_mmio(trapframe: &mut dyn TdxTrapFrame, ve_info: &TdgVeInfo) -> Result<
} }
}, },
InstrMmioType::ReadZeroExtend => InstrMmioType::ReadZeroExtend =>
// Safety: The mmio_gpa obtained from `ve_info` is valid, and the size parsed from the instruction is valid. // SAFETY: The mmio_gpa obtained from `ve_info` is valid, and the size parsed from the instruction is valid.
unsafe { unsafe {
let read_res = read_mmio(size, ve_info.guest_physical_address) let read_res = read_mmio(size, ve_info.guest_physical_address)
.map_err(MmioError::TdVmcallError)? .map_err(MmioError::TdVmcallError)?
@ -331,7 +331,7 @@ fn decode_instr(rip: usize) -> Result<Instruction, MmioError> {
let code_data = { let code_data = {
const MAX_X86_INSTR_LEN: usize = 15; const MAX_X86_INSTR_LEN: usize = 15;
let mut data = [0u8; MAX_X86_INSTR_LEN]; let mut data = [0u8; MAX_X86_INSTR_LEN];
// Safety: // SAFETY:
// This is safe because we are ensuring that 'rip' is a valid kernel virtual address before this operation. // This is safe because we are ensuring that 'rip' is a valid kernel virtual address before this operation.
// We are also ensuring that the size of the data we are copying does not exceed 'MAX_X86_INSTR_LEN'. // We are also ensuring that the size of the data we are copying does not exceed 'MAX_X86_INSTR_LEN'.
// Therefore, we are not reading any memory that we shouldn't be, and we are not causing any undefined behavior. // Therefore, we are not reading any memory that we shouldn't be, and we are not causing any undefined behavior.

View File

@ -22,11 +22,11 @@ pub struct MmioCommonDevice {
impl MmioCommonDevice { impl MmioCommonDevice {
pub(super) fn new(paddr: Paddr, handle: IrqLine) -> Self { pub(super) fn new(paddr: Paddr, handle: IrqLine) -> Self {
// Read magic value // Read magic value
// Safety: It only read the value and judge if the magic value fit 0x74726976 // SAFETY: It only read the value and judge if the magic value fit 0x74726976
unsafe { unsafe {
debug_assert_eq!(*(paddr_to_vaddr(paddr) as *const u32), VIRTIO_MMIO_MAGIC); debug_assert_eq!(*(paddr_to_vaddr(paddr) as *const u32), VIRTIO_MMIO_MAGIC);
} }
// Safety: This range is virtio-mmio device space. // SAFETY: This range is virtio-mmio device space.
let io_mem = unsafe { IoMem::new(paddr..paddr + 0x200) }; let io_mem = unsafe { IoMem::new(paddr..paddr + 0x200) };
let res = Self { let res = Self {
io_mem, io_mem,

View File

@ -27,7 +27,7 @@ static IRQS: SpinLock<Vec<IrqLine>> = SpinLock::new(Vec::new());
pub fn init() { pub fn init() {
#[cfg(feature = "intel_tdx")] #[cfg(feature = "intel_tdx")]
// Safety: // SAFETY:
// This is safe because we are ensuring that the address range 0xFEB0_0000 to 0xFEB0_4000 is valid before this operation. // This is safe because we are ensuring that the address range 0xFEB0_0000 to 0xFEB0_4000 is valid before this operation.
// The address range is page-aligned and falls within the MMIO range, which is a requirement for the `unprotect_gpa_range` function. // The address range is page-aligned and falls within the MMIO range, which is a requirement for the `unprotect_gpa_range` function.
// We are also ensuring that we are only unprotecting four pages. // We are also ensuring that we are only unprotecting four pages.
@ -55,10 +55,10 @@ fn iter_range(range: Range<usize>) {
let mut device_count = 0; let mut device_count = 0;
while current > range.start { while current > range.start {
current -= 0x100; current -= 0x100;
// Safety: It only read the value and judge if the magic value fit 0x74726976 // SAFETY: It only read the value and judge if the magic value fit 0x74726976
let value = unsafe { *(paddr_to_vaddr(current) as *const u32) }; let value = unsafe { *(paddr_to_vaddr(current) as *const u32) };
if value == VIRTIO_MMIO_MAGIC { if value == VIRTIO_MMIO_MAGIC {
// Safety: It only read the device id // SAFETY: It only read the device id
let device_id = unsafe { *(paddr_to_vaddr(current + 8) as *const u32) }; let device_id = unsafe { *(paddr_to_vaddr(current + 8) as *const u32) };
device_count += 1; device_count += 1;
if device_id == 0 { if device_id == 0 {

View File

@ -96,7 +96,7 @@ impl CapabilityMsixData {
// Set message address 0xFEE0_0000 // Set message address 0xFEE0_0000
for i in 0..table_size { for i in 0..table_size {
#[cfg(feature = "intel_tdx")] #[cfg(feature = "intel_tdx")]
// Safety: // SAFETY:
// This is safe because we are ensuring that the physical address of the MSI-X table is valid before this operation. // This is safe because we are ensuring that the physical address of the MSI-X table is valid before this operation.
// We are also ensuring that we are only unprotecting a single page. // We are also ensuring that we are only unprotecting a single page.
// The MSI-X table will not exceed one page size, because the size of an MSI-X entry is 16 bytes, and 256 entries are required to fill a page, // The MSI-X table will not exceed one page size, because the size of an MSI-X entry is 16 bytes, and 256 entries are required to fill a page,

View File

@ -203,7 +203,7 @@ impl IoBar {
if self.size < size_of::<T>() as u32 || offset > self.size - size_of::<T>() as u32 { if self.size < size_of::<T>() as u32 || offset > self.size - size_of::<T>() as u32 {
return Err(Error::InvalidArgs); return Err(Error::InvalidArgs);
} }
// Safety: The range of ports accessed is within the scope managed by the IoBar and // SAFETY: The range of ports accessed is within the scope managed by the IoBar and
// an out-of-bounds check is performed. // an out-of-bounds check is performed.
unsafe { Ok(T::read_from_port((self.base + offset) as u16)) } unsafe { Ok(T::read_from_port((self.base + offset) as u16)) }
} }
@ -217,7 +217,7 @@ impl IoBar {
if size_of::<T>() as u32 > self.size || offset > self.size - size_of::<T>() as u32 { if size_of::<T>() as u32 > self.size || offset > self.size - size_of::<T>() as u32 {
return Err(Error::InvalidArgs); return Err(Error::InvalidArgs);
} }
// Safety: The range of ports accessed is within the scope managed by the IoBar and // SAFETY: The range of ports accessed is within the scope managed by the IoBar and
// an out-of-bounds check is performed. // an out-of-bounds check is performed.
unsafe { T::write_to_port((self.base + offset) as u16, value) } unsafe { T::write_to_port((self.base + offset) as u16, value) }
Ok(()) Ok(())

View File

@ -62,7 +62,7 @@ macro_rules! cpu_local {
/// TODO: re-implement `CpuLocal` /// TODO: re-implement `CpuLocal`
pub struct CpuLocal<T>(UnsafeCell<T>); pub struct CpuLocal<T>(UnsafeCell<T>);
// Safety. At any given time, only one task can access the inner value T of a cpu-local variable. // SAFETY: At any given time, only one task can access the inner value T of a cpu-local variable.
unsafe impl<T> Sync for CpuLocal<T> {} unsafe impl<T> Sync for CpuLocal<T> {}
impl<T> CpuLocal<T> { impl<T> CpuLocal<T> {
@ -82,7 +82,7 @@ impl<T> CpuLocal<T> {
// FIXME: implement disable preemption // FIXME: implement disable preemption
// Disable interrupts when accessing cpu-local variable // Disable interrupts when accessing cpu-local variable
let _guard = disable_local(); let _guard = disable_local();
// Safety. Now that the local IRQs are disabled, this CPU-local object can only be // SAFETY: Now that the local IRQs are disabled, this CPU-local object can only be
// accessed by the current task/thread. So it is safe to get its immutable reference // accessed by the current task/thread. So it is safe to get its immutable reference
// regardless of whether `T` implements `Sync` or not. // regardless of whether `T` implements `Sync` or not.
let val_ref = unsafe { this.do_borrow() }; let val_ref = unsafe { this.do_borrow() };

View File

@ -71,7 +71,7 @@ pub fn init() {
// TODO: We activate the kernel page table here because the new kernel page table // TODO: We activate the kernel page table here because the new kernel page table
// has mappings for MMIO which is required for the components initialization. We // has mappings for MMIO which is required for the components initialization. We
// should refactor the initialization process to avoid this. // should refactor the initialization process to avoid this.
// Safety: we are activating the unique kernel page table. // SAFETY: we are activating the unique kernel page table.
unsafe { unsafe {
vm::kspace::KERNEL_PAGE_TABLE vm::kspace::KERNEL_PAGE_TABLE
.get() .get()

View File

@ -48,7 +48,7 @@ impl AtomicBits {
assert!(index < self.num_bits); assert!(index < self.num_bits);
let i = index / 64; let i = index / 64;
let j = index % 64; let j = index % 64;
// Safety. Variable i is in range as variable index is in range. // SAFETY: Variable i is in range as variable index is in range.
let u64_atomic = unsafe { self.u64s.get_unchecked(i) }; let u64_atomic = unsafe { self.u64s.get_unchecked(i) };
(u64_atomic.load(Relaxed) & 1 << j) != 0 (u64_atomic.load(Relaxed) & 1 << j) != 0
} }
@ -58,7 +58,7 @@ impl AtomicBits {
assert!(index < self.num_bits); assert!(index < self.num_bits);
let i = index / 64; let i = index / 64;
let j = index % 64; let j = index % 64;
// Safety. Variable i is in range as variable index is in range. // SAFETY: Variable i is in range as variable index is in range.
let u64_atomic = unsafe { self.u64s.get_unchecked(i) }; let u64_atomic = unsafe { self.u64s.get_unchecked(i) };
if new_bit { if new_bit {
u64_atomic.fetch_or(1 << j, Relaxed); u64_atomic.fetch_or(1 << j, Relaxed);

View File

@ -124,7 +124,7 @@ impl<T: ?Sized + fmt::Debug> fmt::Debug for SpinLock<T> {
} }
} }
// Safety. Only a single lock holder is permitted to access the inner data of Spinlock. // SAFETY: Only a single lock holder is permitted to access the inner data of Spinlock.
unsafe impl<T: ?Sized + Send> Send for SpinLock<T> {} unsafe impl<T: ?Sized + Send> Send for SpinLock<T> {}
unsafe impl<T: ?Sized + Send> Sync for SpinLock<T> {} unsafe impl<T: ?Sized + Send> Sync for SpinLock<T> {}
@ -170,6 +170,6 @@ impl<T: ?Sized + fmt::Debug, R: Deref<Target = SpinLock<T>>> fmt::Debug for Spin
impl<T: ?Sized, R: Deref<Target = SpinLock<T>>> !Send for SpinLockGuard_<T, R> {} impl<T: ?Sized, R: Deref<Target = SpinLock<T>>> !Send for SpinLockGuard_<T, R> {}
// Safety. `SpinLockGuard_` can be shared between tasks/threads in same CPU. // SAFETY: `SpinLockGuard_` can be shared between tasks/threads in same CPU.
// As `lock()` is only called when there are no race conditions caused by interrupts. // As `lock()` is only called when there are no race conditions caused by interrupts.
unsafe impl<T: ?Sized + Sync, R: Deref<Target = SpinLock<T>> + Sync> Sync for SpinLockGuard_<T, R> {} unsafe impl<T: ?Sized + Sync, R: Deref<Target = SpinLock<T>> + Sync> Sync for SpinLockGuard_<T, R> {}

View File

@ -68,7 +68,7 @@ impl KernelStack {
let guard_page_paddr = stack_segment.start_paddr(); let guard_page_paddr = stack_segment.start_paddr();
crate::vm::paddr_to_vaddr(guard_page_paddr) crate::vm::paddr_to_vaddr(guard_page_paddr)
}; };
// Safety: the segment allocated is not used by others so we can protect it. // SAFETY: the segment allocated is not used by others so we can protect it.
unsafe { unsafe {
page_table page_table
.protect(&(guard_page_vaddr..guard_page_vaddr + PAGE_SIZE), |p| { .protect(&(guard_page_vaddr..guard_page_vaddr + PAGE_SIZE), |p| {
@ -96,7 +96,7 @@ impl Drop for KernelStack {
let guard_page_paddr = self.segment.start_paddr(); let guard_page_paddr = self.segment.start_paddr();
crate::vm::paddr_to_vaddr(guard_page_paddr) crate::vm::paddr_to_vaddr(guard_page_paddr)
}; };
// Safety: the segment allocated is not used by others so we can protect it. // SAFETY: the segment allocated is not used by others so we can protect it.
unsafe { unsafe {
page_table page_table
.protect(&(guard_page_vaddr..guard_page_vaddr + PAGE_SIZE), |p| { .protect(&(guard_page_vaddr..guard_page_vaddr + PAGE_SIZE), |p| {

View File

@ -45,7 +45,7 @@ impl IrqLine {
} }
fn new(irq_num: u8) -> Self { fn new(irq_num: u8) -> Self {
// Safety: The IRQ number is allocated through `RecycleAllocator`, and it is guaranteed that the // SAFETY: The IRQ number is allocated through `RecycleAllocator`, and it is guaranteed that the
// IRQ is not one of the important IRQ like cpu exception IRQ. // IRQ is not one of the important IRQ like cpu exception IRQ.
Self { Self {
irq_num, irq_num,

View File

@ -59,7 +59,7 @@ impl DmaCoherent {
let page_table = KERNEL_PAGE_TABLE.get().unwrap(); let page_table = KERNEL_PAGE_TABLE.get().unwrap();
let vaddr = paddr_to_vaddr(start_paddr); let vaddr = paddr_to_vaddr(start_paddr);
let va_range = vaddr..vaddr + (frame_count * PAGE_SIZE); let va_range = vaddr..vaddr + (frame_count * PAGE_SIZE);
// Safety: the physical mappings is only used by DMA so protecting it is safe. // SAFETY: the physical mappings is only used by DMA so protecting it is safe.
unsafe { unsafe {
page_table page_table
.protect(&va_range, |p| p.cache = CachePolicy::Uncacheable) .protect(&va_range, |p| p.cache = CachePolicy::Uncacheable)
@ -69,7 +69,7 @@ impl DmaCoherent {
let start_daddr = match dma_type() { let start_daddr = match dma_type() {
DmaType::Direct => { DmaType::Direct => {
#[cfg(feature = "intel_tdx")] #[cfg(feature = "intel_tdx")]
// Safety: // SAFETY:
// This is safe because we are ensuring that the physical address range specified by `start_paddr` and `frame_count` is valid before these operations. // This is safe because we are ensuring that the physical address range specified by `start_paddr` and `frame_count` is valid before these operations.
// The `check_and_insert_dma_mapping` function checks if the physical address range is already mapped. // The `check_and_insert_dma_mapping` function checks if the physical address range is already mapped.
// We are also ensuring that we are only modifying the page table entries corresponding to the physical address range specified by `start_paddr` and `frame_count`. // We are also ensuring that we are only modifying the page table entries corresponding to the physical address range specified by `start_paddr` and `frame_count`.
@ -84,7 +84,7 @@ impl DmaCoherent {
DmaType::Iommu => { DmaType::Iommu => {
for i in 0..frame_count { for i in 0..frame_count {
let paddr = start_paddr + (i * PAGE_SIZE); let paddr = start_paddr + (i * PAGE_SIZE);
// Safety: the `paddr` is restricted by the `start_paddr` and `frame_count` of the `vm_segment`. // SAFETY: the `paddr` is restricted by the `start_paddr` and `frame_count` of the `vm_segment`.
unsafe { unsafe {
iommu::map(paddr as Daddr, paddr).unwrap(); iommu::map(paddr as Daddr, paddr).unwrap();
} }
@ -124,7 +124,7 @@ impl Drop for DmaCoherentInner {
match dma_type() { match dma_type() {
DmaType::Direct => { DmaType::Direct => {
#[cfg(feature = "intel_tdx")] #[cfg(feature = "intel_tdx")]
// Safety: // SAFETY:
// This is safe because we are ensuring that the physical address range specified by `start_paddr` and `frame_count` is valid before these operations. // This is safe because we are ensuring that the physical address range specified by `start_paddr` and `frame_count` is valid before these operations.
// The `start_paddr()` ensures the `start_paddr` is page-aligned. // The `start_paddr()` ensures the `start_paddr` is page-aligned.
// We are also ensuring that we are only modifying the page table entries corresponding to the physical address range specified by `start_paddr` and `frame_count`. // We are also ensuring that we are only modifying the page table entries corresponding to the physical address range specified by `start_paddr` and `frame_count`.
@ -146,7 +146,7 @@ impl Drop for DmaCoherentInner {
let page_table = KERNEL_PAGE_TABLE.get().unwrap(); let page_table = KERNEL_PAGE_TABLE.get().unwrap();
let vaddr = paddr_to_vaddr(start_paddr); let vaddr = paddr_to_vaddr(start_paddr);
let va_range = vaddr..vaddr + (frame_count * PAGE_SIZE); let va_range = vaddr..vaddr + (frame_count * PAGE_SIZE);
// Safety: the physical mappings is only used by DMA so protecting it is safe. // SAFETY: the physical mappings is only used by DMA so protecting it is safe.
unsafe { unsafe {
page_table page_table
.protect(&va_range, |p| p.cache = CachePolicy::Writeback) .protect(&va_range, |p| p.cache = CachePolicy::Writeback)

View File

@ -64,7 +64,7 @@ impl DmaStream {
let start_daddr = match dma_type() { let start_daddr = match dma_type() {
DmaType::Direct => { DmaType::Direct => {
#[cfg(feature = "intel_tdx")] #[cfg(feature = "intel_tdx")]
// Safety: // SAFETY:
// This is safe because we are ensuring that the physical address range specified by `start_paddr` and `frame_count` is valid before these operations. // This is safe because we are ensuring that the physical address range specified by `start_paddr` and `frame_count` is valid before these operations.
// The `check_and_insert_dma_mapping` function checks if the physical address range is already mapped. // The `check_and_insert_dma_mapping` function checks if the physical address range is already mapped.
// We are also ensuring that we are only modifying the page table entries corresponding to the physical address range specified by `start_paddr` and `frame_count`. // We are also ensuring that we are only modifying the page table entries corresponding to the physical address range specified by `start_paddr` and `frame_count`.
@ -79,7 +79,7 @@ impl DmaStream {
DmaType::Iommu => { DmaType::Iommu => {
for i in 0..frame_count { for i in 0..frame_count {
let paddr = start_paddr + (i * PAGE_SIZE); let paddr = start_paddr + (i * PAGE_SIZE);
// Safety: the `paddr` is restricted by the `start_paddr` and `frame_count` of the `vm_segment`. // SAFETY: the `paddr` is restricted by the `start_paddr` and `frame_count` of the `vm_segment`.
unsafe { unsafe {
iommu::map(paddr as Daddr, paddr).unwrap(); iommu::map(paddr as Daddr, paddr).unwrap();
} }
@ -134,7 +134,7 @@ impl DmaStream {
let start_va = self.inner.vm_segment.as_ptr(); let start_va = self.inner.vm_segment.as_ptr();
// TODO: Query the CPU for the cache line size via CPUID, we use 64 bytes as the cache line size here. // TODO: Query the CPU for the cache line size via CPUID, we use 64 bytes as the cache line size here.
for i in byte_range.step_by(64) { for i in byte_range.step_by(64) {
// Safety: the addresses is limited by a valid `byte_range`. // SAFETY: the addresses is limited by a valid `byte_range`.
unsafe { unsafe {
_mm_clflush(start_va.wrapping_add(i)); _mm_clflush(start_va.wrapping_add(i));
} }
@ -158,7 +158,7 @@ impl Drop for DmaStreamInner {
match dma_type() { match dma_type() {
DmaType::Direct => { DmaType::Direct => {
#[cfg(feature = "intel_tdx")] #[cfg(feature = "intel_tdx")]
// Safety: // SAFETY:
// This is safe because we are ensuring that the physical address range specified by `start_paddr` and `frame_count` is valid before these operations. // This is safe because we are ensuring that the physical address range specified by `start_paddr` and `frame_count` is valid before these operations.
// The `start_paddr()` ensures the `start_paddr` is page-aligned. // The `start_paddr()` ensures the `start_paddr` is page-aligned.
// We are also ensuring that we are only modifying the page table entries corresponding to the physical address range specified by `start_paddr` and `frame_count`. // We are also ensuring that we are only modifying the page table entries corresponding to the physical address range specified by `start_paddr` and `frame_count`.

View File

@ -247,7 +247,7 @@ impl VmFrame {
return; return;
} }
// Safety: src and dst is not overlapped. // SAFETY: src and dst is not overlapped.
unsafe { unsafe {
crate::arch::mm::fast_copy_nonoverlapping(src.as_ptr(), self.as_mut_ptr(), PAGE_SIZE); crate::arch::mm::fast_copy_nonoverlapping(src.as_ptr(), self.as_mut_ptr(), PAGE_SIZE);
} }
@ -257,13 +257,13 @@ impl VmFrame {
impl<'a> VmFrame { impl<'a> VmFrame {
/// Returns a reader to read data from it. /// Returns a reader to read data from it.
pub fn reader(&'a self) -> VmReader<'a> { pub fn reader(&'a self) -> VmReader<'a> {
// Safety: the memory of the page is contiguous and is valid during `'a`. // SAFETY: the memory of the page is contiguous and is valid during `'a`.
unsafe { VmReader::from_raw_parts(self.as_ptr(), PAGE_SIZE) } unsafe { VmReader::from_raw_parts(self.as_ptr(), PAGE_SIZE) }
} }
/// Returns a writer to write data into it. /// Returns a writer to write data into it.
pub fn writer(&'a self) -> VmWriter<'a> { pub fn writer(&'a self) -> VmWriter<'a> {
// Safety: the memory of the page is contiguous and is valid during `'a`. // SAFETY: the memory of the page is contiguous and is valid during `'a`.
unsafe { VmWriter::from_raw_parts_mut(self.as_mut_ptr(), PAGE_SIZE) } unsafe { VmWriter::from_raw_parts_mut(self.as_mut_ptr(), PAGE_SIZE) }
} }
} }
@ -295,7 +295,7 @@ impl VmIo for VmFrame {
impl Drop for VmFrame { impl Drop for VmFrame {
fn drop(&mut self) { fn drop(&mut self) {
if self.need_dealloc() && Arc::strong_count(&self.frame_index) == 1 { if self.need_dealloc() && Arc::strong_count(&self.frame_index) == 1 {
// Safety: the frame index is valid. // SAFETY: the frame index is valid.
unsafe { unsafe {
frame_allocator::dealloc_single(self.frame_index()); frame_allocator::dealloc_single(self.frame_index());
} }
@ -433,13 +433,13 @@ impl VmSegment {
impl<'a> VmSegment { impl<'a> VmSegment {
/// Returns a reader to read data from it. /// Returns a reader to read data from it.
pub fn reader(&'a self) -> VmReader<'a> { pub fn reader(&'a self) -> VmReader<'a> {
// Safety: the memory of the page frames is contiguous and is valid during `'a`. // SAFETY: the memory of the page frames is contiguous and is valid during `'a`.
unsafe { VmReader::from_raw_parts(self.as_ptr(), self.nbytes()) } unsafe { VmReader::from_raw_parts(self.as_ptr(), self.nbytes()) }
} }
/// Returns a writer to write data into it. /// Returns a writer to write data into it.
pub fn writer(&'a self) -> VmWriter<'a> { pub fn writer(&'a self) -> VmWriter<'a> {
// Safety: the memory of the page frames is contiguous and is valid during `'a`. // SAFETY: the memory of the page frames is contiguous and is valid during `'a`.
unsafe { VmWriter::from_raw_parts_mut(self.as_mut_ptr(), self.nbytes()) } unsafe { VmWriter::from_raw_parts_mut(self.as_mut_ptr(), self.nbytes()) }
} }
} }
@ -471,7 +471,7 @@ impl VmIo for VmSegment {
impl Drop for VmSegment { impl Drop for VmSegment {
fn drop(&mut self) { fn drop(&mut self) {
if self.need_dealloc() && Arc::strong_count(&self.inner.start_frame_index) == 1 { if self.need_dealloc() && Arc::strong_count(&self.inner.start_frame_index) == 1 {
// Safety: the range of contiguous page frames is valid. // SAFETY: the range of contiguous page frames is valid.
unsafe { unsafe {
frame_allocator::dealloc_contiguous( frame_allocator::dealloc_contiguous(
self.inner.start_frame_index(), self.inner.start_frame_index(),
@ -533,7 +533,7 @@ impl<'a> VmReader<'a> {
/// Returns the number of bytes for the remaining data. /// Returns the number of bytes for the remaining data.
pub const fn remain(&self) -> usize { pub const fn remain(&self) -> usize {
// Safety: the end is equal to or greater than the cursor. // SAFETY: the end is equal to or greater than the cursor.
unsafe { self.end.sub_ptr(self.cursor) } unsafe { self.end.sub_ptr(self.cursor) }
} }
@ -552,7 +552,7 @@ impl<'a> VmReader<'a> {
/// This method ensures the postcondition of `self.remain() <= max_remain`. /// This method ensures the postcondition of `self.remain() <= max_remain`.
pub const fn limit(mut self, max_remain: usize) -> Self { pub const fn limit(mut self, max_remain: usize) -> Self {
if max_remain < self.remain() { if max_remain < self.remain() {
// Safety: the new end is less than the old end. // SAFETY: the new end is less than the old end.
unsafe { self.end = self.cursor.add(max_remain) }; unsafe { self.end = self.cursor.add(max_remain) };
} }
self self
@ -567,7 +567,7 @@ impl<'a> VmReader<'a> {
pub fn skip(mut self, nbytes: usize) -> Self { pub fn skip(mut self, nbytes: usize) -> Self {
assert!(nbytes <= self.remain()); assert!(nbytes <= self.remain());
// Safety: the new cursor is less than or equal to the end. // SAFETY: the new cursor is less than or equal to the end.
unsafe { self.cursor = self.cursor.add(nbytes) }; unsafe { self.cursor = self.cursor.add(nbytes) };
self self
} }
@ -586,7 +586,7 @@ impl<'a> VmReader<'a> {
return 0; return 0;
} }
// Safety: the memory range is valid since `copy_len` is the minimum // SAFETY: the memory range is valid since `copy_len` is the minimum
// of the reader's remaining data and the writer's available space. // of the reader's remaining data and the writer's available space.
unsafe { unsafe {
crate::arch::mm::fast_copy(self.cursor, writer.cursor, copy_len); crate::arch::mm::fast_copy(self.cursor, writer.cursor, copy_len);
@ -614,7 +614,7 @@ impl<'a> VmReader<'a> {
impl<'a> From<&'a [u8]> for VmReader<'a> { impl<'a> From<&'a [u8]> for VmReader<'a> {
fn from(slice: &'a [u8]) -> Self { fn from(slice: &'a [u8]) -> Self {
// Safety: the range of memory is contiguous and is valid during `'a`. // SAFETY: the range of memory is contiguous and is valid during `'a`.
unsafe { Self::from_raw_parts(slice.as_ptr(), slice.len()) } unsafe { Self::from_raw_parts(slice.as_ptr(), slice.len()) }
} }
} }
@ -658,7 +658,7 @@ impl<'a> VmWriter<'a> {
/// Returns the number of bytes for the available space. /// Returns the number of bytes for the available space.
pub const fn avail(&self) -> usize { pub const fn avail(&self) -> usize {
// Safety: the end is equal to or greater than the cursor. // SAFETY: the end is equal to or greater than the cursor.
unsafe { self.end.sub_ptr(self.cursor) } unsafe { self.end.sub_ptr(self.cursor) }
} }
@ -677,7 +677,7 @@ impl<'a> VmWriter<'a> {
/// This method ensures the postcondition of `self.avail() <= max_avail`. /// This method ensures the postcondition of `self.avail() <= max_avail`.
pub const fn limit(mut self, max_avail: usize) -> Self { pub const fn limit(mut self, max_avail: usize) -> Self {
if max_avail < self.avail() { if max_avail < self.avail() {
// Safety: the new end is less than the old end. // SAFETY: the new end is less than the old end.
unsafe { self.end = self.cursor.add(max_avail) }; unsafe { self.end = self.cursor.add(max_avail) };
} }
self self
@ -692,7 +692,7 @@ impl<'a> VmWriter<'a> {
pub fn skip(mut self, nbytes: usize) -> Self { pub fn skip(mut self, nbytes: usize) -> Self {
assert!(nbytes <= self.avail()); assert!(nbytes <= self.avail());
// Safety: the new cursor is less than or equal to the end. // SAFETY: the new cursor is less than or equal to the end.
unsafe { self.cursor = self.cursor.add(nbytes) }; unsafe { self.cursor = self.cursor.add(nbytes) };
self self
} }
@ -711,7 +711,7 @@ impl<'a> VmWriter<'a> {
return 0; return 0;
} }
// Safety: the memory range is valid since `copy_len` is the minimum // SAFETY: the memory range is valid since `copy_len` is the minimum
// of the reader's remaining data and the writer's available space. // of the reader's remaining data and the writer's available space.
unsafe { unsafe {
crate::arch::mm::fast_copy(reader.cursor, self.cursor, copy_len); crate::arch::mm::fast_copy(reader.cursor, self.cursor, copy_len);
@ -738,7 +738,7 @@ impl<'a> VmWriter<'a> {
let written_num = avail / core::mem::size_of::<T>(); let written_num = avail / core::mem::size_of::<T>();
for i in 0..written_num { for i in 0..written_num {
// Safety: `written_num` is calculated by the avail size and the size of the type `T`, // SAFETY: `written_num` is calculated by the avail size and the size of the type `T`,
// hence the `add` operation and `write` operation are valid and will only manipulate // hence the `add` operation and `write` operation are valid and will only manipulate
// the memory managed by this writer. // the memory managed by this writer.
unsafe { unsafe {
@ -754,7 +754,7 @@ impl<'a> VmWriter<'a> {
impl<'a> From<&'a mut [u8]> for VmWriter<'a> { impl<'a> From<&'a mut [u8]> for VmWriter<'a> {
fn from(slice: &'a mut [u8]) -> Self { fn from(slice: &'a mut [u8]) -> Self {
// Safety: the range of memory is contiguous and is valid during `'a`. // SAFETY: the range of memory is contiguous and is valid during `'a`.
unsafe { Self::from_raw_parts_mut(slice.as_mut_ptr(), slice.len()) } unsafe { Self::from_raw_parts_mut(slice.as_mut_ptr(), slice.len()) }
} }
} }

View File

@ -24,7 +24,7 @@ pub(crate) fn alloc(nframes: usize, flags: VmFrameFlags) -> Option<VmFrameVec> {
.alloc(nframes) .alloc(nframes)
.map(|start| { .map(|start| {
let mut vector = Vec::new(); let mut vector = Vec::new();
// Safety: The frame index is valid. // SAFETY: The frame index is valid.
unsafe { unsafe {
for i in 0..nframes { for i in 0..nframes {
let frame = VmFrame::new( let frame = VmFrame::new(
@ -40,7 +40,7 @@ pub(crate) fn alloc(nframes: usize, flags: VmFrameFlags) -> Option<VmFrameVec> {
pub(crate) fn alloc_single(flags: VmFrameFlags) -> Option<VmFrame> { pub(crate) fn alloc_single(flags: VmFrameFlags) -> Option<VmFrame> {
FRAME_ALLOCATOR.get().unwrap().lock().alloc(1).map(|idx| FRAME_ALLOCATOR.get().unwrap().lock().alloc(1).map(|idx|
// Safety: The frame index is valid. // SAFETY: The frame index is valid.
unsafe { VmFrame::new(idx * PAGE_SIZE, flags.union(VmFrameFlags::NEED_DEALLOC)) }) unsafe { VmFrame::new(idx * PAGE_SIZE, flags.union(VmFrameFlags::NEED_DEALLOC)) })
} }
@ -51,7 +51,7 @@ pub(crate) fn alloc_contiguous(nframes: usize, flags: VmFrameFlags) -> Option<Vm
.lock() .lock()
.alloc(nframes) .alloc(nframes)
.map(|start| .map(|start|
// Safety: The range of page frames is contiguous and valid. // SAFETY: The range of page frames is contiguous and valid.
unsafe { unsafe {
VmSegment::new( VmSegment::new(
start * PAGE_SIZE, start * PAGE_SIZE,

View File

@ -31,7 +31,7 @@ const INIT_KERNEL_HEAP_SIZE: usize = PAGE_SIZE * 256;
static mut HEAP_SPACE: [u8; INIT_KERNEL_HEAP_SIZE] = [0; INIT_KERNEL_HEAP_SIZE]; static mut HEAP_SPACE: [u8; INIT_KERNEL_HEAP_SIZE] = [0; INIT_KERNEL_HEAP_SIZE];
pub fn init() { pub fn init() {
// Safety: The HEAP_SPACE is a static memory range, so it's always valid. // SAFETY: The HEAP_SPACE is a static memory range, so it's always valid.
unsafe { unsafe {
HEAP_ALLOCATOR.init(HEAP_SPACE.as_ptr(), INIT_KERNEL_HEAP_SIZE); HEAP_ALLOCATOR.init(HEAP_SPACE.as_ptr(), INIT_KERNEL_HEAP_SIZE);
} }
@ -51,12 +51,12 @@ impl<const ORDER: usize> LockedHeapWithRescue<ORDER> {
} }
} }
/// Safety: The range [start, start + size) must be a valid memory region. /// SAFETY: The range [start, start + size) must be a valid memory region.
pub unsafe fn init(&self, start: *const u8, size: usize) { pub unsafe fn init(&self, start: *const u8, size: usize) {
self.heap.lock_irq_disabled().init(start as usize, size); self.heap.lock_irq_disabled().init(start as usize, size);
} }
/// Safety: The range [start, start + size) must be a valid memory region. /// SAFETY: The range [start, start + size) must be a valid memory region.
unsafe fn add_to_heap(&self, start: usize, size: usize) { unsafe fn add_to_heap(&self, start: usize, size: usize) {
self.heap self.heap
.lock_irq_disabled() .lock_irq_disabled()
@ -122,7 +122,7 @@ fn rescue<const ORDER: usize>(heap: &LockedHeapWithRescue<ORDER>, layout: &Layou
// So if the heap is nearly run out, allocating frame will fail too. // So if the heap is nearly run out, allocating frame will fail too.
let vaddr = paddr_to_vaddr(allocation_start * PAGE_SIZE); let vaddr = paddr_to_vaddr(allocation_start * PAGE_SIZE);
// Safety: the frame is allocated from FramAllocator and never be deallocated, // SAFETY: the frame is allocated from FramAllocator and never be deallocated,
// so the addr is always valid. // so the addr is always valid.
unsafe { unsafe {
debug!( debug!(

View File

@ -91,7 +91,7 @@ pub fn init_kernel_page_table() {
cache: CachePolicy::Writeback, cache: CachePolicy::Writeback,
priv_flags: PrivilegedPageFlags::GLOBAL, priv_flags: PrivilegedPageFlags::GLOBAL,
}; };
// Safety: we are doing the linear mapping for the kernel. // SAFETY: we are doing the linear mapping for the kernel.
unsafe { unsafe {
kpt.map(&from, &to, prop).unwrap(); kpt.map(&from, &to, prop).unwrap();
} }
@ -108,7 +108,7 @@ pub fn init_kernel_page_table() {
cache: CachePolicy::Uncacheable, cache: CachePolicy::Uncacheable,
priv_flags: PrivilegedPageFlags::GLOBAL, priv_flags: PrivilegedPageFlags::GLOBAL,
}; };
// Safety: we are doing I/O mappings for the kernel. // SAFETY: we are doing I/O mappings for the kernel.
unsafe { unsafe {
kpt.map(&from, &to, prop).unwrap(); kpt.map(&from, &to, prop).unwrap();
} }
@ -130,7 +130,7 @@ pub fn init_kernel_page_table() {
cache: CachePolicy::Writeback, cache: CachePolicy::Writeback,
priv_flags: PrivilegedPageFlags::GLOBAL, priv_flags: PrivilegedPageFlags::GLOBAL,
}; };
// Safety: we are doing mappings for the kernel. // SAFETY: we are doing mappings for the kernel.
unsafe { unsafe {
kpt.map(&from, &to, prop).unwrap(); kpt.map(&from, &to, prop).unwrap();
} }

View File

@ -15,7 +15,7 @@
#[macro_export] #[macro_export]
macro_rules! offset_of { macro_rules! offset_of {
($container:ty, $($field:tt)+) => ({ ($container:ty, $($field:tt)+) => ({
// SAFETY. It is ok to have this uninitialized value because // SAFETY: It is ok to have this uninitialized value because
// 1) Its memory won't be acccessed; // 1) Its memory won't be acccessed;
// 2) It will be forgotten rather than being dropped; // 2) It will be forgotten rather than being dropped;
// 3) Before it gets forgotten, the code won't return prematurely or panic. // 3) Before it gets forgotten, the code won't return prematurely or panic.

View File

@ -158,7 +158,7 @@ where
huge: bool, huge: bool,
) { ) {
assert!(idx < nr_ptes_per_node::<C>()); assert!(idx < nr_ptes_per_node::<C>());
// Safety: the index is within the bound and the PTE to be written is valid. // SAFETY: the index is within the bound and the PTE to be written is valid.
// And the physical address of PTE points to initialized memory. // And the physical address of PTE points to initialized memory.
// This applies to all the following `write_pte` invocations. // This applies to all the following `write_pte` invocations.
unsafe { unsafe {
@ -196,7 +196,7 @@ where
pub(super) fn protect(&mut self, idx: usize, prop: PageProperty, level: usize) { pub(super) fn protect(&mut self, idx: usize, prop: PageProperty, level: usize) {
debug_assert!(self.children[idx].is_some()); debug_assert!(self.children[idx].is_some());
let paddr = self.children[idx].paddr().unwrap(); let paddr = self.children[idx].paddr().unwrap();
// Safety: the index is within the bound and the PTE is valid. // SAFETY: the index is within the bound and the PTE is valid.
unsafe { unsafe {
self.write_pte( self.write_pte(
idx, idx,
@ -207,7 +207,7 @@ where
fn read_pte(&self, idx: usize) -> E { fn read_pte(&self, idx: usize) -> E {
assert!(idx < nr_ptes_per_node::<C>()); assert!(idx < nr_ptes_per_node::<C>());
// Safety: the index is within the bound and PTE is plain-old-data. // SAFETY: the index is within the bound and PTE is plain-old-data.
unsafe { (self.inner.as_ptr() as *const E).add(idx).read() } unsafe { (self.inner.as_ptr() as *const E).add(idx).read() }
} }

View File

@ -105,7 +105,7 @@ where
[(); C::NR_LEVELS]:, [(); C::NR_LEVELS]:,
{ {
pub(crate) fn activate(&self) { pub(crate) fn activate(&self) {
// Safety: The usermode page table is safe to activate since the kernel // SAFETY: The usermode page table is safe to activate since the kernel
// mappings are shared. // mappings are shared.
unsafe { unsafe {
self.activate_unchecked(); self.activate_unchecked();
@ -118,7 +118,7 @@ where
/// TODO: We may consider making the page table itself copy-on-write. /// TODO: We may consider making the page table itself copy-on-write.
pub(crate) fn fork_copy_on_write(&self) -> Self { pub(crate) fn fork_copy_on_write(&self) -> Self {
let mut cursor = self.cursor_mut(&UserMode::VADDR_RANGE).unwrap(); let mut cursor = self.cursor_mut(&UserMode::VADDR_RANGE).unwrap();
// Safety: Protecting the user page table is safe. // SAFETY: Protecting the user page table is safe.
unsafe { unsafe {
cursor cursor
.protect( .protect(
@ -276,7 +276,7 @@ where
/// cursors concurrently accessing the same virtual address range, just like what /// cursors concurrently accessing the same virtual address range, just like what
/// happens for the hardware MMU walk. /// happens for the hardware MMU walk.
pub(crate) fn query(&self, vaddr: Vaddr) -> Option<(Paddr, PageProperty)> { pub(crate) fn query(&self, vaddr: Vaddr) -> Option<(Paddr, PageProperty)> {
// Safety: The root frame is a valid page table frame so the address is valid. // SAFETY: The root frame is a valid page table frame so the address is valid.
unsafe { page_walk::<E, C>(self.root_paddr(), vaddr) } unsafe { page_walk::<E, C>(self.root_paddr(), vaddr) }
} }
@ -361,7 +361,7 @@ pub(super) unsafe fn page_walk<E: PageTableEntryTrait, C: PagingConstsTrait>(
let mut cur_pte = { let mut cur_pte = {
let frame_addr = paddr_to_vaddr(root_paddr); let frame_addr = paddr_to_vaddr(root_paddr);
let offset = pte_index::<C>(vaddr, cur_level); let offset = pte_index::<C>(vaddr, cur_level);
// Safety: The offset does not exceed the value of PAGE_SIZE. // SAFETY: The offset does not exceed the value of PAGE_SIZE.
unsafe { (frame_addr as *const E).add(offset).read() } unsafe { (frame_addr as *const E).add(offset).read() }
}; };
@ -377,7 +377,7 @@ pub(super) unsafe fn page_walk<E: PageTableEntryTrait, C: PagingConstsTrait>(
cur_pte = { cur_pte = {
let frame_addr = paddr_to_vaddr(cur_pte.paddr()); let frame_addr = paddr_to_vaddr(cur_pte.paddr());
let offset = pte_index::<C>(vaddr, cur_level); let offset = pte_index::<C>(vaddr, cur_level);
// Safety: The offset does not exceed the value of PAGE_SIZE. // SAFETY: The offset does not exceed the value of PAGE_SIZE.
unsafe { (frame_addr as *const E).add(offset).read() } unsafe { (frame_addr as *const E).add(offset).read() }
}; };
} }

View File

@ -93,7 +93,7 @@ impl VmSpace {
}; };
for frame in frames.into_iter() { for frame in frames.into_iter() {
// Safety: mapping in the user space with `VmFrame` is safe. // SAFETY: mapping in the user space with `VmFrame` is safe.
unsafe { unsafe {
cursor.map(frame, prop); cursor.map(frame, prop);
} }
@ -132,7 +132,7 @@ impl VmSpace {
if !UserMode::covers(range) { if !UserMode::covers(range) {
return Err(Error::InvalidArgs); return Err(Error::InvalidArgs);
} }
// Safety: unmapping in the user space is safe. // SAFETY: unmapping in the user space is safe.
unsafe { unsafe {
self.pt.unmap(range)?; self.pt.unmap(range)?;
} }
@ -141,7 +141,7 @@ impl VmSpace {
/// clear all mappings /// clear all mappings
pub fn clear(&self) { pub fn clear(&self) {
// Safety: unmapping user space is safe, and we don't care unmapping // SAFETY: unmapping user space is safe, and we don't care unmapping
// invalid ranges. // invalid ranges.
unsafe { unsafe {
self.pt.unmap(&(0..MAX_USERSPACE_VADDR)).unwrap(); self.pt.unmap(&(0..MAX_USERSPACE_VADDR)).unwrap();
@ -169,7 +169,7 @@ impl VmSpace {
if !UserMode::covers(range) { if !UserMode::covers(range) {
return Err(Error::InvalidArgs); return Err(Error::InvalidArgs);
} }
// Safety: protecting in the user space is safe. // SAFETY: protecting in the user space is safe.
unsafe { unsafe {
self.pt.protect(range, op)?; self.pt.protect(range, op)?;
} }

View File

@ -200,7 +200,7 @@ macro_rules! ktest_array {
} }
let item_size = core::mem::size_of::<KtestItem>(); let item_size = core::mem::size_of::<KtestItem>();
let l = (__ktest_array_end as usize - __ktest_array as usize) / item_size; let l = (__ktest_array_end as usize - __ktest_array as usize) / item_size;
// Safety: __ktest_array is a static section consisting of KtestItem. // SAFETY: __ktest_array is a static section consisting of KtestItem.
unsafe { core::slice::from_raw_parts(__ktest_array as *const KtestItem, l) } unsafe { core::slice::from_raw_parts(__ktest_array as *const KtestItem, l) }
}}; }};
} }

View File

@ -12,13 +12,13 @@ static mut STDOUT: Stdout = Stdout {
serial_port: unsafe { SerialPort::new(0x0) }, serial_port: unsafe { SerialPort::new(0x0) },
}; };
/// safety: this function must only be called once /// SAFETY: this function must only be called once
pub unsafe fn init() { pub unsafe fn init() {
STDOUT = Stdout::init(); STDOUT = Stdout::init();
} }
impl Stdout { impl Stdout {
/// safety: this function must only be called once /// SAFETY: this function must only be called once
pub unsafe fn init() -> Self { pub unsafe fn init() -> Self {
let mut serial_port = unsafe { SerialPort::new(0x3F8) }; let mut serial_port = unsafe { SerialPort::new(0x3F8) };
serial_port.init(); serial_port.init();
@ -35,7 +35,7 @@ impl Write for Stdout {
/// This is used when dyn Trait is not supported or fmt::Arguments is fragile to use in PIE. /// This is used when dyn Trait is not supported or fmt::Arguments is fragile to use in PIE.
/// ///
/// Safety: init() must be called before print_str() and there should be no race conditions. /// SAFETY: init() must be called before print_str() and there should be no race conditions.
pub unsafe fn print_str(s: &str) { pub unsafe fn print_str(s: &str) {
STDOUT.write_str(s).unwrap(); STDOUT.write_str(s).unwrap();
} }
@ -46,7 +46,7 @@ unsafe fn print_char(c: char) {
/// This is used when dyn Trait is not supported or fmt::Arguments is fragile to use in PIE. /// This is used when dyn Trait is not supported or fmt::Arguments is fragile to use in PIE.
/// ///
/// Safety: init() must be called before print_hex() and there should be no race conditions. /// SAFETY: init() must be called before print_hex() and there should be no race conditions.
pub unsafe fn print_hex(n: u64) { pub unsafe fn print_hex(n: u64) {
print_str("0x"); print_str("0x");
for i in (0..16).rev() { for i in (0..16).rev() {
@ -65,7 +65,7 @@ pub unsafe fn print_hex(n: u64) {
/// Glue code for print!() and println!() macros. /// Glue code for print!() and println!() macros.
/// ///
/// Safety: init() must be called before print_fmt() and there should be no race conditions. /// SAFETY: init() must be called before print_fmt() and there should be no race conditions.
pub unsafe fn print_fmt(args: fmt::Arguments) { pub unsafe fn print_fmt(args: fmt::Arguments) {
STDOUT.write_fmt(args).unwrap(); STDOUT.write_fmt(args).unwrap();
} }

View File

@ -22,7 +22,7 @@ fn load_segment(file: &xmas_elf::ElfFile, program: &xmas_elf::program::ProgramHe
let SegmentData::Undefined(header_data) = program.get_data(file).unwrap() else { let SegmentData::Undefined(header_data) = program.get_data(file).unwrap() else {
panic!("[setup] Unexpected segment data type!"); panic!("[setup] Unexpected segment data type!");
}; };
// Safety: the physical address from the ELF file is valid // SAFETY: the physical address from the ELF file is valid
let dst_slice = unsafe { let dst_slice = unsafe {
core::slice::from_raw_parts_mut(program.physical_addr as *mut u8, program.mem_size as usize) core::slice::from_raw_parts_mut(program.physical_addr as *mut u8, program.mem_size as usize)
}; };
@ -40,7 +40,7 @@ fn load_segment(file: &xmas_elf::ElfFile, program: &xmas_elf::program::ProgramHe
print_hex(program.mem_size as u64); print_hex(program.mem_size as u64);
print_str("\n"); print_str("\n");
} }
// Safety: the ELF file is valid // SAFETY: the ELF file is valid
// dst_slice[..program.file_size as usize].copy_from_slice(header_data); // dst_slice[..program.file_size as usize].copy_from_slice(header_data);
unsafe { unsafe {
memcpy( memcpy(

View File

@ -38,7 +38,7 @@ fn get_payload(boot_params: &BootParams) -> &'static [u8] {
let loaded_offset = x86::get_image_loaded_offset(); let loaded_offset = x86::get_image_loaded_offset();
let payload_offset = (loaded_offset + hdr.payload_offset as isize) as usize; let payload_offset = (loaded_offset + hdr.payload_offset as isize) as usize;
let payload_length = hdr.payload_length as usize; let payload_length = hdr.payload_length as usize;
// Safety: the payload_offset and payload_length is valid if we assume that the // SAFETY: the payload_offset and payload_length is valid if we assume that the
// boot_params struct is correct. // boot_params struct is correct.
unsafe { core::slice::from_raw_parts_mut(payload_offset as *mut u8, payload_length) } unsafe { core::slice::from_raw_parts_mut(payload_offset as *mut u8, payload_length) }
} }

View File

@ -47,10 +47,10 @@ fn efi_phase_boot(
system_table: SystemTable<Boot>, system_table: SystemTable<Boot>,
boot_params_ptr: *mut BootParams, boot_params_ptr: *mut BootParams,
) -> ! { ) -> ! {
// Safety: this init function is only called once. // SAFETY: this init function is only called once.
unsafe { crate::console::init() }; unsafe { crate::console::init() };
// Safety: this is the right time to apply relocations. // SAFETY: this is the right time to apply relocations.
unsafe { apply_rela_dyn_relocations() }; unsafe { apply_rela_dyn_relocations() };
uefi_services::println!("[EFI stub] Relocations applied."); uefi_services::println!("[EFI stub] Relocations applied.");

View File

@ -43,7 +43,7 @@ fn get_rela_array() -> &'static [Elf64Rela] {
print_hex(end as u64); print_hex(end as u64);
print_str("\n"); print_str("\n");
} }
// Safety: the linker will ensure that the symbols are valid. // SAFETY: the linker will ensure that the symbols are valid.
unsafe { core::slice::from_raw_parts(start, len) } unsafe { core::slice::from_raw_parts(start, len) }
} }

View File

@ -14,7 +14,7 @@ pub const ASTER_ENTRY_POINT: u32 = 0x8001000;
#[export_name = "_bzimage_entry_32"] #[export_name = "_bzimage_entry_32"]
extern "cdecl" fn bzimage_entry(boot_params_ptr: u32) -> ! { extern "cdecl" fn bzimage_entry(boot_params_ptr: u32) -> ! {
// Safety: this init function is only called once. // SAFETY: this init function is only called once.
unsafe { crate::console::init() }; unsafe { crate::console::init() };
// println!("[setup] bzImage loaded at {:#x}", x86::relocation::get_image_loaded_offset()); // println!("[setup] bzImage loaded at {:#x}", x86::relocation::get_image_loaded_offset());
@ -24,13 +24,13 @@ extern "cdecl" fn bzimage_entry(boot_params_ptr: u32) -> ! {
print_str("\n"); print_str("\n");
} }
// Safety: the boot_params_ptr is a valid pointer to be borrowed. // SAFETY: the boot_params_ptr is a valid pointer to be borrowed.
let boot_params = unsafe { &*(boot_params_ptr as *const BootParams) }; let boot_params = unsafe { &*(boot_params_ptr as *const BootParams) };
// Safety: the payload_offset and payload_length is valid. // SAFETY: the payload_offset and payload_length is valid.
let payload = crate::get_payload(boot_params); let payload = crate::get_payload(boot_params);
crate::loader::load_elf(payload); crate::loader::load_elf(payload);
// Safety: the entrypoint and the ptr is valid. // SAFETY: the entrypoint and the ptr is valid.
unsafe { call_aster_entrypoint(ASTER_ENTRY_POINT, boot_params_ptr.try_into().unwrap()) }; unsafe { call_aster_entrypoint(ASTER_ENTRY_POINT, boot_params_ptr.try_into().unwrap()) };
} }