diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c index b2f0d4afda..8b2447482d 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -4985,6 +4985,40 @@ qemuDomainDefNumaCPUsPostParse(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) @@ -5074,6 +5108,9 @@ qemuDomainDefPostParse(virDomainDefPtr def, if (qemuDomainDefNumaCPUsPostParse(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 c5ca3a872f..5082a29dc7 100644 --- a/src/qemu/qemu_validate.c +++ b/src/qemu/qemu_validate.c @@ -3655,6 +3655,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);