Merge pull request #11562 from Apokleos/clh-initdata

runtime-rs: Add CoCo/protected device for initdata within runtime-rs/Cloud Hypervisor
This commit is contained in:
Saul Paredes
2026-04-17 11:09:19 -07:00
committed by GitHub
4 changed files with 85 additions and 4 deletions

View File

@@ -3,6 +3,7 @@
// SPDX-License-Identifier: Apache-2.0
use crate::NamedHypervisorConfig;
use crate::ProtectionDevConfig;
use crate::VmConfig;
use crate::{
guest_protection_is_tdx, ConsoleConfig, ConsoleOutputMode, CpuFeatures, CpuTopology,
@@ -110,6 +111,7 @@ impl TryFrom<NamedHypervisorConfig> for VmConfig {
let fs = n.shared_fs_devices;
let net = n.network_devices;
let host_devices = n.host_devices;
let protection_dev = n.protection_device;
let cpus = CpusConfig::try_from((cfg.cpu_info, guest_protection_to_use.clone()))
.map_err(VmConfigError::CPUError)?;
@@ -143,6 +145,7 @@ impl TryFrom<NamedHypervisorConfig> for VmConfig {
boot_info.clone(),
kernel_params,
guest_protection_to_use.clone(),
protection_dev,
))
.map_err(VmConfigError::PayloadError)?,
);
@@ -385,13 +388,28 @@ impl From<String> for CpuFeatures {
//
// - The 3rd tuple element determines if TDX is enabled.
//
impl TryFrom<(BootInfo, Option<String>, GuestProtection)> for PayloadConfig {
impl
TryFrom<(
BootInfo,
Option<String>,
GuestProtection,
Option<ProtectionDevConfig>,
)> for PayloadConfig
{
type Error = PayloadConfigError;
fn try_from(args: (BootInfo, Option<String>, GuestProtection)) -> Result<Self, Self::Error> {
fn try_from(
args: (
BootInfo,
Option<String>,
GuestProtection,
Option<ProtectionDevConfig>,
),
) -> Result<Self, Self::Error> {
let boot_info = args.0;
let cmdline = args.1;
let guest_protection_to_use = args.2;
let protection_device = args.3;
// The kernel is always specified here,
// not in the top level VmConfig.kernel.
@@ -419,11 +437,25 @@ impl TryFrom<(BootInfo, Option<String>, GuestProtection)> for PayloadConfig {
Some(PathBuf::from(boot_info.firmware))
};
let mrconfigid = if let Some(ref data) = protection_device {
data.mrconfigid.clone()
} else {
None
};
let host_data = if let Some(ref data) = protection_device {
data.host_data.clone()
} else {
None
};
let payload = PayloadConfig {
kernel: Some(kernel),
initramfs,
cmdline,
firmware,
mrconfigid,
host_data,
};
Ok(payload)
@@ -695,6 +727,8 @@ mod tests {
initramfs: Some(PathBuf::from(initramfs)),
firmware: payload_firmware,
cmdline,
mrconfigid: None,
host_data: None,
};
(boot_info, payload_config)
@@ -1272,6 +1306,7 @@ mod tests {
boot_info: BootInfo,
cmdline: Option<String>,
guest_protection: GuestProtection,
protection_device: Option<ProtectionDevConfig>,
result: Result<PayloadConfig, PayloadConfigError>,
}
@@ -1308,6 +1343,7 @@ mod tests {
boot_info: BootInfo::default(),
cmdline: None,
guest_protection: GuestProtection::NoProtection,
protection_device: None,
result: Err(PayloadConfigError::NoKernel),
},
TestData {
@@ -1320,6 +1356,7 @@ mod tests {
},
cmdline: None,
guest_protection: GuestProtection::NoProtection,
protection_device: None,
result: Ok(PayloadConfig {
kernel: Some(PathBuf::from(kernel)),
cmdline: None,
@@ -1339,11 +1376,14 @@ mod tests {
},
cmdline: None,
guest_protection: GuestProtection::NoProtection,
protection_device: None,
result: Ok(PayloadConfig {
kernel: Some(PathBuf::from(kernel)),
cmdline: None,
initramfs: Some(PathBuf::from(initramfs)),
firmware: Some(PathBuf::from(firmware)),
mrconfigid: None,
host_data: None,
}),
},
TestData {
@@ -1356,6 +1396,7 @@ mod tests {
},
cmdline: Some(cmdline.to_string()),
guest_protection: GuestProtection::NoProtection,
protection_device: None,
result: Ok(PayloadConfig {
kernel: Some(PathBuf::from(kernel)),
initramfs: Some(PathBuf::from(initramfs)),
@@ -1373,18 +1414,21 @@ mod tests {
},
cmdline: None,
guest_protection: GuestProtection::Tdx,
protection_device: None,
result: Err(PayloadConfigError::TDXFirmwareMissing),
},
TestData {
boot_info: boot_info_with_initrd,
cmdline: Some(cmdline.to_string()),
guest_protection: GuestProtection::Tdx,
protection_device: None,
result: Ok(payload_config_with_initrd),
},
TestData {
boot_info: boot_info_without_initrd,
cmdline: Some(cmdline.to_string()),
guest_protection: GuestProtection::Tdx,
protection_device: None,
result: Ok(payload_config_without_initrd),
},
];
@@ -1396,6 +1440,7 @@ mod tests {
d.boot_info.clone(),
d.cmdline.clone(),
d.guest_protection.clone(),
d.protection_device.clone(),
));
let msg = format!("{}: actual result: {:?}", msg, result);

View File

@@ -229,6 +229,12 @@ pub struct MemoryZoneConfig {
pub prefault: bool,
}
#[derive(Clone, Debug, Default, PartialEq, Eq, Deserialize, Serialize)]
pub struct ProtectionDevConfig {
pub mrconfigid: Option<String>,
pub host_data: Option<String>,
}
#[derive(Clone, Debug, PartialEq, Eq, Deserialize, Serialize)]
pub struct NetConfig {
//#[serde(default = "default_netconfig_tap")]
@@ -330,6 +336,10 @@ pub struct PayloadConfig {
pub cmdline: Option<String>,
#[serde(default)]
pub initramfs: Option<PathBuf>,
#[serde(default)]
pub mrconfigid: Option<String>,
#[serde(default)]
pub host_data: Option<String>,
}
#[derive(Clone, Debug, PartialEq, Eq, Deserialize, Serialize, Default)]
@@ -510,6 +520,7 @@ pub struct NamedHypervisorConfig {
// - The hardware supports guest protection.
// - The user has requested that guest protection be used.
pub guest_protection_to_use: GuestProtection,
pub protection_device: Option<ProtectionDevConfig>,
}
#[derive(Clone, Debug, Deserialize, Serialize, Default)]

View File

@@ -13,6 +13,7 @@ use crate::utils::open_named_tuntap;
use crate::HybridVsockDevice;
use crate::NetworkConfig;
use crate::NetworkDevice;
use crate::ProtectionDeviceConfig;
use crate::ShareFsConfig;
use crate::ShareFsDevice;
use crate::VfioDevice;
@@ -28,10 +29,13 @@ use ch_config::ch_api::{
use ch_config::convert::DEFAULT_NUM_PCI_SEGMENTS;
use ch_config::DiskConfig;
use ch_config::ImageType;
use ch_config::{net_util::MacAddr, DeviceConfig, FsConfig, NetConfig, VsockConfig};
use ch_config::{
net_util::MacAddr, DeviceConfig, FsConfig, NetConfig, ProtectionDevConfig, VsockConfig,
};
use kata_sys_util::netns::NetnsGuard;
use kata_types::config::hypervisor::RateLimiterConfig;
use kata_types::rootless::is_rootless;
use safe_path::scoped_join;
use std::convert::TryFrom;
use std::os::fd::AsRawFd;
@@ -72,6 +76,7 @@ impl CloudHypervisorInner {
DeviceType::ShareFs(_) => self.pending_devices.insert(0, device.clone()),
DeviceType::Network(_) => self.pending_devices.insert(0, device.clone()),
DeviceType::Vfio(_) => self.pending_devices.insert(0, device.clone()),
DeviceType::Protection(_) => self.pending_devices.insert(0, device.clone()),
_ => {
debug!(
sl!(),
@@ -404,10 +409,12 @@ impl CloudHypervisorInner {
Option<Vec<FsConfig>>,
Option<Vec<NetConfig>>,
Option<Vec<DeviceConfig>>,
Option<ProtectionDevConfig>,
)> {
let mut shared_fs_devices = Vec::<FsConfig>::new();
let mut network_devices = Vec::<NetConfig>::new();
let mut host_devices = Vec::<DeviceConfig>::new();
let mut protection_device = ProtectionDevConfig::default();
while let Some(dev) = self.pending_devices.pop() {
match dev {
@@ -512,6 +519,20 @@ impl CloudHypervisorInner {
);
host_devices.push(device_config);
}
DeviceType::Protection(pdev) => {
let config = pdev.config;
match config {
ProtectionDeviceConfig::SevSnp(sevsnp_cfg) => {
if sevsnp_cfg.is_snp {
protection_device.host_data = sevsnp_cfg.host_data;
}
}
ProtectionDeviceConfig::Tdx(tdx_config) => {
protection_device.mrconfigid = tdx_config.mrconfigid;
}
_ => info!(sl!(), "CH: unsupported protection device type"),
}
}
_ => continue,
}
}
@@ -520,6 +541,7 @@ impl CloudHypervisorInner {
Some(shared_fs_devices),
Some(network_devices),
Some(host_devices),
Some(protection_device),
))
}
}

View File

@@ -187,7 +187,9 @@ impl CloudHypervisorInner {
}
async fn boot_vm(&mut self) -> Result<()> {
let (shared_fs_devices, network_devices, host_devices) = self.get_shared_devices().await?;
let (shared_fs_devices, network_devices, host_devices, protection_device) =
self.get_shared_devices().await?;
let socket = self
.api_socket
.as_ref()
@@ -217,6 +219,7 @@ impl CloudHypervisorInner {
guest_protection_to_use: self.guest_protection_to_use.clone(),
shared_fs_devices,
host_devices,
protection_device,
..Default::default()
};