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 <muislam@microsoft.com>
This commit is contained in:
Muminul Islam 2024-11-07 10:52:22 -08:00 committed by Wei Liu
parent 5a27bf878c
commit a458351d8b

View File

@ -1029,7 +1029,6 @@ impl cpu::Vcpu for MshvVcpu {
SVM_EXITCODE_MMIO_READ => { SVM_EXITCODE_MMIO_READ => {
let src_gpa = let src_gpa =
info.__bindgen_anon_2.__bindgen_anon_1.sw_exit_info1; 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 = let data_len =
info.__bindgen_anon_2.__bindgen_anon_1.sw_exit_info2 info.__bindgen_anon_2.__bindgen_anon_1.sw_exit_info2
as usize; as usize;
@ -1042,8 +1041,11 @@ impl cpu::Vcpu for MshvVcpu {
cpu::HypervisorCpuError::RunVcpu(e.into()) cpu::HypervisorCpuError::RunVcpu(e.into())
})?; })?;
} }
// Copy the data to the shared buffer of the GHCB page
self.gpa_write(dst_gpa, &data)?; 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 // Clear the SW_EXIT_INFO1 register to indicate no error
self.clear_swexit_info1()?; self.clear_swexit_info1()?;
@ -1051,7 +1053,6 @@ impl cpu::Vcpu for MshvVcpu {
SVM_EXITCODE_MMIO_WRITE => { SVM_EXITCODE_MMIO_WRITE => {
let dst_gpa = let dst_gpa =
info.__bindgen_anon_2.__bindgen_anon_1.sw_exit_info1; 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 = let data_len =
info.__bindgen_anon_2.__bindgen_anon_1.sw_exit_info2 info.__bindgen_anon_2.__bindgen_anon_1.sw_exit_info2
as usize; as usize;
@ -1059,7 +1060,10 @@ impl cpu::Vcpu for MshvVcpu {
assert!(data_len <= 0x8); assert!(data_len <= 0x8);
let mut data = vec![0; data_len]; 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 { if let Some(vm_ops) = &self.vm_ops {
vm_ops.mmio_write(dst_gpa, &data).map_err(|e| { vm_ops.mmio_write(dst_gpa, &data).map_err(|e| {