hypervisor: mshv: implement extended guest requests with empty certs

Previously we didn't handle extended guest requests at all and always
returned an error. This lead to issues with some guests that expected
extended requests to succeed. Instead, handle extended requests like
normal requests and write zeros to the extended area to signal to the
guest that we don't want to supply any additional certificate data.

Signed-off-by: Tom Dohrmann <erbse.13@gmx.de>
This commit is contained in:
Tom Dohrmann 2024-08-26 11:14:34 +02:00 committed by Wei Liu
parent 486c61da5e
commit 8fd0310db9
2 changed files with 21 additions and 13 deletions

View File

@ -977,18 +977,6 @@ impl cpu::Vcpu for MshvVcpu {
} }
} }
} }
SVM_EXITCODE_SNP_EXTENDED_GUEST_REQUEST => {
warn!("Fetching extended guest request is not supported");
// Extended guest request is not supported by the Hypervisor
// Returning the error to the guest
// 0x6 means `The NAE event was not valid`
// Reference: GHCB Spec, page 42
let value: u64 = 0x6;
self.gpa_write(
ghcb_gpa + GHCB_SW_EXITINFO2_OFFSET,
&value.to_le_bytes(),
)?;
}
SVM_EXITCODE_IOIO_PROT => { SVM_EXITCODE_IOIO_PROT => {
let exit_info1 = let exit_info1 =
info.__bindgen_anon_2.__bindgen_anon_1.sw_exit_info1 as u32; info.__bindgen_anon_2.__bindgen_anon_1.sw_exit_info1 as u32;
@ -1082,7 +1070,26 @@ 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
self.clear_swexit_info1(ghcb_gpa)?; self.clear_swexit_info1(ghcb_gpa)?;
} }
SVM_EXITCODE_SNP_GUEST_REQUEST => { SVM_EXITCODE_SNP_GUEST_REQUEST
| SVM_EXITCODE_SNP_EXTENDED_GUEST_REQUEST => {
if exit_code == SVM_EXITCODE_SNP_EXTENDED_GUEST_REQUEST {
info!("Fetching extended guest request is not supported");
// We don't support extended guest request, so we just write empty data.
// This matches the behavior of KVM in Linux 6.11.
// Read RAX & RBX from the GHCB.
let mut data = [0; 8];
self.gpa_read(ghcb_gpa + GHCB_RAX_OFFSET, &mut data)?;
let data_gpa = u64::from_le_bytes(data);
self.gpa_read(ghcb_gpa + GHCB_RBX_OFFSET, &mut data)?;
let data_npages = u64::from_le_bytes(data);
if data_npages > 0 {
// The certificates are terminated by 24 zero bytes.
self.gpa_write(data_gpa, &[0; 24])?;
}
}
let req_gpa = let req_gpa =
info.__bindgen_anon_2.__bindgen_anon_1.sw_exit_info1; info.__bindgen_anon_2.__bindgen_anon_1.sw_exit_info1;
let rsp_gpa = let rsp_gpa =

View File

@ -20,5 +20,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_RAX_OFFSET: u64 = 0x01F8;
pub const GHCB_RBX_OFFSET: u64 = 0x0318;
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;