From fb9d778065a43046eab1ee972f61854ea588e5b2 Mon Sep 17 00:00:00 2001 From: Zvonko Kaiser Date: Tue, 14 Jul 2026 14:58:35 +0000 Subject: [PATCH] qemu/machine: extend data model for Q35 CoCo and NUMA SHM Add the fields needed to express Q35-specific topologies: probe.rs: - HostTopology: +numa_distances (src/dst/val triples), +cold_plug_ports (pre-provisioned pcie-root-port count), +protection (sev-snp-guest / tdx-guest capability detected by the host probe) - SocketInfo: +host_node, +mem_path, +mem_size for per-socket NUMA pinning and /dev/shm or EGM file-backed memory - ProtectionDevice enum: SevSnp and Tdx variants, with an id() accessor used by platform.rs to set confidential_guest_support on the machine line topology.rs: - PciRootPort: +slot, +multifunction (Q35 cold-plug ports carry these; Grace ports do not), +io_reserve (Grace only, absent on Q35) - VfioDevice: rombar: bool -> Option (CoCo Q35 has no rombar field), +iommufd_id for per-device CoCo iommufd (Grace uses a shared iommufd0), +pci_vendor_id/pci_device_id for x86 CoCo measured-boot attestation - VfioDeviceKind::GpuPci: vfio-pci (Q35 / CoCo) vs existing Gpu (vfio-pci- nohotplug for Grace aarch64) - PciTopology: +cold_plug_ports for pre-provisioned Q35 root ports on pcie.0 q35.rs: - Q35: +kernel_irqchip (split for CoCo, absent for vanilla) and +confidential_guest_support referencing the protection object id Signed-off-by: Zvonko Kaiser Assisted-by: Claude Sonnet 4.6 Signed-off-by: Zvonko Kaiser --- .../hypervisor/src/qemu/machine/probe.rs | 42 +++++++++++++++++++ .../crates/hypervisor/src/qemu/machine/q35.rs | 5 +++ .../hypervisor/src/qemu/machine/topology.rs | 22 +++++++++- 3 files changed, 68 insertions(+), 1 deletion(-) diff --git a/src/runtime-rs/crates/hypervisor/src/qemu/machine/probe.rs b/src/runtime-rs/crates/hypervisor/src/qemu/machine/probe.rs index 8b7db31192..e34dddce12 100644 --- a/src/runtime-rs/crates/hypervisor/src/qemu/machine/probe.rs +++ b/src/runtime-rs/crates/hypervisor/src/qemu/machine/probe.rs @@ -8,11 +8,23 @@ pub(crate) struct HostTopology { pub sockets: Vec, pub gpu_smmu_groups: Vec, pub egm_sockets: Vec, + /// `-numa dist` entries emitted after all NUMA nodes. Each tuple is (src, dst, val). + pub numa_distances: Vec<(u32, u32, u32)>, + /// Number of pre-provisioned `pcie-root-port` devices on the Q35 default bus + /// (cold-plug topology; `cold_plug_vfio=root-port` in kata config). + pub cold_plug_ports: u32, + pub protection: Option, } pub(crate) struct SocketInfo { pub id: u32, pub cpu_range: Range, + /// Host NUMA node to bind this socket's memory to via `policy=bind`. + pub host_node: Option, + /// File-backed memory path (e.g. `/dev/shm`). `None` → `memory-backend-ram`. + pub mem_path: Option, + /// Per-socket memory size in bytes. `None` → use the Platform-level default. + pub mem_size: Option, } /// GPUs sharing a physical SMMU must be placed on the same pxb-pcie + arm-smmuv3. @@ -26,3 +38,33 @@ pub(crate) struct EgmSocketInfo { pub socket: u32, pub total_size: u64, } + +/// CoCo hardware protection capability detected by the host probe. +/// +/// Drives three platform decisions: the `-object -guest` preamble, the +/// `kernel_irqchip=split` machine flag, and the `CpuModel` (EpycV4 for SNP, +/// Host for TDX). +#[derive(Clone)] +pub(crate) enum ProtectionDevice { + SevSnp { + id: String, + cbitpos: u8, + reduced_phys_bits: u8, + kernel_hashes: bool, + policy: u64, + host_data: Option, + }, + /// TDX — fields TBD when a production capture is available. + Tdx { + id: String, + }, +} + +impl ProtectionDevice { + pub(crate) fn id(&self) -> &str { + match self { + ProtectionDevice::SevSnp { id, .. } => id, + ProtectionDevice::Tdx { id } => id, + } + } +} diff --git a/src/runtime-rs/crates/hypervisor/src/qemu/machine/q35.rs b/src/runtime-rs/crates/hypervisor/src/qemu/machine/q35.rs index acf467dac0..8e42f325b4 100644 --- a/src/runtime-rs/crates/hypervisor/src/qemu/machine/q35.rs +++ b/src/runtime-rs/crates/hypervisor/src/qemu/machine/q35.rs @@ -6,9 +6,14 @@ use super::platform::BaseMachine; pub(crate) struct Q35 { pub base: BaseMachine, + /// `kernel_irqchip=split` is required for CoCo (SNP/TDX); absent on vanilla Q35. pub kernel_irqchip: Option, + /// References the id of `Objects::protection`. Set by `apply_host_defaults` + /// when `HostTopology::protection` is `Some`. + pub confidential_guest_support: Option, /// Not bus-attached; contrast with BusIommu on PciRootComplex. pub intel_iommu: Option, + // pub runtime: RuntimeFeatures, -- Phase 3+ } pub(crate) struct IntelIommuConfig { diff --git a/src/runtime-rs/crates/hypervisor/src/qemu/machine/topology.rs b/src/runtime-rs/crates/hypervisor/src/qemu/machine/topology.rs index cfcac5e94f..bafb137796 100644 --- a/src/runtime-rs/crates/hypervisor/src/qemu/machine/topology.rs +++ b/src/runtime-rs/crates/hypervisor/src/qemu/machine/topology.rs @@ -5,6 +5,9 @@ pub(crate) struct PciTopology { pub default_bus: Option, pub roots: Vec, + /// Pre-provisioned root ports emitted on the default bus (Q35 cold-plug topology). + /// Contrast with `roots`, which are pxb-pcie complexes for GPU passthrough. + pub cold_plug_ports: Vec, } pub(crate) struct PciRootComplex { @@ -20,18 +23,35 @@ pub(crate) struct PciRootComplex { pub(crate) struct PciRootPort { pub id: String, pub chassis: u8, + /// `slot=N` — required for Q35 root ports; absent on aarch64 Grace ports. + pub slot: Option, + /// `multifunction=on/off` — required for Q35; absent on Grace. + pub multifunction: Option, + /// `io-reserve=N` — required for aarch64 Grace ports; absent on Q35. + pub io_reserve: Option, pub device: Option, } pub(crate) struct VfioDevice { pub id: String, pub host: String, - pub rombar: bool, + pub rombar: Option, pub kind: VfioDeviceKind, + /// When set, an `-object iommufd,id=` is emitted immediately before + /// this device and referenced in the device string. Used for CoCo x86 passthrough; + /// Grace uses a single shared `iommufd0` in `Objects::iommufd` instead. + pub iommufd_id: Option, + /// `x-pci-vendor-id` override required for CoCo measured-boot attestation (#12329). + pub pci_vendor_id: Option, + /// `x-pci-device-id` override required for CoCo measured-boot attestation (#12329). + pub pci_device_id: Option, } pub(crate) enum VfioDeviceKind { + /// `vfio-pci-nohotplug` — aarch64 Grace static binding. Gpu, + /// `vfio-pci` — x86 Q35 / CoCo passthrough and NIC. + GpuPci, Nic, }