This new device will be used to represent a single instance of a TPM Proxy for the domain. XML functions to parse and format the device from the XML definition will be added in the next patch. Signed-off-by: Daniel Henrique Barboza <danielhb413@xxxxxxxxx> --- src/conf/domain_capabilities.c | 1 + src/conf/domain_conf.c | 68 ++++++++++++++++++++++++++++++++++ src/conf/domain_conf.h | 18 +++++++++ src/conf/virconftypes.h | 3 ++ src/qemu/qemu_command.c | 1 + src/qemu/qemu_domain.c | 14 +++++++ src/qemu/qemu_domain_address.c | 2 + src/qemu/qemu_driver.c | 5 +++ src/qemu/qemu_hotplug.c | 3 ++ src/qemu/qemu_validate.c | 37 ++++++++++++++++++ 10 files changed, 152 insertions(+) diff --git a/src/conf/domain_capabilities.c b/src/conf/domain_capabilities.c index 921d795630..485fa9a22d 100644 --- a/src/conf/domain_capabilities.c +++ b/src/conf/domain_capabilities.c @@ -703,6 +703,7 @@ virDomainCapsDeviceDefValidate(const virDomainCaps *caps, case VIR_DOMAIN_DEVICE_TPM: case VIR_DOMAIN_DEVICE_PANIC: case VIR_DOMAIN_DEVICE_IOMMU: + case VIR_DOMAIN_DEVICE_TPMPROXY: case VIR_DOMAIN_DEVICE_NONE: case VIR_DOMAIN_DEVICE_LAST: break; diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 83748354b0..4c731b9f36 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -323,6 +323,7 @@ VIR_ENUM_IMPL(virDomainDevice, "memory", "iommu", "vsock", + "tpmproxy", ); VIR_ENUM_IMPL(virDomainDiskDevice, @@ -1180,6 +1181,12 @@ VIR_ENUM_IMPL(virDomainTPMVersion, "2.0", ); +VIR_ENUM_IMPL(virDomainTPMProxyModel, + VIR_DOMAIN_TPMPROXY_MODEL_LAST, + "default", + "spapr-tpm-proxy", +); + VIR_ENUM_IMPL(virDomainIOMMUModel, VIR_DOMAIN_IOMMU_MODEL_LAST, "intel", @@ -3061,6 +3068,17 @@ void virDomainTPMDefFree(virDomainTPMDefPtr def) VIR_FREE(def); } +void virDomainTPMProxyDefFree(virDomainTPMProxyDefPtr def) +{ + if (!def) + return; + + VIR_FREE(def->path); + virDomainDeviceInfoClear(&def->info); + VIR_FREE(def); + +} + void virDomainHostdevDefFree(virDomainHostdevDefPtr def) { if (!def) @@ -3187,6 +3205,9 @@ void virDomainDeviceDefFree(virDomainDeviceDefPtr def) case VIR_DOMAIN_DEVICE_TPM: virDomainTPMDefFree(def->data.tpm); break; + case VIR_DOMAIN_DEVICE_TPMPROXY: + virDomainTPMProxyDefFree(def->data.tpmproxy); + break; case VIR_DOMAIN_DEVICE_PANIC: virDomainPanicDefFree(def->data.panic); break; @@ -3480,6 +3501,7 @@ void virDomainDefFree(virDomainDefPtr def) VIR_FREE(def->mems); virDomainTPMDefFree(def->tpm); + virDomainTPMProxyDefFree(def->tpmproxy); for (i = 0; i < def->npanics; i++) virDomainPanicDefFree(def->panics[i]); @@ -4038,6 +4060,8 @@ virDomainDeviceGetInfo(virDomainDeviceDefPtr device) return &device->data.memory->info; case VIR_DOMAIN_DEVICE_VSOCK: return &device->data.vsock->info; + case VIR_DOMAIN_DEVICE_TPMPROXY: + return &device->data.tpmproxy->info; /* The following devices do not contain virDomainDeviceInfo */ case VIR_DOMAIN_DEVICE_LEASE: @@ -4137,6 +4161,9 @@ virDomainDeviceSetData(virDomainDeviceDefPtr device, case VIR_DOMAIN_DEVICE_LEASE: device->data.lease = devicedata; break; + case VIR_DOMAIN_DEVICE_TPMPROXY: + device->data.tpmproxy = devicedata; + break; case VIR_DOMAIN_DEVICE_NONE: case VIR_DOMAIN_DEVICE_LAST: break; @@ -4318,6 +4345,12 @@ virDomainDeviceInfoIterateInternal(virDomainDefPtr def, if ((rc = cb(def, &device, &def->tpm->info, opaque)) != 0) return rc; } + if (def->tpmproxy) { + device.type = VIR_DOMAIN_DEVICE_TPMPROXY; + device.data.tpmproxy = def->tpmproxy; + if ((rc = cb(def, &device, &def->tpmproxy->info, opaque)) != 0) + return rc; + } device.type = VIR_DOMAIN_DEVICE_PANIC; for (i = 0; i < def->npanics; i++) { device.data.panic = def->panics[i]; @@ -4403,6 +4436,7 @@ virDomainDeviceInfoIterateInternal(virDomainDefPtr def, case VIR_DOMAIN_DEVICE_MEMORY: case VIR_DOMAIN_DEVICE_IOMMU: case VIR_DOMAIN_DEVICE_VSOCK: + case VIR_DOMAIN_DEVICE_TPMPROXY: break; } #endif @@ -5395,6 +5429,7 @@ virDomainDeviceDefPostParseCommon(virDomainDeviceDefPtr dev, case VIR_DOMAIN_DEVICE_PANIC: case VIR_DOMAIN_DEVICE_MEMORY: case VIR_DOMAIN_DEVICE_IOMMU: + case VIR_DOMAIN_DEVICE_TPMPROXY: ret = 0; break; @@ -6795,6 +6830,7 @@ virDomainDeviceDefValidateInternal(const virDomainDeviceDef *dev, case VIR_DOMAIN_DEVICE_TPM: case VIR_DOMAIN_DEVICE_PANIC: case VIR_DOMAIN_DEVICE_IOMMU: + case VIR_DOMAIN_DEVICE_TPMPROXY: case VIR_DOMAIN_DEVICE_NONE: case VIR_DOMAIN_DEVICE_LAST: break; @@ -17039,6 +17075,7 @@ virDomainDeviceDefParse(const char *xmlStr, flags))) return NULL; break; + case VIR_DOMAIN_DEVICE_TPMPROXY: case VIR_DOMAIN_DEVICE_NONE: case VIR_DOMAIN_DEVICE_LAST: break; @@ -23743,6 +23780,25 @@ virDomainTPMDefCheckABIStability(virDomainTPMDefPtr src, } +static bool +virDomainTPMProxyDefCheckABIStability(virDomainTPMProxyDefPtr src, + virDomainTPMProxyDefPtr dst) +{ + if (src->model != dst->model) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("Target TPM Proxy device model doesn't match source")); + return false; + } + + if (STRNEQ_NULLABLE(src->path, dst->path)) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("Target TPM Proxy device path doesn't match source")); + return false; + } + + return virDomainDeviceInfoCheckABIStability(&src->info, &dst->info); +} + static bool virDomainMemtuneCheckABIStability(const virDomainDef *src, const virDomainDef *dst, @@ -24355,6 +24411,16 @@ virDomainDefCheckABIStabilityFlags(virDomainDefPtr src, goto error; } + if (src->tpmproxy && dst->tpmproxy) { + if (!virDomainTPMProxyDefCheckABIStability(src->tpmproxy, dst->tpmproxy)) + goto error; + } else if (src->tpmproxy || dst->tpmproxy) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("Either both target and source domains or none of " + "them must have TPM Proxy device present")); + goto error; + } + if (src->nmems != dst->nmems) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, _("Target domain memory device count %zu " @@ -24427,6 +24493,7 @@ virDomainDefCheckABIStabilityFlags(virDomainDefPtr src, case VIR_DOMAIN_DEVICE_MEMORY: case VIR_DOMAIN_DEVICE_IOMMU: case VIR_DOMAIN_DEVICE_VSOCK: + case VIR_DOMAIN_DEVICE_TPMPROXY: break; } #endif @@ -30977,6 +31044,7 @@ virDomainDeviceDefCopy(virDomainDeviceDefPtr src, case VIR_DOMAIN_DEVICE_MEMBALLOON: case VIR_DOMAIN_DEVICE_NVRAM: case VIR_DOMAIN_DEVICE_IOMMU: + case VIR_DOMAIN_DEVICE_TPMPROXY: case VIR_DOMAIN_DEVICE_LAST: virReportError(VIR_ERR_INTERNAL_ERROR, _("Copying definition of '%d' type " diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index 4afd8f04bc..d9b6bc5a22 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -85,6 +85,7 @@ typedef enum { VIR_DOMAIN_DEVICE_MEMORY, VIR_DOMAIN_DEVICE_IOMMU, VIR_DOMAIN_DEVICE_VSOCK, + VIR_DOMAIN_DEVICE_TPMPROXY, VIR_DOMAIN_DEVICE_LAST } virDomainDeviceType; @@ -116,6 +117,7 @@ struct _virDomainDeviceDef { virDomainMemoryDefPtr memory; virDomainIOMMUDefPtr iommu; virDomainVsockDefPtr vsock; + virDomainTPMProxyDefPtr tpmproxy; } data; }; @@ -1330,6 +1332,19 @@ struct _virDomainTPMDef { } data; }; +typedef enum { + VIR_DOMAIN_TPMPROXY_MODEL_DEFAULT, + VIR_DOMAIN_TPMPROXY_MODEL_SPAPR, + + VIR_DOMAIN_TPMPROXY_MODEL_LAST +} virDomainTPMProxyModel; + +struct _virDomainTPMProxyDef { + virDomainDeviceInfo info; + int model; /* virDomainTPMProxyModel */ + char *path; +}; + typedef enum { VIR_DOMAIN_INPUT_TYPE_MOUSE, VIR_DOMAIN_INPUT_TYPE_TABLET, @@ -2625,6 +2640,7 @@ struct _virDomainDef { virDomainMemballoonDefPtr memballoon; virDomainNVRAMDefPtr nvram; virDomainTPMDefPtr tpm; + virDomainTPMProxyDefPtr tpmproxy; virCPUDefPtr cpu; virSysinfoDefPtr sysinfo; virDomainRedirFilterDefPtr redirfilter; @@ -3023,6 +3039,7 @@ virDomainDeviceInfoPtr virDomainDeviceGetInfo(virDomainDeviceDefPtr device); void virDomainDeviceSetData(virDomainDeviceDefPtr device, void *devicedata); void virDomainTPMDefFree(virDomainTPMDefPtr def); +void virDomainTPMProxyDefFree(virDomainTPMProxyDefPtr def); typedef int (*virDomainDeviceInfoCallback)(virDomainDefPtr def, virDomainDeviceDefPtr dev, @@ -3594,6 +3611,7 @@ VIR_ENUM_DECL(virDomainRNGBackend); VIR_ENUM_DECL(virDomainTPMModel); VIR_ENUM_DECL(virDomainTPMBackend); VIR_ENUM_DECL(virDomainTPMVersion); +VIR_ENUM_DECL(virDomainTPMProxyModel); VIR_ENUM_DECL(virDomainMemoryModel); VIR_ENUM_DECL(virDomainMemoryBackingModel); VIR_ENUM_DECL(virDomainMemorySource); diff --git a/src/conf/virconftypes.h b/src/conf/virconftypes.h index 1c62cde251..5c4a149f24 100644 --- a/src/conf/virconftypes.h +++ b/src/conf/virconftypes.h @@ -312,6 +312,9 @@ typedef virDomainSoundDef *virDomainSoundDefPtr; typedef struct _virDomainTPMDef virDomainTPMDef; typedef virDomainTPMDef *virDomainTPMDefPtr; +typedef struct _virDomainTPMProxyDef virDomainTPMProxyDef; +typedef virDomainTPMProxyDef *virDomainTPMProxyDefPtr; + typedef struct _virDomainThreadSchedParam virDomainThreadSchedParam; typedef virDomainThreadSchedParam *virDomainThreadSchedParamPtr; diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index 269bdbaf56..9065164b1d 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -537,6 +537,7 @@ qemuBuildVirtioDevStr(virBufferPtr buf, case VIR_DOMAIN_DEVICE_PANIC: case VIR_DOMAIN_DEVICE_MEMORY: case VIR_DOMAIN_DEVICE_IOMMU: + case VIR_DOMAIN_DEVICE_TPMPROXY: case VIR_DOMAIN_DEVICE_LAST: default: return 0; diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c index 9c629c31a3..3e86797093 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -5923,6 +5923,16 @@ qemuDomainTPMDefPostParse(virDomainTPMDefPtr tpm, } +static int +qemuDomainTPMProxyDefPostParse(virDomainTPMProxyDefPtr tpmproxy) +{ + if (tpmproxy->model == VIR_DOMAIN_TPMPROXY_MODEL_DEFAULT) + tpmproxy->model = VIR_DOMAIN_TPMPROXY_MODEL_SPAPR; + + return 0; +} + + static int qemuDomainDeviceDefPostParse(virDomainDeviceDefPtr dev, const virDomainDef *def, @@ -5980,6 +5990,10 @@ qemuDomainDeviceDefPostParse(virDomainDeviceDefPtr dev, ret = qemuDomainTPMDefPostParse(dev->data.tpm, def->os.arch); break; + case VIR_DOMAIN_DEVICE_TPMPROXY: + ret = qemuDomainTPMProxyDefPostParse(dev->data.tpmproxy); + break; + case VIR_DOMAIN_DEVICE_LEASE: case VIR_DOMAIN_DEVICE_FS: case VIR_DOMAIN_DEVICE_INPUT: diff --git a/src/qemu/qemu_domain_address.c b/src/qemu/qemu_domain_address.c index 07431343ed..566516f8b5 100644 --- a/src/qemu/qemu_domain_address.c +++ b/src/qemu/qemu_domain_address.c @@ -528,6 +528,7 @@ qemuDomainDeviceSupportZPCI(virDomainDeviceDefPtr device) case VIR_DOMAIN_DEVICE_MEMORY: case VIR_DOMAIN_DEVICE_IOMMU: case VIR_DOMAIN_DEVICE_VSOCK: + case VIR_DOMAIN_DEVICE_TPMPROXY: break; case VIR_DOMAIN_DEVICE_NONE: @@ -1031,6 +1032,7 @@ qemuDomainDeviceCalculatePCIConnectFlags(virDomainDeviceDefPtr dev, case VIR_DOMAIN_DEVICE_HUB: case VIR_DOMAIN_DEVICE_REDIRDEV: case VIR_DOMAIN_DEVICE_SMARTCARD: + case VIR_DOMAIN_DEVICE_TPMPROXY: /* These devices don't even have a DeviceInfo */ case VIR_DOMAIN_DEVICE_LEASE: case VIR_DOMAIN_DEVICE_GRAPHICS: diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 1c7c87128d..57575b705f 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -7956,6 +7956,7 @@ qemuDomainAttachDeviceLive(virDomainObjPtr vm, case VIR_DOMAIN_DEVICE_TPM: case VIR_DOMAIN_DEVICE_PANIC: case VIR_DOMAIN_DEVICE_IOMMU: + case VIR_DOMAIN_DEVICE_TPMPROXY: case VIR_DOMAIN_DEVICE_LAST: virReportError(VIR_ERR_OPERATION_UNSUPPORTED, _("live attach of device '%s' is not supported"), @@ -8090,6 +8091,7 @@ qemuDomainUpdateDeviceLive(virDomainObjPtr vm, case VIR_DOMAIN_DEVICE_PANIC: case VIR_DOMAIN_DEVICE_IOMMU: case VIR_DOMAIN_DEVICE_VSOCK: + case VIR_DOMAIN_DEVICE_TPMPROXY: case VIR_DOMAIN_DEVICE_LAST: virReportError(VIR_ERR_CONFIG_UNSUPPORTED, _("live update of device '%s' is not supported"), @@ -8311,6 +8313,7 @@ qemuDomainAttachDeviceConfig(virDomainDefPtr vmdef, case VIR_DOMAIN_DEVICE_TPM: case VIR_DOMAIN_DEVICE_PANIC: case VIR_DOMAIN_DEVICE_IOMMU: + case VIR_DOMAIN_DEVICE_TPMPROXY: case VIR_DOMAIN_DEVICE_LAST: virReportError(VIR_ERR_OPERATION_UNSUPPORTED, _("persistent attach of device '%s' is not supported"), @@ -8513,6 +8516,7 @@ qemuDomainDetachDeviceConfig(virDomainDefPtr vmdef, case VIR_DOMAIN_DEVICE_TPM: case VIR_DOMAIN_DEVICE_PANIC: case VIR_DOMAIN_DEVICE_IOMMU: + case VIR_DOMAIN_DEVICE_TPMPROXY: case VIR_DOMAIN_DEVICE_LAST: virReportError(VIR_ERR_OPERATION_UNSUPPORTED, _("persistent detach of device '%s' is not supported"), @@ -8620,6 +8624,7 @@ qemuDomainUpdateDeviceConfig(virDomainDefPtr vmdef, case VIR_DOMAIN_DEVICE_PANIC: case VIR_DOMAIN_DEVICE_IOMMU: case VIR_DOMAIN_DEVICE_VSOCK: + case VIR_DOMAIN_DEVICE_TPMPROXY: case VIR_DOMAIN_DEVICE_LAST: virReportError(VIR_ERR_OPERATION_UNSUPPORTED, _("persistent update of device '%s' is not supported"), diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c index 60d0729f1e..aba80c87d3 100644 --- a/src/qemu/qemu_hotplug.c +++ b/src/qemu/qemu_hotplug.c @@ -4980,6 +4980,7 @@ qemuDomainRemoveAuditDevice(virDomainObjPtr vm, case VIR_DOMAIN_DEVICE_TPM: case VIR_DOMAIN_DEVICE_PANIC: case VIR_DOMAIN_DEVICE_IOMMU: + case VIR_DOMAIN_DEVICE_TPMPROXY: case VIR_DOMAIN_DEVICE_LAST: /* libvirt doesn't yet support detaching these devices */ break; @@ -5078,6 +5079,7 @@ qemuDomainRemoveDevice(virQEMUDriverPtr driver, case VIR_DOMAIN_DEVICE_TPM: case VIR_DOMAIN_DEVICE_PANIC: case VIR_DOMAIN_DEVICE_IOMMU: + case VIR_DOMAIN_DEVICE_TPMPROXY: case VIR_DOMAIN_DEVICE_LAST: virReportError(VIR_ERR_OPERATION_UNSUPPORTED, _("don't know how to remove a %s device"), @@ -5849,6 +5851,7 @@ qemuDomainDetachDeviceLive(virDomainObjPtr vm, case VIR_DOMAIN_DEVICE_TPM: case VIR_DOMAIN_DEVICE_PANIC: case VIR_DOMAIN_DEVICE_IOMMU: + case VIR_DOMAIN_DEVICE_TPMPROXY: case VIR_DOMAIN_DEVICE_LAST: virReportError(VIR_ERR_OPERATION_UNSUPPORTED, _("live detach of device '%s' is not supported"), diff --git a/src/qemu/qemu_validate.c b/src/qemu/qemu_validate.c index 9debac6b30..733850416a 100644 --- a/src/qemu/qemu_validate.c +++ b/src/qemu/qemu_validate.c @@ -3326,6 +3326,38 @@ qemuValidateDomainDeviceDefTPM(virDomainTPMDef *tpm, } +static int +qemuValidateDomainDeviceDefTPMProxy(virDomainTPMProxyDef *tpmproxy, + const virDomainDef *def, + virQEMUCapsPtr qemuCaps) +{ + if (!ARCH_IS_PPC64(def->os.arch)) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("TPM Proxy device is only supported " + "for PPC64 guests")); + return -1; + } + + switch ((virDomainTPMProxyModel)tpmproxy->model) { + case VIR_DOMAIN_TPMPROXY_MODEL_DEFAULT: + case VIR_DOMAIN_TPMPROXY_MODEL_SPAPR: + if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_SPAPR_TPM_PROXY)) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("TPM Proxy is not supported " + "with this QEMU binary")); + return -1; + } + break; + case VIR_DOMAIN_TPMPROXY_MODEL_LAST: + default: + virReportEnumRangeError(virDomainTPMProxyModel, + tpmproxy->model); + return -1; + } + + return 0; +} + static int qemuValidateDomainDeviceDefInput(const virDomainInputDef *input, const virDomainDef *def, @@ -3722,6 +3754,11 @@ qemuValidateDomainDeviceDef(const virDomainDeviceDef *dev, ret = qemuValidateDomainDeviceDefMemory(dev->data.memory, qemuCaps); break; + case VIR_DOMAIN_DEVICE_TPMPROXY: + ret = qemuValidateDomainDeviceDefTPMProxy(dev->data.tpmproxy, + def, qemuCaps); + break; + case VIR_DOMAIN_DEVICE_LEASE: case VIR_DOMAIN_DEVICE_SHMEM: case VIR_DOMAIN_DEVICE_PANIC: -- 2.26.2