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 ef083d4d4d..e0855a2476 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]); @@ -4315,10 +4318,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; @@ -22069,15 +22072,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); @@ -24461,16 +24472,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 " @@ -29917,8 +29931,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 bfafd36be3..6a737591e2 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; @@ -2628,11 +2629,14 @@ struct _virDomainDef { size_t nsysinfo; virSysinfoDefPtr *sysinfo; + /* 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; virDomainRedirFilterDefPtr redirfilter; virDomainIOMMUDefPtr iommu; diff --git a/src/qemu/qemu_alias.c b/src/qemu/qemu_alias.c index d6527cb046..101ab5608f 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], i) < 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 e2cbdf0925..59c6c7253b 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -8954,10 +8954,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", @@ -8996,13 +8996,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; @@ -9056,6 +9055,7 @@ qemuBuildTPMBackendStr(const virDomainDef *def, static int qemuBuildTPMCommandLine(virCommandPtr cmd, const virDomainDef *def, + virDomainTPMDefPtr tpm, virQEMUCapsPtr qemuCaps) { char *optstr; @@ -9064,10 +9064,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; @@ -9096,7 +9093,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); @@ -9105,6 +9102,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) @@ -9787,7 +9801,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 2375b0de35..b2f0d4afda 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -11623,16 +11623,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, @@ -11646,7 +11639,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; } @@ -11872,7 +11883,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; - if (tpm->type == VIR_DOMAIN_TPM_TYPE_EMULATOR) - return qemuExtTPMStartEmulator(driver, vm, incomingMigration); + for (i = 0; i < vm->def->ntpms; i++) { + if (vm->def->tpms[i]->type != VIR_DOMAIN_TPM_TYPE_EMULATOR) + continue; + + 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 afc0a9fcb9..23fe351a32 100644 --- a/src/security/security_dac.c +++ b/src/security/security_dac.c @@ -1997,10 +1997,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; } @@ -2203,10 +2203,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 a16de2466d..f8c1a0a2f1 100644 --- a/src/security/security_selinux.c +++ b/src/security/security_selinux.c @@ -2780,8 +2780,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; } @@ -3183,8 +3183,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; } @@ -3526,19 +3526,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); } @@ -3551,13 +3555,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 7e8f0a84be..08eb162b8c 100644 --- a/src/security/virt-aa-helper.c +++ b/src/security/virt-aa-helper.c @@ -1218,14 +1218,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 7d7aff77ef..cc9e6d9666 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++) {