hypervisor: mshv: modify doorbell page handling for CVM

VMM needs to handle VMG exit for doorbell page. 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 <muislam@microsoft.com>
This commit is contained in:
Muminul Islam 2024-11-07 10:24:45 -08:00 committed by Wei Liu
parent 78895dcc37
commit 310dafb4d7

View File

@ -805,6 +805,10 @@ impl cpu::Vcpu for MshvVcpu {
let ghcb_msr = svm_ghcb_msr { let ghcb_msr = svm_ghcb_msr {
as_uint64: info.ghcb_msr, as_uint64: info.ghcb_msr,
}; };
// Safe to use unwrap, for sev_snp guest we already have the
// GHCB pointer wrapped in the option, otherwise this place is not reached.
let ghcb = self.ghcb.as_ref().unwrap().0;
// SAFETY: Accessing a union element from bindgen generated bindings. // SAFETY: Accessing a union element from bindgen generated bindings.
let ghcb_op = unsafe { ghcb_msr.__bindgen_anon_2.ghcb_info() as u32 }; let ghcb_op = unsafe { ghcb_msr.__bindgen_anon_2.ghcb_info() as u32 };
// Sanity check on the header fields before handling other operations. // Sanity check on the header fields before handling other operations.
@ -914,10 +918,11 @@ impl cpu::Vcpu for MshvVcpu {
SVM_NAE_HV_DOORBELL_PAGE_GET_PREFERRED => { SVM_NAE_HV_DOORBELL_PAGE_GET_PREFERRED => {
// Hypervisor does not have any preference for doorbell GPA. // Hypervisor does not have any preference for doorbell GPA.
let preferred_doorbell_gpa: u64 = 0xFFFFFFFFFFFFFFFF; let preferred_doorbell_gpa: u64 = 0xFFFFFFFFFFFFFFFF;
self.gpa_write( set_svm_field_u64_ptr!(
ghcb_gpa + GHCB_SW_EXITINFO2_OFFSET, ghcb,
&preferred_doorbell_gpa.to_le_bytes(), exit_info2,
)?; preferred_doorbell_gpa
);
} }
SVM_NAE_HV_DOORBELL_PAGE_SET => { SVM_NAE_HV_DOORBELL_PAGE_SET => {
let exit_info2 = info let exit_info2 = info
@ -944,10 +949,7 @@ impl cpu::Vcpu for MshvVcpu {
cpu::HypervisorCpuError::SetRegister(e.into()) cpu::HypervisorCpuError::SetRegister(e.into())
})?; })?;
self.gpa_write( set_svm_field_u64_ptr!(ghcb, exit_info2, exit_info2);
ghcb_gpa + GHCB_SW_EXITINFO2_OFFSET,
&exit_info2.to_le_bytes(),
)?;
// Clear the SW_EXIT_INFO1 register to indicate no error // Clear the SW_EXIT_INFO1 register to indicate no error
self.clear_swexit_info1()?; self.clear_swexit_info1()?;
@ -961,19 +963,13 @@ impl cpu::Vcpu for MshvVcpu {
// SAFETY: Accessing a union element from bindgen generated bindings. // SAFETY: Accessing a union element from bindgen generated bindings.
let doorbell_gpa = unsafe { reg_assocs[0].value.reg64 }; let doorbell_gpa = unsafe { reg_assocs[0].value.reg64 };
self.gpa_write( set_svm_field_u64_ptr!(ghcb, exit_info2, doorbell_gpa);
ghcb_gpa + GHCB_SW_EXITINFO2_OFFSET,
&doorbell_gpa.to_le_bytes(),
)?;
// Clear the SW_EXIT_INFO1 register to indicate no error // Clear the SW_EXIT_INFO1 register to indicate no error
self.clear_swexit_info1()?; self.clear_swexit_info1()?;
} }
SVM_NAE_HV_DOORBELL_PAGE_CLEAR => { SVM_NAE_HV_DOORBELL_PAGE_CLEAR => {
self.gpa_write( set_svm_field_u64_ptr!(ghcb, exit_info2, 0);
ghcb_gpa + GHCB_SW_EXITINFO2_OFFSET,
&[0; 8],
)?;
} }
_ => { _ => {
panic!( panic!(