From ded60173d4b328adffc44651fc6ffcb6ebae0e9f Mon Sep 17 00:00:00 2001 From: Joana Pecholt Date: Fri, 9 Sep 2022 16:23:05 +0200 Subject: [PATCH] runtime: Enable choice between AMD SEV and SNP This is based on a patch from @niteeshkd that adds a config parameter to choose between AMD SEV and SEV-SNP VMs as the confidential guest type in case both types are supported. SEV is the default. Signed-off-by: Joana Pecholt --- src/runtime/config/configuration-qemu.toml.in | 6 ++++++ src/runtime/pkg/katautils/config-settings.go.in | 1 + src/runtime/pkg/katautils/config.go | 3 +++ .../virtcontainers/documentation/api/1.0/api.md | 4 ++++ src/runtime/virtcontainers/hypervisor.go | 3 +++ src/runtime/virtcontainers/hypervisor_linux_amd64.go | 2 +- src/runtime/virtcontainers/qemu_amd64.go | 10 +++++++++- 7 files changed, 27 insertions(+), 2 deletions(-) diff --git a/src/runtime/config/configuration-qemu.toml.in b/src/runtime/config/configuration-qemu.toml.in index 73c30cc1f7..7b9166adc1 100644 --- a/src/runtime/config/configuration-qemu.toml.in +++ b/src/runtime/config/configuration-qemu.toml.in @@ -34,6 +34,12 @@ machine_type = "@MACHINETYPE@" # Default false # confidential_guest = true +# Choose AMD SEV-SNP confidential guests +# In case of using confidential guests on AMD hardware that supports both SEV +# and SEV-SNP, the following enables SEV-SNP guests. SEV guests are default. +# Default false +# sev_snp_guest = true + # Enable running QEMU VMM as a non-root user. # By default QEMU VMM run as root. When this is set to true, QEMU VMM process runs as # a non-root random user. See documentation for the limitations of this mode. diff --git a/src/runtime/pkg/katautils/config-settings.go.in b/src/runtime/pkg/katautils/config-settings.go.in index 37dbfee45a..601d95612c 100644 --- a/src/runtime/pkg/katautils/config-settings.go.in +++ b/src/runtime/pkg/katautils/config-settings.go.in @@ -86,6 +86,7 @@ const defaultVhostUserStorePath string = "/var/run/kata-containers/vhost-user/" const defaultRxRateLimiterMaxRate = uint64(0) const defaultTxRateLimiterMaxRate = uint64(0) const defaultConfidentialGuest = false +const defaultSevSnpGuest = false const defaultGuestSwap = false const defaultRootlessHypervisor = false const defaultDisableSeccomp = false diff --git a/src/runtime/pkg/katautils/config.go b/src/runtime/pkg/katautils/config.go index f3bc06bdf5..dd996b4032 100644 --- a/src/runtime/pkg/katautils/config.go +++ b/src/runtime/pkg/katautils/config.go @@ -149,6 +149,7 @@ type hypervisor struct { DisableVhostNet bool `toml:"disable_vhost_net"` GuestMemoryDumpPaging bool `toml:"guest_memory_dump_paging"` ConfidentialGuest bool `toml:"confidential_guest"` + SevSnpGuest bool `toml:"sev_snp_guest"` GuestSwap bool `toml:"enable_guest_swap"` Rootless bool `toml:"rootless"` DisableSeccomp bool `toml:"disable_seccomp"` @@ -827,6 +828,7 @@ func newQemuHypervisorConfig(h hypervisor) (vc.HypervisorConfig, error) { GuestMemoryDumpPath: h.GuestMemoryDumpPath, GuestMemoryDumpPaging: h.GuestMemoryDumpPaging, ConfidentialGuest: h.ConfidentialGuest, + SevSnpGuest: h.SevSnpGuest, GuestSwap: h.GuestSwap, Rootless: h.Rootless, LegacySerial: h.LegacySerial, @@ -1221,6 +1223,7 @@ func GetDefaultHypervisorConfig() vc.HypervisorConfig { TxRateLimiterMaxRate: defaultTxRateLimiterMaxRate, SGXEPCSize: defaultSGXEPCSize, ConfidentialGuest: defaultConfidentialGuest, + SevSnpGuest: defaultSevSnpGuest, GuestSwap: defaultGuestSwap, Rootless: defaultRootlessHypervisor, DisableSeccomp: defaultDisableSeccomp, diff --git a/src/runtime/virtcontainers/documentation/api/1.0/api.md b/src/runtime/virtcontainers/documentation/api/1.0/api.md index 6455e19d0b..c7215cc97c 100644 --- a/src/runtime/virtcontainers/documentation/api/1.0/api.md +++ b/src/runtime/virtcontainers/documentation/api/1.0/api.md @@ -348,6 +348,10 @@ type HypervisorConfig struct { // Enable or disable different hardware features, ranging // from memory encryption to both memory and CPU-state encryption and integrity. ConfidentialGuest bool + + // Enables SEV-SNP guests in case both AMD SEV and SNP are supported. + // SEV is default. + SevSnpGuest bool } ``` diff --git a/src/runtime/virtcontainers/hypervisor.go b/src/runtime/virtcontainers/hypervisor.go index 784945673f..c898eb9188 100644 --- a/src/runtime/virtcontainers/hypervisor.go +++ b/src/runtime/virtcontainers/hypervisor.go @@ -527,6 +527,9 @@ type HypervisorConfig struct { // from memory encryption to both memory and CPU-state encryption and integrity. ConfidentialGuest bool + // Enable SEV-SNP guests on AMD machines capable of both + SevSnpGuest bool + // BootToBeTemplate used to indicate if the VM is created to be a template VM BootToBeTemplate bool diff --git a/src/runtime/virtcontainers/hypervisor_linux_amd64.go b/src/runtime/virtcontainers/hypervisor_linux_amd64.go index 33d018fa6f..8cfc9aca9a 100644 --- a/src/runtime/virtcontainers/hypervisor_linux_amd64.go +++ b/src/runtime/virtcontainers/hypervisor_linux_amd64.go @@ -29,12 +29,12 @@ func availableGuestProtection() (guestProtection, error) { return tdxProtection, nil } // SEV-SNP is supported and enabled when the kvm module `sev_snp` parameter is set to `Y` + // SEV-SNP support infers SEV (-ES) support if _, err := os.Stat(snpKvmParameterPath); err == nil { if c, err := os.ReadFile(snpKvmParameterPath); err == nil && len(c) > 0 && (c[0] == 'Y') { return snpProtection, nil } } - // Only choose SEV if SEV-SNP unsupported // SEV is supported and enabled when the kvm module `sev` parameter is set to `1` (or `Y` for linux >= 5.12) if _, err := os.Stat(sevKvmParameterPath); err == nil { if c, err := os.ReadFile(sevKvmParameterPath); err == nil && len(c) > 0 && (c[0] == '1' || c[0] == 'Y') { diff --git a/src/runtime/virtcontainers/qemu_amd64.go b/src/runtime/virtcontainers/qemu_amd64.go index 83d1a3d6d2..370a7cd9d8 100644 --- a/src/runtime/virtcontainers/qemu_amd64.go +++ b/src/runtime/virtcontainers/qemu_amd64.go @@ -24,6 +24,8 @@ type qemuAmd64 struct { // inherit from qemuArchBase, overwrite methods if needed qemuArchBase + snpGuest bool + vmFactory bool devLoadersCount uint32 @@ -122,6 +124,7 @@ func newQemuArch(config HypervisorConfig) (qemuArch, error) { legacySerial: config.LegacySerial, }, vmFactory: factory, + snpGuest: config.SevSnpGuest, } if config.ConfidentialGuest { @@ -176,7 +179,7 @@ func (q *qemuAmd64) cpuModel() string { // Temporary until QEMU cpu model 'host' supports AMD SEV-SNP protection, err := availableGuestProtection() if err == nil { - if protection == snpProtection { + if protection == snpProtection && q.snpGuest { cpuModel = "EPYC-v4" } } @@ -212,6 +215,11 @@ func (q *qemuAmd64) enableProtection() error { if err != nil { return err } + // Configure SNP only if specified in config + if q.protection == snpProtection && !q.snpGuest { + q.protection = sevProtection + } + logger := hvLogger.WithFields(logrus.Fields{ "subsystem": "qemuAmd64", "machine": q.qemuMachine,