mirror of
https://github.com/cloud-hypervisor/cloud-hypervisor.git
synced 2024-12-22 13:45:20 +00:00
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 <muislam@microsoft.com>
This commit is contained in:
parent
a458351d8b
commit
e4a5219f53
@ -907,9 +907,7 @@ impl cpu::Vcpu for MshvVcpu {
|
|||||||
GHCB_INFO_NORMAL => {
|
GHCB_INFO_NORMAL => {
|
||||||
let exit_code =
|
let exit_code =
|
||||||
info.__bindgen_anon_2.__bindgen_anon_1.sw_exit_code as u32;
|
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 {
|
match exit_code {
|
||||||
SVM_EXITCODE_HV_DOORBELL_PAGE => {
|
SVM_EXITCODE_HV_DOORBELL_PAGE => {
|
||||||
let exit_info1 =
|
let exit_info1 =
|
||||||
@ -1060,7 +1058,7 @@ 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];
|
||||||
// SAFETY: Accessing the field from a mapped address
|
// SAFETY: Accessing data from a mapped address
|
||||||
let bytes_shared_ghcb =
|
let bytes_shared_ghcb =
|
||||||
unsafe { (*ghcb).shared[0].to_le_bytes() };
|
unsafe { (*ghcb).shared[0].to_le_bytes() };
|
||||||
data.copy_from_slice(&bytes_shared_ghcb[..data_len]);
|
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.
|
// We don't support extended guest request, so we just write empty data.
|
||||||
// This matches the behavior of KVM in Linux 6.11.
|
// This matches the behavior of KVM in Linux 6.11.
|
||||||
|
|
||||||
// Read RAX & RBX from the GHCB.
|
// Read RBX from the GHCB.
|
||||||
let mut data = [0; 8];
|
// SAFETY: Accessing data from a mapped address
|
||||||
self.gpa_read(ghcb_gpa + GHCB_RAX_OFFSET, &mut data)?;
|
let data_gpa = unsafe { (*ghcb).rax };
|
||||||
let data_gpa = u64::from_le_bytes(data);
|
// SAFETY: Accessing data from a mapped address
|
||||||
self.gpa_read(ghcb_gpa + GHCB_RBX_OFFSET, &mut data)?;
|
let data_npages = unsafe { (*ghcb).rbx };
|
||||||
let data_npages = u64::from_le_bytes(data);
|
|
||||||
|
|
||||||
if data_npages > 0 {
|
if data_npages > 0 {
|
||||||
// The certificates are terminated by 24 zero bytes.
|
// 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])?;
|
self.gpa_write(data_gpa, &[0; 24])?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1110,7 +1109,7 @@ impl cpu::Vcpu for MshvVcpu {
|
|||||||
req_gpa, rsp_gpa
|
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 => {
|
SVM_EXITCODE_SNP_AP_CREATION => {
|
||||||
let vmsa_gpa =
|
let vmsa_gpa =
|
||||||
@ -1519,27 +1518,6 @@ impl MshvVcpu {
|
|||||||
Ok(cpu::VmExit::Ignore)
|
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")]
|
#[cfg(feature = "sev_snp")]
|
||||||
fn gpa_write(&self, gpa: u64, data: &[u8]) -> cpu::Result<()> {
|
fn gpa_write(&self, gpa: u64, data: &[u8]) -> cpu::Result<()> {
|
||||||
for (gpa, chunk) in (gpa..)
|
for (gpa, chunk) in (gpa..)
|
||||||
|
@ -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_START: usize = ECDSA_SIG_X_COMPONENT_END;
|
||||||
pub const ECDSA_SIG_Y_COMPONENT_END: usize =
|
pub const ECDSA_SIG_Y_COMPONENT_END: usize =
|
||||||
ECDSA_SIG_X_COMPONENT_END + ECDSA_SIG_Y_COMPONENT_SIZE_IN_BYTES;
|
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;
|
|
||||||
|
Loading…
Reference in New Issue
Block a user