mirror of
https://github.com/kata-containers/kata-containers.git
synced 2025-08-02 00:02:01 +00:00
runtime: Enable connection to Quote Generation Service (QGS)
For the TD attestation to work the connection to QGS on the host is needed. By default QGS runs on vsock port 4050, but can be modified by the host owner. Format of the qemu object follows the SocketAddress structure, so it needs to be provided in the JSON format, as in the example below: -object '{"qom-type":"tdx-guest","id":"tdx","quote-generation-socket":{"type":"vsock","cid":"2","port":"4050"}}' Fixes: #9497 Signed-off-by: Jakub Ledworowski <jakub.ledworowski@intel.com>
This commit is contained in:
parent
0331859740
commit
fc680139e5
@ -179,6 +179,7 @@ QEMUVALIDHYPERVISORPATHS := [\"$(QEMUPATH)\"]
|
||||
#QEMUTDXPATH := $(QEMUBINDIR)/$(QEMUTDXCMD)
|
||||
QEMUTDXPATH := PLACEHOLDER_FOR_DISTRO_QEMU_WITH_TDX_SUPPORT
|
||||
QEMUTDXVALIDHYPERVISORPATHS := [\"$(QEMUTDXPATH)\"]
|
||||
QEMUTDXQUOTEGENERATIONSERVICESOCKETPORT := 4050
|
||||
|
||||
QEMUSNPPATH := $(QEMUBINDIR)/$(QEMUSNPCMD)
|
||||
QEMUSNPVALIDHYPERVISORPATHS := [\"$(QEMUSNPPATH)\"]
|
||||
@ -705,6 +706,7 @@ USER_VARS += QEMUTDXCMD
|
||||
USER_VARS += QEMUSNPCMD
|
||||
USER_VARS += QEMUPATH
|
||||
USER_VARS += QEMUTDXPATH
|
||||
USER_VARS += QEMUTDXQUOTEGENERATIONSERVICESOCKETPORT
|
||||
USER_VARS += QEMUSNPPATH
|
||||
USER_VARS += QEMUVALIDHYPERVISORPATHS
|
||||
USER_VARS += QEMUTDXVALIDHYPERVISORPATHS
|
||||
|
@ -17,6 +17,7 @@ kernel = "@KERNELCONFIDENTIALPATH@"
|
||||
image = "@IMAGECONFIDENTIALPATH@"
|
||||
# initrd = "@INITRDPATH@"
|
||||
machine_type = "@MACHINETYPE@"
|
||||
tdx_quote_generation_service_socket_port = @QEMUTDXQUOTEGENERATIONSERVICESOCKETPORT@
|
||||
|
||||
# rootfs filesystem type:
|
||||
# - ext4 (default)
|
||||
|
@ -15,6 +15,7 @@ package qemu
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"log"
|
||||
@ -44,6 +45,12 @@ const (
|
||||
MachineTypeMicrovm string = "microvm"
|
||||
)
|
||||
|
||||
const (
|
||||
// Well known vsock CID for host system.
|
||||
// https://man7.org/linux/man-pages/man7/vsock.7.html
|
||||
VsockHostCid uint64 = 2
|
||||
)
|
||||
|
||||
// Device is the qemu device interface.
|
||||
type Device interface {
|
||||
Valid() bool
|
||||
@ -306,6 +313,9 @@ type Object struct {
|
||||
|
||||
// Prealloc enables memory preallocation
|
||||
Prealloc bool
|
||||
|
||||
// QgsPort defines Intel Quote Generation Service port exposed from the host
|
||||
QgsPort uint32
|
||||
}
|
||||
|
||||
// Valid returns true if the Object structure is valid and complete.
|
||||
@ -316,7 +326,7 @@ func (object Object) Valid() bool {
|
||||
case MemoryBackendEPC:
|
||||
return object.ID != "" && object.Size != 0
|
||||
case TDXGuest:
|
||||
return object.ID != "" && object.File != "" && object.DeviceID != ""
|
||||
return object.ID != "" && object.File != "" && object.DeviceID != "" && object.QgsPort != 0
|
||||
case SEVGuest:
|
||||
fallthrough
|
||||
case SNPGuest:
|
||||
@ -362,11 +372,7 @@ func (object Object) QemuParams(config *Config) []string {
|
||||
}
|
||||
|
||||
case TDXGuest:
|
||||
objectParams = append(objectParams, string(object.Type))
|
||||
objectParams = append(objectParams, fmt.Sprintf("id=%s", object.ID))
|
||||
if object.Debug {
|
||||
objectParams = append(objectParams, "debug=on")
|
||||
}
|
||||
objectParams = append(objectParams, prepareObjectWithTdxQgs(object))
|
||||
config.Bios = object.File
|
||||
case SEVGuest:
|
||||
fallthrough
|
||||
@ -408,6 +414,52 @@ func (object Object) QemuParams(config *Config) []string {
|
||||
return qemuParams
|
||||
}
|
||||
|
||||
type SocketAddress struct {
|
||||
Type string `json:"type"`
|
||||
Cid string `json:"cid"`
|
||||
Port string `json:"port"`
|
||||
}
|
||||
|
||||
type TdxQomObject struct {
|
||||
QomType string `json:"qom-type"`
|
||||
Id string `json:"id"`
|
||||
QuoteGenerationSocket SocketAddress `json:"quote-generation-socket"`
|
||||
Debug *bool `json:"debug,omitempty"`
|
||||
}
|
||||
|
||||
func (this *SocketAddress) String() string {
|
||||
b, err := json.Marshal(*this)
|
||||
|
||||
if err != nil {
|
||||
log.Fatalf("Unable to marshal SocketAddress object: %s", err.Error())
|
||||
return ""
|
||||
}
|
||||
|
||||
return string(b)
|
||||
}
|
||||
|
||||
func (this *TdxQomObject) String() string {
|
||||
b, err := json.Marshal(*this)
|
||||
|
||||
if err != nil {
|
||||
log.Fatalf("Unable to marshal TDX QOM object: %s", err.Error())
|
||||
return ""
|
||||
}
|
||||
|
||||
return string(b)
|
||||
}
|
||||
|
||||
func prepareObjectWithTdxQgs(object Object) string {
|
||||
qgsSocket := SocketAddress{"vsock", fmt.Sprint(VsockHostCid), fmt.Sprint(object.QgsPort)}
|
||||
tdxObject := TdxQomObject{string(object.Type), object.ID, qgsSocket, nil}
|
||||
|
||||
if object.Debug {
|
||||
*tdxObject.Debug = true
|
||||
}
|
||||
|
||||
return tdxObject.String()
|
||||
}
|
||||
|
||||
// Virtio9PMultidev filesystem behaviour to deal
|
||||
// with multiple devices being shared with a 9p export.
|
||||
type Virtio9PMultidev string
|
||||
|
@ -58,6 +58,7 @@ var systemdUnitName = "kata-containers.target"
|
||||
|
||||
const defaultKernelParams = ""
|
||||
const defaultMachineType = "q35"
|
||||
const defaultQgsPort = 4050
|
||||
|
||||
const defaultVCPUCount uint32 = 1
|
||||
const defaultMaxVCPUCount uint32 = 0
|
||||
|
@ -89,6 +89,7 @@ type hypervisor struct {
|
||||
CPUFeatures string `toml:"cpu_features"`
|
||||
KernelParams string `toml:"kernel_params"`
|
||||
MachineType string `toml:"machine_type"`
|
||||
QgsPort uint32 `toml:"tdx_quote_generation_service_socket_port"`
|
||||
BlockDeviceDriver string `toml:"block_device_driver"`
|
||||
EntropySource string `toml:"entropy_source"`
|
||||
SharedFS string `toml:"shared_fs"`
|
||||
@ -373,6 +374,14 @@ func (h hypervisor) machineType() string {
|
||||
return h.MachineType
|
||||
}
|
||||
|
||||
func (h hypervisor) qgsPort() uint32 {
|
||||
if h.QgsPort == 0 {
|
||||
return defaultQgsPort
|
||||
}
|
||||
|
||||
return h.QgsPort
|
||||
}
|
||||
|
||||
func (h hypervisor) GetEntropySource() string {
|
||||
if h.EntropySource == "" {
|
||||
return defaultEntropySource
|
||||
@ -890,6 +899,7 @@ func newQemuHypervisorConfig(h hypervisor) (vc.HypervisorConfig, error) {
|
||||
CPUFeatures: cpuFeatures,
|
||||
KernelParams: vc.DeserializeParams(vc.KernelParamFields(kernelParams)),
|
||||
HypervisorMachineType: machineType,
|
||||
QgsPort: h.qgsPort(),
|
||||
NumVCPUsF: h.defaultVCPUs(),
|
||||
DefaultMaxVCPUs: h.defaultMaxVCPUs(),
|
||||
MemorySize: h.defaultMemSz(),
|
||||
|
@ -182,6 +182,7 @@ func createAllRuntimeConfigFiles(dir, hypervisor string) (testConfig testRuntime
|
||||
VirtioFSCache: defaultVirtioFSCacheMode,
|
||||
PFlash: []string{},
|
||||
SGXEPCSize: epcSize,
|
||||
QgsPort: defaultQgsPort,
|
||||
}
|
||||
|
||||
if goruntime.GOARCH == "arm64" && len(hypervisorConfig.PFlash) == 0 && hypervisorConfig.FirmwarePath == "" {
|
||||
|
@ -671,6 +671,9 @@ type HypervisorConfig struct {
|
||||
|
||||
// ExtraMonitorSocket allows to add an extra HMP or QMP socket when the VMM is Qemu
|
||||
ExtraMonitorSocket govmmQemu.MonitorProtocol
|
||||
|
||||
// QgsPort defines Intel Quote Generation Service port exposed from the host
|
||||
QgsPort uint32
|
||||
}
|
||||
|
||||
// vcpu mapping from vcpu number to thread number
|
||||
|
@ -31,6 +31,8 @@ type qemuAmd64 struct {
|
||||
devLoadersCount uint32
|
||||
|
||||
sgxEPCSize int64
|
||||
|
||||
qgsPort uint32
|
||||
}
|
||||
|
||||
const (
|
||||
@ -125,6 +127,7 @@ func newQemuArch(config HypervisorConfig) (qemuArch, error) {
|
||||
},
|
||||
vmFactory: factory,
|
||||
snpGuest: config.SevSnpGuest,
|
||||
qgsPort: config.QgsPort,
|
||||
}
|
||||
|
||||
if config.ConfidentialGuest {
|
||||
@ -282,6 +285,7 @@ func (q *qemuAmd64) appendProtectionDevice(devices []govmmQemu.Device, firmware,
|
||||
govmmQemu.Object{
|
||||
Driver: govmmQemu.Loader,
|
||||
Type: govmmQemu.TDXGuest,
|
||||
QgsPort: q.qgsPort,
|
||||
ID: "tdx",
|
||||
DeviceID: fmt.Sprintf("fd%d", id),
|
||||
Debug: false,
|
||||
|
Loading…
Reference in New Issue
Block a user