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 <julio.montes@intel.com>
This commit is contained in:
Julio Montes 2021-05-05 09:12:36 -05:00
parent 539afba03d
commit 0affe8860d
6 changed files with 77 additions and 7 deletions

View File

@ -54,6 +54,7 @@ const defaultDisableImageNvdimm = false
const defaultVhostUserStorePath string = "/var/run/kata-containers/vhost-user/" const defaultVhostUserStorePath string = "/var/run/kata-containers/vhost-user/"
const defaultRxRateLimiterMaxRate = uint64(0) const defaultRxRateLimiterMaxRate = uint64(0)
const defaultTxRateLimiterMaxRate = uint64(0) const defaultTxRateLimiterMaxRate = uint64(0)
const defaultConfidentialGuest = false
var defaultSGXEPCSize = int64(0) var defaultSGXEPCSize = int64(0)

View File

@ -1,4 +1,4 @@
// Copyright (c) 2018 Intel Corporation // Copyright (c) 2018-2021 Intel Corporation
// Copyright (c) 2018 HyperHQ Inc. // Copyright (c) 2018 HyperHQ Inc.
// //
// SPDX-License-Identifier: Apache-2.0 // SPDX-License-Identifier: Apache-2.0
@ -61,6 +61,12 @@ type tomlConfig struct {
Runtime runtime Runtime runtime
Factory factory Factory factory
Netmon netmon Netmon netmon
Image image
}
type image struct {
ServiceOffload bool `toml:"service_offload"`
Provision string `toml:"provision"`
} }
type factory struct { type factory struct {
@ -130,6 +136,7 @@ type hypervisor struct {
HotplugVFIOOnRootBus bool `toml:"hotplug_vfio_on_root_bus"` HotplugVFIOOnRootBus bool `toml:"hotplug_vfio_on_root_bus"`
DisableVhostNet bool `toml:"disable_vhost_net"` DisableVhostNet bool `toml:"disable_vhost_net"`
GuestMemoryDumpPaging bool `toml:"guest_memory_dump_paging"` GuestMemoryDumpPaging bool `toml:"guest_memory_dump_paging"`
ConfidentialGuest bool `toml:"confidential_guest"`
} }
type runtime struct { type runtime struct {
@ -702,6 +709,7 @@ func newQemuHypervisorConfig(h hypervisor) (vc.HypervisorConfig, error) {
EnableAnnotations: h.EnableAnnotations, EnableAnnotations: h.EnableAnnotations,
GuestMemoryDumpPath: h.GuestMemoryDumpPath, GuestMemoryDumpPath: h.GuestMemoryDumpPath,
GuestMemoryDumpPaging: h.GuestMemoryDumpPaging, GuestMemoryDumpPaging: h.GuestMemoryDumpPaging,
ConfidentialGuest: h.ConfidentialGuest,
}, nil }, nil
} }
@ -1055,6 +1063,7 @@ func GetDefaultHypervisorConfig() vc.HypervisorConfig {
RxRateLimiterMaxRate: defaultRxRateLimiterMaxRate, RxRateLimiterMaxRate: defaultRxRateLimiterMaxRate,
TxRateLimiterMaxRate: defaultTxRateLimiterMaxRate, TxRateLimiterMaxRate: defaultTxRateLimiterMaxRate,
SGXEPCSize: defaultSGXEPCSize, SGXEPCSize: defaultSGXEPCSize,
ConfidentialGuest: defaultConfidentialGuest,
} }
} }

View File

@ -453,6 +453,11 @@ type HypervisorConfig struct {
// GuestMemoryDumpPaging is used to indicate if enable paging // GuestMemoryDumpPaging is used to indicate if enable paging
// for QEMU dump-guest-memory command // for QEMU dump-guest-memory command
GuestMemoryDumpPaging bool 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 // vcpu mapping from vcpu number to thread number

View File

@ -605,6 +605,11 @@ func (q *qemu) createSandbox(ctx context.Context, id string, networkNS NetworkNa
PidFile: filepath.Join(q.store.RunVMStoragePath(), q.id, "pid"), 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 { if ioThread != nil {
qemuConfig.IOThreads = []govmmQemu.IOThread{*ioThread} qemuConfig.IOThreads = []govmmQemu.IOThread{*ioThread}
} }

View File

@ -106,17 +106,17 @@ func newQemuArch(config HypervisorConfig) (qemuArch, error) {
factory = true factory = true
} }
if config.IOMMU { // IOMMU and Guest Protection require a split IRQ controller for handling interrupts
var q35QemuIOMMUOptions = "accel=kvm,kernel_irqchip=split" // 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, kernelParams = append(kernelParams,
Param{"intel_iommu", "on"}) Param{"intel_iommu", "on"})
kernelParams = append(kernelParams, kernelParams = append(kernelParams,
Param{"iommu", "pt"}) Param{"iommu", "pt"})
if mp.Type == QemuQ35 {
mp.Options = q35QemuIOMMUOptions
}
} }
q := &qemuAmd64{ q := &qemuAmd64{
@ -129,10 +129,17 @@ func newQemuArch(config HypervisorConfig) (qemuArch, error) {
kernelParams: kernelParams, kernelParams: kernelParams,
disableNvdimm: config.DisableImageNvdimm, disableNvdimm: config.DisableImageNvdimm,
dax: true, dax: true,
protection: noneProtection,
}, },
vmFactory: factory, vmFactory: factory,
} }
if config.ConfidentialGuest {
if err := q.enableProtection(); err != nil {
return nil, err
}
}
q.handleImagePath(config) q.handleImagePath(config)
return q, nil 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 { func (q *qemuAmd64) appendBridges(devices []govmmQemu.Device) []govmmQemu.Device {
return genericAppendBridges(devices, q.Bridges, q.qemuMachine.Type) 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
}

View File

@ -11,6 +11,7 @@ import (
"errors" "errors"
"fmt" "fmt"
"os" "os"
"runtime"
"strconv" "strconv"
"strings" "strings"
@ -142,8 +143,33 @@ type qemuArch interface {
// append pvpanic device // append pvpanic device
appendPVPanicDevice(devices []govmmQemu.Device) ([]govmmQemu.Device, error) 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 { type qemuArchBase struct {
qemuMachine govmmQemu.Machine qemuMachine govmmQemu.Machine
qemuExePath string qemuExePath string
@ -158,6 +184,7 @@ type qemuArchBase struct {
kernelParams []Param kernelParams []Param
Bridges []types.Bridge Bridges []types.Bridge
PFlash []string PFlash []string
protection guestProtection
} }
const ( const (
@ -813,3 +840,9 @@ func (q *qemuArchBase) getPFlash() ([]string, error) {
func (q *qemuArchBase) setPFlash(p []string) { func (q *qemuArchBase) setPFlash(p []string) {
q.PFlash = p 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
}