On 5/21/20 9:07 AM, Daniel Henrique Barboza wrote:
Previous patch handled the conversion of def->tpm to the
array def->tpms and the XML parsing logic. This patch handles
the validations needed to ensure the intended behavior.
The existing qemuValidateDomainDeviceDefTPM() function was updated
to guarantee that the VIR_DOMAIN_TPM_MODEL_SPAPR_PROXY model is
exclusive to PPC64 guests and to the VIR_DOMAIN_TPM_TYPE_PASSTHROUGH
backend.
A new function called qemuDomainDefTPMsPostParse() was added to guarantee
that the following combinations in the same domain are valid:
- a single TPM device
- a single TPM Proxy device
- a single TPM + single TPM Proxy devices
And these combinations in the same domain are NOT valid:
- 2 or more TPM devices
- 2 or more TPM Proxy devices
Signed-off-by: Daniel Henrique Barboza <danielhb413@xxxxxxxxx>
---
src/qemu/qemu_domain.c | 37 +++++++++++++++++++++++++++++++++++++
src/qemu/qemu_validate.c | 19 +++++++++++++++++++
2 files changed, 56 insertions(+)
diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index 3173fc3a3b..b1b50f05d4 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -4953,6 +4953,40 @@ qemuDomainDefTsegPostParse(virDomainDefPtr def,
}
+static int
+qemuDomainDefTPMsPostParse(virDomainDefPtr def)
+{
+ virDomainTPMDefPtr proxyTPM = NULL;
+ virDomainTPMDefPtr regularTPM = NULL;
+ size_t i;
+
+ if (def->ntpms < 2)
+ return 0;
+
+ for (i = 0; i < def->ntpms; i++) {
+ virDomainTPMDefPtr tpm = def->tpms[i];
+
+ if (tpm->model == VIR_DOMAIN_TPM_MODEL_SPAPR_PROXY) {
+ if (proxyTPM) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+ _("only a single TPM Proxy device is supported"));
+ return -1;
+ } else {
+ proxyTPM = tpm;
+ }
+ } else if (regularTPM) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+ _("only a single TPM non-proxy device is supported"));
+ return -1;
+ } else {
+ regularTPM = tpm;
+ }
+ }
+
+ return 0;
+}
+
+
static int
qemuDomainDefPostParseBasic(virDomainDefPtr def,
void *opaque G_GNUC_UNUSED)
@@ -5039,6 +5073,9 @@ qemuDomainDefPostParse(virDomainDefPtr def,
if (qemuDomainDefTsegPostParse(def, qemuCaps) < 0)
return -1;
+ if (qemuDomainDefTPMsPostParse(def) < 0)
+ return -1;
+
return 0;
}
diff --git a/src/qemu/qemu_validate.c b/src/qemu/qemu_validate.c
index 584d1375b8..28e02ebefc 100644
--- a/src/qemu/qemu_validate.c
+++ b/src/qemu/qemu_validate.c
@@ -3623,6 +3623,25 @@ qemuValidateDomainDeviceDefTPM(virDomainTPMDef *tpm,
case VIR_DOMAIN_TPM_MODEL_SPAPR:
flag = QEMU_CAPS_DEVICE_TPM_SPAPR;
break;
+ case VIR_DOMAIN_TPM_MODEL_SPAPR_PROXY:
+ if (!ARCH_IS_PPC64(def->os.arch)) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+ _("TPM Proxy model %s is only available for "
+ "PPC64 guests"),
+ virDomainTPMModelTypeToString(tpm->model));
+ return -1;
+ }
+
+ /* TPM Proxy devices have 'passthrough' backend */
+ if (tpm->type != VIR_DOMAIN_TPM_TYPE_PASSTHROUGH) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+ _("TPM Proxy model %s requires "
+ "'Passthrough' backend"),
+ virDomainTPMModelTypeToString(tpm->model));
+ }
+
+ flag = QEMU_CAPS_DEVICE_SPAPR_TPM_PROXY;
+ break;
case VIR_DOMAIN_TPM_MODEL_LAST:
default:
virReportEnumRangeError(virDomainTPMModel, tpm->model);
Reviewed-by: Stefan Berger <stefanb@xxxxxxxxxxxxx>