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 defaultRxRateLimiterMaxRate = uint64(0)
const defaultTxRateLimiterMaxRate = uint64(0)
const defaultConfidentialGuest = false
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.
//
// 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,
}
}

View File

@ -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

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"),
}
qemuConfig.Devices, qemuConfig.Bios, err = q.arch.appendProtectionDevice(qemuConfig.Devices, firmwarePath)
if err != nil {
return err
}
if ioThread != nil {
qemuConfig.IOThreads = []govmmQemu.IOThread{*ioThread}
}

View File

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

View File

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