mirror of
https://github.com/cloud-hypervisor/cloud-hypervisor.git
synced 2025-01-03 11:25:20 +00:00
hypervisor: Add support for legacy I/O port emulation
Legacy port emulation requires reading RAX register from GHCB page for SEV-SNP guest. This is the major difference between a regular guest and SEV-SNP enabled guest. Signed-off-by: Jinank Jain <jinankjain@microsoft.com> Signed-off-by: Muminul Islam <muislam@microsoft.com>
This commit is contained in:
parent
e2288a8d2c
commit
7975207e0f
@ -848,6 +848,78 @@ impl cpu::Vcpu for MshvVcpu {
|
|||||||
.gpa_write(&mut swei2_rw_gpa_arg)
|
.gpa_write(&mut swei2_rw_gpa_arg)
|
||||||
.map_err(|e| cpu::HypervisorCpuError::GpaWrite(e.into()))?;
|
.map_err(|e| cpu::HypervisorCpuError::GpaWrite(e.into()))?;
|
||||||
}
|
}
|
||||||
|
SVM_EXITCODE_IOIO_PROT => {
|
||||||
|
let exit_info1 =
|
||||||
|
info.__bindgen_anon_2.__bindgen_anon_1.sw_exit_info1 as u32;
|
||||||
|
let port_info = hv_sev_vmgexit_port_info {
|
||||||
|
as_uint32: exit_info1,
|
||||||
|
};
|
||||||
|
|
||||||
|
let port =
|
||||||
|
// SAFETY: Accessing a union element from bindgen generated bindings.
|
||||||
|
unsafe { port_info.__bindgen_anon_1.intercepted_port() };
|
||||||
|
let mut len = 4;
|
||||||
|
// SAFETY: Accessing a union element from bindgen generated bindings.
|
||||||
|
unsafe {
|
||||||
|
if port_info.__bindgen_anon_1.operand_size_16bit() == 1 {
|
||||||
|
len = 2;
|
||||||
|
} else if port_info.__bindgen_anon_1.operand_size_8bit()
|
||||||
|
== 1
|
||||||
|
{
|
||||||
|
len = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let is_write =
|
||||||
|
// SAFETY: Accessing a union element from bindgen generated bindings.
|
||||||
|
unsafe { port_info.__bindgen_anon_1.access_type() == 0 };
|
||||||
|
let mut rax_rw_gpa_arg: mshv_read_write_gpa =
|
||||||
|
mshv_bindings::mshv_read_write_gpa {
|
||||||
|
base_gpa: ghcb_gpa + GHCB_RAX_OFFSET,
|
||||||
|
byte_count: std::mem::size_of::<u64>() as u32,
|
||||||
|
..Default::default()
|
||||||
|
};
|
||||||
|
self.fd
|
||||||
|
.gpa_read(&mut rax_rw_gpa_arg)
|
||||||
|
.map_err(|e| cpu::HypervisorCpuError::GpaRead(e.into()))?;
|
||||||
|
|
||||||
|
if is_write {
|
||||||
|
if let Some(vm_ops) = &self.vm_ops {
|
||||||
|
vm_ops
|
||||||
|
.pio_write(
|
||||||
|
port.into(),
|
||||||
|
&rax_rw_gpa_arg.data[0..len],
|
||||||
|
)
|
||||||
|
.map_err(|e| {
|
||||||
|
cpu::HypervisorCpuError::RunVcpu(e.into())
|
||||||
|
})?;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if let Some(vm_ops) = &self.vm_ops {
|
||||||
|
vm_ops
|
||||||
|
.pio_read(
|
||||||
|
port.into(),
|
||||||
|
&mut rax_rw_gpa_arg.data[0..len],
|
||||||
|
)
|
||||||
|
.map_err(|e| {
|
||||||
|
cpu::HypervisorCpuError::RunVcpu(e.into())
|
||||||
|
})?;
|
||||||
|
}
|
||||||
|
|
||||||
|
self.fd.gpa_write(&mut rax_rw_gpa_arg).map_err(|e| {
|
||||||
|
cpu::HypervisorCpuError::GpaWrite(e.into())
|
||||||
|
})?;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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()))?;
|
||||||
|
}
|
||||||
_ => panic!(
|
_ => panic!(
|
||||||
"GHCB_INFO_NORMAL: Unhandled exit code: {:0x}",
|
"GHCB_INFO_NORMAL: Unhandled exit code: {:0x}",
|
||||||
exit_code
|
exit_code
|
||||||
|
@ -19,5 +19,6 @@ pub const ECDSA_SIG_Y_COMPONENT_END: usize =
|
|||||||
|
|
||||||
// These constants are derived from GHCB spec Sect. 2.6 Table 3 GHCB Layout
|
// 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
|
// 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_SW_EXITINFO1_OFFSET: u64 = 0x398;
|
pub const GHCB_SW_EXITINFO1_OFFSET: u64 = 0x398;
|
||||||
pub const GHCB_SW_EXITINFO2_OFFSET: u64 = 0x3A0;
|
pub const GHCB_SW_EXITINFO2_OFFSET: u64 = 0x3A0;
|
||||||
|
Loading…
Reference in New Issue
Block a user