From nobody Tue Nov 26 00:59:28 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of redhat.com designates 205.139.110.120 as permitted sender) client-ip=205.139.110.120; envelope-from=libvir-list-bounces@redhat.com; helo=us-smtp-1.mimecast.com; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of redhat.com designates 205.139.110.120 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; dmarc=fail(p=none dis=none) header.from=gmail.com ARC-Seal: i=1; a=rsa-sha256; t=1589581564; cv=none; d=zohomail.com; s=zohoarc; b=C+Tw5nSY/1FlZfCQMfG6Jx6TAGlSRY2iZYgNW1+TSTIulwEIEiFyM/lMETw3o2m5a9z2NiHV+IVojtvCcqrqGaX1VbmxLAgcGRY/xn9/etXAkInB3xnfj5ni6QJ1helLSzTbhxOV7pfPxJwKNTIklprhcKWRCp3erz2XtcbS8r0= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1589581564; h=Content-Type:Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=ICwrA2donf5ZtAWVd6CcyrRc7rDs/ShAoM23ofN7CLw=; b=GohAEvlLcZpbJ9EW5SzQaoRVbvc2ZQuM9GrEaM+PiLW0+SAao/TPXEloBLg7S2LW+fBBtCvyE8UtQk3yktTAGhcXcg7dk83iXMpryit1aHE6XfmxxX7iju1cPoBN1KROfHICHFT4a/kqY0joK0/tfi/5g9A/P/BGlr22DZhruEo= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of redhat.com designates 205.139.110.120 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; dmarc=fail header.from= (p=none dis=none) header.from= Return-Path: Received: from us-smtp-1.mimecast.com (us-smtp-delivery-1.mimecast.com [205.139.110.120]) by mx.zohomail.com with SMTPS id 1589581564297487.2042967062115; Fri, 15 May 2020 15:26:04 -0700 (PDT) Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-204-0vlgxIWyMLeNEdAZMbOtJQ-1; Fri, 15 May 2020 18:25:31 -0400 Received: from smtp.corp.redhat.com (int-mx08.intmail.prod.int.phx2.redhat.com [10.5.11.23]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id ACBE791140; Fri, 15 May 2020 22:25:23 +0000 (UTC) Received: from colo-mx.corp.redhat.com (colo-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.21]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 8AD6B2DE74; Fri, 15 May 2020 22:25:23 +0000 (UTC) Received: from lists01.pubmisc.prod.ext.phx2.redhat.com (lists01.pubmisc.prod.ext.phx2.redhat.com [10.5.19.33]) by colo-mx.corp.redhat.com (Postfix) with ESMTP id 5C94A4EA05; Fri, 15 May 2020 22:25:23 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx04.intmail.prod.int.rdu2.redhat.com [10.11.54.4]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id 04FMPGtA015298 for ; Fri, 15 May 2020 18:25:16 -0400 Received: by smtp.corp.redhat.com (Postfix) id 305E9200A773; Fri, 15 May 2020 22:25:16 +0000 (UTC) Received: from mimecast-mx02.redhat.com (mimecast01.extmail.prod.ext.rdu2.redhat.com [10.11.55.17]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 2B44820110C8 for ; Fri, 15 May 2020 22:25:16 +0000 (UTC) Received: from us-smtp-1.mimecast.com (us-smtp-2.mimecast.com [205.139.110.61]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-SHA384 (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id 057BD8A19E1 for ; Fri, 15 May 2020 22:25:16 +0000 (UTC) Received: from mail-qk1-f195.google.com (mail-qk1-f195.google.com [209.85.222.195]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-326-FBlzPg9FOQulHZj0d8J-4w-1; Fri, 15 May 2020 18:25:11 -0400 Received: by mail-qk1-f195.google.com with SMTP id b6so4273870qkh.11; Fri, 15 May 2020 15:25:11 -0700 (PDT) Received: from rekt.ibmuc.com ([2804:431:c7c7:fbf2:bc5e:c314:af31:7070]) by smtp.gmail.com with ESMTPSA id o18sm3181386qtb.7.2020.05.15.15.25.08 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 15 May 2020 15:25:09 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1589581562; h=from:from:sender:sender:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references:list-id:list-help: list-unsubscribe:list-subscribe:list-post; bh=ICwrA2donf5ZtAWVd6CcyrRc7rDs/ShAoM23ofN7CLw=; b=WqlF7+e9wuH/tjKidYR2S7w2LOB2Yy+mcDfgbLQw4LGKawZHZXsS07ISZxWolM4OzZ+Bgs 8OeBbPezNyDvC8UrI9venIcEwZ63orMuuvXqxgFY2pTkYXLqnbD8x354xJNemEV7HVmBhW Dms1++A9ot02QSXgQ4Gwwk1nV7UTAxU= X-MC-Unique: 0vlgxIWyMLeNEdAZMbOtJQ-1 X-MC-Unique: FBlzPg9FOQulHZj0d8J-4w-1 X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=ICwrA2donf5ZtAWVd6CcyrRc7rDs/ShAoM23ofN7CLw=; b=lXZK62yCTlwgv1DEddaeFSb1ysaoadqadOUqkeJSIWqemEtJ2g8SUAZSD571PygJB1 2TvLTX9MfjwEHsRb7LK+EPHc79E7ctpZlENJXwJs7adgfoBQ0Q8mh1sOUxynsvj0W8W2 JjV6ULH3v6tGFJ/cM5XulZkemNr/kw5DRukNs2ut+OXfUgfAbBoxDOLdHFgEHNYViabb G+gDBXqk6CtFwHniaYm7B8RVhWAUB/+C1XqxzKFCvlmDygLwr82HV76+WrMY8xNUUJ3C z0J4+vPe+E/F4p76qfG8/MwnHWeKC4P0IgiToO2c6QaqmGRzLQ88Yx8TgTtTq/E/SpK0 Nr0Q== X-Gm-Message-State: AOAM533g0C5/bl1rYC9y76gkMJ7PgwpxPjP1ySCjroZL5gFs/mJAk9RJ jEHssdqceYTB87pIR9eTGL8c9d35 X-Google-Smtp-Source: ABdhPJwnmLEY362WBIjF308QJzbsXK5QLnPCLfOVXsSmDfCPM1Rk9wa3+DMptouKSwLv2CZGamoNMA== X-Received: by 2002:ae9:dcc2:: with SMTP id q185mr5603487qkf.239.1589581510239; Fri, 15 May 2020 15:25:10 -0700 (PDT) From: Daniel Henrique Barboza To: libvir-list@redhat.com Subject: [PATCH v4 05/10] conf, qemu, security, tests: introducing 'def->tpms' array Date: Fri, 15 May 2020 19:24:08 -0300 Message-Id: <20200515222413.1231605-6-danielhb413@gmail.com> In-Reply-To: <20200515222413.1231605-1-danielhb413@gmail.com> References: <20200515222413.1231605-1-danielhb413@gmail.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.78 on 10.11.54.4 X-loop: libvir-list@redhat.com Cc: Daniel Henrique Barboza , stefanb@linux.ibm.com, jtomko@redhat.com, david@gibson.dropbear.id.au X-BeenThere: libvir-list@redhat.com X-Mailman-Version: 2.1.12 Precedence: junk List-Id: Development discussions about the libvirt library & tools List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: libvir-list-bounces@redhat.com Errors-To: libvir-list-bounces@redhat.com X-Scanned-By: MIMEDefang 2.84 on 10.5.11.23 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @redhat.com) Content-Type: text/plain; charset="utf-8" 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 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 Signed-off-by: Daniel Henrique Barboza --- src/conf/domain_audit.c | 4 +- src/conf/domain_conf.c | 72 ++++++++++++++++++++++++--------- 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, 208 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 *rea= son, bool success) for (i =3D 0; i < vm->def->nrngs; i++) virDomainAuditRNG(vm, NULL, vm->def->rngs[i], "start", true); =20 - if (vm->def->tpm) - virDomainAuditTPM(vm, vm->def->tpm, "start", true); + for (i =3D 0; i < vm->def->ntpms; i++) + virDomainAuditTPM(vm, vm->def->tpms[i], "start", true); =20 for (i =3D 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 c201fc901d..f8fee62c0c 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", ); =20 VIR_ENUM_IMPL(virDomainTPMBackend, @@ -3479,7 +3480,9 @@ void virDomainDefFree(virDomainDefPtr def) virDomainMemoryDefFree(def->mems[i]); VIR_FREE(def->mems); =20 - virDomainTPMDefFree(def->tpm); + for (i =3D 0; i < def->ntpms; i++) + virDomainTPMDefFree(def->tpms[i]); + VIR_FREE(def->tpms); =20 for (i =3D 0; i < def->npanics; i++) virDomainPanicDefFree(def->panics[i]); @@ -4312,10 +4315,10 @@ virDomainDeviceInfoIterateInternal(virDomainDefPtr = def, if ((rc =3D cb(def, &device, &def->shmems[i]->info, opaque)) !=3D = 0) return rc; } - if (def->tpm) { - device.type =3D VIR_DOMAIN_DEVICE_TPM; - device.data.tpm =3D def->tpm; - if ((rc =3D cb(def, &device, &def->tpm->info, opaque)) !=3D 0) + device.type =3D VIR_DOMAIN_DEVICE_TPM; + for (i =3D 0; i < def->ntpms; i++) { + device.data.tpm =3D def->tpms[i]; + if ((rc =3D cb(def, &device, &def->tpms[i]->info, opaque)) !=3D 0) return rc; } device.type =3D VIR_DOMAIN_DEVICE_PANIC; @@ -21964,15 +21967,45 @@ virDomainDefParseXML(xmlDocPtr xml, if ((n =3D virXPathNodeSet("./devices/tpm", ctxt, &nodes)) < 0) goto error; =20 - 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 o= f " + "them being a TPM Proxy device")); goto error; } =20 + if (n && VIR_ALLOC_N(def->tpms, n) < 0) + goto error; + if (n > 0) { - if (!(def->tpm =3D virDomainTPMDefParseXML(xmlopt, nodes[0], ctxt,= flags))) - goto error; + virDomainTPMDefPtr proxyTPM =3D NULL; + virDomainTPMDefPtr regularTPM =3D NULL; + + for (i =3D 0; i < n; i++) { + virDomainTPMDefPtr tpm =3D virDomainTPMDefParseXML(xmlopt, nod= es[i], + ctxt, flags); + + if (!tpm) + goto error; + + if (tpm->model =3D=3D VIR_DOMAIN_TPM_MODEL_SPAPR_PROXY) { + if (proxyTPM) { + virReportError(VIR_ERR_XML_ERROR, "%s", + _("only a single TPM Proxy device is sup= ported")); + goto error; + } else { + proxyTPM =3D tpm; + } + } else if (regularTPM) { + virReportError(VIR_ERR_XML_ERROR, "%s", + _("only a single TPM non-proxy device is su= pported")); + goto error; + } else { + regularTPM =3D tpm; + } + + def->tpms[def->ntpms++] =3D tpm; + } } VIR_FREE(nodes); =20 @@ -24334,16 +24367,19 @@ virDomainDefCheckABIStabilityFlags(virDomainDefPt= r src, goto error; } =20 - 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 !=3D dst->ntpms) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("Target domain TPM device count %zu " + "does not match source %zu"), + dst->ntpms, src->ntpms); goto error; } =20 + for (i =3D 0; i < src->ntpms; i++) { + if (!virDomainTPMDefCheckABIStability(src->tpms[i], dst->tpms[i])) + goto error; + } + if (src->nmems !=3D dst->nmems) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, _("Target domain memory device count %zu " @@ -29784,8 +29820,8 @@ virDomainDefFormatInternalSetRootName(virDomainDefP= tr def, goto error; } =20 - if (def->tpm) { - if (virDomainTPMDefFormat(buf, def->tpm, flags) < 0) + for (n =3D 0; n < def->ntpms; n++) { + if (virDomainTPMDefFormat(buf, def->tpms[n], flags) < 0) goto error; } =20 diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index ddc75d8de2..32ae272cac 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -1293,6 +1293,7 @@ typedef enum { VIR_DOMAIN_TPM_MODEL_TIS, VIR_DOMAIN_TPM_MODEL_CRB, VIR_DOMAIN_TPM_MODEL_SPAPR, + VIR_DOMAIN_TPM_MODEL_SPAPR_PROXY, =20 VIR_DOMAIN_TPM_MODEL_LAST } virDomainTPMModel; @@ -2623,11 +2624,14 @@ struct _virDomainDef { size_t npanics; virDomainPanicDefPtr *panics; =20 + /* 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 b0ea62af39..9d72391ddb 100644 --- a/src/qemu/qemu_alias.c +++ b/src/qemu/qemu_alias.c @@ -669,8 +669,8 @@ qemuAssignDeviceAliases(virDomainDefPtr def, virQEMUCap= sPtr qemuCaps) if (qemuAssignDeviceRNGAlias(def, def->rngs[i]) < 0) return -1; } - if (def->tpm) { - if (qemuAssignDeviceTPMAlias(def->tpm, 0) < 0) + for (i =3D 0; i < def->ntpms; i++) { + if (qemuAssignDeviceTPMAlias(def->tpms[i], 0) < 0) return -1; } for (i =3D 0; i < def->nmems; i++) { diff --git a/src/qemu/qemu_cgroup.c b/src/qemu/qemu_cgroup.c index 2e019b64af..647609e12e 100644 --- a/src/qemu/qemu_cgroup.c +++ b/src/qemu/qemu_cgroup.c @@ -333,10 +333,10 @@ qemuSetupChardevCgroupCB(virDomainDefPtr def G_GNUC_U= NUSED, =20 =20 static int -qemuSetupTPMCgroup(virDomainObjPtr vm) +qemuSetupTPMCgroup(virDomainObjPtr vm, + virDomainTPMDefPtr dev) { int ret =3D 0; - virDomainTPMDefPtr dev =3D vm->def->tpm; =20 switch (dev->type) { case VIR_DOMAIN_TPM_TYPE_PASSTHROUGH: @@ -806,8 +806,10 @@ qemuSetupDevicesCgroup(virDomainObjPtr vm) vm) < 0) return -1; =20 - if (vm->def->tpm && qemuSetupTPMCgroup(vm) < 0) - return -1; + for (i =3D 0; i < vm->def->ntpms; i++) { + if (qemuSetupTPMCgroup(vm, vm->def->tpms[i]) < 0) + return -1; + } =20 for (i =3D 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 bfe70ed228..d2ac19a7a8 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -8830,10 +8830,10 @@ qemuBuildDomainLoaderCommandLine(virCommandPtr cmd, =20 static char * qemuBuildTPMDevStr(const virDomainDef *def, + virDomainTPMDefPtr tpm, virQEMUCapsPtr qemuCaps) { g_auto(virBuffer) buf =3D VIR_BUFFER_INITIALIZER; - virDomainTPMDef *tpm =3D def->tpm; const char *model =3D virDomainTPMModelTypeToString(tpm->model); =20 virBufferAsprintf(&buf, "%s,tpmdev=3Dtpm-%s,id=3D%s", @@ -8872,13 +8872,12 @@ qemuBuildTPMOpenBackendFDs(const char *tpmdev, =20 =20 static char * -qemuBuildTPMBackendStr(const virDomainDef *def, - virCommandPtr cmd, +qemuBuildTPMBackendStr(virCommandPtr cmd, + virDomainTPMDefPtr tpm, int *tpmfd, int *cancelfd, char **chardev) { - const virDomainTPMDef *tpm =3D def->tpm; g_auto(virBuffer) buf =3D VIR_BUFFER_INITIALIZER; g_autofree char *cancel_path =3D NULL; g_autofree char *devset =3D NULL; @@ -8932,6 +8931,7 @@ qemuBuildTPMBackendStr(const virDomainDef *def, static int qemuBuildTPMCommandLine(virCommandPtr cmd, const virDomainDef *def, + virDomainTPMDefPtr tpm, virQEMUCapsPtr qemuCaps) { char *optstr; @@ -8940,10 +8940,7 @@ qemuBuildTPMCommandLine(virCommandPtr cmd, int cancelfd =3D -1; char *fdset; =20 - if (!def->tpm) - return 0; - - if (!(optstr =3D qemuBuildTPMBackendStr(def, cmd, + if (!(optstr =3D qemuBuildTPMBackendStr(cmd, tpm, &tpmfd, &cancelfd, &chardev))) return -1; @@ -8972,7 +8969,7 @@ qemuBuildTPMCommandLine(virCommandPtr cmd, VIR_FREE(fdset); } =20 - if (!(optstr =3D qemuBuildTPMDevStr(def, qemuCaps))) + if (!(optstr =3D qemuBuildTPMDevStr(def, tpm, qemuCaps))) return -1; =20 virCommandAddArgList(cmd, "-device", optstr, NULL); @@ -8981,6 +8978,23 @@ qemuBuildTPMCommandLine(virCommandPtr cmd, return 0; } =20 + +static int +qemuBuildTPMsCommandLine(virCommandPtr cmd, + const virDomainDef *def, + virQEMUCapsPtr qemuCaps) +{ + size_t i; + + for (i =3D 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) @@ -9659,7 +9673,7 @@ qemuBuildCommandLine(virQEMUDriverPtr driver, chardevStdioLogd) < 0) return NULL; =20 - if (qemuBuildTPMCommandLine(cmd, def, qemuCaps) < 0) + if (qemuBuildTPMsCommandLine(cmd, def, qemuCaps) < 0) return NULL; =20 if (qemuBuildInputCommandLine(cmd, def, qemuCaps) < 0) diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c index d0528dbfe0..2f30633eac 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -11575,16 +11575,9 @@ qemuDomainSetupAllChardevs(virQEMUDriverConfigPtr = cfg G_GNUC_UNUSED, =20 static int qemuDomainSetupTPM(virQEMUDriverConfigPtr cfg G_GNUC_UNUSED, - virDomainObjPtr vm, + virDomainTPMDefPtr dev, const struct qemuDomainCreateDeviceData *data) { - virDomainTPMDefPtr dev =3D 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, @@ -11598,7 +11591,25 @@ qemuDomainSetupTPM(virQEMUDriverConfigPtr cfg G_GN= UC_UNUSED, break; } =20 - 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 =3D 0; i < vm->def->ntpms; i++) { + if (qemuDomainSetupTPM(cfg, vm->def->tpms[i], data) < 0) + return -1; + } + + VIR_DEBUG("Setup all TPMs"); return 0; } =20 @@ -11824,7 +11835,7 @@ qemuDomainBuildNamespace(virQEMUDriverConfigPtr cfg, if (qemuDomainSetupAllChardevs(cfg, vm, &data) < 0) goto cleanup; =20 - if (qemuDomainSetupTPM(cfg, vm, &data) < 0) + if (qemuDomainSetupAllTPMs(cfg, vm, &data) < 0) goto cleanup; =20 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; } =20 - if (def->tpm) { - if (qemuDomainIsPSeries(def)) - def->tpm->info.type =3D VIR_DOMAIN_DEVICE_ADDRESS_TYPE_SPAPRVI= O; - if (qemuDomainAssignSpaprVIOAddress(def, &def->tpm->info, + for (i =3D 0; i < def->ntpms; i++) { + virDomainTPMDefPtr tpm =3D def->tpms[i]; + + if (tpm->model !=3D VIR_DOMAIN_TPM_MODEL_SPAPR_PROXY && + qemuDomainIsPSeries(def)) + tpm->info.type =3D 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 2ff3f68f5d..db18c82640 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); =20 return 0; @@ -132,7 +132,7 @@ qemuExtDevicesPrepareHost(virQEMUDriverPtr driver, virDomainDefPtr def =3D vm->def; size_t i; =20 - if (def->tpm && + if (def->ntpms > 0 && qemuExtTPMPrepareHost(driver, def) < 0) return -1; =20 @@ -155,7 +155,7 @@ qemuExtDevicesCleanupHost(virQEMUDriverPtr driver, if (qemuExtDevicesInitPaths(driver, def) < 0) return; =20 - if (def->tpm) + if (def->ntpms > 0) qemuExtTPMCleanupHost(def); } =20 @@ -181,7 +181,7 @@ qemuExtDevicesStart(virQEMUDriverPtr driver, } } =20 - if (def->tpm && qemuExtTPMStart(driver, vm, incomingMigration) < 0) + if (def->ntpms > 0 && qemuExtTPMStart(driver, vm, incomingMigration) <= 0) return -1; =20 for (i =3D 0; i < def->nnets; i++) { @@ -223,7 +223,7 @@ qemuExtDevicesStop(virQEMUDriverPtr driver, qemuExtVhostUserGPUStop(driver, vm, video); } =20 - if (def->tpm) + if (def->ntpms > 0) qemuExtTPMStop(driver, vm); =20 for (i =3D 0; i < def->nnets; i++) { @@ -253,8 +253,10 @@ qemuExtDevicesHasDevice(virDomainDefPtr def) return true; } =20 - if (def->tpm && def->tpm->type =3D=3D VIR_DOMAIN_TPM_TYPE_EMULATOR) - return true; + for (i =3D 0; i < def->ntpms; i++) { + if (def->tpms[i]->type =3D=3D VIR_DOMAIN_TPM_TYPE_EMULATOR) + return true; + } =20 for (i =3D 0; i < def->nfss; i++) { virDomainFSDefPtr fs =3D def->fss[i]; @@ -294,7 +296,7 @@ qemuExtDevicesSetupCgroup(virQEMUDriverPtr driver, return -1; } =20 - if (def->tpm && + if (def->ntpms > 0 && qemuExtTPMSetupCgroup(driver, def, cgroup) < 0) return -1; =20 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 =3D virQEMUDriverGetConfig(driver); + size_t i; =20 - if (def->tpm->type =3D=3D VIR_DOMAIN_TPM_TYPE_EMULATOR) - return qemuTPMEmulatorInitPaths(def->tpm, cfg->swtpmStorageDir, + for (i =3D 0; i < def->ntpms; i++) { + if (def->tpms[i]->type !=3D VIR_DOMAIN_TPM_TYPE_EMULATOR) + continue; + + return qemuTPMEmulatorInitPaths(def->tpms[i], cfg->swtpmStorageDir, def->uuid); + } =20 return 0; } @@ -694,13 +699,17 @@ qemuExtTPMPrepareHost(virQEMUDriverPtr driver, { g_autoptr(virQEMUDriverConfig) cfg =3D virQEMUDriverGetConfig(driver); g_autofree char *shortName =3D NULL; + size_t i; + + for (i =3D 0; i < def->ntpms; i++) { + if (def->tpms[i]->type !=3D VIR_DOMAIN_TPM_TYPE_EMULATOR) + continue; =20 - if (def->tpm->type =3D=3D VIR_DOMAIN_TPM_TYPE_EMULATOR) { shortName =3D virDomainDefGetShortName(def); if (!shortName) return -1; =20 - 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 =3D=3D VIR_DOMAIN_TPM_TYPE_EMULATOR) - qemuTPMDeleteEmulatorStorage(def->tpm); + size_t i; + + for (i =3D 0; i < def->ntpms; i++) { + if (def->tpms[i]->type !=3D VIR_DOMAIN_TPM_TYPE_EMULATOR) + continue; + + qemuTPMDeleteEmulatorStorage(def->tpms[i]); + } } =20 =20 @@ -733,13 +748,13 @@ qemuExtTPMCleanupHost(virDomainDefPtr def) static int qemuExtTPMStartEmulator(virQEMUDriverPtr driver, virDomainObjPtr vm, + virDomainTPMDefPtr tpm, bool incomingMigration) { g_autoptr(virCommand) cmd =3D NULL; int exitstatus =3D 0; g_autofree char *errbuf =3D NULL; g_autoptr(virQEMUDriverConfig) cfg =3D NULL; - virDomainTPMDefPtr tpm =3D vm->def->tpm; g_autofree char *shortName =3D virDomainDefGetShortName(vm->def); int cmdret =3D 0, timeout, rc; pid_t pid; @@ -807,10 +822,15 @@ qemuExtTPMStart(virQEMUDriverPtr driver, virDomainObjPtr vm, bool incomingMigration) { - virDomainTPMDefPtr tpm =3D vm->def->tpm; + size_t i; + + for (i =3D 0; i < vm->def->ntpms; i++) { + if (vm->def->tpms[i]->type !=3D VIR_DOMAIN_TPM_TYPE_EMULATOR) + continue; =20 - if (tpm->type =3D=3D VIR_DOMAIN_TPM_TYPE_EMULATOR) - return qemuExtTPMStartEmulator(driver, vm, incomingMigration); + return qemuExtTPMStartEmulator(driver, vm, vm->def->tpms[i], + incomingMigration); + } =20 return 0; } @@ -822,8 +842,12 @@ qemuExtTPMStop(virQEMUDriverPtr driver, { g_autoptr(virQEMUDriverConfig) cfg =3D virQEMUDriverGetConfig(driver); g_autofree char *shortName =3D NULL; + size_t i; + + for (i =3D 0; i < vm->def->ntpms; i++) { + if (vm->def->tpms[i]->type !=3D VIR_DOMAIN_TPM_TYPE_EMULATOR) + continue; =20 - if (vm->def->tpm->type =3D=3D VIR_DOMAIN_TPM_TYPE_EMULATOR) { shortName =3D virDomainDefGetShortName(vm->def); if (!shortName) return; @@ -845,8 +869,12 @@ qemuExtTPMSetupCgroup(virQEMUDriverPtr driver, g_autofree char *shortName =3D NULL; int rc; pid_t pid; + size_t i; + + for (i =3D 0; i < def->ntpms; i++) { + if (def->tpms[i]->type !=3D VIR_DOMAIN_TPM_TYPE_EMULATOR) + continue; =20 - if (def->tpm->type =3D=3D VIR_DOMAIN_TPM_TYPE_EMULATOR) { shortName =3D virDomainDefGetShortName(def); if (!shortName) return -1; diff --git a/src/security/security_dac.c b/src/security/security_dac.c index bdc2d7edf3..79123f384c 100644 --- a/src/security/security_dac.c +++ b/src/security/security_dac.c @@ -1973,10 +1973,10 @@ virSecurityDACRestoreAllLabel(virSecurityManagerPtr= mgr, &chardevData) < 0) rc =3D -1; =20 - if (def->tpm) { + for (i =3D 0; i < def->ntpms; i++) { if (virSecurityDACRestoreTPMFileLabel(mgr, def, - def->tpm) < 0) + def->tpms[i]) < 0) rc =3D -1; } =20 @@ -2152,10 +2152,10 @@ virSecurityDACSetAllLabel(virSecurityManagerPtr mgr, &chardevData) < 0) return -1; =20 - if (def->tpm) { + for (i =3D 0; i < def->ntpms; i++) { if (virSecurityDACSetTPMFileLabel(mgr, def, - def->tpm) < 0) + def->tpms[i]) < 0) return -1; } =20 diff --git a/src/security/security_selinux.c b/src/security/security_selinu= x.c index 914a252df1..39928aef3e 100644 --- a/src/security/security_selinux.c +++ b/src/security/security_selinux.c @@ -2758,8 +2758,8 @@ virSecuritySELinuxRestoreAllLabel(virSecurityManagerP= tr mgr, return -1; } =20 - if (def->tpm) { - if (virSecuritySELinuxRestoreTPMFileLabelInt(mgr, def, def->tpm) <= 0) + for (i =3D 0; i < def->ntpms; i++) { + if (virSecuritySELinuxRestoreTPMFileLabelInt(mgr, def, def->tpms[i= ]) < 0) rc =3D -1; } =20 @@ -3166,8 +3166,8 @@ virSecuritySELinuxSetAllLabel(virSecurityManagerPtr m= gr, return -1; } =20 - if (def->tpm) { - if (virSecuritySELinuxSetTPMFileLabel(mgr, def, def->tpm) < 0) + for (i =3D 0; i < def->ntpms; i++) { + if (virSecuritySELinuxSetTPMFileLabel(mgr, def, def->tpms[i]) < 0) return -1; } =20 @@ -3487,19 +3487,23 @@ virSecuritySELinuxSetTPMLabels(virSecurityManagerPt= r mgr, virDomainDefPtr def) { int ret =3D 0; + size_t i; virSecurityLabelDefPtr seclabel; =20 seclabel =3D virDomainDefGetSecurityLabelDef(def, SECURITY_SELINUX_NAM= E); if (seclabel =3D=3D NULL) return 0; =20 - if (def->tpm->type =3D=3D VIR_DOMAIN_TPM_TYPE_EMULATOR) { + for (i =3D 0; i < def->ntpms; i++) { + if (def->tpms[i]->type !=3D VIR_DOMAIN_TPM_TYPE_EMULATOR) + continue; + ret =3D virSecuritySELinuxSetFileLabels( - mgr, def->tpm->data.emulator.storagepath, + mgr, def->tpms[i]->data.emulator.storagepath, seclabel); - if (ret =3D=3D 0 && def->tpm->data.emulator.logfile) + if (ret =3D=3D 0 && def->tpms[i]->data.emulator.logfile) ret =3D virSecuritySELinuxSetFileLabels( - mgr, def->tpm->data.emulator.logfile, + mgr, def->tpms[i]->data.emulator.logfile, seclabel); } =20 @@ -3512,13 +3516,17 @@ virSecuritySELinuxRestoreTPMLabels(virSecurityManag= erPtr mgr, virDomainDefPtr def) { int ret =3D 0; + size_t i; + + for (i =3D 0; i < def->ntpms; i++) { + if (def->tpms[i]->type !=3D VIR_DOMAIN_TPM_TYPE_EMULATOR) + continue; =20 - if (def->tpm->type =3D=3D VIR_DOMAIN_TPM_TYPE_EMULATOR) { ret =3D virSecuritySELinuxRestoreFileLabels( - mgr, def->tpm->data.emulator.storagepath); - if (ret =3D=3D 0 && def->tpm->data.emulator.logfile) + mgr, def->tpms[i]->data.emulator.storagepath); + if (ret =3D=3D 0 && def->tpms[i]->data.emulator.logfile) ret =3D virSecuritySELinuxRestoreFileLabels( - mgr, def->tpm->data.emulator.logfile); + mgr, def->tpms[i]->data.emulator.logfile); } =20 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) } =20 =20 - if (ctl->def->tpm) { + if (ctl->def->ntpms > 0) { char *shortName =3D NULL; const char *tpmpath =3D NULL; =20 - if (ctl->def->tpm->type =3D=3D VIR_DOMAIN_TPM_TYPE_EMULATOR) { + for (i =3D 0; i < ctl->def->ntpms; i++) { + if (ctl->def->tpms[i]->type !=3D VIR_DOMAIN_TPM_TYPE_EMULATOR) + continue; + shortName =3D virDomainDefGetShortName(ctl->def); =20 - switch (ctl->def->tpm->version) { + switch (ctl->def->tpms[i]->version) { case VIR_DOMAIN_TPM_VERSION_1_2: tpmpath =3D "tpm1.2"; break; diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c index fd060bec4e..e5f129ea4c 100644 --- a/tests/qemuxml2argvtest.c +++ b/tests/qemuxml2argvtest.c @@ -514,12 +514,13 @@ testCompareXMLToArgv(const void *data) vsockPriv->vhostfd =3D 6789; } =20 - if (vm->def->tpm) { - if (vm->def->tpm->type =3D=3D 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 =3D g_strdup= ("/dev/test"); - vm->def->tpm->data.emulator.source.type =3D VIR_DOMAIN_CHR_TYP= E_FILE; - } + for (i =3D 0; i < vm->def->ntpms; i++) { + if (vm->def->tpms[i]->type !=3D 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 =3D g_strdup= ("/dev/test"); + vm->def->tpms[i]->data.emulator.source.type =3D VIR_DOMAIN_CHR_TYP= E_FILE; } =20 for (i =3D 0; i < vm->def->nvideos; i++) { --=20 2.26.2