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(a)gmail.com>
---
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