Commit Graph

2348 Commits

Author SHA1 Message Date
Fabiano Fidêncio
c7e91684b8 runtime: nest pcie-pci-bridge under root-port on OVMF
Use a nested root-port plus pcie-pci-bridge topology on Q35+OVMF so
firmware reserves hot-plug resources and NIC hot-plug works reliably.

Signed-off-by: Fabiano Fidêncio <ffidencio@nvidia.com>
Assisted-by: OpenAI Codex <codex@openai.com>
2026-07-08 13:12:19 +02:00
Fabiano Fidêncio
da4fe9a0f4 runtime: avoid addr=0 on auto-assigned root ports
Stop forcing addr=0 for auto-assigned PCIe root ports to avoid slot
conflicts with Q35 host bridge devices.

Signed-off-by: Fabiano Fidêncio <ffidencio@nvidia.com>
Assisted-by: OpenAI Codex <codex@openai.com>
2026-07-08 13:12:19 +02:00
Fabiano Fidêncio
7d91b15a3b govmm/qemu: always honor explicit PCIe root-port addr
Emit addr= for PCIe root ports regardless of multifunction so guest PCI
paths stay stable for downstream hot-plug resolution.

Signed-off-by: Fabiano Fidêncio <ffidencio@nvidia.com>
Assisted-by: OpenAI Codex <codex@openai.com>
2026-07-08 13:12:19 +02:00
Alex Lyn
7e987cd6c8 Merge pull request #13321 from PiotrProkop/fix-vfio-init
runtime: Hotplug VFIO network devices before any container starts
2026-07-08 11:08:14 +08:00
Dimitris Karakasilis
95edf90073 runtime: remove cgo from KVM capability checks
The host KVM capability checks obtained the KVM_CREATE_VM and
KVM_CHECK_EXTENSION ioctl request numbers from <linux/kvm.h> via cgo
(kata-check.go for the generic check, hypervisor_linux_arm64.go for the
Arm RME check). This was the only remaining use of cgo in the runtime,
and it forced the runtime to be linked against the host libc.

Replacing these with plain Go constants lets kata-runtime,
containerd-shim-kata-v2 and kata-monitor build with CGO_ENABLED=0,
which is a prerequisite for producing fully static, libc-agnostic
binaries that run on musl-only hosts (the kata-deploy payload otherwise
fails to exec on a glibc-free distribution because its requested dynamic
loader is absent).

The ioctl numbers are stable kernel ABI. The asm-generic encoding used
by amd64, arm64, s390x and riscv64 gives _IO(KVMIO, nr) == (0xAE << 8) |
nr, while powerpc uses the legacy encoding (_IOC_NONE == 1, direction
shifted by 29). The values are split into kvm_ioctls_generic.go and
kvm_ioctls_ppc64le.go accordingly so each architecture keeps the exact
value its kernel headers would have produced.

No functional change: the runtime issues the same ioctls as before.

Signed-off-by: Dimitris Karakasilis <dimitris@spectrocloud.com>
Generated-By: Claude Opus 4.8 (1M context) noreply@anthropic.com
2026-07-06 12:02:13 +02:00
PiotrProkop
86ab1b22a3 runtime: Hotplug VFIO network devices before any container starts
A VFIO-backed network interface used to be hotplugged only as a side
effect of creating the workload container that references the VFIO
device in its OCI spec: setupNetworks() skipped VfioEndpoints when it
ran at sandbox start and applied their configuration later, on the
second invocation from createContainer(), guarded by the
hotplugNetworkConfigApplied flag.

Init containers run before that workload container, so they started
with the VFIO interface absent and thus without pod networking.

Attach the device at sandbox scope instead, from setupNetworks() at
sandbox start, before any container is created:

- Add Sandbox.hotplugVfioNetworkDevice(): resolve the VFIO device
  node backing the endpoint's host BDF, hotplug it and record the
  guest PCI path on the endpoint. When the workload container later
  references the same VFIO group through a device plugin, the device
  manager finds the device by major:minor and only bumps reference
  counts, so it is neither plugged twice nor unplugged when that
  container exits.

- Configure all endpoints, VfioEndpoints included, in a single
  setupNetworks() pass at sandbox start. The Container parameter, the
  second invocation from createContainer() and the
  hotplugNetworkConfigApplied flag are no longer needed.

Add unit tests for the hotplugVfioNetworkDevice() guard paths.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Signed-off-by: PiotrProkop <pprokop@nvidia.com>
2026-07-03 15:14:22 +02:00
Fabiano Fidêncio
159df44abf Merge pull request #13290 from fidencio/topic/runtime-fix-multi-node-pxb-pxie-when-using-less-vcpus-than-numa-nodes
runtime: fix multi-node pxb-pcie topology for dual-socket GPU pods
2026-07-01 17:08:46 +02:00
Fabiano Fidêncio
6d456811e3 Merge pull request #13302 from stevenhorsman/opencontainers/runc-1.3.6-bump
runtime: bump github.com/opencontainers/runc
2026-07-01 14:37:32 +02:00
Fabiano Fidêncio
51aa51a377 runtime: fix multi-node pxb-pcie topology for dual-socket GPU pods
When VFIO GPUs span both host NUMA nodes, emit guest NUMA nodes even
if vCPUs < node count (memory-only nodes), and pin each pxb-pcie to
bus=pcie.0 so QEMU does not attach the second expander to the first.

Also fix checkVCPUsPinningNUMA to tolerate vCPUs < NUMA node count.
The memory-only NUMA topology (emitted for pxb-pcie placement when
default_vcpus=1) creates more guest NUMA nodes than there are vCPUs;
the previous hard error silently tore down every sandbox.  Now the
available vCPU(s) are pinned to the first node(s) and memory-only
nodes are skipped.

Signed-off-by: Fabiano Fidêncio <ffidencio@nvidia.com>
Assisted-by: Cursor <cursoragent@cursor.com>
2026-07-01 12:41:59 +02:00
Fabiano Fidêncio
968d6e9431 runtime: add guest_extension_images cold-plug support for Go runtime
Mirror the Rust runtime's guest_extension_images support in the Go runtime:

- hypervisor.go: add GuestExtensionImage struct and GuestExtensionImages field to
  HypervisorConfig.
- config.go: parse [[hypervisor.qemu.guest_extension_images]] TOML sections
  via toGuestExtensionImages(), validating that every extension has a non-empty
  name and valid dm-verity parameters.
- qemu.go: in buildDevices(), attach each extra image as a virtio-blk
  drive with ID extension-<name>; in kernelParameters(), append
  kata.extension.<name>.verity_params=... for each extra image.

Signed-off-by: Fabiano Fidêncio <ffidencio@nvidia.com>
Assisted-by: Cursor <cursoragent@cursor.com>
2026-06-30 21:51:48 +02:00
stevenhorsman
c292d93ec3 runtime: bump github.com/opencontainers/runc
Bumps github.com/opencontainers/runc from v1.2.8 to v1.3.6 to fix
GHSA-xjvp-4fhw-gc47 (CVE, CVSS 4.8).

The libcontainer/cgroups/systemd sub-package was removed from runc in
v1.3.x and moved to the standalone github.com/opencontainers/cgroups
module. Update the import in pkg/resourcecontrol/utils_linux.go
accordingly, and promote github.com/opencontainers/cgroups to a direct
dependency.

Fixes: https://osv.dev/GHSA-xjvp-4fhw-gc47
Generated-by: IBM Bob
Signed-off-by: stevenhorsman <steven@uk.ibm.com>
2026-06-30 09:55:40 +01:00
Manuel Huber
c9352ffffe runtime: plumb block discard unmap
Pass block-device discard support through the Go QEMU stack.

Block drives can now carry a DiscardUnmap request into govmm. QEMU
command-line and QMP hotplug paths set discard=unmap on the backend and
enable discard on virtio-blk frontends, while leaving SCSI frontend
arguments unchanged.

Signed-off-by: Manuel Huber <manuelh@nvidia.com>
Assisted-by: OpenAI Codex <codex@openai.com>
2026-06-26 21:05:51 +00:00
Manuel Huber
24c51cfbbf runtime: support block-plain emptyDirs
Add Go runtime support for the block-plain emptyDir mode.

Disk-backed Kubernetes emptyDir mounts remain bind mounts so the block
emptyDir handling path can intercept them. The runtime creates a sparse
disk.img in the kubelet emptyDir directory and records direct-volume
metadata for the agent-visible block storage path.

Fresh block emptyDirs request filesystem creation through a dedicated
metadata flag. Plain emptyDirs also record discard support on the block
device. Encrypted emptyDirs keep the existing ephemeral encryption
metadata and carry the same filesystem-creation signal.

Signed-off-by: Manuel Huber <manuelh@nvidia.com>
Assisted-by: OpenAI Codex <codex@openai.com>
2026-06-26 21:05:51 +00:00
Aurélien Bombo
1217dd1584 Merge pull request #12373 from kata-containers/disable-guest-empty-dir
runtime: Set `disable_guest_empty_dir = true` by default
2026-06-24 20:09:46 -05:00
Aurélien Bombo
3acb618f6b genpolicy: Assume disable_guest_empty_dir = true
This option should be removed for 4.0, so we don't handle `false`.

Signed-off-by: Aurélien Bombo <abombo@microsoft.com>
2026-06-24 15:22:13 -05:00
Aurélien Bombo
e191c5b716 runtime-go/rs: Reconcile hugepage emptyDirs and disable_guest_empty_dir
This addresses an issue where the disable_guest_empty_dir=true code paths did
not take into account that hugepage-backed emptyDirs should always be recreated
in the guest (using guest hugepages).

Signed-off-by: Aurélien Bombo <abombo@microsoft.com>
2026-06-24 15:22:13 -05:00
Aurélien Bombo
a3e91d9ed2 runtime-go/rs: Set disable_guest_empty_dir = true by default
This makes the runtime share the host Kubelet emptyDir folder with the guest
instead of the agent creating an empty folder in the container rootfs. Doing so
enables the Kubelet to track emptyDir usage and evict greedy pods.

In other words, with virtio-fs the container rootfs uses host storage whether
this is true or false, however with true, Kata uses the k8s emptyDir folder so
the sizeLimit is properly enforced by k8s.

Addresses the ephemeral storage part of #12203.

History:

 * Initially, emptyDirs are slow because they are shared from the host with 9p.
   https://github.com/kata-containers/runtime/issues/1472

 * To address above, emptyDirs are hardcoded to be created by the agent in the
   pause container's rootfs, potentially leveraging devicemapper and improving
   perf.
   https://github.com/kata-containers/runtime/pull/1485

 * The previous PR regressed an (interesting?) use case where emptyDirs were
   used to share data from the host to the guest, so the behavior was made
   configurable and `disable_guest_empty_dir = false` is introduced, defaulting
   to the behavior of the previous PR.
   https://github.com/kata-containers/kata-containers/pull/2056

 * Another resource accounting regression remains which is addressed in this PR.

Signed-off-by: Aurélien Bombo <abombo@microsoft.com>
2026-06-24 15:21:53 -05:00
Christophe de Dinechin
631fd96715 runtime: Change default log level from Warn to Info
When the kata configuration does not set log_level to debug, the
containerd-shim-v2 defaults to WarnLevel, which suppresses important
diagnostic information logged at Info level.

Key Info-level logs that are currently hidden:
- QEMU command line (qemu.go:3566) - critical for debugging VM issues
- VM lifecycle events (creation, start, stop)
- Device hotplug operations (VFIO, network, volumes)
- Resource configuration (NUMA, memory)
- QMP socket details

Info level provides significantly better diagnostic data without
flooding logs with excessive detail (which would occur at Debug level).
This change improves troubleshooting capabilities for production
deployments where debug mode is not enabled.

Note: runtime-rs already defaults to Info level (see
src/runtime-rs/crates/shim/src/logger.rs:13,30), so this change only
affects the Go runtime.

Fixes: #13260

Signed-off-by: Christophe de Dinechin <dinechin@redhat.com>
2026-06-23 10:29:33 +02:00
Steve Horsman
a87d71763e Merge pull request #13255 from kata-containers/dependabot/go_modules/src/runtime/github.com/containerd/containerd-1.7.33
build(deps): bump github.com/containerd/containerd from 1.7.32 to 1.7.33 in /src/runtime
2026-06-22 11:17:54 +01:00
Steve Horsman
20bcff185f Merge pull request #13254 from kata-containers/dependabot/go_modules/src/runtime/go.mongodb.org/mongo-driver-1.17.7
build(deps): bump go.mongodb.org/mongo-driver from 1.14.0 to 1.17.7 in /src/runtime
2026-06-22 11:17:29 +01:00
dependabot[bot]
9c6cccb483 build(deps): bump github.com/containerd/containerd in /src/runtime
Bumps [github.com/containerd/containerd](https://github.com/containerd/containerd) from 1.7.32 to 1.7.33.
- [Release notes](https://github.com/containerd/containerd/releases)
- [Changelog](https://github.com/containerd/containerd/blob/main/RELEASES.md)
- [Commits](https://github.com/containerd/containerd/compare/v1.7.32...v1.7.33)

---
updated-dependencies:
- dependency-name: github.com/containerd/containerd
  dependency-version: 1.7.33
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-06-21 14:32:17 +00:00
dependabot[bot]
399c863cd2 build(deps): bump go.mongodb.org/mongo-driver in /src/runtime
Bumps [go.mongodb.org/mongo-driver](https://github.com/mongodb/mongo-go-driver) from 1.14.0 to 1.17.7.
- [Release notes](https://github.com/mongodb/mongo-go-driver/releases)
- [Commits](https://github.com/mongodb/mongo-go-driver/compare/v1.14.0...v1.17.7)

---
updated-dependencies:
- dependency-name: go.mongodb.org/mongo-driver
  dependency-version: 1.17.7
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-06-20 10:22:56 +00:00
Cameron Baird
730307f32c factory: Default to normal sandbox boot path when factory init not done
The behavior we had before was that, for a starting k8s pod,
it sees enable_template=true and therefore:

1. Tries NewFactory with fetchOnly=true
2. When that fails (because template.Fetch fails to find the artifacts,
	we retry with fetchOnly=false. This creates a direct factory
	which creates the template from scratch
	(hence we pay a full pod sandbox boot time here)
	and then restores from that. Hence the boot times
	are strictly worse on this path.

Now, even when enable_template=true, we don't try to force a direct factory.
Instead we just revert to the standard sandbox boot path.

Signed-off-by: Cameron Baird <cameronbaird@microsoft.com>
2026-06-19 18:00:02 +00:00
Cameron Baird
65a5f272f8 ci: Introduce tests for VM template factory
Add k8s-vm-templating-test.bats which exercises pod create
with the factory initialized on the target node.

Signed-off-by: Cameron Baird <cameronbaird@microsoft.com>
2026-06-19 18:00:02 +00:00
Cameron Baird
c0f9744225 runtime: Implement support for VM Template factory in clh
Add support for VM Template factory on the clh path.

In order to support snapshot/restore-based VM templating,
the following changes were needed:
1. For clh.go, implement SaveVM, PauseVM, restoreVM, ResumeVM
2. Remove initrd config check for VM Templating path. The
        root disk image (when using image mode) is created in memory
        and therefore captured in the VM snapshot.
3. Truncate the memory file to the size of the VM at factory VM
        create time. This allows CLH to use the memory file
        as the backing for the template VM memory, allowing O(1)
        snapshot times.
4. CLH uses memory zones as backing for its memory on the template paths
5. Update StartVM in CLH to use the restore path when template is
        configured and available

Signed-off-by: Cameron Baird <cameronbaird@microsoft.com>
2026-06-19 18:00:02 +00:00
Fabiano Fidêncio
0ddb2ee1f1 Merge pull request #13160 from LandonTClipp/kata_visible_devices
feat(agent): translate KATA_VISIBLE_DEVICES into CDI GPU requests
2026-06-16 19:10:35 +02:00
LandonTClipp
a1dd28cb52 feat(runtime): plumb VISIBLE_CDI_DEVICES through the Go runtime
Add a `visible_cdi_devices` TOML option to the Go runtime so the
agent.visible_cdi_devices=true kernel parameter is emitted to the guest
when enabled. Wire the option through the NVIDIA GPU configuration
templates and add tests verifying the kernel-params flow.

Signed-off-by: LandonTClipp <lclipp@coreweave.com>
2026-06-16 11:44:09 +02:00
Fabiano Fidêncio
6203e28bef runtime: Propagate block-mode device read-only flag to the VMM
Block-mode volumes (e.g. Kubernetes volumeDevices) are passed to the
container as device nodes in spec.Linux.Devices and carry no mount "ro"
option. Their read-only intent is expressed only via the cgroup device
access in spec.Linux.Resources.Devices ("rm" = read+mknod, no write, for
read-only; "rwm" for read-write).

The device path ignored that signal: newLinuxDeviceInfo() built the
DeviceInfo without ever setting ReadOnly (it only consumed FileMode, the
node permission bits, not the read/write access), so the device was
always attached read-write.

This is problematic for filesystems such as XFS, which inspect the block
device read-only state to decide whether to attempt journal/log recovery.
When the guest device is writable, XFS tries to replay the log even for a
read-only mount, which fails badly. Mounting "-o ro" in the guest is not
enough; the device itself must advertise read-only, which only happens
when the VMM opens the backing device read-only (DeviceInfo.ReadOnly ->
BlockDrive.ReadOnly -> qemu read-only=on / clh Readonly).

Derive the read-only flag from two independent signals, combined with OR
so either one marks the device read-only:

  - the cgroup device access rule that exactly matches the device, so a
    block-mode volume marked read-only by the orchestrator (e.g. a pod
    volume with persistentVolumeClaim.readOnly: true) is honored, and
  - the host block device's own read-only flag (queried via the BLKROGET
    ioctl). Block-mode volumes frequently carry no read-only signal in
    the OCI spec at all, so the device flag is often the only reliable
    source.

The BLKROGET probe is shared (pkg/device/config.BlockDeviceIsReadOnly,
Linux-only with a stub on other platforms) between the device-node path
(newLinuxDeviceInfo, probing /dev/block/<major>:<minor>) and the
bind-mounted/filesystem block path (createDeviceInfo). None of this
relies on external host tooling such as "blockdev --setro".

Signed-off-by: Fabiano Fidêncio <ffidencio@nvidia.com>
Assisted-by: Cursor
2026-06-15 23:18:36 +02:00
Manuel Huber
70d8f1bf3d runtime: remove file_mem_backend config option
Remove the Go runtime file_mem_backend and valid_file_mem_backends
config knobs, along with the corresponding sandbox annotation handling.

The runtime still enables file-backed shared memory automatically for
virtio-fs by using /dev/shm as the backing directory. This only removes
the user-selectable backend path.

Signed-off-by: Manuel Huber <manuelh@nvidia.com>
Assisted-by: OpenAI Codex <codex@openai.com>
2026-06-12 00:07:16 +00:00
Hyounggyu Choi
7cc6767fa2 runtime*: use static_sandbox_resource_mgmt defaults for qemu-se
Switch qemu-se config templates to use the TEE/CoCo-specific
static_sandbox_resource_mgmt defaults instead of the generic
QEMU defaults.

qemu-se-runtime-rs config now uses DEFSTATICRESOURCEMGMT_COCO
while runtime qemu-se config now uses DEFSTATICRESOURCEMGMT_TEE.
This aligns static sandbox resource management behavior with confidential
container expectations for qemu-se variants.

Signed-off-by: Hyounggyu Choi <Hyounggyu.Choi@ibm.com>
2026-06-09 14:45:50 +02:00
Fabiano Fidêncio
743b0a4839 Merge pull request #13165 from stevenhorsman/bump-go-to-1.25.11
versions: bump golang to 1.25.11
2026-06-04 20:24:57 +02:00
Fabiano Fidêncio
2a1ce7b8c4 Merge pull request #12539 from mythi/no-vcpu-hotplug
Disable CPU hotplug when confidential guest setting enabled
2026-06-04 10:56:52 +02:00
stevenhorsman
879912be25 versions: bump golang to 1.25.11
Bump the go version to resolve CVEs:
- GO-2026-5037
- GO-2026-5038
- GO-2026-5039

Signed-off-by: stevenhorsman <steven@uk.ibm.com>
Generated-By: IBM Bob
2026-06-04 08:49:17 +01:00
Mikko Ylinen
e475d870fb runtime: qemu: don't set maxcpus when confidential guest is enabled
QEMU maxcpus enables CPU hotplug capabilities but it's unused when
confidential guest is enabled.

Change Go runtime code to skip setting maxcpus QEMU cmdline if CPU hotplug
is not needed.

Commit 07db945b09 built a relationship between kernel's cmdline nr_cpus and
the maxcpus config. Now that maxcpus is dropped for confidential guests, drop
nr_cpus from kernel commandline too. This hopefully helps with the reference
values computation too.

Signed-off-by: Mikko Ylinen <mikko.ylinen@intel.com>
2026-06-03 15:27:35 +03:00
stevenhorsman
c0f549860e runtime: bump golang.org/x dependencies
Bump golang.org/x/net from v0.53.0 to v0.55.0 and golang.org/x/sys
from v0.43.0 to v0.44.0 to resolve CVEs:
- GO-2026-5024
- GO-2026-5025
- GO-2026-5026
- GO-2026-5027
- GO-2026-5028
- GO-2026-5029
- GO-2026-5030

Signed-off-by: stevenhorsman <steven@uk.ibm.com>
Generated-By: IBM Bob
2026-06-03 09:56:54 +01:00
Fabiano Fidêncio
a2bb3f64b0 Merge pull request #12436 from mythi/tdx-updates-2026-3
runtime(-rs): tdx: use TDX QGS via unix-domain-socket by default
2026-06-03 08:50:26 +02:00
Fabiano Fidêncio
230e01b04e Merge pull request #13126 from kata-containers/topic/runtimes-introduce-azure-specific-configs
runtime/runtime-rs: introduce Azure specific configs
2026-06-02 09:17:09 +02:00
Fabiano Fidêncio
9b5b829265 runtime: oci: derive sandbox CPUs from shares only if unconstrained
The shares-based fallback added for cpuManagerPolicy=static fired whenever
the quota-based CPU count was 0, including for BestEffort sandboxes that
have no CPU request. Those sandboxes still carry the cgroup-floor shares
value (2), so the fallback derived ceil(2/1024)=1 and inflated every such
sandbox by one vCPU. For peer-pods (static resource management) this
changed the VM sizing to default_vcpus+1, regressing the libvirt
instance-type CI checks.

Gate the fallback on the quota being explicitly unconstrained (< 0), which
is the actual cpuManagerPolicy=static signal, instead of on numCPU == 0.
BestEffort sandboxes (quota 0/absent) now correctly contribute 0 vCPUs
while the static-policy case still recovers the CPU count from shares.

Add unit tests covering the static-policy, rounding, BestEffort, and
explicit-quota cases.

Signed-off-by: Fabiano Fidêncio <ffidencio@nvidia.com>
2026-06-01 09:50:49 +02:00
Aurélien Bombo
9acef4bc55 Merge pull request #13133 from microsoft/cameronbaird/upstream/revert-macvtap-simple
Revert "runtime: Enforce >= 1 queue pairs for tapNetworkPair"
2026-05-29 14:57:07 -05:00
Cameron Baird
7a9d207ab2 Revert "runtime: Enforce >= 1 queue pairs for tapNetworkPair"
This reverts commit 2799f7d36b.
2026-05-29 17:05:40 +00:00
Fabiano Fidêncio
025202a52a runtime: expose InfiniBand devices to VFIO containers
The NVIDIA BF3 SR-IOV device plugin injects the VF BDF only as a
PCIDEVICE_* environment variable; it does not add the VFIO char device
to linux.devices in the OCI spec.  As a result the agent's
container_has_vfio_device() gate stays closed and
expose_guest_infiniband_devices() is never triggered — leaving
/dev/infiniband absent from the container even though the guest kernel
created the IB devices (mlx5_core.rdma.0 probes successfully).

Add appendPhysicalEndpointDevices() which runs after appendDevices()
in createContainer().  It walks the sandbox network endpoints; for
each PhysicalEndpoint with a resolved guest PCI path it derives the
VFIO group char path from sysfs (iommu_group symlink) and synthesises
a vfio-pci-gk Device entry.  Both legacy group paths (/dev/vfio/N)
and iommufd cdev paths (/dev/vfio/devices/vfioN) are supported by
reading the iommu_group sysfs symlink.

Signed-off-by: Fabiano Fidêncio <ffidencio@nvidia.com>
Assisted-by: Cursor <cursoragent@cursor.com>
2026-05-29 13:07:45 +02:00
Fabiano Fidêncio
f36c383b4f runtime: generate dedicated CLH Azure config variants
Create configuration-clh-azure{,-runtime-rs}.toml from the base CLH
configs during build.

This keeps Mariner-specific defaults in explicit config artifacts
instead of ad-hoc runtime mutation.

Signed-off-by: Fabiano Fidêncio <ffidencio@nvidia.com>
2026-05-28 23:32:37 +02:00
Fabiano Fidêncio
fa9a9f3aeb runtime: set VF admin MAC before vfio-pci rebind for IB/RoCE support
Without an admin MAC, the guest's mlx5_core inherits the VF's
firmware-default MAC. This MAC differs from the IB port's HCA MAC, so
mlx5_ib's GID cache refuses to populate
/sys/class/infiniband/mlx5_*/ports/N/gids/*. RoCE then appears active
(port = ACTIVE, link_layer = Ethernet) but every verb that needs a GID
— RoCEv2 packets, address handles, librdmacm bind — fails silently.

Push the CNI-assigned MAC down to the VF as an "admin MAC" via the PF
using RTM_SETLINK before the bind-to-vfio-pci step. The firmware
applies the admin MAC during the VF reset that accompanies the
unbind/rebind cycle, so the guest sees a single consistent MAC across
netdev, IB port, and HCA.

Best-effort: failures are logged at warn and the existing agent-side
MAC reconciliation (rpc.rs::update_interface) remains as a fallback for
L2/L3 connectivity.

Signed-off-by: Fabiano Fidêncio <ffidencio@nvidia.com>
Assisted-by: Cursor <cursoragent@cursor.com>
2026-05-28 21:54:52 +02:00
Fabiano Fidêncio
992a723392 runtime: resolve cold-plug VFIO guest PCI path via QMP
For QEMU cold-plug + guest-kernel mode the guest BDF of a cold-plugged
VFIO device is auto-allocated at boot (each pcie-root-port is added with
chassis=N,slot=N but no pinned addr=, so QEMU picks the next free slot
on pcie.0). The hot-plug path already queries QMP via qomGetPciPath;
reuse that same mechanism for cold-plugged devices.

Add ResolveColdPlugVFIOGuestPciPaths to the Hypervisor interface.
Implement it in qemu.go using qomGetPciPath. Add no-op stubs for all
other hypervisors.

Call it at the start of setupNetworks so that the PCI paths are resolved
before generateVCNetworkStructures emits the agent Interface proto. Also
stamp the resolved path onto PhysicalEndpoints (used by SR-IOV VFs
exposed as physical network devices) so that update_interface carries a
non-empty devicePath. Without devicePath the agent falls back to a
by-MAC link lookup which fails when the VF firmware MAC differs from the
CNI-assigned MAC after the vfio-pci unbind/rebind cycle.

Signed-off-by: Fabiano Fidêncio <ffidencio@nvidia.com>
Assisted-by: Cursor <cursoragent@cursor.com>
2026-05-28 21:54:52 +02:00
Fabiano Fidêncio
23c5250933 runtime/qemu: emit id= for VFIODevice on -device cmdline
Without an explicit id= on the vfio-pci device, QEMU auto-generates
an internal name that does not match vfioDev.ID, so any subsequent
qomGetPciPath(vfioDev.ID) call via QMP fails with "Device 'X' not
found". This breaks resolveColdPlugVFIOGuestPciPaths which needs the
device ID to look up the guest PCI path, leaving GuestPciPath nil and
causing update_interface to fail repeatedly as the agent can't find
the interface to configure.

Signed-off-by: Fabiano Fidêncio <ffidencio@nvidia.com>
Assisted-by: Cursor <cursoragent@cursor.com>
2026-05-28 21:54:52 +02:00
Fabiano Fidêncio
e6777f0866 runtime: keep cold-plug VFIO devices in guest-kernel mode
Container.createDevices was dropping cold-plug VFIO entries from the
container's deviceInfos whenever vfio_mode = "guest-kernel", which
in turn meant the agent's CreateContainer request carried no
vfio-pci-gk device entry and sandbox.pcimap[cid] stayed empty. The
SR-IOV device plugin still set PCIDEVICE_<RES>=<host-BDF> on the
workload container, so update_env_pci then aborted with
"No PCI mapping found for container <id>" and the container failed
with CrashLoopBackOff.

Include cold-plug VFIO devices in deviceInfos for both VFIO modes.
The existing vfio-pci-gk agent handler returns dev: None (so
/dev/vfio/<group> is not materialised in the container spec, and
constrainGRPCSpec(stripVfio=true) already strips it from the grpc
spec for guest-kernel mode), while still recording the host->guest
PCI mapping into sandbox.pcimap[cid] so env-var translation works.

devManager.NewDevice calls FindDevice first, which matches the
already cold-plugged sandbox-level device by HostPath / major / minor,
so this does not double-attach.

Signed-off-by: Fabiano Fidêncio <ffidencio@nvidia.com>
Assisted-by: Cursor <cursoragent@cursor.com>
2026-05-28 21:54:52 +02:00
Fabiano Fidêncio
9893b6dc03 runtime: correctly resolve cold-plug VFIO guest PCI paths
Populate missing VFIO guest PCI paths via QMP before serializing
container devices so guest-kernel PCI env translation has the mappings
it needs.

Signed-off-by: Fabiano Fidêncio <ffidencio@nvidia.com>
Assisted-by: Cursor <cursoragent@cursor.com>
2026-05-28 21:54:52 +02:00
Cameron Baird
2799f7d36b runtime: Enforce >= 1 queue pairs for tapNetworkPair
In the xConnectVMNetwork path, we have queues = 0 as a baseline,
set to h.HypervisorConfig().NumVCPUs() iff h.Capabilities() advertise
MultiQueueSupport. This is certainly incorrect as we always want, as
a baseline, at least one queue pair. Make queues := 1 by default
to ensure the NetworkPair has at least one queue pair for all
virtio-net paths.

Signed-off-by: Cameron Baird <cameronbaird@microsoft.com>
2026-05-27 18:55:11 +00:00
Mikko Ylinen
2b38d9f45e runtime(-rs): tdx: use TDX QGS via unix-domain-socket by default
TDX QGS takes raw TD report from QEMU/guest VM and signs it in an SGX
enclave. Historically, QGS has supported two transports: vsock and
unix-domain-socket. The former was necessary before the guest kernel
supported the GetQuote "TDVMCALL" hypercall: DCAP library inside the
guest used vsock to talk to QGS directly.

However, with GetQuote, QEMU gets the TDREPORT and sends it to QGS.
In process-to-process communication, unix-domain-socket is a better
approach. This is also the only transport supported by libvirt by default.

With that, align Kata default configuration to use unix-domain-socket
as well. The change in impacts QEMU commandline:

old:
"quote-generation-socket":{"type":"vsock","cid":"2","port":"4050"}
new:
"quote-generation-socket":{"type":"unix","path":"/var/run/tdx-qgs/qgs.socket"}

Host QGS configuration must be changed to listen unix-domain-sockets.

Signed-off-by: Mikko Ylinen <mikko.ylinen@intel.com>
2026-05-26 17:08:56 +03:00
Mikko Ylinen
733c6791d3 runtime(-rs): make TDX QGS port=0 change backwards compatible
Changing Kata runtime configurations to use TDX QGS port=0 (unix domain
socket transport) means cluster admins must also reconfigure qgsd to
the same and have /var/run/tdx-qgs/qgs.sock available.

Since the early days of TDX attestation in Kata, the configuration has used
vsock with cid=2, port=4050. To avoid unncessary breakages when Kata default
moves to unix domain socket, fall back to the old configuration if
/var/run/tdx-qgs/qgs.sock is not available on the worker node.

Signed-off-by: Mikko Ylinen <mikko.ylinen@intel.com>
2026-05-26 17:01:52 +03:00