mirror of
https://github.com/kata-containers/kata-containers.git
synced 2025-06-28 16:27:50 +00:00
runtime-rs: ch: Generate Cloud Hypervisor config for confidential guests
This change provides a preliminary implementation for the Cloud Hypervisor (CH) feature ([currently disabled](https://github.com/kata-containers/kata-containers/pull/6201)) to allow it to generate the CH configuration for handling confidential guests. This change also introduces concrete errors using the `thiserror` crate (see `src/runtime-rs/crates/hypervisor/ch-config/src/errors.rs`) and a lot of unit tests for the conversion code that generates the CH configuration from the generic Hypervisor configuration. Fixes: #6430. Signed-off-by: James O. D. Hunt <james.o.hunt@intel.com>
This commit is contained in:
parent
96555186b3
commit
ac58588682
1
src/runtime-rs/Cargo.lock
generated
1
src/runtime-rs/Cargo.lock
generated
@ -423,6 +423,7 @@ dependencies = [
|
|||||||
"nix 0.26.2",
|
"nix 0.26.2",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
|
"thiserror",
|
||||||
"tokio",
|
"tokio",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -23,3 +23,4 @@ api_client = { git = "https://github.com/cloud-hypervisor/cloud-hypervisor", cra
|
|||||||
|
|
||||||
kata-types = { path = "../../../../libs/kata-types"}
|
kata-types = { path = "../../../../libs/kata-types"}
|
||||||
nix = "0.26.2"
|
nix = "0.26.2"
|
||||||
|
thiserror = "1.0.38"
|
||||||
|
File diff suppressed because it is too large
Load Diff
107
src/runtime-rs/crates/hypervisor/ch-config/src/errors.rs
Normal file
107
src/runtime-rs/crates/hypervisor/ch-config/src/errors.rs
Normal file
@ -0,0 +1,107 @@
|
|||||||
|
// Copyright (c) 2023 Intel Corporation
|
||||||
|
//
|
||||||
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
|
use std::convert::TryFrom;
|
||||||
|
use thiserror::Error;
|
||||||
|
|
||||||
|
#[derive(Error, Debug, PartialEq)]
|
||||||
|
pub enum VmConfigError {
|
||||||
|
#[error("empty sandbox path")]
|
||||||
|
EmptySandboxPath,
|
||||||
|
|
||||||
|
#[error("empty VSOCK socket path")]
|
||||||
|
EmptyVsockSocketPath,
|
||||||
|
|
||||||
|
#[error("cannot specify image and initrd")]
|
||||||
|
MultipleBootFiles,
|
||||||
|
|
||||||
|
#[error("missing boot image (no rootfs image or initrd)")]
|
||||||
|
NoBootFile,
|
||||||
|
|
||||||
|
#[error("CPU config error: {0}")]
|
||||||
|
CPUError(CpusConfigError),
|
||||||
|
|
||||||
|
#[error("Pmem config error: {0}")]
|
||||||
|
PmemError(PmemConfigError),
|
||||||
|
|
||||||
|
#[error("Payload config error: {0}")]
|
||||||
|
PayloadError(PayloadConfigError),
|
||||||
|
|
||||||
|
#[error("Disk config error: {0}")]
|
||||||
|
DiskError(DiskConfigError),
|
||||||
|
|
||||||
|
#[error("Memory config error: {0}")]
|
||||||
|
MemoryError(MemoryConfigError),
|
||||||
|
|
||||||
|
// The 2nd arg is actually a std::io::Error but that doesn't implement
|
||||||
|
// PartialEq, so we convert it to a String.
|
||||||
|
#[error("Failed to create sandbox path ({0}: {1}")]
|
||||||
|
SandboxError(String, String),
|
||||||
|
|
||||||
|
#[error("VSOCK config error: {0}")]
|
||||||
|
VsockError(VsockConfigError),
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Error, Debug, PartialEq)]
|
||||||
|
pub enum PmemConfigError {
|
||||||
|
#[error("Need rootfs image for PmemConfig")]
|
||||||
|
MissingImage,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Error, Debug, PartialEq)]
|
||||||
|
pub enum DiskConfigError {
|
||||||
|
#[error("Need path for DiskConfig")]
|
||||||
|
MissingPath,
|
||||||
|
|
||||||
|
#[error("Found unexpected path for DiskConfig with TDX: {0}")]
|
||||||
|
UnexpectedPathForTDX(String),
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Error, Debug, PartialEq)]
|
||||||
|
pub enum CpusConfigError {
|
||||||
|
#[error("Too many boot vCPUs specified: {0}")]
|
||||||
|
BootVCPUsTooBig(<u8 as TryFrom<i32>>::Error),
|
||||||
|
|
||||||
|
#[error("Too many max vCPUs specified: {0}")]
|
||||||
|
MaxVCPUsTooBig(<u8 as TryFrom<u32>>::Error),
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Error, Debug, PartialEq)]
|
||||||
|
pub enum PayloadConfigError {
|
||||||
|
#[error("No kernel specified")]
|
||||||
|
NoKernel,
|
||||||
|
|
||||||
|
#[error("No initrd/initramfs specified")]
|
||||||
|
NoInitrd,
|
||||||
|
|
||||||
|
#[error("Need firmware for TDX")]
|
||||||
|
TDXFirmwareMissing,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Error, Debug, PartialEq)]
|
||||||
|
pub enum MemoryConfigError {
|
||||||
|
#[error("No default memory specified")]
|
||||||
|
NoDefaultMemory,
|
||||||
|
|
||||||
|
#[error("Default memory size > available RAM")]
|
||||||
|
DefaultMemSizeTooBig,
|
||||||
|
|
||||||
|
#[error("Cannot convert default memory to bytes: {0}")]
|
||||||
|
BadDefaultMemSize(u32),
|
||||||
|
|
||||||
|
#[error("Cannot calculate hotplug memory size from default memory: {0}")]
|
||||||
|
BadMemSizeForHotplug(u64),
|
||||||
|
|
||||||
|
#[error("Cannot align hotplug memory size from pmem: {0}")]
|
||||||
|
BadPmemAlign(u64),
|
||||||
|
|
||||||
|
#[error("Failed to query system memory information: {0}")]
|
||||||
|
SysInfoFail(#[source] nix::errno::Errno),
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Error, Debug, PartialEq)]
|
||||||
|
pub enum VsockConfigError {
|
||||||
|
#[error("Missing VSOCK socket path")]
|
||||||
|
NoVsockSocketPath,
|
||||||
|
}
|
@ -17,6 +17,8 @@ pub use net_util::MacAddr;
|
|||||||
|
|
||||||
pub const MAX_NUM_PCI_SEGMENTS: u16 = 16;
|
pub const MAX_NUM_PCI_SEGMENTS: u16 = 16;
|
||||||
|
|
||||||
|
mod errors;
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq, Eq, Deserialize, Serialize, Default)]
|
#[derive(Clone, Debug, PartialEq, Eq, Deserialize, Serialize, Default)]
|
||||||
pub struct BalloonConfig {
|
pub struct BalloonConfig {
|
||||||
pub size: u64,
|
pub size: u64,
|
||||||
@ -330,7 +332,6 @@ pub struct PlatformConfig {
|
|||||||
pub uuid: Option<String>,
|
pub uuid: Option<String>,
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
pub oem_strings: Option<Vec<String>>,
|
pub oem_strings: Option<Vec<String>>,
|
||||||
#[cfg(feature = "tdx")]
|
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
pub tdx: bool,
|
pub tdx: bool,
|
||||||
}
|
}
|
||||||
@ -425,9 +426,7 @@ pub struct VmConfig {
|
|||||||
pub fs: Option<Vec<FsConfig>>,
|
pub fs: Option<Vec<FsConfig>>,
|
||||||
#[serde(skip_serializing_if = "Option::is_none")]
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
pub pmem: Option<Vec<PmemConfig>>,
|
pub pmem: Option<Vec<PmemConfig>>,
|
||||||
//#[serde(default = "ConsoleConfig::default_serial")]
|
|
||||||
pub serial: ConsoleConfig,
|
pub serial: ConsoleConfig,
|
||||||
//#[serde(default = "ConsoleConfig::default_console")]
|
|
||||||
pub console: ConsoleConfig,
|
pub console: ConsoleConfig,
|
||||||
#[serde(skip_serializing_if = "Option::is_none")]
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
pub devices: Option<Vec<DeviceConfig>>,
|
pub devices: Option<Vec<DeviceConfig>>,
|
||||||
@ -484,12 +483,13 @@ fn u16_is_zero(v: &u16) -> bool {
|
|||||||
|
|
||||||
// Type used to simplify conversion from a generic Hypervisor config
|
// Type used to simplify conversion from a generic Hypervisor config
|
||||||
// to a CH specific VmConfig.
|
// to a CH specific VmConfig.
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone, Default)]
|
||||||
pub struct NamedHypervisorConfig {
|
pub struct NamedHypervisorConfig {
|
||||||
pub kernel_params: String,
|
pub kernel_params: String,
|
||||||
pub sandbox_path: String,
|
pub sandbox_path: String,
|
||||||
pub vsock_socket_path: String,
|
pub vsock_socket_path: String,
|
||||||
pub cfg: HypervisorConfig,
|
pub cfg: HypervisorConfig,
|
||||||
|
pub tdx_enabled: bool,
|
||||||
|
|
||||||
pub shared_fs_devices: Option<Vec<FsConfig>>,
|
pub shared_fs_devices: Option<Vec<FsConfig>>,
|
||||||
}
|
}
|
||||||
|
@ -68,6 +68,8 @@ impl CloudHypervisorInner {
|
|||||||
|
|
||||||
let enable_debug = cfg.debug_info.enable_debug;
|
let enable_debug = cfg.debug_info.enable_debug;
|
||||||
|
|
||||||
|
let confidential_guest = cfg.security_info.confidential_guest;
|
||||||
|
|
||||||
// Note that the configuration option hypervisor.block_device_driver is not used.
|
// Note that the configuration option hypervisor.block_device_driver is not used.
|
||||||
let rootfs_driver = VM_ROOTFS_DRIVER_PMEM;
|
let rootfs_driver = VM_ROOTFS_DRIVER_PMEM;
|
||||||
|
|
||||||
@ -81,6 +83,18 @@ impl CloudHypervisorInner {
|
|||||||
|
|
||||||
let mut rootfs_param = KernelParams::new_rootfs_kernel_params(rootfs_driver, rootfs_type)?;
|
let mut rootfs_param = KernelParams::new_rootfs_kernel_params(rootfs_driver, rootfs_type)?;
|
||||||
|
|
||||||
|
let mut extra_params = if enable_debug {
|
||||||
|
if confidential_guest {
|
||||||
|
KernelParams::from_string("console=hvc0")
|
||||||
|
} else {
|
||||||
|
KernelParams::from_string("console=ttyS0,115200n8")
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
KernelParams::from_string("quiet")
|
||||||
|
};
|
||||||
|
|
||||||
|
params.append(&mut extra_params);
|
||||||
|
|
||||||
// Add the rootfs device
|
// Add the rootfs device
|
||||||
params.append(&mut rootfs_param);
|
params.append(&mut rootfs_param);
|
||||||
|
|
||||||
@ -121,11 +135,18 @@ impl CloudHypervisorInner {
|
|||||||
|
|
||||||
let kernel_params = self.get_kernel_params().await?;
|
let kernel_params = self.get_kernel_params().await?;
|
||||||
|
|
||||||
|
// FIXME: See:
|
||||||
|
//
|
||||||
|
// - https://github.com/kata-containers/kata-containers/issues/6383
|
||||||
|
// - https://github.com/kata-containers/kata-containers/pull/6257
|
||||||
|
let tdx_enabled = false;
|
||||||
|
|
||||||
let named_cfg = NamedHypervisorConfig {
|
let named_cfg = NamedHypervisorConfig {
|
||||||
kernel_params,
|
kernel_params,
|
||||||
sandbox_path,
|
sandbox_path,
|
||||||
vsock_socket_path,
|
vsock_socket_path,
|
||||||
cfg: hypervisor_config.clone(),
|
cfg: hypervisor_config.clone(),
|
||||||
|
tdx_enabled,
|
||||||
shared_fs_devices,
|
shared_fs_devices,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user