diff --git a/src/libs/kata-sys-util/src/protection.rs b/src/libs/kata-sys-util/src/protection.rs index 9cb11a117..8e06117c8 100644 --- a/src/libs/kata-sys-util/src/protection.rs +++ b/src/libs/kata-sys-util/src/protection.rs @@ -3,8 +3,6 @@ // 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"))] use anyhow::Result; use serde::{Deserialize, Serialize}; @@ -25,12 +23,6 @@ use nix::unistd::Uid; #[cfg(target_arch = "x86_64")] use std::fs; -#[derive(Debug, Clone, PartialEq, Eq, Default, Serialize, Deserialize)] -pub struct TDXDetails { - pub major_version: u32, - pub minor_version: u32, -} - #[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] pub struct SevSnpDetails { pub cbitpos: u32, @@ -41,7 +33,7 @@ pub struct SevSnpDetails { pub enum GuestProtection { #[default] NoProtection, - Tdx(TDXDetails), + Tdx, Sev(SevSnpDetails), Snp(SevSnpDetails), Pef, @@ -51,11 +43,7 @@ pub enum GuestProtection { impl fmt::Display for GuestProtection { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match self { - GuestProtection::Tdx(details) => write!( - f, - "tdx (major_version: {}, minor_version: {})", - details.major_version, details.minor_version - ), + GuestProtection::Tdx => write!(f, "tdx"), GuestProtection::Sev(details) => write!(f, "sev (cbitpos: {}", details.cbitpos), GuestProtection::Snp(details) => write!(f, "snp (cbitpos: {}", details.cbitpos), GuestProtection::Pef => write!(f, "pef"), @@ -88,95 +76,29 @@ pub enum ProtectionError { } #[cfg(target_arch = "x86_64")] -pub const TDX_SYS_FIRMWARE_DIR: &str = "/sys/firmware/tdx/"; +pub const TDX_KVM_PARAMETER_PATH: &str = "/sys/module/kvm_intel/parameters/tdx"; #[cfg(target_arch = "x86_64")] pub const SEV_KVM_PARAMETER_PATH: &str = "/sys/module/kvm_amd/parameters/sev"; #[cfg(target_arch = "x86_64")] 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")] pub fn available_guest_protection() -> Result { - arch_guest_protection( - TDX_SYS_FIRMWARE_DIR, - SEV_KVM_PARAMETER_PATH, - SNP_KVM_PARAMETER_PATH, - ) + arch_guest_protection(SEV_KVM_PARAMETER_PATH, SNP_KVM_PARAMETER_PATH) } #[cfg(target_arch = "x86_64")] pub fn arch_guest_protection( - tdx_path: &str, sev_path: &str, snp_path: &str, ) -> Result { - let metadata = fs::metadata(tdx_path); - - if metadata.is_ok() && metadata.unwrap().is_dir() { - 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)); + // Check if /sys/module/kvm_intel/parameters/tdx is set to 'Y' + if Path::new(TDX_KVM_PARAMETER_PATH).exists() { + if let Ok(content) = fs::read(TDX_KVM_PARAMETER_PATH) { + if !content.is_empty() && content[0] == b'Y' { + return Ok(GuestProtection::Tdx); + } + } } let check_contents = |file_name: &str| -> Result { @@ -301,12 +223,12 @@ mod tests { let mut snp_file = fs::File::create(snp_file_path).unwrap(); writeln!(snp_file, "Y").unwrap(); - let actual = arch_guest_protection("/xyz/tmp", "/xyz/tmp", path.to_str().unwrap()); + let actual = arch_guest_protection("/xyz/tmp", path.to_str().unwrap()); assert!(actual.is_ok()); assert_eq!(actual.unwrap(), GuestProtection::Snp); writeln!(snp_file, "N").unwrap(); - let actual = arch_guest_protection("/xyz/tmp", "/xyz/tmp", path.to_str().unwrap()); + let actual = arch_guest_protection("/xyz/tmp", path.to_str().unwrap()); assert!(actual.is_ok()); assert_eq!(actual.unwrap(), GuestProtection::NoProtection); } @@ -320,12 +242,12 @@ mod tests { let mut sev_file = fs::File::create(sev_file_path).unwrap(); writeln!(sev_file, "Y").unwrap(); - let actual = arch_guest_protection("/xyz/tmp", sev_path.to_str().unwrap(), "/xyz/tmp"); + let actual = arch_guest_protection(sev_path.to_str().unwrap(), "/xyz/tmp"); assert!(actual.is_ok()); assert_eq!(actual.unwrap(), GuestProtection::Sev); writeln!(sev_file, "N").unwrap(); - let actual = arch_guest_protection("/xyz/tmp", sev_path.to_str().unwrap(), "/xyz/tmp"); + let actual = arch_guest_protection(sev_path.to_str().unwrap(), "/xyz/tmp"); assert!(actual.is_ok()); assert_eq!(actual.unwrap(), GuestProtection::NoProtection); } @@ -342,49 +264,19 @@ mod tests { std::fs::create_dir_all(tdx_path.clone()).unwrap(); - let actual = arch_guest_protection(invalid_dir, invalid_dir, invalid_dir); + let actual = arch_guest_protection(invalid_dir, invalid_dir); assert!(actual.is_ok()); 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(invalid_dir, invalid_dir); assert!(actual.is_err()); - 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); + let result = arch_guest_protection(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); - let displayed_value = result.to_string(); - assert_eq!(displayed_value, "tdx (major_version: 1, minor_version: 0)"); + assert_eq!(displayed_value, "tdx"); } } 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 ebd56c3a9..09443323c 100644 --- a/src/runtime-rs/crates/hypervisor/ch-config/src/convert.rs +++ b/src/runtime-rs/crates/hypervisor/ch-config/src/convert.rs @@ -549,7 +549,7 @@ fn get_platform_cfg(guest_protection_to_use: GuestProtection) -> Option bool { - matches!(guest_protection_to_use, GuestProtection::Tdx(_)) + matches!(guest_protection_to_use, GuestProtection::Tdx) } #[cfg(test)] mod tests { use super::*; - use kata_sys_util::protection::{SevSnpDetails, TDXDetails}; + use kata_sys_util::protection::SevSnpDetails; #[test] fn test_guest_protection_is_tdx() { - let tdx_details = TDXDetails { - major_version: 1, - minor_version: 0, - }; - let sev_snp_details = SevSnpDetails { cbitpos: 42 }; #[derive(Debug)] @@ -547,7 +542,7 @@ mod tests { result: false, }, TestData { - protection: GuestProtection::Tdx(tdx_details), + protection: GuestProtection::Tdx, result: true, }, ]; diff --git a/src/runtime-rs/crates/hypervisor/src/ch/inner.rs b/src/runtime-rs/crates/hypervisor/src/ch/inner.rs index c8f1c2d90..40f3c5d33 100644 --- a/src/runtime-rs/crates/hypervisor/src/ch/inner.rs +++ b/src/runtime-rs/crates/hypervisor/src/ch/inner.rs @@ -197,7 +197,6 @@ impl Persist for CloudHypervisorInner { #[cfg(test)] mod tests { use super::*; - use kata_sys_util::protection::TDXDetails; #[actix_rt::test] async fn test_save_clh() { @@ -209,12 +208,7 @@ mod tests { clh.vm_path = String::from("/opt/kata/bin/cloud-hypervisor"); clh.run_dir = String::from("/var/run/kata-containers/") + &clh.id; - let details = TDXDetails { - major_version: 1, - minor_version: 0, - }; - - clh.guest_protection_to_use = GuestProtection::Tdx(details); + clh.guest_protection_to_use = GuestProtection::Tdx; let state = clh.save().await.unwrap(); assert_eq!(state.id, clh.id); 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 41660ea14..954ce3034 100644 --- a/src/runtime-rs/crates/hypervisor/src/ch/inner_hypervisor.rs +++ b/src/runtime-rs/crates/hypervisor/src/ch/inner_hypervisor.rs @@ -568,7 +568,7 @@ impl CloudHypervisorInner { if protection == GuestProtection::NoProtection { // User wants protection, but none available. return Err(anyhow!(GuestProtectionError::NoProtectionAvailable)); - } else if let GuestProtection::Tdx(_) = protection { + } else if let GuestProtection::Tdx = protection { info!(sl!(), "guest protection available and requested"; "guest-protection" => protection.to_string()); } else { return Err(anyhow!(GuestProtectionError::ExpectedTDXProtection( @@ -577,7 +577,7 @@ impl CloudHypervisorInner { } } else if protection == GuestProtection::NoProtection { debug!(sl!(), "no guest protection available"); - } else if let GuestProtection::Tdx(_) = protection { + } else if let GuestProtection::Tdx = protection { // CH requires TDX protection to be used. return Err(anyhow!(GuestProtectionError::TDXProtectionMustBeUsedWithCH)); } else { @@ -956,15 +956,13 @@ fn get_ch_vcpu_tids(proc_path: &str) -> Result> { #[cfg(test)] mod tests { use super::*; - use kata_sys_util::protection::{SevSnpDetails, TDXDetails}; + use kata_sys_util::protection::SevSnpDetails; #[cfg(target_arch = "x86_64")] - use kata_sys_util::protection::TDX_SYS_FIRMWARE_DIR; + use kata_sys_util::protection::TDX_KVM_PARAMETER_PATH; use kata_types::config::hypervisor::{Hypervisor as HypervisorConfig, SecurityInfo}; use serial_test::serial; - #[cfg(target_arch = "x86_64")] - use std::path::PathBuf; use test_utils::{assert_result, skip_if_not_root}; use std::fs::File; @@ -985,11 +983,6 @@ mod tests { // available_guest_protection() requires super user privs. skip_if_not_root!(); - let tdx_details = TDXDetails { - major_version: 1, - minor_version: 0, - }; - let sev_snp_details = SevSnpDetails { cbitpos: 42 }; #[derive(Debug)] @@ -1020,8 +1013,8 @@ mod tests { result: Ok(GuestProtection::Snp(sev_snp_details.clone())), }, TestData { - value: Some(GuestProtection::Tdx(tdx_details.clone())), - result: Ok(GuestProtection::Tdx(tdx_details.clone())), + value: Some(GuestProtection::Tdx), + result: Ok(GuestProtection::Tdx), }, ]; @@ -1055,26 +1048,11 @@ mod tests { // available_guest_protection() requires super user privs. skip_if_not_root!(); - let tdx_details = TDXDetails { - major_version: 1, - minor_version: 0, - }; - // Use the hosts protection, not a fake one. set_fake_guest_protection(None); - let tdx_fw_path = PathBuf::from(TDX_SYS_FIRMWARE_DIR); - - // Simple test for Intel TDX - let have_tdx = if tdx_fw_path.exists() { - if let Ok(metadata) = std::fs::metadata(tdx_fw_path.clone()) { - metadata.is_dir() - } else { - false - } - } else { - false - }; + let have_tdx = fs::read(TDX_KVM_PARAMETER_PATH) + .map_or(false, |content| !content.is_empty() && content[0] == b'Y'); let protection = task::spawn_blocking(|| -> Result { get_guest_protection() }) @@ -1083,16 +1061,13 @@ mod tests { .unwrap(); if std::env::var("DEBUG").is_ok() { - let msg = format!( - "tdx_fw_path: {:?}, have_tdx: {:?}, protection: {:?}", - tdx_fw_path, have_tdx, protection - ); + let msg = format!("have_tdx: {:?}, protection: {:?}", have_tdx, protection); eprintln!("DEBUG: {}", msg); } if have_tdx { - assert_eq!(protection, GuestProtection::Tdx(tdx_details)); + assert_eq!(protection, GuestProtection::Tdx); } else { assert_eq!(protection, GuestProtection::NoProtection); } @@ -1115,11 +1090,6 @@ mod tests { guest_protection_to_use: GuestProtection, } - let tdx_details = TDXDetails { - major_version: 1, - minor_version: 0, - }; - let tests = &[ TestData { confidential_guest: false, @@ -1135,15 +1105,15 @@ mod tests { }, TestData { confidential_guest: false, - available_protection: Some(GuestProtection::Tdx(tdx_details.clone())), + available_protection: Some(GuestProtection::Tdx), result: Err(anyhow!(GuestProtectionError::TDXProtectionMustBeUsedWithCH)), - guest_protection_to_use: GuestProtection::Tdx(tdx_details.clone()), + guest_protection_to_use: GuestProtection::Tdx, }, TestData { confidential_guest: true, - available_protection: Some(GuestProtection::Tdx(tdx_details.clone())), + available_protection: Some(GuestProtection::Tdx), result: Ok(()), - guest_protection_to_use: GuestProtection::Tdx(tdx_details), + guest_protection_to_use: GuestProtection::Tdx, }, TestData { confidential_guest: false, diff --git a/src/runtime-rs/crates/runtimes/virt_container/src/sandbox.rs b/src/runtime-rs/crates/runtimes/virt_container/src/sandbox.rs index 2e5936d85..bf504f394 100644 --- a/src/runtime-rs/crates/runtimes/virt_container/src/sandbox.rs +++ b/src/runtime-rs/crates/runtimes/virt_container/src/sandbox.rs @@ -398,7 +398,7 @@ impl VirtSandbox { GuestProtection::Se => { Ok(Some(ProtectionDeviceConfig::Se)) } - GuestProtection::Tdx(_details) => { + GuestProtection::Tdx => { Ok(Some(ProtectionDeviceConfig::Tdx(TdxConfig { id: "tdx".to_owned(), firmware: hypervisor_config.boot_info.firmware.clone(),