[PATCH v6 06/10] qemu: add validations after TPM Proxy model introduction

Daniel Henrique Barboza danielhb413 at gmail.com
Tue Jun 2 13:31:03 UTC 2020


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 at linux.vnet.ibm.com>
Reviewed-by: Stefan Berger <stefanb at linux.ibm.com>
Signed-off-by: Daniel Henrique Barboza <danielhb413 at gmail.com>
---
 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




More information about the libvir-list mailing list