cloud-hypervisor-cvm: add upstream patch to work around lack of support for extended guest requests (#10335)

Signed-off-by: Aurélien Bombo <abombo@microsoft.com>
This commit is contained in:
Aurélien Bombo 2024-11-11 12:27:54 -06:00 коммит произвёл GitHub
Родитель 446a8bbdfc
Коммит 5623842af3
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: B5690EEEBB952194
2 изменённых файлов: 532 добавлений и 1 удалений

Просмотреть файл

@ -5,7 +5,7 @@
Name: cloud-hypervisor-cvm
Summary: Cloud Hypervisor CVM is an open source Virtual Machine Monitor (VMM) that enables running SEV SNP enabled VMs on top of MSHV using the IGVM file format as payload.
Version: 38.0.72.2
Release: 3%{?dist}
Release: 4%{?dist}
License: ASL 2.0 OR BSD-3-clause
Vendor: Microsoft Corporation
Distribution: Mariner
@ -32,6 +32,7 @@ Source2: config.toml
# diff -u ../cloud-hypervisor-msft-v38.0.72.2.backup/Cargo.lock Cargo.lock > ../upgrade-openssl-to-3.3.2-to-address-CVE-2024-6119.patch
Patch0: upgrade-openssl-to-3.3.2-to-address-CVE-2024-6119.patch
Patch1: 0001-hypervisor-mshv-Fix-panic-when-rejecting-extended-gu.patch
Patch2: microsoft-cloud-hypervisor-6695.patch
Conflicts: cloud-hypervisor
@ -150,6 +151,9 @@ cargo build --release --target=%{rust_musl_target} %{cargo_pkg_feature_opts} %{c
%license LICENSE-BSD-3-Clause
%changelog
* Tue Oct 01 2024 Aurelien Bombo <abombo@microsoft.com> - 38.0.72.2-4
- Add upstream patch from microsoft/cloud-hypervisor#6695
* Mon Sep 23 2024 Manuel Huber <mahuber@microsoft.com> - 38.0.72.2-3
- Add upstream patch to prevent crash

Просмотреть файл

@ -0,0 +1,527 @@
From b775bc89e6d15000a92aeff89a08b1bece037879 Mon Sep 17 00:00:00 2001
From: Jinank Jain <jinankjain@microsoft.com>
Date: Mon, 22 Jul 2024 13:22:41 +0530
Subject: [PATCH 1/3] 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>
(cherry picked from commit 330e1aac3698e15eddbe1f1627aa40e5d81ebb89)
[ liuwe: fix contextual conflicts ]
Signed-off-by: Wei Liu <liuwe@microsoft.com>
---
hypervisor/src/mshv/mod.rs | 60 +++++++++++++++++++++-----------------
1 file changed, 34 insertions(+), 26 deletions(-)
diff --git a/hypervisor/src/mshv/mod.rs b/hypervisor/src/mshv/mod.rs
index 91cad92a9..cc62c1844 100644
--- a/hypervisor/src/mshv/mod.rs
+++ b/hypervisor/src/mshv/mod.rs
@@ -918,15 +918,7 @@ impl cpu::Vcpu for MshvVcpu {
)?;
// 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()),
- )?;
+ self.clear_swexit_info1(ghcb_gpa)?;
}
SVM_NAE_HV_DOORBELL_PAGE_QUERY => {
let mut reg_assocs = [ hv_register_assoc {
@@ -948,6 +940,9 @@ impl cpu::Vcpu for MshvVcpu {
self.fd.gpa_write(&mut swei2_rw_gpa_arg).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_NAE_HV_DOORBELL_PAGE_CLEAR => {
let mut swei2_rw_gpa_arg =
@@ -1049,14 +1044,7 @@ impl cpu::Vcpu for MshvVcpu {
}
// 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()))?;
+ self.clear_swexit_info1(ghcb_gpa)?;
}
SVM_EXITCODE_MMIO_READ => {
let src_gpa =
@@ -1085,6 +1073,9 @@ impl cpu::Vcpu for MshvVcpu {
self.fd
.gpa_write(&mut arg)
.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 => {
let dst_gpa =
@@ -1113,6 +1104,9 @@ impl cpu::Vcpu for MshvVcpu {
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 => {
let req_gpa =
@@ -1158,15 +1152,8 @@ impl cpu::Vcpu for MshvVcpu {
.sev_snp_ap_create(&mshv_ap_create_req)
.map_err(|e| cpu::HypervisorCpuError::RunVcpu(e.into()))?;
- let mut swei2_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 swei2_rw_gpa_arg)
- .map_err(|e| cpu::HypervisorCpuError::GpaWrite(e.into()))?;
+ // Clear the SW_EXIT_INFO1 register to indicate no error
+ self.clear_swexit_info1(ghcb_gpa)?;
}
_ => panic!(
"GHCB_INFO_NORMAL: Unhandled exit code: {:0x}",
@@ -1482,6 +1469,27 @@ impl MshvVcpu {
.set_vcpu_events(events)
.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)
+ }
}
struct MshvEmulatorContext<'a> {
--
2.34.1
From 054319b212fca0d0212a3a243e386edfb3b4f58f Mon Sep 17 00:00:00 2001
From: Tom Dohrmann <erbse.13@gmx.de>
Date: Wed, 28 Aug 2024 09:07:41 +0200
Subject: [PATCH 2/3] hypervisor: mshv: add helpers for reading and writing
guest memory
Signed-off-by: Tom Dohrmann <erbse.13@gmx.de>
(cherry picked from commit 486c61da5e21da7e35b41c0cc104226944ea2f61)
Signed-off-by: Wei Liu <liuwe@microsoft.com>
---
hypervisor/src/mshv/mod.rs | 197 +++++++++++++++----------------------
1 file changed, 80 insertions(+), 117 deletions(-)
diff --git a/hypervisor/src/mshv/mod.rs b/hypervisor/src/mshv/mod.rs
index cc62c1844..67690704d 100644
--- a/hypervisor/src/mshv/mod.rs
+++ b/hypervisor/src/mshv/mod.rs
@@ -867,17 +867,9 @@ impl cpu::Vcpu for MshvVcpu {
SVM_NAE_HV_DOORBELL_PAGE_GET_PREFERRED => {
// Hypervisor does not have any preference for doorbell GPA.
let preferred_doorbell_gpa: u64 = 0xFFFFFFFFFFFFFFFF;
- let mut swei2_rw_gpa_arg =
- mshv_bindings::mshv_read_write_gpa {
- base_gpa: ghcb_gpa + GHCB_SW_EXITINFO2_OFFSET,
- byte_count: std::mem::size_of::<u64>() as u32,
- ..Default::default()
- };
- swei2_rw_gpa_arg.data.copy_from_slice(
+ self.gpa_write(
+ ghcb_gpa + GHCB_SW_EXITINFO2_OFFSET,
&preferred_doorbell_gpa.to_le_bytes(),
- );
- self.fd.gpa_write(&mut swei2_rw_gpa_arg).map_err(
- |e| cpu::HypervisorCpuError::GpaWrite(e.into()),
)?;
}
SVM_NAE_HV_DOORBELL_PAGE_SET => {
@@ -905,16 +897,9 @@ impl cpu::Vcpu for MshvVcpu {
cpu::HypervisorCpuError::SetRegister(e.into())
})?;
- let mut swei2_rw_gpa_arg =
- mshv_bindings::mshv_read_write_gpa {
- base_gpa: ghcb_gpa + GHCB_SW_EXITINFO2_OFFSET,
- byte_count: std::mem::size_of::<u64>() as u32,
- ..Default::default()
- };
- swei2_rw_gpa_arg.data[0..8]
- .copy_from_slice(&exit_info2.to_le_bytes());
- self.fd.gpa_write(&mut swei2_rw_gpa_arg).map_err(
- |e| cpu::HypervisorCpuError::GpaWrite(e.into()),
+ self.gpa_write(
+ ghcb_gpa + GHCB_SW_EXITINFO2_OFFSET,
+ &exit_info2.to_le_bytes(),
)?;
// Clear the SW_EXIT_INFO1 register to indicate no error
@@ -928,31 +913,19 @@ impl cpu::Vcpu for MshvVcpu {
self.fd.get_reg(&mut reg_assocs).unwrap();
// SAFETY: Accessing a union element from bindgen generated bindings.
let doorbell_gpa = unsafe { reg_assocs[0].value.reg64 };
- let mut swei2_rw_gpa_arg =
- mshv_bindings::mshv_read_write_gpa {
- base_gpa: ghcb_gpa + GHCB_SW_EXITINFO2_OFFSET,
- byte_count: std::mem::size_of::<u64>() as u32,
- ..Default::default()
- };
- swei2_rw_gpa_arg
- .data
- .copy_from_slice(&doorbell_gpa.to_le_bytes());
- self.fd.gpa_write(&mut swei2_rw_gpa_arg).map_err(
- |e| cpu::HypervisorCpuError::GpaWrite(e.into()),
+
+ self.gpa_write(
+ ghcb_gpa + GHCB_SW_EXITINFO2_OFFSET,
+ &doorbell_gpa.to_le_bytes(),
)?;
// Clear the SW_EXIT_INFO1 register to indicate no error
self.clear_swexit_info1(ghcb_gpa)?;
}
SVM_NAE_HV_DOORBELL_PAGE_CLEAR => {
- let mut swei2_rw_gpa_arg =
- mshv_bindings::mshv_read_write_gpa {
- base_gpa: ghcb_gpa + GHCB_SW_EXITINFO2_OFFSET,
- byte_count: std::mem::size_of::<u64>() as u32,
- ..Default::default()
- };
- self.fd.gpa_write(&mut swei2_rw_gpa_arg).map_err(
- |e| cpu::HypervisorCpuError::GpaWrite(e.into()),
+ self.gpa_write(
+ ghcb_gpa + GHCB_SW_EXITINFO2_OFFSET,
+ &[0; 8],
)?;
}
_ => {
@@ -970,16 +943,10 @@ impl cpu::Vcpu for MshvVcpu {
// 0x6 means `The NAE event was not valid`
// Reference: GHCB Spec, page 42
let value: u64 = 0x6;
- let mut swei2_rw_gpa_arg = mshv_bindings::mshv_read_write_gpa {
- base_gpa: ghcb_gpa + GHCB_SW_EXITINFO2_OFFSET,
- byte_count: std::mem::size_of::<u64>() as u32,
- ..Default::default()
- };
- swei2_rw_gpa_arg.data[0..8]
- .copy_from_slice(&value.to_le_bytes());
- self.fd
- .gpa_write(&mut swei2_rw_gpa_arg)
- .map_err(|e| cpu::HypervisorCpuError::GpaWrite(e.into()))?;
+ self.gpa_write(
+ ghcb_gpa + GHCB_SW_EXITINFO2_OFFSET,
+ &value.to_le_bytes(),
+ )?;
}
SVM_EXITCODE_IOIO_PROT => {
let exit_info1 =
@@ -1005,42 +972,26 @@ impl cpu::Vcpu for MshvVcpu {
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()))?;
+
+ let mut data = [0; 8];
+ self.gpa_read(ghcb_gpa + GHCB_RAX_OFFSET, &mut data)?;
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())
- })?;
+ vm_ops.pio_write(port.into(), &data[..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],
- )
+ .pio_read(port.into(), &mut data[..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())
- })?;
+ self.gpa_write(ghcb_gpa + GHCB_RAX_OFFSET, &data)?;
}
// Clear the SW_EXIT_INFO1 register to indicate no error
@@ -1058,21 +1009,12 @@ impl cpu::Vcpu for MshvVcpu {
let mut data: Vec<u8> = vec![0; data_len];
if let Some(vm_ops) = &self.vm_ops {
- vm_ops.mmio_read(src_gpa, &mut data[0..data_len]).map_err(
- |e| cpu::HypervisorCpuError::RunVcpu(e.into()),
- )?;
+ vm_ops.mmio_read(src_gpa, &mut data).map_err(|e| {
+ cpu::HypervisorCpuError::RunVcpu(e.into())
+ })?;
}
- let mut arg: mshv_read_write_gpa =
- mshv_bindings::mshv_read_write_gpa {
- base_gpa: dst_gpa,
- byte_count: data_len as u32,
- ..Default::default()
- };
- arg.data[0..data_len].copy_from_slice(&data);
-
- self.fd
- .gpa_write(&mut arg)
- .map_err(|e| cpu::HypervisorCpuError::GpaWrite(e.into()))?;
+
+ self.gpa_write(dst_gpa, &data)?;
// Clear the SW_EXIT_INFO1 register to indicate no error
self.clear_swexit_info1(ghcb_gpa)?;
@@ -1086,23 +1028,14 @@ impl cpu::Vcpu for MshvVcpu {
as usize;
// Sanity check to make sure data len is within supported range.
assert!(data_len <= 0x8);
- let mut arg: mshv_read_write_gpa =
- mshv_bindings::mshv_read_write_gpa {
- base_gpa: src_gpa,
- byte_count: data_len as u32,
- ..Default::default()
- };
- self.fd
- .gpa_read(&mut arg)
- .map_err(|e| cpu::HypervisorCpuError::GpaRead(e.into()))?;
+ let mut data = vec![0; data_len];
+ self.gpa_read(src_gpa, &mut data)?;
if let Some(vm_ops) = &self.vm_ops {
- vm_ops
- .mmio_write(dst_gpa, &arg.data[0..data_len])
- .map_err(|e| {
- cpu::HypervisorCpuError::RunVcpu(e.into())
- })?;
+ vm_ops.mmio_write(dst_gpa, &data).map_err(|e| {
+ cpu::HypervisorCpuError::RunVcpu(e.into())
+ })?;
}
// Clear the SW_EXIT_INFO1 register to indicate no error
@@ -1125,14 +1058,7 @@ impl cpu::Vcpu for MshvVcpu {
req_gpa, rsp_gpa
);
- let mut swei2_rw_gpa_arg = mshv_bindings::mshv_read_write_gpa {
- base_gpa: ghcb_gpa + GHCB_SW_EXITINFO2_OFFSET,
- byte_count: std::mem::size_of::<u64>() as u32,
- ..Default::default()
- };
- self.fd
- .gpa_write(&mut swei2_rw_gpa_arg)
- .map_err(|e| cpu::HypervisorCpuError::GpaWrite(e.into()))?;
+ self.gpa_write(ghcb_gpa + GHCB_SW_EXITINFO2_OFFSET, &[0; 8])?;
}
SVM_EXITCODE_SNP_AP_CREATION => {
let vmsa_gpa =
@@ -1479,17 +1405,54 @@ impl MshvVcpu {
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()))?;
+ self.gpa_write(ghcb_gpa + GHCB_SW_EXITINFO1_OFFSET, &[0; 4])?;
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")]
+ fn gpa_write(&self, gpa: u64, data: &[u8]) -> cpu::Result<()> {
+ for (gpa, chunk) in (gpa..)
+ .step_by(HV_READ_WRITE_GPA_MAX_SIZE as usize)
+ .zip(data.chunks(HV_READ_WRITE_GPA_MAX_SIZE as usize))
+ {
+ let mut data = [0; HV_READ_WRITE_GPA_MAX_SIZE as usize];
+ data[..chunk.len()].copy_from_slice(chunk);
+
+ let mut rw_gpa_arg = mshv_bindings::mshv_read_write_gpa {
+ base_gpa: gpa,
+ byte_count: chunk.len() as u32,
+ data,
+ ..Default::default()
+ };
+ self.fd
+ .gpa_write(&mut rw_gpa_arg)
+ .map_err(|e| cpu::HypervisorCpuError::GpaWrite(e.into()))?;
+ }
+
+ Ok(())
+ }
}
struct MshvEmulatorContext<'a> {
--
2.34.1
From e82fe7585376cb8579d1cca208609f5507fde615 Mon Sep 17 00:00:00 2001
From: Tom Dohrmann <erbse.13@gmx.de>
Date: Mon, 26 Aug 2024 11:14:34 +0200
Subject: [PATCH 3/3] 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>
(cherry picked from commit 8fd0310db9b816c5f3dae2cf5e714359e96478a9)
Signed-off-by: Wei Liu <liuwe@microsoft.com>
---
hypervisor/src/mshv/mod.rs | 33 +++++++++++++++++-----------
hypervisor/src/mshv/snp_constants.rs | 1 +
2 files changed, 21 insertions(+), 13 deletions(-)
diff --git a/hypervisor/src/mshv/mod.rs b/hypervisor/src/mshv/mod.rs
index 67690704d..afe17694d 100644
--- a/hypervisor/src/mshv/mod.rs
+++ b/hypervisor/src/mshv/mod.rs
@@ -936,18 +936,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 => {
let exit_info1 =
info.__bindgen_anon_2.__bindgen_anon_1.sw_exit_info1 as u32;
@@ -1041,7 +1029,26 @@ impl cpu::Vcpu for MshvVcpu {
// 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
+ | 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 =
info.__bindgen_anon_2.__bindgen_anon_1.sw_exit_info1;
let rsp_gpa =
diff --git a/hypervisor/src/mshv/snp_constants.rs b/hypervisor/src/mshv/snp_constants.rs
index 307326ddd..69b123647 100644
--- a/hypervisor/src/mshv/snp_constants.rs
+++ b/hypervisor/src/mshv/snp_constants.rs
@@ -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
// 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_EXITINFO1_OFFSET: u64 = 0x398;
pub const GHCB_SW_EXITINFO2_OFFSET: u64 = 0x3A0;
--
2.34.1