[PATCH v6 05/10] conf, qemu, security, tests: introducing 'def->tpms' array

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


A TPM Proxy device can coexist with a regular TPM, but the
current domain definition supports only a single TPM device
in the 'tpm' pointer. This patch replaces this existing pointer
in the domain definition to an array of TPM devices.

All files that references the old pointer were adapted to
handle the new array instead. virDomainDefParseXML() TPM related
code was adapted to handle the parsing of an extra TPM device.
TPM validations after this new scenario will be updated in
the next patch.

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/conf/domain_audit.c         |  4 +--
 src/conf/domain_conf.c          | 50 +++++++++++++++++++------------
 src/conf/domain_conf.h          |  6 +++-
 src/qemu/qemu_alias.c           |  4 +--
 src/qemu/qemu_cgroup.c          | 10 ++++---
 src/qemu/qemu_command.c         | 34 ++++++++++++++-------
 src/qemu/qemu_domain.c          | 31 +++++++++++++-------
 src/qemu/qemu_domain_address.c  | 11 ++++---
 src/qemu/qemu_extdevice.c       | 18 +++++++-----
 src/qemu/qemu_tpm.c             | 52 +++++++++++++++++++++++++--------
 src/security/security_dac.c     |  8 ++---
 src/security/security_selinux.c | 32 ++++++++++++--------
 src/security/virt-aa-helper.c   |  9 ++++--
 tests/qemuxml2argvtest.c        | 13 +++++----
 14 files changed, 186 insertions(+), 96 deletions(-)

diff --git a/src/conf/domain_audit.c b/src/conf/domain_audit.c
index 1b0abb21a0..8bc6633af4 100644
--- a/src/conf/domain_audit.c
+++ b/src/conf/domain_audit.c
@@ -821,8 +821,8 @@ virDomainAuditStart(virDomainObjPtr vm, const char *reason, bool success)
     for (i = 0; i < vm->def->nrngs; i++)
         virDomainAuditRNG(vm, NULL, vm->def->rngs[i], "start", true);
 
-    if (vm->def->tpm)
-        virDomainAuditTPM(vm, vm->def->tpm, "start", true);
+    for (i = 0; i < vm->def->ntpms; i++)
+        virDomainAuditTPM(vm, vm->def->tpms[i], "start", true);
 
     for (i = 0; i < vm->def->nshmems; i++)
         virDomainAuditShmem(vm, vm->def->shmems[i], "start", true);
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 1406cf079e..899f994e23 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -1165,6 +1165,7 @@ VIR_ENUM_IMPL(virDomainTPMModel,
               "tpm-tis",
               "tpm-crb",
               "tpm-spapr",
+              "spapr-tpm-proxy",
 );
 
 VIR_ENUM_IMPL(virDomainTPMBackend,
@@ -3480,7 +3481,9 @@ void virDomainDefFree(virDomainDefPtr def)
         virDomainMemoryDefFree(def->mems[i]);
     VIR_FREE(def->mems);
 
-    virDomainTPMDefFree(def->tpm);
+    for (i = 0; i < def->ntpms; i++)
+        virDomainTPMDefFree(def->tpms[i]);
+    VIR_FREE(def->tpms);
 
     for (i = 0; i < def->npanics; i++)
         virDomainPanicDefFree(def->panics[i]);
@@ -4313,10 +4316,10 @@ virDomainDeviceInfoIterateInternal(virDomainDefPtr def,
         if ((rc = cb(def, &device, &def->shmems[i]->info, opaque)) != 0)
             return rc;
     }
-    if (def->tpm) {
-        device.type = VIR_DOMAIN_DEVICE_TPM;
-        device.data.tpm = def->tpm;
-        if ((rc = cb(def, &device, &def->tpm->info, opaque)) != 0)
+    device.type = VIR_DOMAIN_DEVICE_TPM;
+    for (i = 0; i < def->ntpms; i++) {
+        device.data.tpm = def->tpms[i];
+        if ((rc = cb(def, &device, &def->tpms[i]->info, opaque)) != 0)
             return rc;
     }
     device.type = VIR_DOMAIN_DEVICE_PANIC;
@@ -21971,15 +21974,23 @@ virDomainDefParseXML(xmlDocPtr xml,
     if ((n = virXPathNodeSet("./devices/tpm", ctxt, &nodes)) < 0)
         goto error;
 
-    if (n > 1) {
+    if (n > 2) {
         virReportError(VIR_ERR_XML_ERROR, "%s",
-                       _("only a single TPM device is supported"));
+                       _("a maximum of two TPM devices is supported, one of "
+                         "them being a TPM Proxy device"));
         goto error;
     }
 
-    if (n > 0) {
-        if (!(def->tpm = virDomainTPMDefParseXML(xmlopt, nodes[0], ctxt, flags)))
+    if (n && VIR_ALLOC_N(def->tpms, n) < 0)
+        goto error;
+
+    for (i = 0; i < n; i++) {
+        virDomainTPMDefPtr tpm = virDomainTPMDefParseXML(xmlopt, nodes[i],
+                                                         ctxt, flags);
+        if (!tpm)
             goto error;
+
+        def->tpms[def->ntpms++] = tpm;
     }
     VIR_FREE(nodes);
 
@@ -24341,16 +24352,19 @@ virDomainDefCheckABIStabilityFlags(virDomainDefPtr src,
             goto error;
     }
 
-    if (src->tpm && dst->tpm) {
-        if (!virDomainTPMDefCheckABIStability(src->tpm, dst->tpm))
-            goto error;
-    } else if (src->tpm || dst->tpm) {
-        virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
-                       _("Either both target and source domains or none of "
-                         "them must have TPM device present"));
+    if (src->ntpms != dst->ntpms) {
+        virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+                       _("Target domain TPM device count %zu "
+                         "does not match source %zu"),
+                       dst->ntpms, src->ntpms);
         goto error;
     }
 
+    for (i = 0; i < src->ntpms; i++) {
+        if (!virDomainTPMDefCheckABIStability(src->tpms[i], dst->tpms[i]))
+            goto error;
+    }
+
     if (src->nmems != dst->nmems) {
         virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                        _("Target domain memory device count %zu "
@@ -29793,8 +29807,8 @@ virDomainDefFormatInternalSetRootName(virDomainDefPtr def,
             goto error;
     }
 
-    if (def->tpm) {
-        if (virDomainTPMDefFormat(buf, def->tpm, flags) < 0)
+    for (n = 0; n < def->ntpms; n++) {
+        if (virDomainTPMDefFormat(buf, def->tpms[n], flags) < 0)
             goto error;
     }
 
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index e152c599ca..84e36e03f4 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -1294,6 +1294,7 @@ typedef enum {
     VIR_DOMAIN_TPM_MODEL_TIS,
     VIR_DOMAIN_TPM_MODEL_CRB,
     VIR_DOMAIN_TPM_MODEL_SPAPR,
+    VIR_DOMAIN_TPM_MODEL_SPAPR_PROXY,
 
     VIR_DOMAIN_TPM_MODEL_LAST
 } virDomainTPMModel;
@@ -2624,11 +2625,14 @@ struct _virDomainDef {
     size_t npanics;
     virDomainPanicDefPtr *panics;
 
+    /* At maximum 2 TPMs on the domain, if a TPM Proxy is present. */
+    size_t ntpms;
+    virDomainTPMDefPtr *tpms;
+
     /* Only 1 */
     virDomainWatchdogDefPtr watchdog;
     virDomainMemballoonDefPtr memballoon;
     virDomainNVRAMDefPtr nvram;
-    virDomainTPMDefPtr tpm;
     virCPUDefPtr cpu;
     virSysinfoDefPtr sysinfo;
     virDomainRedirFilterDefPtr redirfilter;
diff --git a/src/qemu/qemu_alias.c b/src/qemu/qemu_alias.c
index d6527cb046..85fdb85940 100644
--- a/src/qemu/qemu_alias.c
+++ b/src/qemu/qemu_alias.c
@@ -669,8 +669,8 @@ qemuAssignDeviceAliases(virDomainDefPtr def, virQEMUCapsPtr qemuCaps)
         if (qemuAssignDeviceRNGAlias(def, def->rngs[i]) < 0)
             return -1;
     }
-    if (def->tpm) {
-        if (qemuAssignDeviceTPMAlias(def->tpm, 0) < 0)
+    for (i = 0; i < def->ntpms; i++) {
+        if (qemuAssignDeviceTPMAlias(def->tpms[i], 0) < 0)
             return -1;
     }
     for (i = 0; i < def->nmems; i++) {
diff --git a/src/qemu/qemu_cgroup.c b/src/qemu/qemu_cgroup.c
index d92202f847..eb0f03d4aa 100644
--- a/src/qemu/qemu_cgroup.c
+++ b/src/qemu/qemu_cgroup.c
@@ -332,10 +332,10 @@ qemuSetupChardevCgroupCB(virDomainDefPtr def G_GNUC_UNUSED,
 
 
 static int
-qemuSetupTPMCgroup(virDomainObjPtr vm)
+qemuSetupTPMCgroup(virDomainObjPtr vm,
+                   virDomainTPMDefPtr dev)
 {
     int ret = 0;
-    virDomainTPMDefPtr dev = vm->def->tpm;
 
     switch (dev->type) {
     case VIR_DOMAIN_TPM_TYPE_PASSTHROUGH:
@@ -805,8 +805,10 @@ qemuSetupDevicesCgroup(virDomainObjPtr vm)
                                vm) < 0)
         return -1;
 
-    if (vm->def->tpm && qemuSetupTPMCgroup(vm) < 0)
-        return -1;
+    for (i = 0; i < vm->def->ntpms; i++) {
+        if (qemuSetupTPMCgroup(vm, vm->def->tpms[i]) < 0)
+            return -1;
+    }
 
     for (i = 0; i < vm->def->nhostdevs; i++) {
         /* This may allow /dev/vfio/vfio multiple times, but that
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index 419eca5675..59caff08f2 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -8890,10 +8890,10 @@ qemuBuildDomainLoaderCommandLine(virCommandPtr cmd,
 
 static char *
 qemuBuildTPMDevStr(const virDomainDef *def,
+                   virDomainTPMDefPtr tpm,
                    virQEMUCapsPtr qemuCaps)
 {
     g_auto(virBuffer) buf = VIR_BUFFER_INITIALIZER;
-    virDomainTPMDef *tpm = def->tpm;
     const char *model = virDomainTPMModelTypeToString(tpm->model);
 
     virBufferAsprintf(&buf, "%s,tpmdev=tpm-%s,id=%s",
@@ -8932,13 +8932,12 @@ qemuBuildTPMOpenBackendFDs(const char *tpmdev,
 
 
 static char *
-qemuBuildTPMBackendStr(const virDomainDef *def,
-                       virCommandPtr cmd,
+qemuBuildTPMBackendStr(virCommandPtr cmd,
+                       virDomainTPMDefPtr tpm,
                        int *tpmfd,
                        int *cancelfd,
                        char **chardev)
 {
-    const virDomainTPMDef *tpm = def->tpm;
     g_auto(virBuffer) buf = VIR_BUFFER_INITIALIZER;
     g_autofree char *cancel_path = NULL;
     g_autofree char *devset = NULL;
@@ -8992,6 +8991,7 @@ qemuBuildTPMBackendStr(const virDomainDef *def,
 static int
 qemuBuildTPMCommandLine(virCommandPtr cmd,
                         const virDomainDef *def,
+                        virDomainTPMDefPtr tpm,
                         virQEMUCapsPtr qemuCaps)
 {
     char *optstr;
@@ -9000,10 +9000,7 @@ qemuBuildTPMCommandLine(virCommandPtr cmd,
     int cancelfd = -1;
     char *fdset;
 
-    if (!def->tpm)
-        return 0;
-
-    if (!(optstr = qemuBuildTPMBackendStr(def, cmd,
+    if (!(optstr = qemuBuildTPMBackendStr(cmd, tpm,
                                           &tpmfd, &cancelfd,
                                           &chardev)))
         return -1;
@@ -9032,7 +9029,7 @@ qemuBuildTPMCommandLine(virCommandPtr cmd,
         VIR_FREE(fdset);
     }
 
-    if (!(optstr = qemuBuildTPMDevStr(def, qemuCaps)))
+    if (!(optstr = qemuBuildTPMDevStr(def, tpm, qemuCaps)))
         return -1;
 
     virCommandAddArgList(cmd, "-device", optstr, NULL);
@@ -9041,6 +9038,23 @@ qemuBuildTPMCommandLine(virCommandPtr cmd,
     return 0;
 }
 
+
+static int
+qemuBuildTPMsCommandLine(virCommandPtr cmd,
+                         const virDomainDef *def,
+                         virQEMUCapsPtr qemuCaps)
+{
+    size_t i;
+
+    for (i = 0; i < def->ntpms; i++) {
+        if (qemuBuildTPMCommandLine(cmd, def, def->tpms[i], qemuCaps) < 0)
+            return -1;
+    }
+
+    return 0;
+}
+
+
 static int
 qemuBuildSEVCommandLine(virDomainObjPtr vm, virCommandPtr cmd,
                         virDomainSEVDefPtr sev)
@@ -9720,7 +9734,7 @@ qemuBuildCommandLine(virQEMUDriverPtr driver,
                                     chardevStdioLogd) < 0)
         return NULL;
 
-    if (qemuBuildTPMCommandLine(cmd, def, qemuCaps) < 0)
+    if (qemuBuildTPMsCommandLine(cmd, def, qemuCaps) < 0)
         return NULL;
 
     if (qemuBuildInputCommandLine(cmd, def, qemuCaps) < 0)
diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index d5e3d1a3cc..3173fc3a3b 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -11585,16 +11585,9 @@ qemuDomainSetupAllChardevs(virQEMUDriverConfigPtr cfg G_GNUC_UNUSED,
 
 static int
 qemuDomainSetupTPM(virQEMUDriverConfigPtr cfg G_GNUC_UNUSED,
-                   virDomainObjPtr vm,
+                   virDomainTPMDefPtr dev,
                    const struct qemuDomainCreateDeviceData *data)
 {
-    virDomainTPMDefPtr dev = vm->def->tpm;
-
-    if (!dev)
-        return 0;
-
-    VIR_DEBUG("Setting up TPM");
-
     switch (dev->type) {
     case VIR_DOMAIN_TPM_TYPE_PASSTHROUGH:
         if (qemuDomainCreateDevice(dev->data.passthrough.source.data.file.path,
@@ -11608,7 +11601,25 @@ qemuDomainSetupTPM(virQEMUDriverConfigPtr cfg G_GNUC_UNUSED,
         break;
     }
 
-    VIR_DEBUG("Setup TPM");
+    return 0;
+}
+
+
+static int
+qemuDomainSetupAllTPMs(virQEMUDriverConfigPtr cfg G_GNUC_UNUSED,
+                       virDomainObjPtr vm,
+                       const struct qemuDomainCreateDeviceData *data)
+{
+    size_t i;
+
+    VIR_DEBUG("Setting up TPMs");
+
+    for (i = 0; i < vm->def->ntpms; i++) {
+        if (qemuDomainSetupTPM(cfg, vm->def->tpms[i], data) < 0)
+            return -1;
+    }
+
+    VIR_DEBUG("Setup all TPMs");
     return 0;
 }
 
@@ -11834,7 +11845,7 @@ qemuDomainBuildNamespace(virQEMUDriverConfigPtr cfg,
     if (qemuDomainSetupAllChardevs(cfg, vm, &data) < 0)
         goto cleanup;
 
-    if (qemuDomainSetupTPM(cfg, vm, &data) < 0)
+    if (qemuDomainSetupAllTPMs(cfg, vm, &data) < 0)
         goto cleanup;
 
     if (qemuDomainSetupAllGraphics(cfg, vm, &data) < 0)
diff --git a/src/qemu/qemu_domain_address.c b/src/qemu/qemu_domain_address.c
index 07431343ed..4c26070022 100644
--- a/src/qemu/qemu_domain_address.c
+++ b/src/qemu/qemu_domain_address.c
@@ -268,10 +268,13 @@ qemuDomainAssignSpaprVIOAddresses(virDomainDefPtr def)
             return -1;
     }
 
-    if (def->tpm) {
-        if (qemuDomainIsPSeries(def))
-            def->tpm->info.type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_SPAPRVIO;
-        if (qemuDomainAssignSpaprVIOAddress(def, &def->tpm->info,
+    for (i = 0; i < def->ntpms; i++) {
+        virDomainTPMDefPtr tpm = def->tpms[i];
+
+        if (tpm->model != VIR_DOMAIN_TPM_MODEL_SPAPR_PROXY &&
+            qemuDomainIsPSeries(def))
+            tpm->info.type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_SPAPRVIO;
+        if (qemuDomainAssignSpaprVIOAddress(def, &tpm->info,
                                             VIO_ADDR_TPM) < 0)
             return -1;
     }
diff --git a/src/qemu/qemu_extdevice.c b/src/qemu/qemu_extdevice.c
index 8f1bd9311e..2fb71dd334 100644
--- a/src/qemu/qemu_extdevice.c
+++ b/src/qemu/qemu_extdevice.c
@@ -73,7 +73,7 @@ static int
 qemuExtDevicesInitPaths(virQEMUDriverPtr driver,
                         virDomainDefPtr def)
 {
-    if (def->tpm)
+    if (def->ntpms > 0)
         return qemuExtTPMInitPaths(driver, def);
 
     return 0;
@@ -132,7 +132,7 @@ qemuExtDevicesPrepareHost(virQEMUDriverPtr driver,
     virDomainDefPtr def = vm->def;
     size_t i;
 
-    if (def->tpm &&
+    if (def->ntpms > 0 &&
         qemuExtTPMPrepareHost(driver, def) < 0)
         return -1;
 
@@ -155,7 +155,7 @@ qemuExtDevicesCleanupHost(virQEMUDriverPtr driver,
     if (qemuExtDevicesInitPaths(driver, def) < 0)
         return;
 
-    if (def->tpm)
+    if (def->ntpms > 0)
         qemuExtTPMCleanupHost(def);
 }
 
@@ -181,7 +181,7 @@ qemuExtDevicesStart(virQEMUDriverPtr driver,
         }
     }
 
-    if (def->tpm && qemuExtTPMStart(driver, vm, incomingMigration) < 0)
+    if (def->ntpms > 0 && qemuExtTPMStart(driver, vm, incomingMigration) < 0)
         return -1;
 
     for (i = 0; i < def->nnets; i++) {
@@ -223,7 +223,7 @@ qemuExtDevicesStop(virQEMUDriverPtr driver,
             qemuExtVhostUserGPUStop(driver, vm, video);
     }
 
-    if (def->tpm)
+    if (def->ntpms > 0)
         qemuExtTPMStop(driver, vm);
 
     for (i = 0; i < def->nnets; i++) {
@@ -256,8 +256,10 @@ qemuExtDevicesHasDevice(virDomainDefPtr def)
             return true;
     }
 
-    if (def->tpm && def->tpm->type == VIR_DOMAIN_TPM_TYPE_EMULATOR)
-        return true;
+    for (i = 0; i < def->ntpms; i++) {
+        if (def->tpms[i]->type == VIR_DOMAIN_TPM_TYPE_EMULATOR)
+            return true;
+    }
 
     for (i = 0; i < def->nfss; i++) {
         virDomainFSDefPtr fs = def->fss[i];
@@ -297,7 +299,7 @@ qemuExtDevicesSetupCgroup(virQEMUDriverPtr driver,
             return -1;
     }
 
-    if (def->tpm &&
+    if (def->ntpms > 0 &&
         qemuExtTPMSetupCgroup(driver, def, cgroup) < 0)
         return -1;
 
diff --git a/src/qemu/qemu_tpm.c b/src/qemu/qemu_tpm.c
index afec0e5328..8adb0e42b8 100644
--- a/src/qemu/qemu_tpm.c
+++ b/src/qemu/qemu_tpm.c
@@ -679,10 +679,15 @@ qemuExtTPMInitPaths(virQEMUDriverPtr driver,
                     virDomainDefPtr def)
 {
     g_autoptr(virQEMUDriverConfig) cfg = virQEMUDriverGetConfig(driver);
+    size_t i;
 
-    if (def->tpm->type == VIR_DOMAIN_TPM_TYPE_EMULATOR)
-        return qemuTPMEmulatorInitPaths(def->tpm, cfg->swtpmStorageDir,
+    for (i = 0; i < def->ntpms; i++) {
+        if (def->tpms[i]->type != VIR_DOMAIN_TPM_TYPE_EMULATOR)
+            continue;
+
+        return qemuTPMEmulatorInitPaths(def->tpms[i], cfg->swtpmStorageDir,
                                         def->uuid);
+    }
 
     return 0;
 }
@@ -694,13 +699,17 @@ qemuExtTPMPrepareHost(virQEMUDriverPtr driver,
 {
     g_autoptr(virQEMUDriverConfig) cfg = virQEMUDriverGetConfig(driver);
     g_autofree char *shortName = NULL;
+    size_t i;
+
+    for (i = 0; i < def->ntpms; i++) {
+        if (def->tpms[i]->type != VIR_DOMAIN_TPM_TYPE_EMULATOR)
+            continue;
 
-    if (def->tpm->type == VIR_DOMAIN_TPM_TYPE_EMULATOR) {
         shortName = virDomainDefGetShortName(def);
         if (!shortName)
             return -1;
 
-        return qemuTPMEmulatorPrepareHost(def->tpm, cfg->swtpmLogDir,
+        return qemuTPMEmulatorPrepareHost(def->tpms[i], cfg->swtpmLogDir,
                                           def->name, cfg->swtpm_user,
                                           cfg->swtpm_group,
                                           cfg->swtpmStateDir, cfg->user,
@@ -714,8 +723,14 @@ qemuExtTPMPrepareHost(virQEMUDriverPtr driver,
 void
 qemuExtTPMCleanupHost(virDomainDefPtr def)
 {
-    if (def->tpm->type == VIR_DOMAIN_TPM_TYPE_EMULATOR)
-        qemuTPMDeleteEmulatorStorage(def->tpm);
+    size_t i;
+
+    for (i = 0; i < def->ntpms; i++) {
+        if (def->tpms[i]->type != VIR_DOMAIN_TPM_TYPE_EMULATOR)
+            continue;
+
+        qemuTPMDeleteEmulatorStorage(def->tpms[i]);
+    }
 }
 
 
@@ -733,13 +748,13 @@ qemuExtTPMCleanupHost(virDomainDefPtr def)
 static int
 qemuExtTPMStartEmulator(virQEMUDriverPtr driver,
                         virDomainObjPtr vm,
+                        virDomainTPMDefPtr tpm,
                         bool incomingMigration)
 {
     g_autoptr(virCommand) cmd = NULL;
     int exitstatus = 0;
     g_autofree char *errbuf = NULL;
     g_autoptr(virQEMUDriverConfig) cfg = NULL;
-    virDomainTPMDefPtr tpm = vm->def->tpm;
     g_autofree char *shortName = virDomainDefGetShortName(vm->def);
     int cmdret = 0, timeout, rc;
     pid_t pid;
@@ -807,10 +822,15 @@ qemuExtTPMStart(virQEMUDriverPtr driver,
                 virDomainObjPtr vm,
                 bool incomingMigration)
 {
-    virDomainTPMDefPtr tpm = vm->def->tpm;
+    size_t i;
+
+    for (i = 0; i < vm->def->ntpms; i++) {
+        if (vm->def->tpms[i]->type != VIR_DOMAIN_TPM_TYPE_EMULATOR)
+            continue;
 
-    if (tpm->type == VIR_DOMAIN_TPM_TYPE_EMULATOR)
-        return qemuExtTPMStartEmulator(driver, vm, incomingMigration);
+        return qemuExtTPMStartEmulator(driver, vm, vm->def->tpms[i],
+                                       incomingMigration);
+    }
 
     return 0;
 }
@@ -822,8 +842,12 @@ qemuExtTPMStop(virQEMUDriverPtr driver,
 {
     g_autoptr(virQEMUDriverConfig) cfg = virQEMUDriverGetConfig(driver);
     g_autofree char *shortName = NULL;
+    size_t i;
+
+    for (i = 0; i < vm->def->ntpms; i++) {
+        if (vm->def->tpms[i]->type != VIR_DOMAIN_TPM_TYPE_EMULATOR)
+            continue;
 
-    if (vm->def->tpm->type == VIR_DOMAIN_TPM_TYPE_EMULATOR) {
         shortName = virDomainDefGetShortName(vm->def);
         if (!shortName)
             return;
@@ -845,8 +869,12 @@ qemuExtTPMSetupCgroup(virQEMUDriverPtr driver,
     g_autofree char *shortName = NULL;
     int rc;
     pid_t pid;
+    size_t i;
+
+    for (i = 0; i < def->ntpms; i++) {
+        if (def->tpms[i]->type != VIR_DOMAIN_TPM_TYPE_EMULATOR)
+            continue;
 
-    if (def->tpm->type == VIR_DOMAIN_TPM_TYPE_EMULATOR) {
         shortName = virDomainDefGetShortName(def);
         if (!shortName)
             return -1;
diff --git a/src/security/security_dac.c b/src/security/security_dac.c
index 7b95a6f86d..6201c13f92 100644
--- a/src/security/security_dac.c
+++ b/src/security/security_dac.c
@@ -1979,10 +1979,10 @@ virSecurityDACRestoreAllLabel(virSecurityManagerPtr mgr,
                                &chardevData) < 0)
         rc = -1;
 
-    if (def->tpm) {
+    for (i = 0; i < def->ntpms; i++) {
         if (virSecurityDACRestoreTPMFileLabel(mgr,
                                               def,
-                                              def->tpm) < 0)
+                                              def->tpms[i]) < 0)
             rc = -1;
     }
 
@@ -2158,10 +2158,10 @@ virSecurityDACSetAllLabel(virSecurityManagerPtr mgr,
                                &chardevData) < 0)
         return -1;
 
-    if (def->tpm) {
+    for (i = 0; i < def->ntpms; i++) {
         if (virSecurityDACSetTPMFileLabel(mgr,
                                           def,
-                                          def->tpm) < 0)
+                                          def->tpms[i]) < 0)
             return -1;
     }
 
diff --git a/src/security/security_selinux.c b/src/security/security_selinux.c
index c4c0504b56..7b7c2c12b1 100644
--- a/src/security/security_selinux.c
+++ b/src/security/security_selinux.c
@@ -2764,8 +2764,8 @@ virSecuritySELinuxRestoreAllLabel(virSecurityManagerPtr mgr,
             return -1;
     }
 
-    if (def->tpm) {
-        if (virSecuritySELinuxRestoreTPMFileLabelInt(mgr, def, def->tpm) < 0)
+    for (i = 0; i < def->ntpms; i++) {
+        if (virSecuritySELinuxRestoreTPMFileLabelInt(mgr, def, def->tpms[i]) < 0)
             rc = -1;
     }
 
@@ -3172,8 +3172,8 @@ virSecuritySELinuxSetAllLabel(virSecurityManagerPtr mgr,
             return -1;
     }
 
-    if (def->tpm) {
-        if (virSecuritySELinuxSetTPMFileLabel(mgr, def, def->tpm) < 0)
+    for (i = 0; i < def->ntpms; i++) {
+        if (virSecuritySELinuxSetTPMFileLabel(mgr, def, def->tpms[i]) < 0)
             return -1;
     }
 
@@ -3493,19 +3493,23 @@ virSecuritySELinuxSetTPMLabels(virSecurityManagerPtr mgr,
                                virDomainDefPtr def)
 {
     int ret = 0;
+    size_t i;
     virSecurityLabelDefPtr seclabel;
 
     seclabel = virDomainDefGetSecurityLabelDef(def, SECURITY_SELINUX_NAME);
     if (seclabel == NULL)
         return 0;
 
-    if (def->tpm->type == VIR_DOMAIN_TPM_TYPE_EMULATOR) {
+    for (i = 0; i < def->ntpms; i++) {
+        if (def->tpms[i]->type != VIR_DOMAIN_TPM_TYPE_EMULATOR)
+            continue;
+
         ret = virSecuritySELinuxSetFileLabels(
-            mgr, def->tpm->data.emulator.storagepath,
+            mgr, def->tpms[i]->data.emulator.storagepath,
             seclabel);
-        if (ret == 0 && def->tpm->data.emulator.logfile)
+        if (ret == 0 && def->tpms[i]->data.emulator.logfile)
             ret = virSecuritySELinuxSetFileLabels(
-                mgr, def->tpm->data.emulator.logfile,
+                mgr, def->tpms[i]->data.emulator.logfile,
                 seclabel);
     }
 
@@ -3518,13 +3522,17 @@ virSecuritySELinuxRestoreTPMLabels(virSecurityManagerPtr mgr,
                                    virDomainDefPtr def)
 {
     int ret = 0;
+    size_t i;
+
+    for (i = 0; i < def->ntpms; i++) {
+        if (def->tpms[i]->type != VIR_DOMAIN_TPM_TYPE_EMULATOR)
+            continue;
 
-    if (def->tpm->type == VIR_DOMAIN_TPM_TYPE_EMULATOR) {
         ret = virSecuritySELinuxRestoreFileLabels(
-            mgr, def->tpm->data.emulator.storagepath);
-        if (ret == 0 && def->tpm->data.emulator.logfile)
+            mgr, def->tpms[i]->data.emulator.storagepath);
+        if (ret == 0 && def->tpms[i]->data.emulator.logfile)
             ret = virSecuritySELinuxRestoreFileLabels(
-                mgr, def->tpm->data.emulator.logfile);
+                mgr, def->tpms[i]->data.emulator.logfile);
     }
 
     return ret;
diff --git a/src/security/virt-aa-helper.c b/src/security/virt-aa-helper.c
index 6e8f77e4dd..7abb6e70be 100644
--- a/src/security/virt-aa-helper.c
+++ b/src/security/virt-aa-helper.c
@@ -1206,14 +1206,17 @@ get_files(vahControl * ctl)
     }
 
 
-    if (ctl->def->tpm) {
+    if (ctl->def->ntpms > 0) {
         char *shortName = NULL;
         const char *tpmpath = NULL;
 
-        if (ctl->def->tpm->type == VIR_DOMAIN_TPM_TYPE_EMULATOR) {
+        for (i = 0; i < ctl->def->ntpms; i++) {
+            if (ctl->def->tpms[i]->type != VIR_DOMAIN_TPM_TYPE_EMULATOR)
+                continue;
+
             shortName = virDomainDefGetShortName(ctl->def);
 
-            switch (ctl->def->tpm->version) {
+            switch (ctl->def->tpms[i]->version) {
             case VIR_DOMAIN_TPM_VERSION_1_2:
                 tpmpath = "tpm1.2";
                 break;
diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c
index 7c4b4e2134..5a4ac187ef 100644
--- a/tests/qemuxml2argvtest.c
+++ b/tests/qemuxml2argvtest.c
@@ -437,12 +437,13 @@ testCompareXMLToArgvCreateArgs(virQEMUDriverPtr drv,
         vsockPriv->vhostfd = 6789;
     }
 
-    if (vm->def->tpm) {
-        if (vm->def->tpm->type == VIR_DOMAIN_TPM_TYPE_EMULATOR) {
-            VIR_FREE(vm->def->tpm->data.emulator.source.data.file.path);
-            vm->def->tpm->data.emulator.source.data.file.path = g_strdup("/dev/test");
-            vm->def->tpm->data.emulator.source.type = VIR_DOMAIN_CHR_TYPE_FILE;
-       }
+    for (i = 0; i < vm->def->ntpms; i++) {
+        if (vm->def->tpms[i]->type != VIR_DOMAIN_TPM_TYPE_EMULATOR)
+            continue;
+
+        VIR_FREE(vm->def->tpms[i]->data.emulator.source.data.file.path);
+        vm->def->tpms[i]->data.emulator.source.data.file.path = g_strdup("/dev/test");
+        vm->def->tpms[i]->data.emulator.source.type = VIR_DOMAIN_CHR_TYPE_FILE;
     }
 
     for (i = 0; i < vm->def->nvideos; i++) {
-- 
2.26.2




More information about the libvir-list mailing list