diff --git a/src/runtime/go.mod b/src/runtime/go.mod index 272cd837b7..1f3acc11fa 100644 --- a/src/runtime/go.mod +++ b/src/runtime/go.mod @@ -31,7 +31,7 @@ require ( github.com/gogo/googleapis v1.4.0 // indirect github.com/gogo/protobuf v1.3.1 github.com/hashicorp/go-multierror v1.0.0 - github.com/kata-containers/govmm v0.0.0-20210428163604-f0e9a35308ee + github.com/kata-containers/govmm v0.0.0-20210520142420-eb57f004d89f github.com/mdlayher/vsock v0.0.0-20191108225356-d9c65923cb8f github.com/opencontainers/image-spec v1.0.1 // indirect github.com/opencontainers/runc v1.0.0-rc9.0.20200102164712-2b52db75279c diff --git a/src/runtime/go.sum b/src/runtime/go.sum index 9d495d5314..3d63149e25 100644 --- a/src/runtime/go.sum +++ b/src/runtime/go.sum @@ -274,12 +274,10 @@ github.com/juju/errors v0.0.0-20180806074554-22422dad46e1/go.mod h1:W54LbzXuIE0b github.com/juju/loggo v0.0.0-20190526231331-6e530bcce5d8/go.mod h1:vgyd7OREkbtVEN/8IXZe5Ooef3LQePvuBm9UWj6ZL8U= github.com/juju/testing v0.0.0-20190613124551-e81189438503/go.mod h1:63prj8cnj0tU0S9OHjGJn+b1h0ZghCndfnbQolrYTwA= github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= -github.com/kata-containers/govmm v0.0.0-20210112013750-7d320e8f5dca h1:UdXFthwasAPnmv37gLJUEFsW9FaabYA+mM6FoSi8kzU= -github.com/kata-containers/govmm v0.0.0-20210112013750-7d320e8f5dca/go.mod h1:VmAHbsL5lLfzHW/MNL96NVLF840DNEV5i683kISgFKk= -github.com/kata-containers/govmm v0.0.0-20210329205824-7fbc685865d2 h1:oDJsQ5avmW8PFUkSJdsuaGL3SR4/YQRno51GNGl+IDU= -github.com/kata-containers/govmm v0.0.0-20210329205824-7fbc685865d2/go.mod h1:VmAHbsL5lLfzHW/MNL96NVLF840DNEV5i683kISgFKk= github.com/kata-containers/govmm v0.0.0-20210428163604-f0e9a35308ee h1:M4N7AdSHgWz/ubV5AZQdeqmK+9Ztpea6oqeXgk8GCHk= github.com/kata-containers/govmm v0.0.0-20210428163604-f0e9a35308ee/go.mod h1:VmAHbsL5lLfzHW/MNL96NVLF840DNEV5i683kISgFKk= +github.com/kata-containers/govmm v0.0.0-20210520142420-eb57f004d89f h1:jXMZY7GIz5kSv3/Rdiesg1WMvgXJKNOk3KxwxgNWAVk= +github.com/kata-containers/govmm v0.0.0-20210520142420-eb57f004d89f/go.mod h1:VmAHbsL5lLfzHW/MNL96NVLF840DNEV5i683kISgFKk= github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/konsorten/go-windows-terminal-sequences v1.0.1 h1:mweAR1A6xJ3oS2pRaGiHgQ4OO8tzTaLawm8vnODuwDk= diff --git a/src/runtime/vendor/github.com/kata-containers/govmm/qemu/qemu.go b/src/runtime/vendor/github.com/kata-containers/govmm/qemu/qemu.go index 61ab2cc20b..1eddc79e2a 100644 --- a/src/runtime/vendor/github.com/kata-containers/govmm/qemu/qemu.go +++ b/src/runtime/vendor/github.com/kata-containers/govmm/qemu/qemu.go @@ -134,6 +134,9 @@ const ( // Loader is the Loader device driver. Loader DeviceDriver = "loader" + + // SpaprTPMProxy is used for enabling guest to run in secure mode on ppc64le. + SpaprTPMProxy DeviceDriver = "spapr-tpm-proxy" ) func isDimmSupported(config *Config) bool { @@ -230,6 +233,14 @@ const ( // TDXGuest represents a TDX object TDXGuest ObjectType = "tdx-guest" + + // SEVGuest represents an SEV guest object + SEVGuest ObjectType = "sev-guest" + + // SecExecGuest represents an s390x Secure Execution (Protected Virtualization in QEMU) object + SecExecGuest ObjectType = "s390-pv-guest" + // PEFGuest represent ppc64le PEF(Protected Execution Facility) object. + PEFGuest ObjectType = "pef-guest" ) // Object is a qemu object representation. @@ -258,37 +269,42 @@ type Object struct { // File is the device file File string + + // CBitPos is the location of the C-bit in a guest page table entry + // This is only relevant for sev-guest objects + CBitPos uint32 + + // ReducedPhysBits is the reduction in the guest physical address space + // This is only relevant for sev-guest objects + ReducedPhysBits uint32 } // Valid returns true if the Object structure is valid and complete. func (object Object) Valid() bool { switch object.Type { case MemoryBackendFile: - if object.ID == "" || object.MemPath == "" || object.Size == 0 { - return false - } - + return object.ID != "" && object.MemPath != "" && object.Size != 0 case TDXGuest: - if object.ID == "" || object.File == "" || object.DeviceID == "" { - return false - } + return object.ID != "" && object.File != "" && object.DeviceID != "" + case SEVGuest: + return object.ID != "" && object.File != "" && object.CBitPos != 0 && object.ReducedPhysBits != 0 + case SecExecGuest: + return object.ID != "" + case PEFGuest: + return object.ID != "" && object.File != "" default: return false } - - return true } // QemuParams returns the qemu parameters built out of this Object device. func (object Object) QemuParams(config *Config) []string { var objectParams []string var deviceParams []string + var driveParams []string var qemuParams []string - deviceParams = append(deviceParams, string(object.Driver)) - deviceParams = append(deviceParams, fmt.Sprintf(",id=%s", object.DeviceID)) - switch object.Type { case MemoryBackendFile: objectParams = append(objectParams, string(object.Type)) @@ -296,6 +312,8 @@ func (object Object) QemuParams(config *Config) []string { objectParams = append(objectParams, fmt.Sprintf(",mem-path=%s", object.MemPath)) objectParams = append(objectParams, fmt.Sprintf(",size=%d", object.Size)) + deviceParams = append(deviceParams, string(object.Driver)) + deviceParams = append(deviceParams, fmt.Sprintf(",id=%s", object.DeviceID)) deviceParams = append(deviceParams, fmt.Sprintf(",memdev=%s", object.ID)) case TDXGuest: objectParams = append(objectParams, string(object.Type)) @@ -303,14 +321,44 @@ func (object Object) QemuParams(config *Config) []string { if object.Debug { objectParams = append(objectParams, ",debug=on") } + deviceParams = append(deviceParams, string(object.Driver)) + deviceParams = append(deviceParams, fmt.Sprintf(",id=%s", object.DeviceID)) deviceParams = append(deviceParams, fmt.Sprintf(",file=%s", object.File)) + case SEVGuest: + objectParams = append(objectParams, string(object.Type)) + objectParams = append(objectParams, fmt.Sprintf(",id=%s", object.ID)) + objectParams = append(objectParams, fmt.Sprintf(",cbitpos=%d", object.CBitPos)) + objectParams = append(objectParams, fmt.Sprintf(",reduced-phys-bits=%d", object.ReducedPhysBits)) + + driveParams = append(driveParams, "if=pflash,format=raw,readonly=on") + driveParams = append(driveParams, fmt.Sprintf(",file=%s", object.File)) + case SecExecGuest: + objectParams = append(objectParams, string(object.Type)) + objectParams = append(objectParams, fmt.Sprintf(",id=%s", object.ID)) + case PEFGuest: + objectParams = append(objectParams, string(object.Type)) + objectParams = append(objectParams, fmt.Sprintf(",id=%s", object.ID)) + + deviceParams = append(deviceParams, string(object.Driver)) + deviceParams = append(deviceParams, fmt.Sprintf(",id=%s", object.DeviceID)) + deviceParams = append(deviceParams, fmt.Sprintf(",host-path=%s", object.File)) + } - qemuParams = append(qemuParams, "-device") - qemuParams = append(qemuParams, strings.Join(deviceParams, "")) + if len(deviceParams) > 0 { + qemuParams = append(qemuParams, "-device") + qemuParams = append(qemuParams, strings.Join(deviceParams, "")) + } - qemuParams = append(qemuParams, "-object") - qemuParams = append(qemuParams, strings.Join(objectParams, "")) + if len(objectParams) > 0 { + qemuParams = append(qemuParams, "-object") + qemuParams = append(qemuParams, strings.Join(objectParams, "")) + } + + if len(driveParams) > 0 { + qemuParams = append(qemuParams, "-drive") + qemuParams = append(qemuParams, strings.Join(driveParams, "")) + } return qemuParams } diff --git a/src/runtime/vendor/modules.txt b/src/runtime/vendor/modules.txt index fb825ff845..fc1113b0df 100644 --- a/src/runtime/vendor/modules.txt +++ b/src/runtime/vendor/modules.txt @@ -222,7 +222,7 @@ github.com/hashicorp/errwrap # github.com/hashicorp/go-multierror v1.0.0 ## explicit github.com/hashicorp/go-multierror -# github.com/kata-containers/govmm v0.0.0-20210428163604-f0e9a35308ee +# github.com/kata-containers/govmm v0.0.0-20210520142420-eb57f004d89f ## explicit github.com/kata-containers/govmm/qemu # github.com/konsorten/go-windows-terminal-sequences v1.0.1 diff --git a/src/runtime/virtcontainers/hypervisor_ppc64le.go b/src/runtime/virtcontainers/hypervisor_ppc64le.go new file mode 100644 index 0000000000..60a8a168bb --- /dev/null +++ b/src/runtime/virtcontainers/hypervisor_ppc64le.go @@ -0,0 +1,17 @@ +// Copyright (c) 2021 IBM +// +// SPDX-License-Identifier: Apache-2.0 + +package virtcontainers + +import "os" + +//Returns pefProtection if the firmware directory exists +func availableGuestProtection() (guestProtection, error) { + + if d, err := os.Stat(pefSysFirmwareDir); err == nil && d.IsDir() { + return pefProtection, err + } + + return noneProtection, nil +} diff --git a/src/runtime/virtcontainers/qemu_ppc64le.go b/src/runtime/virtcontainers/qemu_ppc64le.go index 0a8bbeb6b2..bff6feff16 100644 --- a/src/runtime/virtcontainers/qemu_ppc64le.go +++ b/src/runtime/virtcontainers/qemu_ppc64le.go @@ -27,6 +27,14 @@ const defaultQemuMachineOptions = "accel=kvm,usb=off" const qmpMigrationWaitTimeout = 5 * time.Second +const pefSysFirmwareDir = "/sys/firmware/ultravisor/" + +const pefID = "pef0" + +const tpmID = "tpm0" + +const tpmHostPath = "/dev/tpmrm0" + var kernelParams = []Param{ {"rcupdate.rcu_expedited", "1"}, {"reboot", "k"}, @@ -43,7 +51,7 @@ var supportedQemuMachine = govmmQemu.Machine{ // Logger returns a logrus logger appropriate for logging qemu messages func (q *qemuPPC64le) Logger() *logrus.Entry { - return virtLog.WithField("subsystem", "qemu") + return virtLog.WithField("subsystem", "qemuPPC64le") } // MaxQemuVCPUs returns the maximum number of vCPUs supported @@ -69,9 +77,16 @@ func newQemuArch(config HypervisorConfig) (qemuArch, error) { kernelParamsNonDebug: kernelParamsNonDebug, kernelParamsDebug: kernelParamsDebug, kernelParams: kernelParams, + protection: noneProtection, }, } + if config.ConfidentialGuest { + if err := q.enableProtection(); err != nil { + return nil, err + } + } + q.handleImagePath(config) q.memoryOffset = config.MemOffset @@ -116,3 +131,49 @@ func (q *qemuPPC64le) appendBridges(devices []govmmQemu.Device) []govmmQemu.Devi func (q *qemuPPC64le) appendIOMMU(devices []govmmQemu.Device) ([]govmmQemu.Device, error) { return devices, fmt.Errorf("PPC64le does not support appending a vIOMMU") } + +// Enables guest protection +func (q *qemuPPC64le) enableProtection() error { + var err error + q.protection, err = availableGuestProtection() + if err != nil { + return err + } + + switch q.protection { + case pefProtection: + if q.qemuMachine.Options != "" { + q.qemuMachine.Options += "," + } + q.qemuMachine.Options += fmt.Sprintf("confidential-guest-support=%s", pefID) + virtLog.WithFields(logrus.Fields{ + "subsystem": "qemuPPC64le", + "machine": q.qemuMachine, + "kernel-params": q.kernelParams, + }).Info("Enabling PEF protection") + return nil + + default: + return fmt.Errorf("This system doesn't support Confidential Computing (Guest Protection)") + } +} + +// append protection device +func (q *qemuPPC64le) appendProtectionDevice(devices []govmmQemu.Device, firmware string) ([]govmmQemu.Device, string, error) { + switch q.protection { + case pefProtection: + return append(devices, + govmmQemu.Object{ + Driver: govmmQemu.SpaprTPMProxy, + Type: govmmQemu.PEFGuest, + ID: pefID, + DeviceID: tpmID, + File: tpmHostPath, + }), firmware, nil + case noneProtection: + return devices, firmware, nil + + default: + return devices, "", fmt.Errorf("Unsupported guest protection technology: %v", q.protection) + } +}