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 Tested-by: Satheesh Rajendran <sathnaga@xxxxxxxxxxxxxxxxxx> Reviewed-by: Stefan Berger <stefanb@xxxxxxxxxxxxx> 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); -- 2.26.2