diff --git a/src/aarch64/reg.rs b/src/aarch64/reg.rs index e131cf0..6042f42 100644 --- a/src/aarch64/reg.rs +++ b/src/aarch64/reg.rs @@ -360,10 +360,13 @@ pub(crate) fn is_this_page_table_active(page_table_base: PhysicalAddress) -> boo /// 1. Ensure that the compiler does not optimize out the zeroing /// 2. Ensure that the zeroing is done as quickly as possible as without this, the zero takes a long time on /// non-optimized builds +/// 3. This function must not be inlined to ensure that the register reads and writes don't affect the caller's +/// registers. /// /// # Safety /// This function is unsafe because it operates on raw pointers. It requires the caller to ensure the VA passed in /// is mapped. +#[inline(never)] pub(crate) unsafe fn zero_page(page: u64) { // If the MMU is diabled, invalidate the cache so that any stale data does // not get later evicted to memory. diff --git a/src/x64.rs b/src/x64.rs index 6ba7cd7..67c126b 100644 --- a/src/x64.rs +++ b/src/x64.rs @@ -89,6 +89,10 @@ impl PageTableHal for PageTableArchX64 { type PTE = X64PageTableEntry; const DEFAULT_ATTRIBUTES: MemoryAttributes = MemoryAttributes::empty(); + // This function must not be inlined to ensure that the register reads and writes don't affect the + // caller's registers. It has been viewed that this function is inlined several layers up the stack and has + // corrupted the rdi register, causing a crash. + #[inline(never)] unsafe fn zero_page(base: VirtualAddress) { let _page: u64 = base.into(); #[cfg(all(not(test), target_arch = "x86_64"))] @@ -99,7 +103,7 @@ impl PageTableHal for PageTableArchX64 { in("rcx") 0x200, // we write 512 qwords (4096 bytes) in("rdi") _page, // start at the page in("rax") 0, // store 0 - options(nostack, preserves_flags) + options(nostack) ); } }