diff --git a/src/runtime-rs/crates/hypervisor/ch-config/src/convert.rs b/src/runtime-rs/crates/hypervisor/ch-config/src/convert.rs index cd6998a649..4d35292262 100644 --- a/src/runtime-rs/crates/hypervisor/ch-config/src/convert.rs +++ b/src/runtime-rs/crates/hypervisor/ch-config/src/convert.rs @@ -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 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 for VmConfig { boot_info.clone(), kernel_params, guest_protection_to_use.clone(), + protection_dev, )) .map_err(VmConfigError::PayloadError)?, ); @@ -385,13 +388,28 @@ impl From for CpuFeatures { // // - The 3rd tuple element determines if TDX is enabled. // -impl TryFrom<(BootInfo, Option, GuestProtection)> for PayloadConfig { +impl + TryFrom<( + BootInfo, + Option, + GuestProtection, + Option, + )> for PayloadConfig +{ type Error = PayloadConfigError; - fn try_from(args: (BootInfo, Option, GuestProtection)) -> Result { + fn try_from( + args: ( + BootInfo, + Option, + GuestProtection, + Option, + ), + ) -> Result { 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, 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, guest_protection: GuestProtection, + protection_device: Option, result: Result, } @@ -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); diff --git a/src/runtime-rs/crates/hypervisor/ch-config/src/lib.rs b/src/runtime-rs/crates/hypervisor/ch-config/src/lib.rs index 8b6dfa69ca..19b0489c4a 100644 --- a/src/runtime-rs/crates/hypervisor/ch-config/src/lib.rs +++ b/src/runtime-rs/crates/hypervisor/ch-config/src/lib.rs @@ -229,6 +229,12 @@ pub struct MemoryZoneConfig { pub prefault: bool, } +#[derive(Clone, Debug, Default, PartialEq, Eq, Deserialize, Serialize)] +pub struct ProtectionDevConfig { + pub mrconfigid: Option, + pub host_data: Option, +} + #[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, #[serde(default)] pub initramfs: Option, + #[serde(default)] + pub mrconfigid: Option, + #[serde(default)] + pub host_data: Option, } #[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, } #[derive(Clone, Debug, Deserialize, Serialize, Default)] diff --git a/src/runtime-rs/crates/hypervisor/src/ch/inner_device.rs b/src/runtime-rs/crates/hypervisor/src/ch/inner_device.rs index 7ef5fd7dad..816b18bf7d 100644 --- a/src/runtime-rs/crates/hypervisor/src/ch/inner_device.rs +++ b/src/runtime-rs/crates/hypervisor/src/ch/inner_device.rs @@ -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>, Option>, Option>, + Option, )> { let mut shared_fs_devices = Vec::::new(); let mut network_devices = Vec::::new(); let mut host_devices = Vec::::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), )) } } diff --git a/src/runtime-rs/crates/hypervisor/src/ch/inner_hypervisor.rs b/src/runtime-rs/crates/hypervisor/src/ch/inner_hypervisor.rs index 68146b6b4c..7a3a4bb013 100644 --- a/src/runtime-rs/crates/hypervisor/src/ch/inner_hypervisor.rs +++ b/src/runtime-rs/crates/hypervisor/src/ch/inner_hypervisor.rs @@ -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() };