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 +}