runtime: make SEV-SNP guest CPU model configurable (cpu_model)

Author: hgowda-amdCreated Sep 18, 2026Updated Sep 18, 2026
Labelsenhancementneeds-review

Problem

On SEV-SNP, the guest CPU model passed to QEMU is currently hardcoded to EPYC-v4 (Naples-generation), regardless of the actual host CPU. This means guests never see any instruction sets introduced after Naples. On newer EPYC generations (Milan, Genoa, Turin etc.) this blocks workloads notably AI/ML workloads to make use of optimization capabilities the underlying hardware actually has. Issue #12382 already highlights concrete interest in enabling newer AES/AVX instruction sets for SEV-SNP pods for exactly this performance reason. Today, the only way to get any of that is by extending cpu_features on top of a model that doesn't actually support them, which risks the guest failing to launch if the host doesn't have the corresponding instructions. As AMD ships new EPYC generations, this gap compounds every year, pinning to any single fixed model just moves the problem rather than solving it.

The natural fix, -cpu host, is not a safe drop-in replacement: for SEV-SNP, the CPU model/family-model-stepping is part of the launch measurement. Changing the CPU model dynamically breaks the reproducible, predictable measurements that attestation reference-value distribution (e.g. Trustee's RVPS) currently relies on. -cpu host also has known additional stability issues on current firmware in some environments, independent of the measurement question. In addition to also introducing runtime unpredictability issues.

A prior attempt at -cpu host (#12329) was rejected on these grounds. In the discussion on that PR, one of the comments was that Kata intentionally validates {kernel, OVMF, QEMU, CPU model} as a single unit, and treats the runtime environment as something the project controls and validates as a whole rather than something that should vary dynamically per host, which is why an unconditional switch to host was seen as introducing an unacceptable amount of untested variability. We agree host isn't the right default today. But short of that, we should still find ways to let customers pick a specific, named CPU model that matches their hardware generation (e.g. EPYC-Milan, EPYC-Genoa, EPYC-Turin), so they can make use of the newer instruction sets, capabilities, and performance benefits they've already paid for without requiring the fully dynamic, unpinned behavior of host.

Options considered

We (AMD) evaluated three approaches internally before proposing one here:

  1. Runtime auto-selection — detect the host CPU at sandbox start and pick the matching QEMU model automatically (Milan host → EPYC-Milan, Genoa → EPYC-Genoa, etc.). No user configuration needed, and Kata never picks a model the host can't run. Downside: the resulting measurement still varies per host, which reintroduces the same reference-value management problem as host, and the same "runtime as a controlled, validated unit" concern from #12329.
  2. Configurable CPU model with a pinned default — keep a fixed default model for predictability/CI/reference-value distribution, but add a config option so users can override it to match their fleet's hardware. Users who override take on managing their own reference values.
  3. Keep EPYC-v4, only extend cpu_features — no new config surface. Lowest risk to change, but puts the burden on users to know the correct feature flags for their hardware, and a mismatch (features the host doesn't support) causes guest launch failure. So, is more error prone.

Proposed solution

We would like to propose option 2: a new cpu_model setting in Kata's SEV-SNP hypervisor configuration, alongside the existing cpu_features setting that SNP users already configure today.

At a high level:

  • What's added: a new cpu_model config field in the qemu-snp hypervisor configuration section (same section that already holds cpu_features), exposed the same way other hypervisor tunables are, via the Kata config TOML, with a compiled-in default baked into the packaged config.
  • How it's read: at guest start time, the runtime reads the configured value the same way it already reads cpu_features and other hypervisor options today, and uses it as the CPU model argument when building the QEMU command line for the SNP guest replacing today's hardcoded model string.
  • Default value: stays pinned to a single, known-good model so existing CI behavior and attestation reference-value management unaffected for anyone who doesn't touch the setting. We would propose moving the default forward from EPYC-v4 to EPYC-Milan as a starting point since Milan is the first generation with SNP support ans sev is deprecated in kata.
  • User override: users who need a newer model (or eventually host) set cpu_model explicitly to match their fleet's hardware, and take on generating/distributing their own attestation reference value for that model.

This is explicitly framed as an interim, opt-in improvement, not the end state. It doesn't solve fleet-wide management for mixed-SKU deployments the way host passthrough eventually would, a user with heterogeneous hardware still has to pick/manage a value per SKU. The long-term direction we think is worth pursuing separately is enabling -cpu host reliably, which requires:

  • Trustee/attestation tooling that can validate dynamic (per-host) measurements instead of only a static allow-list of known reference values, and
  • resolving known stability issues with host CPU passthrough on current firmware.

We see that as a larger, separately-tracked effort that AMD intends to help drive, not something this issue is meant to resolve.

Related: #12329, #12382

Source: kata-containers/kata-containers