diff --git a/src/hyperlight_guest_bin/src/arch/aarch64/paging.rs b/src/hyperlight_guest_bin/src/arch/aarch64/paging.rs index c05d7843d..69f6f3cf4 100644 --- a/src/hyperlight_guest_bin/src/arch/aarch64/paging.rs +++ b/src/hyperlight_guest_bin/src/arch/aarch64/paging.rs @@ -138,6 +138,8 @@ pub fn phys_to_virt(gpa: vmem::PhysAddr) -> Option<*mut u8> { } pub mod barrier { + use hyperlight_common::vmem; + /// # Architecture-specific (aarch64) notes /// /// I_WZCBG from [1]: @@ -171,4 +173,16 @@ pub mod barrier { ); } } + + #[inline(always)] + pub fn downgrade_in_place(var: core::ops::Range) { + unsafe { + core::arch::asm!("dsb ish"); + // todo: use TLBI RVAE1IS if FEAT_TLBIRANGE is available + for va in var.step_by(vmem::PAGE_SIZE) { + core::arch::asm!("tlbi vae1is, {}", in(reg) va >> 12); + } + core::arch::asm!("dsb ish\nisb"); + } + } } diff --git a/src/hyperlight_guest_bin/src/arch/amd64/paging.rs b/src/hyperlight_guest_bin/src/arch/amd64/paging.rs index c0eb5a113..19b9796f2 100644 --- a/src/hyperlight_guest_bin/src/arch/amd64/paging.rs +++ b/src/hyperlight_guest_bin/src/arch/amd64/paging.rs @@ -153,6 +153,8 @@ pub fn phys_to_virt(gpa: vmem::PhysAddr) -> Option<*mut u8> { /// Barriers that other code may need to use when updating page tables pub mod barrier { + use hyperlight_common::vmem; + /// Call this function when a virtual address has just been made /// valid for the first time after the last tlb invalidate that /// affected it, and it will be used for the first time in the @@ -204,4 +206,13 @@ pub mod barrier { ", out("rax") _); } } + + pub fn downgrade_in_place(var: core::ops::Range) { + unsafe { + // todo: use TLBI RVAE1IS if FEAT_TLBIRANGE is available + for va in var.step_by(vmem::PAGE_SIZE) { + core::arch::asm!("invlpg [{}]", in(reg) va, options(readonly, nostack, preserves_flags)); + } + } + } } diff --git a/src/hyperlight_guest_bin/src/paging.rs b/src/hyperlight_guest_bin/src/paging.rs index 7aa19213b..d569e0100 100644 --- a/src/hyperlight_guest_bin/src/paging.rs +++ b/src/hyperlight_guest_bin/src/paging.rs @@ -8,6 +8,12 @@ mod arch; pub use arch::{map_region, modify_mapping, phys_to_virt, virt_to_phys}; /// Barriers that other code may need to use when updating page tables pub mod barrier { + /// Call this function when a virtual address has had its + /// permissions changed in a way that makes previously-valid + /// accesses invalid. + /// + /// Range must be page-aligned. + pub use arch::downgrade_in_place; /// Call this function when a virtual address has just been made /// valid for the first time after the last tlb invalidate that /// affected it, and it will be used for the first time in the