diff --git a/hypervisor/src/kvm/mod.rs b/hypervisor/src/kvm/mod.rs index c7ae516dd..6f2b92c13 100644 --- a/hypervisor/src/kvm/mod.rs +++ b/hypervisor/src/kvm/mod.rs @@ -44,6 +44,10 @@ use vmm_sys_util::eventfd::EventFd; pub mod x86_64; #[cfg(target_arch = "x86_64")] use crate::arch::x86::NUM_IOAPIC_PINS; +use crate::{ + UserMemoryRegion, USER_MEMORY_REGION_LOG_DIRTY, USER_MEMORY_REGION_READ, + USER_MEMORY_REGION_WRITE, +}; #[cfg(target_arch = "aarch64")] use aarch64::{RegList, Register, StandardRegisters}; #[cfg(target_arch = "x86_64")] @@ -160,6 +164,51 @@ pub struct TdxCapabilities { pub cpuid_configs: [TdxCpuidConfig; TDX_MAX_NR_CPUID_CONFIGS], } +impl From for UserMemoryRegion { + fn from(region: kvm_userspace_memory_region) -> Self { + let mut flags = USER_MEMORY_REGION_READ; + if region.flags & KVM_MEM_READONLY == 0 { + flags |= USER_MEMORY_REGION_WRITE; + } + if region.flags & KVM_MEM_LOG_DIRTY_PAGES != 0 { + flags |= USER_MEMORY_REGION_LOG_DIRTY; + } + + UserMemoryRegion { + slot: region.slot, + guest_phys_addr: region.guest_phys_addr, + memory_size: region.memory_size, + userspace_addr: region.userspace_addr, + flags, + } + } +} + +impl From for kvm_userspace_memory_region { + fn from(region: UserMemoryRegion) -> Self { + assert!( + region.flags & USER_MEMORY_REGION_READ != 0, + "KVM mapped memory is always readable" + ); + + let mut flags = 0; + if region.flags & USER_MEMORY_REGION_WRITE == 0 { + flags |= KVM_MEM_READONLY; + } + if region.flags & USER_MEMORY_REGION_LOG_DIRTY != 0 { + flags |= KVM_MEM_LOG_DIRTY_PAGES; + } + + kvm_userspace_memory_region { + slot: region.slot, + guest_phys_addr: region.guest_phys_addr, + memory_size: region.memory_size, + userspace_addr: region.userspace_addr, + flags, + } + } +} + #[derive(Clone, Copy, Debug, PartialEq, Eq, Deserialize, Serialize)] pub struct KvmVmState {} diff --git a/hypervisor/src/mshv/mod.rs b/hypervisor/src/mshv/mod.rs index 086305f5c..bc8246168 100644 --- a/hypervisor/src/mshv/mod.rs +++ b/hypervisor/src/mshv/mod.rs @@ -23,6 +23,9 @@ use vm::DataMatch; #[cfg(target_arch = "x86_64")] pub mod x86_64; use crate::device; +use crate::{ + UserMemoryRegion, USER_MEMORY_REGION_EXECUTE, USER_MEMORY_REGION_READ, USER_MEMORY_REGION_WRITE, +}; use vmm_sys_util::eventfd::EventFd; #[cfg(target_arch = "x86_64")] pub use x86_64::VcpuMshvState as CpuState; @@ -47,6 +50,52 @@ pub use { pub const PAGE_SHIFT: usize = 12; +impl From for UserMemoryRegion { + fn from(region: mshv_user_mem_region) -> Self { + let mut flags: u32 = 0; + if region.flags & HV_MAP_GPA_READABLE != 0 { + flags |= USER_MEMORY_REGION_READ; + } + if region.flags & HV_MAP_GPA_WRITABLE != 0 { + flags |= USER_MEMORY_REGION_WRITE; + } + if region.flags & HV_MAP_GPA_EXECUTABLE != 0 { + flags |= USER_MEMORY_REGION_EXECUTE; + } + + UserMemoryRegion { + guest_phys_addr: (region.guest_pfn << PAGE_SHIFT as u64) + + (region.userspace_addr & ((1 << PAGE_SHIFT) - 1)), + memory_size: region.size, + userspace_addr: region.userspace_addr, + flags, + ..Default::default() + } + } +} + +impl From for mshv_user_mem_region { + fn from(region: UserMemoryRegion) -> Self { + let mut flags: u32 = 0; + if region.flags & USER_MEMORY_REGION_READ != 0 { + flags |= HV_MAP_GPA_READABLE; + } + if region.flags & USER_MEMORY_REGION_WRITE != 0 { + flags |= HV_MAP_GPA_WRITABLE; + } + if region.flags & USER_MEMORY_REGION_EXECUTE != 0 { + flags |= HV_MAP_GPA_EXECUTABLE; + } + + mshv_user_mem_region { + guest_pfn: region.guest_phys_addr >> PAGE_SHIFT, + size: region.memory_size, + userspace_addr: region.userspace_addr, + flags, + } + } +} + #[derive(Debug, Default, Copy, Clone, Serialize, Deserialize)] pub struct HvState { hypercall_page: u64,