From e4a5219f53696787d12199918bc924b0272e0717 Mon Sep 17 00:00:00 2001 From: Muminul Islam Date: Thu, 7 Nov 2024 11:12:52 -0800 Subject: [PATCH] hypervisor: mshv: modify GuestRequest handling for CVM VMM needs to handle VMG exit for guest request. 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 | 42 +++++++--------------------- hypervisor/src/mshv/snp_constants.rs | 6 ---- 2 files changed, 10 insertions(+), 38 deletions(-) diff --git a/hypervisor/src/mshv/mod.rs b/hypervisor/src/mshv/mod.rs index 3f13578c9..20f4fe9d7 100644 --- a/hypervisor/src/mshv/mod.rs +++ b/hypervisor/src/mshv/mod.rs @@ -907,9 +907,7 @@ impl cpu::Vcpu for MshvVcpu { GHCB_INFO_NORMAL => { let exit_code = info.__bindgen_anon_2.__bindgen_anon_1.sw_exit_code as u32; - // SAFETY: Accessing a union element from bindgen generated bindings. - let pfn = unsafe { ghcb_msr.__bindgen_anon_2.gpa_page_number() }; - let ghcb_gpa = pfn << GHCB_INFO_BIT_WIDTH; + match exit_code { SVM_EXITCODE_HV_DOORBELL_PAGE => { let exit_info1 = @@ -1060,7 +1058,7 @@ impl cpu::Vcpu for MshvVcpu { assert!(data_len <= 0x8); let mut data = vec![0; data_len]; - // SAFETY: Accessing the field from a mapped address + // SAFETY: Accessing data from a mapped address let bytes_shared_ghcb = unsafe { (*ghcb).shared[0].to_le_bytes() }; data.copy_from_slice(&bytes_shared_ghcb[..data_len]); @@ -1081,15 +1079,16 @@ impl cpu::Vcpu for MshvVcpu { // We don't support extended guest request, so we just write empty data. // This matches the behavior of KVM in Linux 6.11. - // Read RAX & RBX from the GHCB. - let mut data = [0; 8]; - self.gpa_read(ghcb_gpa + GHCB_RAX_OFFSET, &mut data)?; - let data_gpa = u64::from_le_bytes(data); - self.gpa_read(ghcb_gpa + GHCB_RBX_OFFSET, &mut data)?; - let data_npages = u64::from_le_bytes(data); + // Read RBX from the GHCB. + // SAFETY: Accessing data from a mapped address + let data_gpa = unsafe { (*ghcb).rax }; + // SAFETY: Accessing data from a mapped address + let data_npages = unsafe { (*ghcb).rbx }; if data_npages > 0 { // The certificates are terminated by 24 zero bytes. + // TODO: Need to check if data_gpa is the address of the shared buffer in the GHCB page + // in that case we should clear the shared buffer(24 bytes) self.gpa_write(data_gpa, &[0; 24])?; } } @@ -1110,7 +1109,7 @@ impl cpu::Vcpu for MshvVcpu { req_gpa, rsp_gpa ); - self.gpa_write(ghcb_gpa + GHCB_SW_EXITINFO2_OFFSET, &[0; 8])?; + set_svm_field_u64_ptr!(ghcb, exit_info2, 0); } SVM_EXITCODE_SNP_AP_CREATION => { let vmsa_gpa = @@ -1519,27 +1518,6 @@ impl MshvVcpu { Ok(cpu::VmExit::Ignore) } - #[cfg(feature = "sev_snp")] - fn gpa_read(&self, gpa: u64, data: &mut [u8]) -> cpu::Result<()> { - for (gpa, chunk) in (gpa..) - .step_by(HV_READ_WRITE_GPA_MAX_SIZE as usize) - .zip(data.chunks_mut(HV_READ_WRITE_GPA_MAX_SIZE as usize)) - { - let mut rw_gpa_arg = mshv_bindings::mshv_read_write_gpa { - base_gpa: gpa, - byte_count: chunk.len() as u32, - ..Default::default() - }; - self.fd - .gpa_read(&mut rw_gpa_arg) - .map_err(|e| cpu::HypervisorCpuError::GpaRead(e.into()))?; - - chunk.copy_from_slice(&rw_gpa_arg.data[..chunk.len()]); - } - - Ok(()) - } - #[cfg(feature = "sev_snp")] fn gpa_write(&self, gpa: u64, data: &[u8]) -> cpu::Result<()> { for (gpa, chunk) in (gpa..) diff --git a/hypervisor/src/mshv/snp_constants.rs b/hypervisor/src/mshv/snp_constants.rs index 5273244f3..84e240c49 100644 --- a/hypervisor/src/mshv/snp_constants.rs +++ b/hypervisor/src/mshv/snp_constants.rs @@ -16,9 +16,3 @@ pub const ECDSA_SIG_X_COMPONENT_END: usize = pub const ECDSA_SIG_Y_COMPONENT_START: usize = ECDSA_SIG_X_COMPONENT_END; pub const ECDSA_SIG_Y_COMPONENT_END: usize = ECDSA_SIG_X_COMPONENT_END + ECDSA_SIG_Y_COMPONENT_SIZE_IN_BYTES; - -// These constants are derived from GHCB spec Sect. 2.6 Table 3 GHCB Layout -// Link: https://www.amd.com/content/dam/amd/en/documents/epyc-technical-docs/specifications/56421.pdf -pub const GHCB_RAX_OFFSET: u64 = 0x01F8; -pub const GHCB_RBX_OFFSET: u64 = 0x0318; -pub const GHCB_SW_EXITINFO2_OFFSET: u64 = 0x3A0;