qemu: add validations after TPM Proxy model introduction

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@linux.vnet.ibm.com>
Reviewed-by: Stefan Berger <stefanb@linux.ibm.com>
Signed-off-by: Daniel Henrique Barboza <danielhb413@gmail.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
Signed-off-by: Ján Tomko <jtomko@redhat.com>
This commit is contained in:
Daniel Henrique Barboza 2020-06-10 15:11:48 -03:00 committed by Ján Tomko
parent 19d74fdf0e
commit 0f7e8649c7
2 changed files with 56 additions and 0 deletions

View File

@ -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;
}

View File

@ -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);