mirror of
https://github.com/kata-containers/kata-containers.git
synced 2025-06-18 11:50:03 +00:00
runtime-rs: ch: Detect Intel TDX version
Improve the `GuestProtection` handling to detect the version of Intel TDX available. The TDX version is now logged by the Cloud Hypervisor driver. Fixes: #8147. Signed-off-by: James O. D. Hunt <james.o.hunt@intel.com>
This commit is contained in:
parent
538131ab44
commit
87b760f569
1
src/libs/Cargo.lock
generated
1
src/libs/Cargo.lock
generated
@ -558,6 +558,7 @@ dependencies = [
|
|||||||
"oci",
|
"oci",
|
||||||
"once_cell",
|
"once_cell",
|
||||||
"rand",
|
"rand",
|
||||||
|
"safe-path",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"serial_test",
|
"serial_test",
|
||||||
"slog",
|
"slog",
|
||||||
|
@ -30,6 +30,7 @@ thiserror = "1.0.30"
|
|||||||
|
|
||||||
kata-types = { path = "../kata-types" }
|
kata-types = { path = "../kata-types" }
|
||||||
oci = { path = "../oci" }
|
oci = { path = "../oci" }
|
||||||
|
safe-path = { path = "../safe-path" }
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
num_cpus = "1.13.1"
|
num_cpus = "1.13.1"
|
||||||
|
@ -3,11 +3,14 @@
|
|||||||
// SPDX-License-Identifier: Apache-2.0
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
//
|
//
|
||||||
|
|
||||||
|
#[cfg(target_arch = "x86_64")]
|
||||||
|
use anyhow::anyhow;
|
||||||
#[cfg(any(target_arch = "s390x", target_arch = "x86_64", target_arch = "aarch64"))]
|
#[cfg(any(target_arch = "s390x", target_arch = "x86_64", target_arch = "aarch64"))]
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
#[cfg(target_arch = "x86_64")]
|
#[cfg(target_arch = "x86_64")]
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
|
use std::path::PathBuf;
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
|
|
||||||
#[cfg(any(target_arch = "s390x", target_arch = "x86_64"))]
|
#[cfg(any(target_arch = "s390x", target_arch = "x86_64"))]
|
||||||
@ -16,12 +19,18 @@ use nix::unistd::Uid;
|
|||||||
#[cfg(target_arch = "x86_64")]
|
#[cfg(target_arch = "x86_64")]
|
||||||
use std::fs;
|
use std::fs;
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialEq, Eq, Default)]
|
||||||
|
pub struct TDXDetails {
|
||||||
|
pub major_version: u32,
|
||||||
|
pub minor_version: u32,
|
||||||
|
}
|
||||||
|
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
#[derive(Debug, Clone, PartialEq, Default)]
|
#[derive(Debug, Clone, PartialEq, Default)]
|
||||||
pub enum GuestProtection {
|
pub enum GuestProtection {
|
||||||
#[default]
|
#[default]
|
||||||
NoProtection,
|
NoProtection,
|
||||||
Tdx,
|
Tdx(TDXDetails),
|
||||||
Sev,
|
Sev,
|
||||||
Snp,
|
Snp,
|
||||||
Pef,
|
Pef,
|
||||||
@ -31,7 +40,11 @@ pub enum GuestProtection {
|
|||||||
impl fmt::Display for GuestProtection {
|
impl fmt::Display for GuestProtection {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
match self {
|
match self {
|
||||||
GuestProtection::Tdx => write!(f, "tdx"),
|
GuestProtection::Tdx(details) => write!(
|
||||||
|
f,
|
||||||
|
"tdx (major_version: {}, minor_version: {}",
|
||||||
|
details.major_version, details.minor_version
|
||||||
|
),
|
||||||
GuestProtection::Sev => write!(f, "sev"),
|
GuestProtection::Sev => write!(f, "sev"),
|
||||||
GuestProtection::Snp => write!(f, "snp"),
|
GuestProtection::Snp => write!(f, "snp"),
|
||||||
GuestProtection::Pef => write!(f, "pef"),
|
GuestProtection::Pef => write!(f, "pef"),
|
||||||
@ -52,6 +65,15 @@ pub enum ProtectionError {
|
|||||||
|
|
||||||
#[error("Invalid guest protection value: {0}")]
|
#[error("Invalid guest protection value: {0}")]
|
||||||
InvalidValue(String),
|
InvalidValue(String),
|
||||||
|
|
||||||
|
#[error("Cannot resolve path {0} below {1}: {2}")]
|
||||||
|
CannotResolvePath(String, PathBuf, anyhow::Error),
|
||||||
|
|
||||||
|
#[error("Expected file {0} not found: {1}")]
|
||||||
|
FileMissing(String, std::io::Error),
|
||||||
|
|
||||||
|
#[error("File {0} contains unexpected content: {1}")]
|
||||||
|
FileInvalid(PathBuf, anyhow::Error),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(target_arch = "x86_64")]
|
#[cfg(target_arch = "x86_64")]
|
||||||
@ -61,6 +83,18 @@ pub const SEV_KVM_PARAMETER_PATH: &str = "/sys/module/kvm_amd/parameters/sev";
|
|||||||
#[cfg(target_arch = "x86_64")]
|
#[cfg(target_arch = "x86_64")]
|
||||||
pub const SNP_KVM_PARAMETER_PATH: &str = "/sys/module/kvm_amd/parameters/sev_snp";
|
pub const SNP_KVM_PARAMETER_PATH: &str = "/sys/module/kvm_amd/parameters/sev_snp";
|
||||||
|
|
||||||
|
// Module directory below TDX_SYS_FIRMWARE_DIR.
|
||||||
|
#[cfg(target_arch = "x86_64")]
|
||||||
|
const TDX_FW_MODULE_DIR: &str = "tdx_module";
|
||||||
|
|
||||||
|
// File in TDX_FW_MODULE_DIR that specifies TDX major version number.
|
||||||
|
#[cfg(target_arch = "x86_64")]
|
||||||
|
const TDX_MAJOR_FILE: &str = "major_version";
|
||||||
|
|
||||||
|
// File in TDX_FW_MODULE_DIR that specifies TDX minor version number.
|
||||||
|
#[cfg(target_arch = "x86_64")]
|
||||||
|
const TDX_MINOR_FILE: &str = "minor_version";
|
||||||
|
|
||||||
#[cfg(target_arch = "x86_64")]
|
#[cfg(target_arch = "x86_64")]
|
||||||
pub fn available_guest_protection() -> Result<GuestProtection, ProtectionError> {
|
pub fn available_guest_protection() -> Result<GuestProtection, ProtectionError> {
|
||||||
if !Uid::effective().is_root() {
|
if !Uid::effective().is_root() {
|
||||||
@ -83,7 +117,59 @@ pub fn arch_guest_protection(
|
|||||||
let metadata = fs::metadata(tdx_path);
|
let metadata = fs::metadata(tdx_path);
|
||||||
|
|
||||||
if metadata.is_ok() && metadata.unwrap().is_dir() {
|
if metadata.is_ok() && metadata.unwrap().is_dir() {
|
||||||
return Ok(GuestProtection::Tdx);
|
let module_dir = safe_path::scoped_join(tdx_path, TDX_FW_MODULE_DIR).map_err(|e| {
|
||||||
|
ProtectionError::CannotResolvePath(
|
||||||
|
TDX_FW_MODULE_DIR.to_string(),
|
||||||
|
PathBuf::from(tdx_path),
|
||||||
|
anyhow!(e),
|
||||||
|
)
|
||||||
|
})?;
|
||||||
|
|
||||||
|
let major_file =
|
||||||
|
safe_path::scoped_join(module_dir.clone(), TDX_MAJOR_FILE).map_err(|e| {
|
||||||
|
ProtectionError::CannotResolvePath(
|
||||||
|
TDX_MAJOR_FILE.to_string(),
|
||||||
|
module_dir.clone(),
|
||||||
|
anyhow!(e),
|
||||||
|
)
|
||||||
|
})?;
|
||||||
|
|
||||||
|
let minor_file =
|
||||||
|
safe_path::scoped_join(module_dir.clone(), TDX_MINOR_FILE).map_err(|e| {
|
||||||
|
ProtectionError::CannotResolvePath(
|
||||||
|
TDX_MINOR_FILE.to_string(),
|
||||||
|
module_dir,
|
||||||
|
anyhow!(e),
|
||||||
|
)
|
||||||
|
})?;
|
||||||
|
|
||||||
|
const HEX_BASE: u32 = 16;
|
||||||
|
const HEX_PREFIX: &str = "0x";
|
||||||
|
|
||||||
|
let major_version_str = std::fs::read_to_string(major_file.clone()).map_err(|e| {
|
||||||
|
ProtectionError::FileMissing(major_file.clone().to_string_lossy().into(), e)
|
||||||
|
})?;
|
||||||
|
|
||||||
|
let major_version_str = major_version_str.trim_start_matches(HEX_PREFIX);
|
||||||
|
|
||||||
|
let major_version = u32::from_str_radix(&major_version_str, HEX_BASE)
|
||||||
|
.map_err(|e| ProtectionError::FileInvalid(major_file, anyhow!(e)))?;
|
||||||
|
|
||||||
|
let minor_version_str = std::fs::read_to_string(minor_file.clone()).map_err(|e| {
|
||||||
|
ProtectionError::FileMissing(minor_file.clone().to_string_lossy().into(), e)
|
||||||
|
})?;
|
||||||
|
|
||||||
|
let minor_version_str = minor_version_str.trim_start_matches(HEX_PREFIX);
|
||||||
|
|
||||||
|
let minor_version = u32::from_str_radix(&minor_version_str, HEX_BASE)
|
||||||
|
.map_err(|e| ProtectionError::FileInvalid(minor_file, anyhow!(e)))?;
|
||||||
|
|
||||||
|
let details = TDXDetails {
|
||||||
|
major_version,
|
||||||
|
minor_version,
|
||||||
|
};
|
||||||
|
|
||||||
|
return Ok(GuestProtection::Tdx(details));
|
||||||
}
|
}
|
||||||
|
|
||||||
let check_contents = |file_name: &str| -> Result<bool, ProtectionError> {
|
let check_contents = |file_name: &str| -> Result<bool, ProtectionError> {
|
||||||
@ -248,7 +334,41 @@ mod tests {
|
|||||||
assert_eq!(actual.unwrap(), GuestProtection::NoProtection);
|
assert_eq!(actual.unwrap(), GuestProtection::NoProtection);
|
||||||
|
|
||||||
let actual = arch_guest_protection(tdx_path.to_str().unwrap(), invalid_dir, invalid_dir);
|
let actual = arch_guest_protection(tdx_path.to_str().unwrap(), invalid_dir, invalid_dir);
|
||||||
assert!(actual.is_ok());
|
assert!(actual.is_err());
|
||||||
assert_eq!(actual.unwrap(), GuestProtection::Tdx);
|
|
||||||
|
let tdx_module = tdx_path.join(TDX_FW_MODULE_DIR);
|
||||||
|
std::fs::create_dir_all(tdx_module.clone()).unwrap();
|
||||||
|
|
||||||
|
let major_file = tdx_module.join(TDX_MAJOR_FILE);
|
||||||
|
std::fs::File::create(&major_file).unwrap();
|
||||||
|
|
||||||
|
let minor_file = tdx_module.join(TDX_MINOR_FILE);
|
||||||
|
std::fs::File::create(&minor_file).unwrap();
|
||||||
|
|
||||||
|
let result = arch_guest_protection(tdx_path.to_str().unwrap(), invalid_dir, invalid_dir);
|
||||||
|
assert!(result.is_err());
|
||||||
|
|
||||||
|
std::fs::write(&major_file, b"invalid").unwrap();
|
||||||
|
std::fs::write(&minor_file, b"invalid").unwrap();
|
||||||
|
|
||||||
|
let result = arch_guest_protection(tdx_path.to_str().unwrap(), invalid_dir, invalid_dir);
|
||||||
|
assert!(result.is_err());
|
||||||
|
|
||||||
|
// Fake a TDX 1.0 environment
|
||||||
|
std::fs::write(&major_file, b"0x00000001").unwrap();
|
||||||
|
std::fs::write(&minor_file, b"0x00000000").unwrap();
|
||||||
|
|
||||||
|
let result = arch_guest_protection(tdx_path.to_str().unwrap(), invalid_dir, invalid_dir);
|
||||||
|
assert!(result.is_ok());
|
||||||
|
|
||||||
|
let result = result.unwrap();
|
||||||
|
|
||||||
|
let details = match result {
|
||||||
|
GuestProtection::Tdx(details) => details,
|
||||||
|
_ => panic!(),
|
||||||
|
};
|
||||||
|
|
||||||
|
assert_eq!(details.major_version, 1);
|
||||||
|
assert_eq!(details.minor_version, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
1
src/runtime-rs/Cargo.lock
generated
1
src/runtime-rs/Cargo.lock
generated
@ -1574,6 +1574,7 @@ dependencies = [
|
|||||||
"oci",
|
"oci",
|
||||||
"once_cell",
|
"once_cell",
|
||||||
"rand 0.8.5",
|
"rand 0.8.5",
|
||||||
|
"safe-path 0.1.0",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"slog",
|
"slog",
|
||||||
"slog-scope",
|
"slog-scope",
|
||||||
|
@ -580,6 +580,7 @@ where
|
|||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
use kata_sys_util::protection::TDXDetails;
|
||||||
use kata_types::config::hypervisor::{
|
use kata_types::config::hypervisor::{
|
||||||
BlockDeviceInfo, Hypervisor as HypervisorConfig, SecurityInfo,
|
BlockDeviceInfo, Hypervisor as HypervisorConfig, SecurityInfo,
|
||||||
};
|
};
|
||||||
@ -755,6 +756,11 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_get_serial_cfg() {
|
fn test_get_serial_cfg() {
|
||||||
|
let tdx_details = TDXDetails {
|
||||||
|
major_version: 1,
|
||||||
|
minor_version: 0,
|
||||||
|
};
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
struct TestData {
|
struct TestData {
|
||||||
debug: bool,
|
debug: bool,
|
||||||
@ -783,7 +789,7 @@ mod tests {
|
|||||||
},
|
},
|
||||||
TestData {
|
TestData {
|
||||||
debug: false,
|
debug: false,
|
||||||
guest_protection: GuestProtection::Tdx,
|
guest_protection: GuestProtection::Tdx(tdx_details.clone()),
|
||||||
result: ConsoleConfig {
|
result: ConsoleConfig {
|
||||||
file: None,
|
file: None,
|
||||||
mode: ConsoleOutputMode::Off,
|
mode: ConsoleOutputMode::Off,
|
||||||
@ -792,7 +798,7 @@ mod tests {
|
|||||||
},
|
},
|
||||||
TestData {
|
TestData {
|
||||||
debug: true,
|
debug: true,
|
||||||
guest_protection: GuestProtection::Tdx,
|
guest_protection: GuestProtection::Tdx(tdx_details.clone()),
|
||||||
result: ConsoleConfig {
|
result: ConsoleConfig {
|
||||||
file: None,
|
file: None,
|
||||||
mode: ConsoleOutputMode::Off,
|
mode: ConsoleOutputMode::Off,
|
||||||
@ -838,6 +844,11 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_get_console_cfg() {
|
fn test_get_console_cfg() {
|
||||||
|
let tdx_details = TDXDetails {
|
||||||
|
major_version: 1,
|
||||||
|
minor_version: 0,
|
||||||
|
};
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
struct TestData {
|
struct TestData {
|
||||||
debug: bool,
|
debug: bool,
|
||||||
@ -866,7 +877,7 @@ mod tests {
|
|||||||
},
|
},
|
||||||
TestData {
|
TestData {
|
||||||
debug: false,
|
debug: false,
|
||||||
guest_protection: GuestProtection::Tdx,
|
guest_protection: GuestProtection::Tdx(tdx_details.clone()),
|
||||||
result: ConsoleConfig {
|
result: ConsoleConfig {
|
||||||
file: None,
|
file: None,
|
||||||
mode: ConsoleOutputMode::Off,
|
mode: ConsoleOutputMode::Off,
|
||||||
@ -875,7 +886,7 @@ mod tests {
|
|||||||
},
|
},
|
||||||
TestData {
|
TestData {
|
||||||
debug: true,
|
debug: true,
|
||||||
guest_protection: GuestProtection::Tdx,
|
guest_protection: GuestProtection::Tdx(tdx_details.clone()),
|
||||||
result: ConsoleConfig {
|
result: ConsoleConfig {
|
||||||
file: None,
|
file: None,
|
||||||
mode: ConsoleOutputMode::Tty,
|
mode: ConsoleOutputMode::Tty,
|
||||||
@ -919,6 +930,11 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_get_platform_cfg() {
|
fn test_get_platform_cfg() {
|
||||||
|
let tdx_details = TDXDetails {
|
||||||
|
major_version: 1,
|
||||||
|
minor_version: 0,
|
||||||
|
};
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
struct TestData {
|
struct TestData {
|
||||||
guest_protection: GuestProtection,
|
guest_protection: GuestProtection,
|
||||||
@ -931,7 +947,7 @@ mod tests {
|
|||||||
result: None,
|
result: None,
|
||||||
},
|
},
|
||||||
TestData {
|
TestData {
|
||||||
guest_protection: GuestProtection::Tdx,
|
guest_protection: GuestProtection::Tdx(tdx_details.clone()),
|
||||||
result: Some(PlatformConfig {
|
result: Some(PlatformConfig {
|
||||||
tdx: true,
|
tdx: true,
|
||||||
num_pci_segments: DEFAULT_NUM_PCI_SEGMENTS,
|
num_pci_segments: DEFAULT_NUM_PCI_SEGMENTS,
|
||||||
@ -1168,6 +1184,11 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_cpuinfo_to_cpusconfig() {
|
fn test_cpuinfo_to_cpusconfig() {
|
||||||
|
let tdx_details = TDXDetails {
|
||||||
|
major_version: 1,
|
||||||
|
minor_version: 0,
|
||||||
|
};
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
struct TestData {
|
struct TestData {
|
||||||
cpu_info: CpuInfo,
|
cpu_info: CpuInfo,
|
||||||
@ -1258,7 +1279,7 @@ mod tests {
|
|||||||
default_maxvcpus: 13,
|
default_maxvcpus: 13,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
guest_protection: GuestProtection::Tdx,
|
guest_protection: GuestProtection::Tdx(tdx_details.clone()),
|
||||||
result: Ok(CpusConfig {
|
result: Ok(CpusConfig {
|
||||||
boot_vcpus: 1,
|
boot_vcpus: 1,
|
||||||
max_vcpus: 1,
|
max_vcpus: 1,
|
||||||
@ -1304,6 +1325,11 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_bootinfo_to_payloadconfig() {
|
fn test_bootinfo_to_payloadconfig() {
|
||||||
|
let tdx_details = TDXDetails {
|
||||||
|
major_version: 1,
|
||||||
|
minor_version: 0,
|
||||||
|
};
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
struct TestData {
|
struct TestData {
|
||||||
boot_info: BootInfo,
|
boot_info: BootInfo,
|
||||||
@ -1409,19 +1435,19 @@ mod tests {
|
|||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
cmdline: None,
|
cmdline: None,
|
||||||
guest_protection: GuestProtection::Tdx,
|
guest_protection: GuestProtection::Tdx(tdx_details.clone()),
|
||||||
result: Err(PayloadConfigError::TDXFirmwareMissing),
|
result: Err(PayloadConfigError::TDXFirmwareMissing),
|
||||||
},
|
},
|
||||||
TestData {
|
TestData {
|
||||||
boot_info: boot_info_with_initrd,
|
boot_info: boot_info_with_initrd,
|
||||||
cmdline: Some(cmdline.to_string()),
|
cmdline: Some(cmdline.to_string()),
|
||||||
guest_protection: GuestProtection::Tdx,
|
guest_protection: GuestProtection::Tdx(tdx_details.clone()),
|
||||||
result: Ok(payload_config_with_initrd),
|
result: Ok(payload_config_with_initrd),
|
||||||
},
|
},
|
||||||
TestData {
|
TestData {
|
||||||
boot_info: boot_info_without_initrd,
|
boot_info: boot_info_without_initrd,
|
||||||
cmdline: Some(cmdline.to_string()),
|
cmdline: Some(cmdline.to_string()),
|
||||||
guest_protection: GuestProtection::Tdx,
|
guest_protection: GuestProtection::Tdx(tdx_details.clone()),
|
||||||
result: Ok(payload_config_without_initrd),
|
result: Ok(payload_config_without_initrd),
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
@ -1460,6 +1486,11 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_memoryinfo_to_memoryconfig() {
|
fn test_memoryinfo_to_memoryconfig() {
|
||||||
|
let tdx_details = TDXDetails {
|
||||||
|
major_version: 1,
|
||||||
|
minor_version: 0,
|
||||||
|
};
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
struct TestData {
|
struct TestData {
|
||||||
mem_info: MemoryInfo,
|
mem_info: MemoryInfo,
|
||||||
@ -1494,7 +1525,7 @@ mod tests {
|
|||||||
|
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
guest_protection: GuestProtection::Tdx,
|
guest_protection: GuestProtection::Tdx(tdx_details.clone()),
|
||||||
result: Ok(MemoryConfig {
|
result: Ok(MemoryConfig {
|
||||||
size: (17 * MIB),
|
size: (17 * MIB),
|
||||||
shared: true,
|
shared: true,
|
||||||
@ -1509,7 +1540,7 @@ mod tests {
|
|||||||
|
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
guest_protection: GuestProtection::Tdx,
|
guest_protection: GuestProtection::Tdx(tdx_details.clone()),
|
||||||
result: Ok(MemoryConfig {
|
result: Ok(MemoryConfig {
|
||||||
size: usable_max_mem_bytes,
|
size: usable_max_mem_bytes,
|
||||||
shared: true,
|
shared: true,
|
||||||
@ -1524,7 +1555,7 @@ mod tests {
|
|||||||
|
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
guest_protection: GuestProtection::Tdx,
|
guest_protection: GuestProtection::Tdx(tdx_details.clone()),
|
||||||
result: Err(MemoryConfigError::DefaultMemSizeTooBig),
|
result: Err(MemoryConfigError::DefaultMemSizeTooBig),
|
||||||
},
|
},
|
||||||
TestData {
|
TestData {
|
||||||
@ -1552,7 +1583,7 @@ mod tests {
|
|||||||
},
|
},
|
||||||
TestData {
|
TestData {
|
||||||
mem_info: mem_info_confidential_guest,
|
mem_info: mem_info_confidential_guest,
|
||||||
guest_protection: GuestProtection::Tdx,
|
guest_protection: GuestProtection::Tdx(tdx_details.clone()),
|
||||||
result: Ok(mem_cfg_confidential_guest),
|
result: Ok(mem_cfg_confidential_guest),
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
@ -1642,6 +1673,11 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_named_hypervisor_config_to_vmconfig() {
|
fn test_named_hypervisor_config_to_vmconfig() {
|
||||||
|
let tdx_details = TDXDetails {
|
||||||
|
major_version: 1,
|
||||||
|
minor_version: 0,
|
||||||
|
};
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
struct TestData {
|
struct TestData {
|
||||||
cfg: NamedHypervisorConfig,
|
cfg: NamedHypervisorConfig,
|
||||||
@ -1813,7 +1849,7 @@ mod tests {
|
|||||||
..Default::default()
|
..Default::default()
|
||||||
};
|
};
|
||||||
|
|
||||||
let platform_config_tdx = get_platform_cfg(GuestProtection::Tdx);
|
let platform_config_tdx = get_platform_cfg(GuestProtection::Tdx(tdx_details.clone()));
|
||||||
|
|
||||||
let vmconfig_tdx_image = VmConfig {
|
let vmconfig_tdx_image = VmConfig {
|
||||||
cpus: cpus_config_tdx.clone(),
|
cpus: cpus_config_tdx.clone(),
|
||||||
@ -1922,7 +1958,7 @@ mod tests {
|
|||||||
vsock_socket_path: vsock_socket_path.into(),
|
vsock_socket_path: vsock_socket_path.into(),
|
||||||
|
|
||||||
cfg: hypervisor_cfg_tdx_image,
|
cfg: hypervisor_cfg_tdx_image,
|
||||||
guest_protection_to_use: GuestProtection::Tdx,
|
guest_protection_to_use: GuestProtection::Tdx(tdx_details.clone()),
|
||||||
|
|
||||||
..Default::default()
|
..Default::default()
|
||||||
};
|
};
|
||||||
@ -1932,7 +1968,7 @@ mod tests {
|
|||||||
vsock_socket_path: vsock_socket_path.into(),
|
vsock_socket_path: vsock_socket_path.into(),
|
||||||
|
|
||||||
cfg: hypervisor_cfg_tdx_initrd,
|
cfg: hypervisor_cfg_tdx_initrd,
|
||||||
guest_protection_to_use: GuestProtection::Tdx,
|
guest_protection_to_use: GuestProtection::Tdx(tdx_details.clone()),
|
||||||
|
|
||||||
..Default::default()
|
..Default::default()
|
||||||
};
|
};
|
||||||
@ -2169,6 +2205,11 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_check_tdx_rootfs_settings() {
|
fn test_check_tdx_rootfs_settings() {
|
||||||
|
let tdx_details = TDXDetails {
|
||||||
|
major_version: 1,
|
||||||
|
minor_version: 0,
|
||||||
|
};
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
struct TestData<'a> {
|
struct TestData<'a> {
|
||||||
use_image: bool,
|
use_image: bool,
|
||||||
@ -2220,7 +2261,7 @@ mod tests {
|
|||||||
use_image: true,
|
use_image: true,
|
||||||
container_rootfs_driver: "container",
|
container_rootfs_driver: "container",
|
||||||
vm_rootfs_driver: "vm",
|
vm_rootfs_driver: "vm",
|
||||||
guest_protection_to_use: GuestProtection::Tdx,
|
guest_protection_to_use: GuestProtection::Tdx(tdx_details.clone()),
|
||||||
result: Err(VmConfigError::TDXContainerRootfsNotVirtioBlk),
|
result: Err(VmConfigError::TDXContainerRootfsNotVirtioBlk),
|
||||||
},
|
},
|
||||||
// Partially correct
|
// Partially correct
|
||||||
@ -2228,28 +2269,28 @@ mod tests {
|
|||||||
use_image: true,
|
use_image: true,
|
||||||
container_rootfs_driver: VIRTIO_BLK_PCI,
|
container_rootfs_driver: VIRTIO_BLK_PCI,
|
||||||
vm_rootfs_driver: "vm",
|
vm_rootfs_driver: "vm",
|
||||||
guest_protection_to_use: GuestProtection::Tdx,
|
guest_protection_to_use: GuestProtection::Tdx(tdx_details.clone()),
|
||||||
result: Err(VmConfigError::TDXVMRootfsNotVirtioBlk),
|
result: Err(VmConfigError::TDXVMRootfsNotVirtioBlk),
|
||||||
},
|
},
|
||||||
TestData {
|
TestData {
|
||||||
use_image: true,
|
use_image: true,
|
||||||
container_rootfs_driver: VIRTIO_BLK_MMIO,
|
container_rootfs_driver: VIRTIO_BLK_MMIO,
|
||||||
vm_rootfs_driver: "vm",
|
vm_rootfs_driver: "vm",
|
||||||
guest_protection_to_use: GuestProtection::Tdx,
|
guest_protection_to_use: GuestProtection::Tdx(tdx_details.clone()),
|
||||||
result: Err(VmConfigError::TDXVMRootfsNotVirtioBlk),
|
result: Err(VmConfigError::TDXVMRootfsNotVirtioBlk),
|
||||||
},
|
},
|
||||||
TestData {
|
TestData {
|
||||||
use_image: true,
|
use_image: true,
|
||||||
container_rootfs_driver: "container",
|
container_rootfs_driver: "container",
|
||||||
vm_rootfs_driver: VIRTIO_BLK_PCI,
|
vm_rootfs_driver: VIRTIO_BLK_PCI,
|
||||||
guest_protection_to_use: GuestProtection::Tdx,
|
guest_protection_to_use: GuestProtection::Tdx(tdx_details.clone()),
|
||||||
result: Err(VmConfigError::TDXContainerRootfsNotVirtioBlk),
|
result: Err(VmConfigError::TDXContainerRootfsNotVirtioBlk),
|
||||||
},
|
},
|
||||||
TestData {
|
TestData {
|
||||||
use_image: true,
|
use_image: true,
|
||||||
container_rootfs_driver: "container",
|
container_rootfs_driver: "container",
|
||||||
vm_rootfs_driver: VIRTIO_BLK_MMIO,
|
vm_rootfs_driver: VIRTIO_BLK_MMIO,
|
||||||
guest_protection_to_use: GuestProtection::Tdx,
|
guest_protection_to_use: GuestProtection::Tdx(tdx_details.clone()),
|
||||||
result: Err(VmConfigError::TDXContainerRootfsNotVirtioBlk),
|
result: Err(VmConfigError::TDXContainerRootfsNotVirtioBlk),
|
||||||
},
|
},
|
||||||
// Same types
|
// Same types
|
||||||
@ -2257,14 +2298,14 @@ mod tests {
|
|||||||
use_image: true,
|
use_image: true,
|
||||||
container_rootfs_driver: VIRTIO_BLK_MMIO,
|
container_rootfs_driver: VIRTIO_BLK_MMIO,
|
||||||
vm_rootfs_driver: VIRTIO_BLK_MMIO,
|
vm_rootfs_driver: VIRTIO_BLK_MMIO,
|
||||||
guest_protection_to_use: GuestProtection::Tdx,
|
guest_protection_to_use: GuestProtection::Tdx(tdx_details.clone()),
|
||||||
result: Ok(()),
|
result: Ok(()),
|
||||||
},
|
},
|
||||||
TestData {
|
TestData {
|
||||||
use_image: true,
|
use_image: true,
|
||||||
container_rootfs_driver: VIRTIO_BLK_PCI,
|
container_rootfs_driver: VIRTIO_BLK_PCI,
|
||||||
vm_rootfs_driver: VIRTIO_BLK_PCI,
|
vm_rootfs_driver: VIRTIO_BLK_PCI,
|
||||||
guest_protection_to_use: GuestProtection::Tdx,
|
guest_protection_to_use: GuestProtection::Tdx(tdx_details.clone()),
|
||||||
result: Ok(()),
|
result: Ok(()),
|
||||||
},
|
},
|
||||||
// Alternate types
|
// Alternate types
|
||||||
@ -2272,14 +2313,14 @@ mod tests {
|
|||||||
use_image: true,
|
use_image: true,
|
||||||
container_rootfs_driver: VIRTIO_BLK_MMIO,
|
container_rootfs_driver: VIRTIO_BLK_MMIO,
|
||||||
vm_rootfs_driver: VIRTIO_BLK_PCI,
|
vm_rootfs_driver: VIRTIO_BLK_PCI,
|
||||||
guest_protection_to_use: GuestProtection::Tdx,
|
guest_protection_to_use: GuestProtection::Tdx(tdx_details.clone()),
|
||||||
result: Ok(()),
|
result: Ok(()),
|
||||||
},
|
},
|
||||||
TestData {
|
TestData {
|
||||||
use_image: true,
|
use_image: true,
|
||||||
container_rootfs_driver: VIRTIO_BLK_PCI,
|
container_rootfs_driver: VIRTIO_BLK_PCI,
|
||||||
vm_rootfs_driver: VIRTIO_BLK_MMIO,
|
vm_rootfs_driver: VIRTIO_BLK_MMIO,
|
||||||
guest_protection_to_use: GuestProtection::Tdx,
|
guest_protection_to_use: GuestProtection::Tdx(tdx_details.clone()),
|
||||||
result: Ok(()),
|
result: Ok(()),
|
||||||
},
|
},
|
||||||
// Using an initrd (not currently supported)
|
// Using an initrd (not currently supported)
|
||||||
@ -2287,28 +2328,28 @@ mod tests {
|
|||||||
use_image: false,
|
use_image: false,
|
||||||
container_rootfs_driver: VIRTIO_BLK_PCI,
|
container_rootfs_driver: VIRTIO_BLK_PCI,
|
||||||
vm_rootfs_driver: VIRTIO_BLK_PCI,
|
vm_rootfs_driver: VIRTIO_BLK_PCI,
|
||||||
guest_protection_to_use: GuestProtection::Tdx,
|
guest_protection_to_use: GuestProtection::Tdx(tdx_details.clone()),
|
||||||
result: Err(VmConfigError::TDXDisallowsInitrd),
|
result: Err(VmConfigError::TDXDisallowsInitrd),
|
||||||
},
|
},
|
||||||
TestData {
|
TestData {
|
||||||
use_image: false,
|
use_image: false,
|
||||||
container_rootfs_driver: "container",
|
container_rootfs_driver: "container",
|
||||||
vm_rootfs_driver: "vm",
|
vm_rootfs_driver: "vm",
|
||||||
guest_protection_to_use: GuestProtection::Tdx,
|
guest_protection_to_use: GuestProtection::Tdx(tdx_details.clone()),
|
||||||
result: Err(VmConfigError::TDXDisallowsInitrd),
|
result: Err(VmConfigError::TDXDisallowsInitrd),
|
||||||
},
|
},
|
||||||
TestData {
|
TestData {
|
||||||
use_image: false,
|
use_image: false,
|
||||||
container_rootfs_driver: VIRTIO_BLK_PCI,
|
container_rootfs_driver: VIRTIO_BLK_PCI,
|
||||||
vm_rootfs_driver: "vm",
|
vm_rootfs_driver: "vm",
|
||||||
guest_protection_to_use: GuestProtection::Tdx,
|
guest_protection_to_use: GuestProtection::Tdx(tdx_details.clone()),
|
||||||
result: Err(VmConfigError::TDXDisallowsInitrd),
|
result: Err(VmConfigError::TDXDisallowsInitrd),
|
||||||
},
|
},
|
||||||
TestData {
|
TestData {
|
||||||
use_image: false,
|
use_image: false,
|
||||||
container_rootfs_driver: VIRTIO_BLK_MMIO,
|
container_rootfs_driver: VIRTIO_BLK_MMIO,
|
||||||
vm_rootfs_driver: "vm",
|
vm_rootfs_driver: "vm",
|
||||||
guest_protection_to_use: GuestProtection::Tdx,
|
guest_protection_to_use: GuestProtection::Tdx(tdx_details.clone()),
|
||||||
result: Err(VmConfigError::TDXDisallowsInitrd),
|
result: Err(VmConfigError::TDXDisallowsInitrd),
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
@ -504,15 +504,21 @@ pub struct NamedHypervisorConfig {
|
|||||||
|
|
||||||
// Returns true if the enabled guest protection is Intel TDX.
|
// Returns true if the enabled guest protection is Intel TDX.
|
||||||
pub fn guest_protection_is_tdx(guest_protection_to_use: GuestProtection) -> bool {
|
pub fn guest_protection_is_tdx(guest_protection_to_use: GuestProtection) -> bool {
|
||||||
matches!(guest_protection_to_use, GuestProtection::Tdx)
|
matches!(guest_protection_to_use, GuestProtection::Tdx(_))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
use kata_sys_util::protection::TDXDetails;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_guest_protection_is_tdx() {
|
fn test_guest_protection_is_tdx() {
|
||||||
|
let tdx_details = TDXDetails {
|
||||||
|
major_version: 1,
|
||||||
|
minor_version: 0,
|
||||||
|
};
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
struct TestData {
|
struct TestData {
|
||||||
protection: GuestProtection,
|
protection: GuestProtection,
|
||||||
@ -541,7 +547,7 @@ mod tests {
|
|||||||
result: false,
|
result: false,
|
||||||
},
|
},
|
||||||
TestData {
|
TestData {
|
||||||
protection: GuestProtection::Tdx,
|
protection: GuestProtection::Tdx(tdx_details),
|
||||||
result: true,
|
result: true,
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
@ -492,7 +492,7 @@ impl CloudHypervisorInner {
|
|||||||
self.guest_protection_to_use = protection.clone();
|
self.guest_protection_to_use = protection.clone();
|
||||||
|
|
||||||
info!(sl!(), "guest protection available and requested"; "guest-protection" => protection.to_string());
|
info!(sl!(), "guest protection available and requested"; "guest-protection" => protection.to_string());
|
||||||
} else if protection == GuestProtection::Tdx {
|
} else if let GuestProtection::Tdx(_) = protection {
|
||||||
return Err(anyhow!(GuestProtectionError::TDXProtectionMustBeUsedWithCH));
|
return Err(anyhow!(GuestProtectionError::TDXProtectionMustBeUsedWithCH));
|
||||||
} else {
|
} else {
|
||||||
info!(sl!(), "guest protection available but not requested"; "guest-protection" => protection.to_string());
|
info!(sl!(), "guest protection available but not requested"; "guest-protection" => protection.to_string());
|
||||||
@ -724,6 +724,7 @@ fn get_guest_protection() -> Result<GuestProtection> {
|
|||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
use kata_sys_util::protection::TDXDetails;
|
||||||
|
|
||||||
#[cfg(target_arch = "x86_64")]
|
#[cfg(target_arch = "x86_64")]
|
||||||
use kata_sys_util::protection::TDX_SYS_FIRMWARE_DIR;
|
use kata_sys_util::protection::TDX_SYS_FIRMWARE_DIR;
|
||||||
@ -748,6 +749,11 @@ mod tests {
|
|||||||
// available_guest_protection() requires super user privs.
|
// available_guest_protection() requires super user privs.
|
||||||
skip_if_not_root!();
|
skip_if_not_root!();
|
||||||
|
|
||||||
|
let tdx_details = TDXDetails {
|
||||||
|
major_version: 1,
|
||||||
|
minor_version: 0,
|
||||||
|
};
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
struct TestData {
|
struct TestData {
|
||||||
value: Option<GuestProtection>,
|
value: Option<GuestProtection>,
|
||||||
@ -776,8 +782,8 @@ mod tests {
|
|||||||
result: Ok(GuestProtection::Snp),
|
result: Ok(GuestProtection::Snp),
|
||||||
},
|
},
|
||||||
TestData {
|
TestData {
|
||||||
value: Some(GuestProtection::Tdx),
|
value: Some(GuestProtection::Tdx(tdx_details.clone())),
|
||||||
result: Ok(GuestProtection::Tdx),
|
result: Ok(GuestProtection::Tdx(tdx_details.clone())),
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
@ -811,6 +817,11 @@ mod tests {
|
|||||||
// available_guest_protection() requires super user privs.
|
// available_guest_protection() requires super user privs.
|
||||||
skip_if_not_root!();
|
skip_if_not_root!();
|
||||||
|
|
||||||
|
let tdx_details = TDXDetails {
|
||||||
|
major_version: 1,
|
||||||
|
minor_version: 0,
|
||||||
|
};
|
||||||
|
|
||||||
// Use the hosts protection, not a fake one.
|
// Use the hosts protection, not a fake one.
|
||||||
set_fake_guest_protection(None);
|
set_fake_guest_protection(None);
|
||||||
|
|
||||||
@ -843,7 +854,7 @@ mod tests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if have_tdx {
|
if have_tdx {
|
||||||
assert_eq!(protection, GuestProtection::Tdx);
|
assert_eq!(protection, GuestProtection::Tdx(tdx_details));
|
||||||
} else {
|
} else {
|
||||||
assert_eq!(protection, GuestProtection::NoProtection);
|
assert_eq!(protection, GuestProtection::NoProtection);
|
||||||
}
|
}
|
||||||
@ -866,6 +877,11 @@ mod tests {
|
|||||||
guest_protection_to_use: GuestProtection,
|
guest_protection_to_use: GuestProtection,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let tdx_details = TDXDetails {
|
||||||
|
major_version: 1,
|
||||||
|
minor_version: 0,
|
||||||
|
};
|
||||||
|
|
||||||
let tests = &[
|
let tests = &[
|
||||||
TestData {
|
TestData {
|
||||||
confidential_guest: false,
|
confidential_guest: false,
|
||||||
@ -881,15 +897,15 @@ mod tests {
|
|||||||
},
|
},
|
||||||
TestData {
|
TestData {
|
||||||
confidential_guest: false,
|
confidential_guest: false,
|
||||||
available_protection: Some(GuestProtection::Tdx),
|
available_protection: Some(GuestProtection::Tdx(tdx_details.clone())),
|
||||||
result: Err(anyhow!(GuestProtectionError::TDXProtectionMustBeUsedWithCH)),
|
result: Err(anyhow!(GuestProtectionError::TDXProtectionMustBeUsedWithCH)),
|
||||||
guest_protection_to_use: GuestProtection::NoProtection,
|
guest_protection_to_use: GuestProtection::NoProtection,
|
||||||
},
|
},
|
||||||
TestData {
|
TestData {
|
||||||
confidential_guest: true,
|
confidential_guest: true,
|
||||||
available_protection: Some(GuestProtection::Tdx),
|
available_protection: Some(GuestProtection::Tdx(tdx_details.clone())),
|
||||||
result: Ok(()),
|
result: Ok(()),
|
||||||
guest_protection_to_use: GuestProtection::Tdx,
|
guest_protection_to_use: GuestProtection::Tdx(tdx_details.clone()),
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user