mirror of
https://github.com/cloud-hypervisor/cloud-hypervisor.git
synced 2024-10-18 10:59:16 +00:00
hypervisor: mshv: Clear SW_EXIT_INFO1 in case of no error
There were some scenarios where we are not clearing SW_EXIT_INFO1 to indicate that there were no error while handling the GHCB exit. Recently, new Linux guests got stricter with checking the value of SW_EXIT_INFO1 after coming back from VMGEXIT and started crashing. Fix this behavior by clearing out SW_EXIT_INFO1 in case of no error. Signed-off-by: Jinank Jain <jinankjain@microsoft.com>
This commit is contained in:
parent
5fddf76a3b
commit
330e1aac36
@ -926,15 +926,7 @@ impl cpu::Vcpu for MshvVcpu {
|
|||||||
)?;
|
)?;
|
||||||
|
|
||||||
// Clear the SW_EXIT_INFO1 register to indicate no error
|
// Clear the SW_EXIT_INFO1 register to indicate no error
|
||||||
let mut swei1_rw_gpa_arg =
|
self.clear_swexit_info1(ghcb_gpa)?;
|
||||||
mshv_bindings::mshv_read_write_gpa {
|
|
||||||
base_gpa: ghcb_gpa + GHCB_SW_EXITINFO1_OFFSET,
|
|
||||||
byte_count: std::mem::size_of::<u64>() as u32,
|
|
||||||
..Default::default()
|
|
||||||
};
|
|
||||||
self.fd.gpa_write(&mut swei1_rw_gpa_arg).map_err(
|
|
||||||
|e| cpu::HypervisorCpuError::GpaWrite(e.into()),
|
|
||||||
)?;
|
|
||||||
}
|
}
|
||||||
SVM_NAE_HV_DOORBELL_PAGE_QUERY => {
|
SVM_NAE_HV_DOORBELL_PAGE_QUERY => {
|
||||||
let mut reg_assocs = [ hv_register_assoc {
|
let mut reg_assocs = [ hv_register_assoc {
|
||||||
@ -956,6 +948,9 @@ impl cpu::Vcpu for MshvVcpu {
|
|||||||
self.fd.gpa_write(&mut swei2_rw_gpa_arg).map_err(
|
self.fd.gpa_write(&mut swei2_rw_gpa_arg).map_err(
|
||||||
|e| cpu::HypervisorCpuError::GpaWrite(e.into()),
|
|e| cpu::HypervisorCpuError::GpaWrite(e.into()),
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
|
// Clear the SW_EXIT_INFO1 register to indicate no error
|
||||||
|
self.clear_swexit_info1(ghcb_gpa)?;
|
||||||
}
|
}
|
||||||
SVM_NAE_HV_DOORBELL_PAGE_CLEAR => {
|
SVM_NAE_HV_DOORBELL_PAGE_CLEAR => {
|
||||||
let mut swei2_rw_gpa_arg =
|
let mut swei2_rw_gpa_arg =
|
||||||
@ -1056,14 +1051,7 @@ impl cpu::Vcpu for MshvVcpu {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Clear the SW_EXIT_INFO1 register to indicate no error
|
// Clear the SW_EXIT_INFO1 register to indicate no error
|
||||||
let mut swei1_rw_gpa_arg = mshv_bindings::mshv_read_write_gpa {
|
self.clear_swexit_info1(ghcb_gpa)?;
|
||||||
base_gpa: ghcb_gpa + GHCB_SW_EXITINFO1_OFFSET,
|
|
||||||
byte_count: std::mem::size_of::<u64>() as u32,
|
|
||||||
..Default::default()
|
|
||||||
};
|
|
||||||
self.fd
|
|
||||||
.gpa_write(&mut swei1_rw_gpa_arg)
|
|
||||||
.map_err(|e| cpu::HypervisorCpuError::GpaWrite(e.into()))?;
|
|
||||||
}
|
}
|
||||||
SVM_EXITCODE_MMIO_READ => {
|
SVM_EXITCODE_MMIO_READ => {
|
||||||
let src_gpa =
|
let src_gpa =
|
||||||
@ -1092,6 +1080,9 @@ impl cpu::Vcpu for MshvVcpu {
|
|||||||
self.fd
|
self.fd
|
||||||
.gpa_write(&mut arg)
|
.gpa_write(&mut arg)
|
||||||
.map_err(|e| cpu::HypervisorCpuError::GpaWrite(e.into()))?;
|
.map_err(|e| cpu::HypervisorCpuError::GpaWrite(e.into()))?;
|
||||||
|
|
||||||
|
// Clear the SW_EXIT_INFO1 register to indicate no error
|
||||||
|
self.clear_swexit_info1(ghcb_gpa)?;
|
||||||
}
|
}
|
||||||
SVM_EXITCODE_MMIO_WRITE => {
|
SVM_EXITCODE_MMIO_WRITE => {
|
||||||
let dst_gpa =
|
let dst_gpa =
|
||||||
@ -1120,6 +1111,9 @@ impl cpu::Vcpu for MshvVcpu {
|
|||||||
cpu::HypervisorCpuError::RunVcpu(e.into())
|
cpu::HypervisorCpuError::RunVcpu(e.into())
|
||||||
})?;
|
})?;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Clear the SW_EXIT_INFO1 register to indicate no error
|
||||||
|
self.clear_swexit_info1(ghcb_gpa)?;
|
||||||
}
|
}
|
||||||
SVM_EXITCODE_SNP_GUEST_REQUEST => {
|
SVM_EXITCODE_SNP_GUEST_REQUEST => {
|
||||||
let req_gpa =
|
let req_gpa =
|
||||||
@ -1165,15 +1159,8 @@ impl cpu::Vcpu for MshvVcpu {
|
|||||||
.sev_snp_ap_create(&mshv_ap_create_req)
|
.sev_snp_ap_create(&mshv_ap_create_req)
|
||||||
.map_err(|e| cpu::HypervisorCpuError::RunVcpu(e.into()))?;
|
.map_err(|e| cpu::HypervisorCpuError::RunVcpu(e.into()))?;
|
||||||
|
|
||||||
let mut swei1_rw_gpa_arg = mshv_bindings::mshv_read_write_gpa {
|
// Clear the SW_EXIT_INFO1 register to indicate no error
|
||||||
base_gpa: ghcb_gpa + GHCB_SW_EXITINFO1_OFFSET,
|
self.clear_swexit_info1(ghcb_gpa)?;
|
||||||
byte_count: std::mem::size_of::<u64>() as u32,
|
|
||||||
..Default::default()
|
|
||||||
};
|
|
||||||
|
|
||||||
self.fd
|
|
||||||
.gpa_write(&mut swei1_rw_gpa_arg)
|
|
||||||
.map_err(|e| cpu::HypervisorCpuError::GpaWrite(e.into()))?;
|
|
||||||
}
|
}
|
||||||
_ => panic!(
|
_ => panic!(
|
||||||
"GHCB_INFO_NORMAL: Unhandled exit code: {:0x}",
|
"GHCB_INFO_NORMAL: Unhandled exit code: {:0x}",
|
||||||
@ -1510,6 +1497,27 @@ impl MshvVcpu {
|
|||||||
.set_vcpu_events(events)
|
.set_vcpu_events(events)
|
||||||
.map_err(|e| cpu::HypervisorCpuError::SetVcpuEvents(e.into()))
|
.map_err(|e| cpu::HypervisorCpuError::SetVcpuEvents(e.into()))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Clear SW_EXIT_INFO1 register for SEV-SNP guests.
|
||||||
|
///
|
||||||
|
#[cfg(feature = "sev_snp")]
|
||||||
|
fn clear_swexit_info1(
|
||||||
|
&self,
|
||||||
|
ghcb_gpa: u64,
|
||||||
|
) -> std::result::Result<cpu::VmExit, cpu::HypervisorCpuError> {
|
||||||
|
// Clear the SW_EXIT_INFO1 register to indicate no error
|
||||||
|
let mut swei1_rw_gpa_arg = mshv_bindings::mshv_read_write_gpa {
|
||||||
|
base_gpa: ghcb_gpa + GHCB_SW_EXITINFO1_OFFSET,
|
||||||
|
byte_count: std::mem::size_of::<u64>() as u32,
|
||||||
|
..Default::default()
|
||||||
|
};
|
||||||
|
self.fd
|
||||||
|
.gpa_write(&mut swei1_rw_gpa_arg)
|
||||||
|
.map_err(|e| cpu::HypervisorCpuError::GpaWrite(e.into()))?;
|
||||||
|
|
||||||
|
Ok(cpu::VmExit::Ignore)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Wrapper over Mshv VM ioctls.
|
/// Wrapper over Mshv VM ioctls.
|
||||||
|
Loading…
Reference in New Issue
Block a user