From 3fe7d6d904b28c1dcf70b666ae6a54753a94e3cf Mon Sep 17 00:00:00 2001 From: Jinank Jain Date: Mon, 12 Aug 2024 18:31:59 +0530 Subject: [PATCH] hypervisor: mshv: Disable previous GHCB page before setting new one CVM guests can configure GHCB page multiple times during it's lifetime depending on it's requirement. For example a Linux CVM guest configures a different GHCB page during compressed kernel boot and sets up a new one after decompressing the kernel. As a cleanup step, VMM should unset the previous GHCB page before registering a new one for a particular vcpu thread. Signed-off-by: Jinank Jain --- hypervisor/src/mshv/mod.rs | 41 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/hypervisor/src/mshv/mod.rs b/hypervisor/src/mshv/mod.rs index 161eb0f59..6063ec6df 100644 --- a/hypervisor/src/mshv/mod.rs +++ b/hypervisor/src/mshv/mod.rs @@ -799,6 +799,10 @@ impl cpu::Vcpu for MshvVcpu { } GHCB_INFO_REGISTER_REQUEST => { let mut ghcb_gpa = hv_x64_register_sev_ghcb::default(); + + // Disable the previously used GHCB page. + self.disable_prev_ghcb_page()?; + // SAFETY: Accessing a union element from bindgen generated bindings. unsafe { ghcb_gpa.__bindgen_anon_1.set_enabled(1); @@ -826,6 +830,7 @@ impl cpu::Vcpu for MshvVcpu { resp_ghcb_msr.__bindgen_anon_2.set_gpa_page_number( ghcb_msr.__bindgen_anon_2.gpa_page_number(), ); + debug!("GHCB GPA is {:x}", ghcb_gpa.as_uint64); } // SAFETY: Accessing a union element from bindgen generated bindings. let reg_name_value = unsafe { @@ -1456,6 +1461,42 @@ impl cpu::Vcpu for MshvVcpu { } impl MshvVcpu { + /// + /// Deactivate previously used GHCB page. + /// + #[cfg(feature = "sev_snp")] + fn disable_prev_ghcb_page(&self) -> cpu::Result<()> { + let mut reg_assocs = [hv_register_assoc { + name: hv_register_name_HV_X64_REGISTER_SEV_GHCB_GPA, + ..Default::default() + }]; + self.fd.get_reg(&mut reg_assocs).unwrap(); + // SAFETY: Accessing a union element from bindgen generated bindings. + let prev_ghcb_gpa = unsafe { reg_assocs[0].value.reg64 }; + + debug!("Prev GHCB GPA is {:x}", prev_ghcb_gpa); + + let mut ghcb_gpa = hv_x64_register_sev_ghcb::default(); + + // SAFETY: Accessing a union element from bindgen generated bindings. + unsafe { + ghcb_gpa.__bindgen_anon_1.set_enabled(0); + ghcb_gpa.__bindgen_anon_1.set_page_number(prev_ghcb_gpa); + } + + // SAFETY: Accessing a union element from bindgen generated bindings. + let reg_name_value = unsafe { + [( + hv_register_name_HV_X64_REGISTER_SEV_GHCB_GPA, + ghcb_gpa.as_uint64, + )] + }; + + set_registers_64!(self.fd, reg_name_value) + .map_err(|e| cpu::HypervisorCpuError::SetRegister(e.into()))?; + + Ok(()) + } #[cfg(target_arch = "x86_64")] /// /// X86 specific call that returns the vcpu's current "xcrs".