From 0affe8860dd93fd5404f7d80c1f6cbe73ec2a199 Mon Sep 17 00:00:00 2001 From: Julio Montes Date: Wed, 5 May 2021 09:12:36 -0500 Subject: [PATCH] virtcontainers: define confidential guest framework Define the structure and functions needed to support confidential guests, this commit doesn't add support for any specific technology, support for TDX, SEV, PEF and others will be added in following commits. Signed-off-by: Julio Montes --- .../pkg/katautils/config-settings.go.in | 1 + src/runtime/pkg/katautils/config.go | 11 ++++++- src/runtime/virtcontainers/hypervisor.go | 5 +++ src/runtime/virtcontainers/qemu.go | 5 +++ src/runtime/virtcontainers/qemu_amd64.go | 29 ++++++++++++---- src/runtime/virtcontainers/qemu_arch_base.go | 33 +++++++++++++++++++ 6 files changed, 77 insertions(+), 7 deletions(-) diff --git a/src/runtime/pkg/katautils/config-settings.go.in b/src/runtime/pkg/katautils/config-settings.go.in index 7cd9138baa..470527998f 100644 --- a/src/runtime/pkg/katautils/config-settings.go.in +++ b/src/runtime/pkg/katautils/config-settings.go.in @@ -54,6 +54,7 @@ const defaultDisableImageNvdimm = false const defaultVhostUserStorePath string = "/var/run/kata-containers/vhost-user/" const defaultRxRateLimiterMaxRate = uint64(0) const defaultTxRateLimiterMaxRate = uint64(0) +const defaultConfidentialGuest = false var defaultSGXEPCSize = int64(0) diff --git a/src/runtime/pkg/katautils/config.go b/src/runtime/pkg/katautils/config.go index e3f3b3bc9c..e1db0da8c0 100644 --- a/src/runtime/pkg/katautils/config.go +++ b/src/runtime/pkg/katautils/config.go @@ -1,4 +1,4 @@ -// Copyright (c) 2018 Intel Corporation +// Copyright (c) 2018-2021 Intel Corporation // Copyright (c) 2018 HyperHQ Inc. // // SPDX-License-Identifier: Apache-2.0 @@ -61,6 +61,12 @@ type tomlConfig struct { Runtime runtime Factory factory Netmon netmon + Image image +} + +type image struct { + ServiceOffload bool `toml:"service_offload"` + Provision string `toml:"provision"` } type factory struct { @@ -130,6 +136,7 @@ type hypervisor struct { HotplugVFIOOnRootBus bool `toml:"hotplug_vfio_on_root_bus"` DisableVhostNet bool `toml:"disable_vhost_net"` GuestMemoryDumpPaging bool `toml:"guest_memory_dump_paging"` + ConfidentialGuest bool `toml:"confidential_guest"` } type runtime struct { @@ -702,6 +709,7 @@ func newQemuHypervisorConfig(h hypervisor) (vc.HypervisorConfig, error) { EnableAnnotations: h.EnableAnnotations, GuestMemoryDumpPath: h.GuestMemoryDumpPath, GuestMemoryDumpPaging: h.GuestMemoryDumpPaging, + ConfidentialGuest: h.ConfidentialGuest, }, nil } @@ -1055,6 +1063,7 @@ func GetDefaultHypervisorConfig() vc.HypervisorConfig { RxRateLimiterMaxRate: defaultRxRateLimiterMaxRate, TxRateLimiterMaxRate: defaultTxRateLimiterMaxRate, SGXEPCSize: defaultSGXEPCSize, + ConfidentialGuest: defaultConfidentialGuest, } } diff --git a/src/runtime/virtcontainers/hypervisor.go b/src/runtime/virtcontainers/hypervisor.go index 05d1117bac..0b8cac7761 100644 --- a/src/runtime/virtcontainers/hypervisor.go +++ b/src/runtime/virtcontainers/hypervisor.go @@ -453,6 +453,11 @@ type HypervisorConfig struct { // GuestMemoryDumpPaging is used to indicate if enable paging // for QEMU dump-guest-memory command GuestMemoryDumpPaging bool + + // Enable confidential guest support. + // Enable or disable different hardware features, ranging + // from memory encryption to both memory and CPU-state encryption and integrity. + ConfidentialGuest bool } // vcpu mapping from vcpu number to thread number diff --git a/src/runtime/virtcontainers/qemu.go b/src/runtime/virtcontainers/qemu.go index 9f00a12a44..126fb0d36f 100644 --- a/src/runtime/virtcontainers/qemu.go +++ b/src/runtime/virtcontainers/qemu.go @@ -605,6 +605,11 @@ func (q *qemu) createSandbox(ctx context.Context, id string, networkNS NetworkNa PidFile: filepath.Join(q.store.RunVMStoragePath(), q.id, "pid"), } + qemuConfig.Devices, qemuConfig.Bios, err = q.arch.appendProtectionDevice(qemuConfig.Devices, firmwarePath) + if err != nil { + return err + } + if ioThread != nil { qemuConfig.IOThreads = []govmmQemu.IOThread{*ioThread} } diff --git a/src/runtime/virtcontainers/qemu_amd64.go b/src/runtime/virtcontainers/qemu_amd64.go index 1a045fae08..ec2e764083 100644 --- a/src/runtime/virtcontainers/qemu_amd64.go +++ b/src/runtime/virtcontainers/qemu_amd64.go @@ -106,17 +106,17 @@ func newQemuArch(config HypervisorConfig) (qemuArch, error) { factory = true } - if config.IOMMU { - var q35QemuIOMMUOptions = "accel=kvm,kernel_irqchip=split" + // IOMMU and Guest Protection require a split IRQ controller for handling interrupts + // otherwise QEMU won't be able to create the kernel irqchip + if config.IOMMU || config.ConfidentialGuest { + mp.Options = "accel=kvm,kernel_irqchip=split" + } + if config.IOMMU { kernelParams = append(kernelParams, Param{"intel_iommu", "on"}) kernelParams = append(kernelParams, Param{"iommu", "pt"}) - - if mp.Type == QemuQ35 { - mp.Options = q35QemuIOMMUOptions - } } q := &qemuAmd64{ @@ -129,10 +129,17 @@ func newQemuArch(config HypervisorConfig) (qemuArch, error) { kernelParams: kernelParams, disableNvdimm: config.DisableImageNvdimm, dax: true, + protection: noneProtection, }, vmFactory: factory, } + if config.ConfidentialGuest { + if err := q.enableProtection(); err != nil { + return nil, err + } + } + q.handleImagePath(config) return q, nil @@ -191,3 +198,13 @@ func (q *qemuAmd64) appendImage(ctx context.Context, devices []govmmQemu.Device, func (q *qemuAmd64) appendBridges(devices []govmmQemu.Device) []govmmQemu.Device { return genericAppendBridges(devices, q.Bridges, q.qemuMachine.Type) } + +// enable protection +func (q *qemuAmd64) enableProtection() error { + return nil +} + +// append protection device +func (q *qemuAmd64) appendProtectionDevice(devices []govmmQemu.Device, firmware string) ([]govmmQemu.Device, string, error) { + return devices, firmware, nil +} diff --git a/src/runtime/virtcontainers/qemu_arch_base.go b/src/runtime/virtcontainers/qemu_arch_base.go index d2ffac4a1d..5c7b1218c4 100644 --- a/src/runtime/virtcontainers/qemu_arch_base.go +++ b/src/runtime/virtcontainers/qemu_arch_base.go @@ -11,6 +11,7 @@ import ( "errors" "fmt" "os" + "runtime" "strconv" "strings" @@ -142,8 +143,33 @@ type qemuArch interface { // append pvpanic device appendPVPanicDevice(devices []govmmQemu.Device) ([]govmmQemu.Device, error) + + // append protection device. + // This implementation is architecture specific, some archs may need + // a firmware, returns a string containing the path to the firmware that should + // be used with the -bios option, ommit -bios option if the path is empty. + appendProtectionDevice(devices []govmmQemu.Device, firmware string) ([]govmmQemu.Device, string, error) } +// Kind of guest protection +type guestProtection uint8 + +const ( + noneProtection guestProtection = iota + + //Intel Trust Domain Extensions + //https://software.intel.com/content/www/us/en/develop/articles/intel-trust-domain-extensions.html + tdxProtection + + // AMD Secure Encrypted Virtualization + // https://developer.amd.com/sev/ + sevProtection + + // IBM POWER 9 Protected Execution Facility + // https://www.kernel.org/doc/html/latest/powerpc/ultravisor.html + pefProtection +) + type qemuArchBase struct { qemuMachine govmmQemu.Machine qemuExePath string @@ -158,6 +184,7 @@ type qemuArchBase struct { kernelParams []Param Bridges []types.Bridge PFlash []string + protection guestProtection } const ( @@ -813,3 +840,9 @@ func (q *qemuArchBase) getPFlash() ([]string, error) { func (q *qemuArchBase) setPFlash(p []string) { q.PFlash = p } + +// append protection device +func (q *qemuArchBase) appendProtectionDevice(devices []govmmQemu.Device, firmware string) ([]govmmQemu.Device, string, error) { + virtLog.WithField("arch", runtime.GOARCH).Warnf("Confidential Computing has not been implemented for this architecture") + return devices, firmware, nil +}