From a458351d8b809bba80c675d420c7f195b978d708 Mon Sep 17 00:00:00 2001 From: Muminul Islam Date: Thu, 7 Nov 2024 10:52:22 -0800 Subject: [PATCH] hypervisor: mshv: modify MMIO exit handling for CVM VMM needs to handle VMG exit for MMIO. This patch removes the old method that uses gpa_read/write(IOCTL and hypercall), which is expensive and update the GHCB page using mapped(root partition) struct. Signed-off-by: Muminul Islam --- hypervisor/src/mshv/mod.rs | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/hypervisor/src/mshv/mod.rs b/hypervisor/src/mshv/mod.rs index a025ead53..3f13578c9 100644 --- a/hypervisor/src/mshv/mod.rs +++ b/hypervisor/src/mshv/mod.rs @@ -1029,7 +1029,6 @@ impl cpu::Vcpu for MshvVcpu { SVM_EXITCODE_MMIO_READ => { let src_gpa = info.__bindgen_anon_2.__bindgen_anon_1.sw_exit_info1; - let dst_gpa = info.__bindgen_anon_2.__bindgen_anon_1.sw_scratch; let data_len = info.__bindgen_anon_2.__bindgen_anon_1.sw_exit_info2 as usize; @@ -1042,8 +1041,11 @@ impl cpu::Vcpu for MshvVcpu { cpu::HypervisorCpuError::RunVcpu(e.into()) })?; } - - self.gpa_write(dst_gpa, &data)?; + // Copy the data to the shared buffer of the GHCB page + let mut buffer_data = [0; 8]; + buffer_data[..data_len].copy_from_slice(&data[..data_len]); + // SAFETY: Updating the value of mapped area + unsafe { (*ghcb).shared[0] = u64::from_le_bytes(buffer_data) }; // Clear the SW_EXIT_INFO1 register to indicate no error self.clear_swexit_info1()?; @@ -1051,7 +1053,6 @@ impl cpu::Vcpu for MshvVcpu { SVM_EXITCODE_MMIO_WRITE => { let dst_gpa = info.__bindgen_anon_2.__bindgen_anon_1.sw_exit_info1; - let src_gpa = info.__bindgen_anon_2.__bindgen_anon_1.sw_scratch; let data_len = info.__bindgen_anon_2.__bindgen_anon_1.sw_exit_info2 as usize; @@ -1059,7 +1060,10 @@ impl cpu::Vcpu for MshvVcpu { assert!(data_len <= 0x8); let mut data = vec![0; data_len]; - self.gpa_read(src_gpa, &mut data)?; + // SAFETY: Accessing the field from a mapped address + let bytes_shared_ghcb = + unsafe { (*ghcb).shared[0].to_le_bytes() }; + data.copy_from_slice(&bytes_shared_ghcb[..data_len]); if let Some(vm_ops) = &self.vm_ops { vm_ops.mmio_write(dst_gpa, &data).map_err(|e| {