From 09fddac2c4f8defd1c3242060d2ded731a59b37c Mon Sep 17 00:00:00 2001 From: "alex.lyn" Date: Wed, 23 Apr 2025 15:33:56 +0800 Subject: [PATCH] runtime-rs: Introduce 'tdx-guest' object and its builder for TDX CVMs This commit introduces the `tdx-guest` designed to facilitate the launch of CVMs leveraging Intel's TDX. Launching a TDX-based CVM requires various properties, including `quote-generation-socket`, and `mrconfigid`,`sept-ve-disable` .etc. (1) The `quote-generation-socket` property is added to the `tdx-guest` object, which is of type `SocketAddress`, specifies the address of the Quote Generation Service (QGS). (2) The `mrconfigid` property, representing the SHA384 hash for non-owner-defined configurations of the guest TD, is introduced as a runtime or OS configuration parameter. (3) And the `sept-ve-disable` property allows control over whether EPT violation conversions to #VE exceptions are disabled when the guest TD accesses PENDING pages. With the introduction of the `tdx-guest` object and its associated properties, launching TDX-based CVMs is now supported. For example, a TDX guest can be configured via the command line as follows: ```shell -object {"qom-type":"tdx-guest", "id":"tdx", "sept-ve-disable":true,\ "mrconfigid":"vHswGkzG4B3Kikg96sLQ5vPCYx4AtuB4Ubfzz9UOXvZtCGat8b8ok7Ubz4AxDDHh",\ "quote-generation-socket":{"type":"vsock","cid":"2","port":"4050"} \ -machine q35,accel=kvm,confidential-guest-support=tdx ``` Signed-off-by: alex.lyn --- .../hypervisor/src/qemu/cmdline_generator.rs | 103 +++++++++++++++++- 1 file changed, 102 insertions(+), 1 deletion(-) diff --git a/src/runtime-rs/crates/hypervisor/src/qemu/cmdline_generator.rs b/src/runtime-rs/crates/hypervisor/src/qemu/cmdline_generator.rs index 384753dd9e..41475a3bbe 100644 --- a/src/runtime-rs/crates/hypervisor/src/qemu/cmdline_generator.rs +++ b/src/runtime-rs/crates/hypervisor/src/qemu/cmdline_generator.rs @@ -4,12 +4,15 @@ // use crate::device::topology::{PCIePortBusPrefix, TopologyPortDevice, DEFAULT_PCIE_ROOT_BUS}; -use crate::utils::{clear_cloexec, create_vhost_net_fds, open_named_tuntap}; +use crate::utils::{clear_cloexec, create_vhost_net_fds, open_named_tuntap, SocketAddress}; + use crate::{kernel_param::KernelParams, Address, HypervisorConfig}; use anyhow::{anyhow, Context, Result}; use async_trait::async_trait; use kata_types::config::hypervisor::VIRTIO_SCSI; +use serde::{Deserialize, Serialize}; +use serde_json; use std::collections::HashMap; use std::fmt::Display; use std::fs::{read_to_string, File}; @@ -1825,6 +1828,87 @@ impl ToQemuParams for ObjectSevSnpGuest { } } +#[derive(Clone, Debug, Serialize, Deserialize)] +#[serde(rename_all = "kebab-case")] +pub struct ObjectTdxGuest { + // QOM Object type + qom_type: String, + + // unique ID + id: String, + + // The sept-ve-disable option prevents EPT violation conversions to #VE on guest TD + // accesses of PENDING pages, which is essential for certain guest OS compatibility, + // like Linux TD guests. + sept_ve_disable: bool, + + // Base64 encoded 48 bytes of data (e.g., a sha384 digest). + // ID for non-owner-defined configuration of the guest TD, which identifies the guest TD's run-time/OS configuration via a SHA384 digest. + // Defaults to zero if unspecified. + #[serde(skip_serializing_if = "Option::is_none")] + mrconfigid: Option, + + // Base64 encoded 48 bytes of data (e.g., a sha384 digest). ID for the guest TD's owner. + // Defaults to all zeros. + #[serde(skip_serializing_if = "Option::is_none")] + mrowner: Option, + + // Base64 encoded 48 bytes of data (e.g., a sha384 digest). + // ID for owner-defined configuration of the guest TD, e.g., specific to the workload rather than the run-time or OS. + // Defaults to all zeros. + #[serde(skip_serializing_if = "Option::is_none")] + mrownerconfig: Option, + + // Quote generation socket. + #[serde(skip_serializing_if = "Option::is_none")] + quote_generation_socket: Option, + + // Debug mode + #[serde(skip_serializing_if = "Option::is_none")] + debug: Option, +} + +impl std::fmt::Display for ObjectTdxGuest { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + serde_json::to_string(self) + .map_err(|_| std::fmt::Error) + .and_then(|s| write!(f, "{}", s)) + } +} + +#[allow(clippy::doc_lazy_continuation)] +/// 1. Add property "quote-generation-socket" to tdx-guest +/// https://lore.kernel.org/qemu-devel/Zv7dtghi20DZ9ozz@redhat.com/ +/// 2. Support user configurable mrconfigid/mrowner/mrownerconfig +/// https://patchew.org/QEMU/20241105062408.3533704-1-xiaoyao.li@intel.com/20241105062408.3533704-15-xiaoyao.li@intel.com/ +/// 3. Add command line and validation for TDX type +/// https://lists.libvirt.org/archives/list/devel@lists.libvirt.org/message/6N7KP5F5Z44NI3R5U7STSPWUYXK6QYUO/ +/// Example: +/// -object { "qom-type": "tdx-guest","id": "tdx", "mrconfigid": "mrconfigid2", "debug":true,"sept-ve-disable":true, \ +/// "quote-generation-socket": { "type": "vsock","cid": "2","port": "4050" }} +impl ObjectTdxGuest { + pub fn new(id: &str, mrconfigid: Option, qgs_port: u32, debug: bool) -> Self { + let qgs_socket = SocketAddress::new(qgs_port); + Self { + qom_type: "tdx-guest".to_owned(), + id: id.to_owned(), + mrconfigid, + mrowner: None, + mrownerconfig: None, + sept_ve_disable: true, + quote_generation_socket: Some(qgs_socket), + debug: if debug { Some(debug) } else { None }, + } + } +} + +#[async_trait] +impl ToQemuParams for ObjectTdxGuest { + async fn qemu_params(&self) -> Result> { + Ok(vec!["-object".to_owned(), self.to_string()]) + } +} + /// PCIeRootPortDevice directly attached onto the root bus /// -device pcie-root-port,id=rp0,bus=pcie.0,chassis=0,slot=0,multifunction=off,pref64-reserve=B,mem-reserve=B #[derive(Debug, Default)] @@ -2354,6 +2438,23 @@ impl<'a> QemuCmdLine<'a> { self.cpu.set_type("EPYC-v4"); } + pub fn add_tdx_protection_device( + &mut self, + id: &str, + firmware: &str, + qgs_port: u32, + mrconfigid: &Option, + debug: bool, + ) { + let tdx_object = ObjectTdxGuest::new(id, mrconfigid.clone(), qgs_port, debug); + self.devices.push(Box::new(tdx_object)); + self.devices.push(Box::new(Bios::new(firmware.to_owned()))); + + self.machine + .set_confidential_guest_support("tdx") + .set_nvdimm(false); + } + /// Note: add_pcie_root_port and add_pcie_switch_port follow kata-runtime's related implementations of vfio devices. /// The design origins from https://github.com/qemu/qemu/blob/master/docs/pcie.txt ///