From nobody Sat May 4 12:08:07 2024 Delivered-To: importer@patchew.org Received-SPF: temperror (zoho.com: Error in retrieving data from DNS) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=temperror (zoho.com: Error in retrieving data from DNS) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (208.118.235.17 [208.118.235.17]) by mx.zohomail.com with SMTPS id 1507757989773400.4232997677441; Wed, 11 Oct 2017 14:39:49 -0700 (PDT) Received: from localhost ([::1]:42756 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1e2Oiz-0004HU-GD for importer@patchew.org; Wed, 11 Oct 2017 17:39:33 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:34227) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1e2OhN-0003TV-U6 for qemu-devel@nongnu.org; Wed, 11 Oct 2017 17:37:54 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1e2OhJ-0003c5-0I for qemu-devel@nongnu.org; Wed, 11 Oct 2017 17:37:53 -0400 Received: from mx0b-001b2d01.pphosted.com ([148.163.158.5]:46346 helo=mx0a-001b2d01.pphosted.com) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1e2OhI-0003bo-Qg for qemu-devel@nongnu.org; Wed, 11 Oct 2017 17:37:48 -0400 Received: from pps.filterd (m0098416.ppops.net [127.0.0.1]) by mx0b-001b2d01.pphosted.com (8.16.0.21/8.16.0.21) with SMTP id v9BLYv0Y021849 for ; Wed, 11 Oct 2017 17:37:45 -0400 Received: from e18.ny.us.ibm.com (e18.ny.us.ibm.com [129.33.205.208]) by mx0b-001b2d01.pphosted.com with ESMTP id 2dhrsyxdj3-1 (version=TLSv1.2 cipher=AES256-SHA bits=256 verify=NOT) for ; Wed, 11 Oct 2017 17:37:44 -0400 Received: from localhost by e18.ny.us.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Wed, 11 Oct 2017 17:37:44 -0400 Received: from b01cxnp23032.gho.pok.ibm.com (9.57.198.27) by e18.ny.us.ibm.com (146.89.104.205) with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted; Wed, 11 Oct 2017 17:37:42 -0400 Received: from b01ledav002.gho.pok.ibm.com (b01ledav002.gho.pok.ibm.com [9.57.199.107]) by b01cxnp23032.gho.pok.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id v9BLbfWw36831282; Wed, 11 Oct 2017 21:37:41 GMT Received: from b01ledav002.gho.pok.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id C95C0124037; Wed, 11 Oct 2017 17:34:53 -0400 (EDT) Received: from sbct-3.watson.ibm.com (unknown [9.47.158.153]) by b01ledav002.gho.pok.ibm.com (Postfix) with ESMTP id B387B124035; Wed, 11 Oct 2017 17:34:53 -0400 (EDT) From: Stefan Berger To: qemu-devel@nongnu.org Date: Wed, 11 Oct 2017 17:37:28 -0400 X-Mailer: git-send-email 2.5.5 In-Reply-To: <1507757851-12580-1-git-send-email-stefanb@linux.vnet.ibm.com> References: <1507757851-12580-1-git-send-email-stefanb@linux.vnet.ibm.com> X-TM-AS-GCONF: 00 x-cbid: 17101121-0044-0000-0000-0000039E3300 X-IBM-SpamModules-Scores: X-IBM-SpamModules-Versions: BY=3.00007879; HX=3.00000241; KW=3.00000007; PH=3.00000004; SC=3.00000236; SDB=6.00929762; UDB=6.00467984; IPR=6.00710033; BA=6.00005634; NDR=6.00000001; ZLA=6.00000005; ZF=6.00000009; ZB=6.00000000; ZP=6.00000000; ZH=6.00000000; ZU=6.00000002; MB=3.00017496; XFM=3.00000015; UTC=2017-10-11 21:37:43 X-IBM-AV-DETECTION: SAVI=unused REMOTE=unused XFE=unused x-cbparentid: 17101121-0045-0000-0000-000007CD34D1 Message-Id: <1507757851-12580-2-git-send-email-stefanb@linux.vnet.ibm.com> X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10432:, , definitions=2017-10-11_07:, , signatures=0 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 spamscore=0 suspectscore=1 malwarescore=0 phishscore=0 adultscore=0 bulkscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1707230000 definitions=main-1710110292 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x [generic] [fuzzy] X-Received-From: 148.163.158.5 Subject: [Qemu-devel] [RFC PATCH 1/4] tpm: print buffers received from TPM when debugging X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: amarnath.valluri@intel.com, marcandre.lureau@gmail.com, Stefan Berger Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_6 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Signed-off-by: Stefan Berger Reviewed-by: Marc-Andr=C3=A9 Lureau --- hw/tpm/tpm_tis.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/hw/tpm/tpm_tis.c b/hw/tpm/tpm_tis.c index d5118e7..9bf0bce 100644 --- a/hw/tpm/tpm_tis.c +++ b/hw/tpm/tpm_tis.c @@ -373,6 +373,8 @@ static void tpm_tis_receive_bh(void *opaque) tis->loc[locty].r_offset =3D 0; tis->loc[locty].w_offset =3D 0; =20 + tpm_tis_show_buffer(&tis->loc[locty].r_buffer, "tpm_tis: From TPM"); + if (TPM_TIS_IS_VALID_LOCTY(tis->next_locty)) { tpm_tis_abort(s, locty); } --=20 2.5.5 From nobody Sat May 4 12:08:07 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1507758102527442.8616190269845; Wed, 11 Oct 2017 14:41:42 -0700 (PDT) Received: from localhost ([::1]:42769 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1e2Okx-0005oc-MG for importer@patchew.org; Wed, 11 Oct 2017 17:41:35 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:34247) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1e2OhP-0003Td-LB for qemu-devel@nongnu.org; Wed, 11 Oct 2017 17:37:56 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1e2OhK-0003dU-PO for qemu-devel@nongnu.org; Wed, 11 Oct 2017 17:37:55 -0400 Received: from mx0b-001b2d01.pphosted.com ([148.163.158.5]:60622 helo=mx0a-001b2d01.pphosted.com) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1e2OhK-0003d7-KK for qemu-devel@nongnu.org; Wed, 11 Oct 2017 17:37:50 -0400 Received: from pps.filterd (m0098421.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.16.0.21/8.16.0.21) with SMTP id v9BLYYU0094282 for ; Wed, 11 Oct 2017 17:37:46 -0400 Received: from e13.ny.us.ibm.com (e13.ny.us.ibm.com [129.33.205.203]) by mx0a-001b2d01.pphosted.com with ESMTP id 2dhs4adrft-1 (version=TLSv1.2 cipher=AES256-SHA bits=256 verify=NOT) for ; Wed, 11 Oct 2017 17:37:46 -0400 Received: from localhost by e13.ny.us.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Wed, 11 Oct 2017 17:37:45 -0400 Received: from b01cxnp22033.gho.pok.ibm.com (9.57.198.23) by e13.ny.us.ibm.com (146.89.104.200) with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted; Wed, 11 Oct 2017 17:37:43 -0400 Received: from b01ledav002.gho.pok.ibm.com (b01ledav002.gho.pok.ibm.com [9.57.199.107]) by b01cxnp22033.gho.pok.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id v9BLbgOU39387210; Wed, 11 Oct 2017 21:37:42 GMT Received: from b01ledav002.gho.pok.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id D6655124047; Wed, 11 Oct 2017 17:34:54 -0400 (EDT) Received: from sbct-3.watson.ibm.com (unknown [9.47.158.153]) by b01ledav002.gho.pok.ibm.com (Postfix) with ESMTP id C024712403D; Wed, 11 Oct 2017 17:34:54 -0400 (EDT) From: Stefan Berger To: qemu-devel@nongnu.org Date: Wed, 11 Oct 2017 17:37:29 -0400 X-Mailer: git-send-email 2.5.5 In-Reply-To: <1507757851-12580-1-git-send-email-stefanb@linux.vnet.ibm.com> References: <1507757851-12580-1-git-send-email-stefanb@linux.vnet.ibm.com> X-TM-AS-GCONF: 00 x-cbid: 17101121-0008-0000-0000-0000028F3109 X-IBM-SpamModules-Scores: X-IBM-SpamModules-Versions: BY=3.00007879; HX=3.00000241; KW=3.00000007; PH=3.00000004; SC=3.00000236; SDB=6.00929762; UDB=6.00467984; IPR=6.00710033; BA=6.00005634; NDR=6.00000001; ZLA=6.00000005; ZF=6.00000009; ZB=6.00000000; ZP=6.00000000; ZH=6.00000000; ZU=6.00000002; MB=3.00017496; XFM=3.00000015; UTC=2017-10-11 21:37:44 X-IBM-AV-DETECTION: SAVI=unused REMOTE=unused XFE=unused x-cbparentid: 17101121-0009-0000-0000-000036F9ECE5 Message-Id: <1507757851-12580-3-git-send-email-stefanb@linux.vnet.ibm.com> X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10432:, , definitions=2017-10-11_07:, , signatures=0 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 spamscore=0 suspectscore=1 malwarescore=0 phishscore=0 adultscore=0 bulkscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1707230000 definitions=main-1710110292 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x [generic] [fuzzy] X-Received-From: 148.163.158.5 Subject: [Qemu-devel] [RFC PATCH 2/4] tpm: Introduce condition to notify waiters of completed command X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: amarnath.valluri@intel.com, marcandre.lureau@gmail.com, Stefan Berger Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Introduce a lock and a condition to notify anyone waiting for the completion of the execution of a TPM command by the backend (thread). The backend uses the condition to signal anyone waiting for command completion. We need to place the condition in two locations: one is invoked by the backend thread, the other by the bottom half thread. We will use the signalling to wait for command completion before VM suspend. Signed-off-by: Stefan Berger --- hw/tpm/tpm_int.h | 3 +++ hw/tpm/tpm_tis.c | 14 ++++++++++++++ 2 files changed, 17 insertions(+) diff --git a/hw/tpm/tpm_int.h b/hw/tpm/tpm_int.h index f2f285b..b766b3d 100644 --- a/hw/tpm/tpm_int.h +++ b/hw/tpm/tpm_int.h @@ -30,6 +30,9 @@ struct TPMState { char *backend; TPMBackend *be_driver; TPMVersion be_tpm_version; + + QemuMutex state_lock; + QemuCond cmd_complete; }; =20 #define TPM(obj) OBJECT_CHECK(TPMState, (obj), TYPE_TPM_TIS) diff --git a/hw/tpm/tpm_tis.c b/hw/tpm/tpm_tis.c index 9bf0bce..b9b9a2f 100644 --- a/hw/tpm/tpm_tis.c +++ b/hw/tpm/tpm_tis.c @@ -367,6 +367,8 @@ static void tpm_tis_receive_bh(void *opaque) TPMTISEmuState *tis =3D &s->s.tis; uint8_t locty =3D s->locty_number; =20 + qemu_mutex_lock(&s->state_lock); + tpm_tis_sts_set(&tis->loc[locty], TPM_TIS_STS_VALID | TPM_TIS_STS_DATA_AVAILABLE); tis->loc[locty].state =3D TPM_TIS_STATE_COMPLETION; @@ -385,6 +387,10 @@ static void tpm_tis_receive_bh(void *opaque) tpm_tis_raise_irq(s, locty, TPM_TIS_INT_DATA_AVAILABLE | TPM_TIS_INT_STS_VALID); #endif + + /* notify of completed command */ + qemu_cond_signal(&s->cmd_complete); + qemu_mutex_unlock(&s->state_lock); } =20 /* @@ -404,6 +410,11 @@ static void tpm_tis_receive_cb(TPMState *s, uint8_t lo= cty, } } =20 + qemu_mutex_lock(&s->state_lock); + /* notify of completed command */ + qemu_cond_signal(&s->cmd_complete); + qemu_mutex_unlock(&s->state_lock); + qemu_bh_schedule(tis->bh); } =20 @@ -1083,6 +1094,9 @@ static void tpm_tis_initfn(Object *obj) memory_region_init_io(&s->mmio, OBJECT(s), &tpm_tis_memory_ops, s, "tpm-tis-mmio", TPM_TIS_NUM_LOCALITIES << TPM_TIS_LOCALITY_SHIFT= ); + + qemu_mutex_init(&s->state_lock); + qemu_cond_init(&s->cmd_complete); } =20 static void tpm_tis_class_init(ObjectClass *klass, void *data) --=20 2.5.5 From nobody Sat May 4 12:08:07 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (208.118.235.17 [208.118.235.17]) by mx.zohomail.com with SMTPS id 1507757993205857.6534943614434; Wed, 11 Oct 2017 14:39:53 -0700 (PDT) Received: from localhost ([::1]:42757 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1e2Oj4-0004LN-PO for importer@patchew.org; Wed, 11 Oct 2017 17:39:38 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:34244) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1e2OhP-0003Tb-IK for qemu-devel@nongnu.org; Wed, 11 Oct 2017 17:37:56 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1e2OhK-0003dH-Lm for qemu-devel@nongnu.org; Wed, 11 Oct 2017 17:37:55 -0400 Received: from mx0b-001b2d01.pphosted.com ([148.163.158.5]:58954 helo=mx0a-001b2d01.pphosted.com) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1e2OhK-0003d1-Fo for qemu-devel@nongnu.org; Wed, 11 Oct 2017 17:37:50 -0400 Received: from pps.filterd (m0098417.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.16.0.21/8.16.0.21) with SMTP id v9BLYY53068888 for ; Wed, 11 Oct 2017 17:37:47 -0400 Received: from e12.ny.us.ibm.com (e12.ny.us.ibm.com [129.33.205.202]) by mx0a-001b2d01.pphosted.com with ESMTP id 2dht8njn3y-1 (version=TLSv1.2 cipher=AES256-SHA bits=256 verify=NOT) for ; Wed, 11 Oct 2017 17:37:47 -0400 Received: from localhost by e12.ny.us.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Wed, 11 Oct 2017 17:37:46 -0400 Received: from b01cxnp22036.gho.pok.ibm.com (9.57.198.26) by e12.ny.us.ibm.com (146.89.104.199) with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted; Wed, 11 Oct 2017 17:37:44 -0400 Received: from b01ledav002.gho.pok.ibm.com (b01ledav002.gho.pok.ibm.com [9.57.199.107]) by b01cxnp22036.gho.pok.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id v9BLbhRJ48693408; Wed, 11 Oct 2017 21:37:43 GMT Received: from b01ledav002.gho.pok.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id E55DC12403D; Wed, 11 Oct 2017 17:34:55 -0400 (EDT) Received: from sbct-3.watson.ibm.com (unknown [9.47.158.153]) by b01ledav002.gho.pok.ibm.com (Postfix) with ESMTP id CD1FE124035; Wed, 11 Oct 2017 17:34:55 -0400 (EDT) From: Stefan Berger To: qemu-devel@nongnu.org Date: Wed, 11 Oct 2017 17:37:30 -0400 X-Mailer: git-send-email 2.5.5 In-Reply-To: <1507757851-12580-1-git-send-email-stefanb@linux.vnet.ibm.com> References: <1507757851-12580-1-git-send-email-stefanb@linux.vnet.ibm.com> X-TM-AS-GCONF: 00 x-cbid: 17101121-0048-0000-0000-000001F4349C X-IBM-SpamModules-Scores: X-IBM-SpamModules-Versions: BY=3.00007879; HX=3.00000241; KW=3.00000007; PH=3.00000004; SC=3.00000236; SDB=6.00929762; UDB=6.00467984; IPR=6.00710033; BA=6.00005634; NDR=6.00000001; ZLA=6.00000005; ZF=6.00000009; ZB=6.00000000; ZP=6.00000000; ZH=6.00000000; ZU=6.00000002; MB=3.00017496; XFM=3.00000015; UTC=2017-10-11 21:37:45 X-IBM-AV-DETECTION: SAVI=unused REMOTE=unused XFE=unused x-cbparentid: 17101121-0049-0000-0000-000042D6F3CB Message-Id: <1507757851-12580-4-git-send-email-stefanb@linux.vnet.ibm.com> X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10432:, , definitions=2017-10-11_07:, , signatures=0 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 spamscore=0 suspectscore=1 malwarescore=0 phishscore=0 adultscore=0 bulkscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1707230000 definitions=main-1710110292 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x [generic] [fuzzy] X-Received-From: 148.163.158.5 Subject: [Qemu-devel] [RFC PATCH 3/4] tpm: Introduce condition in TPM backend for notification X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: amarnath.valluri@intel.com, marcandre.lureau@gmail.com, Stefan Berger Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" TPM backends will suspend independently of the frontends. Also here we need to be able to wait for the TPM command to have been completely processed. Signed-off-by: Stefan Berger --- backends/tpm.c | 16 ++++++++++++++++ hw/tpm/tpm_emulator.c | 3 +++ include/sysemu/tpm_backend.h | 14 ++++++++++++++ 3 files changed, 33 insertions(+) diff --git a/backends/tpm.c b/backends/tpm.c index 37c84b7..334836b 100644 --- a/backends/tpm.c +++ b/backends/tpm.c @@ -52,10 +52,22 @@ int tpm_backend_init(TPMBackend *s, TPMState *state, s->tpm_state =3D state; s->recv_data_callback =3D datacb; s->had_startup_error =3D false; + s->tpm_busy =3D false; + + qemu_mutex_init(&s->state_lock); + qemu_cond_init(&s->cmd_complete); =20 return k->ops->init ? k->ops->init(s) : 0; } =20 +void tpm_backend_cmd_completed(TPMBackend *s) +{ + qemu_mutex_lock(&s->state_lock); + s->tpm_busy =3D false; + qemu_cond_signal(&s->cmd_complete); + qemu_mutex_unlock(&s->state_lock); +} + int tpm_backend_startup_tpm(TPMBackend *s) { int res =3D 0; @@ -82,6 +94,10 @@ bool tpm_backend_had_startup_error(TPMBackend *s) =20 void tpm_backend_deliver_request(TPMBackend *s) { + qemu_mutex_lock(&s->state_lock); + s->tpm_busy =3D true; + qemu_mutex_unlock(&s->state_lock); + g_thread_pool_push(s->thread_pool, (gpointer)TPM_BACKEND_CMD_PROCESS_C= MD, NULL); } diff --git a/hw/tpm/tpm_emulator.c b/hw/tpm/tpm_emulator.c index 95e1e04..556b8c8 100644 --- a/hw/tpm/tpm_emulator.c +++ b/hw/tpm/tpm_emulator.c @@ -200,6 +200,9 @@ static void tpm_emulator_handle_request(TPMBackend *tb,= TPMBackendCmd cmd) tb->recv_data_callback(tb->tpm_state, tb->tpm_state->locty_number, selftest_done); =20 + /* result delivered */ + tpm_backend_cmd_completed(tb); + break; case TPM_BACKEND_CMD_INIT: case TPM_BACKEND_CMD_END: diff --git a/include/sysemu/tpm_backend.h b/include/sysemu/tpm_backend.h index 2c798a1..cdc4742 100644 --- a/include/sysemu/tpm_backend.h +++ b/include/sysemu/tpm_backend.h @@ -18,6 +18,7 @@ #include "qapi-types.h" #include "qemu/option.h" #include "sysemu/tpm.h" +#include "qemu/thread.h" =20 #define TYPE_TPM_BACKEND "tpm-backend" #define TPM_BACKEND(obj) \ @@ -54,6 +55,10 @@ struct TPMBackend { enum TpmModel fe_model; =20 QLIST_ENTRY(TPMBackend) list; + + QemuMutex state_lock; + QemuCond cmd_complete; /* signaled once tpm_busy is false */ + bool tpm_busy; }; =20 struct TPMBackendClass { @@ -213,6 +218,15 @@ TPMVersion tpm_backend_get_tpm_version(TPMBackend *s); */ TPMInfo *tpm_backend_query_tpm(TPMBackend *s); =20 +/** + * tpm_backend_cmd_completed: + * @s: the backend + * + * Mark the backend as not busy and notify anyone interested + * in the state changed + */ +void tpm_backend_cmd_completed(TPMBackend *s); + TPMBackend *qemu_find_tpm(const char *id); =20 const TPMDriverOps *tpm_get_backend_driver(const char *type); --=20 2.5.5 From nobody Sat May 4 12:08:07 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1507757999063881.5542910977206; Wed, 11 Oct 2017 14:39:59 -0700 (PDT) Received: from localhost ([::1]:42758 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1e2OjC-0004Qz-2l for importer@patchew.org; Wed, 11 Oct 2017 17:39:46 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:34279) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1e2OhT-0003WA-94 for qemu-devel@nongnu.org; Wed, 11 Oct 2017 17:38:05 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1e2OhO-0003gC-9O for qemu-devel@nongnu.org; Wed, 11 Oct 2017 17:37:59 -0400 Received: from mx0a-001b2d01.pphosted.com ([148.163.156.1]:50114) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1e2OhN-0003fF-T4 for qemu-devel@nongnu.org; Wed, 11 Oct 2017 17:37:54 -0400 Received: from pps.filterd (m0098396.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.16.0.21/8.16.0.21) with SMTP id v9BLbWYG145836 for ; Wed, 11 Oct 2017 17:37:48 -0400 Received: from e14.ny.us.ibm.com (e14.ny.us.ibm.com [129.33.205.204]) by mx0a-001b2d01.pphosted.com with ESMTP id 2dhs4a5wtg-1 (version=TLSv1.2 cipher=AES256-SHA bits=256 verify=NOT) for ; Wed, 11 Oct 2017 17:37:48 -0400 Received: from localhost by e14.ny.us.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Wed, 11 Oct 2017 17:37:47 -0400 Received: from b01cxnp22033.gho.pok.ibm.com (9.57.198.23) by e14.ny.us.ibm.com (146.89.104.201) with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted; Wed, 11 Oct 2017 17:37:45 -0400 Received: from b01ledav002.gho.pok.ibm.com (b01ledav002.gho.pok.ibm.com [9.57.199.107]) by b01cxnp22033.gho.pok.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id v9BLbjxk41681016; Wed, 11 Oct 2017 21:37:45 GMT Received: from b01ledav002.gho.pok.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 01E0A124037; Wed, 11 Oct 2017 17:34:57 -0400 (EDT) Received: from sbct-3.watson.ibm.com (unknown [9.47.158.153]) by b01ledav002.gho.pok.ibm.com (Postfix) with ESMTP id DBE8512403F; Wed, 11 Oct 2017 17:34:56 -0400 (EDT) From: Stefan Berger To: qemu-devel@nongnu.org Date: Wed, 11 Oct 2017 17:37:31 -0400 X-Mailer: git-send-email 2.5.5 In-Reply-To: <1507757851-12580-1-git-send-email-stefanb@linux.vnet.ibm.com> References: <1507757851-12580-1-git-send-email-stefanb@linux.vnet.ibm.com> X-TM-AS-GCONF: 00 x-cbid: 17101121-0052-0000-0000-000002703AF2 X-IBM-SpamModules-Scores: X-IBM-SpamModules-Versions: BY=3.00007880; HX=3.00000241; KW=3.00000007; PH=3.00000004; SC=3.00000236; SDB=6.00929762; UDB=6.00467984; IPR=6.00710033; BA=6.00005634; NDR=6.00000001; ZLA=6.00000005; ZF=6.00000009; ZB=6.00000000; ZP=6.00000000; ZH=6.00000000; ZU=6.00000002; MB=3.00017496; XFM=3.00000015; UTC=2017-10-11 21:37:46 X-IBM-AV-DETECTION: SAVI=unused REMOTE=unused XFE=unused x-cbparentid: 17101121-0053-0000-0000-00005249F4F9 Message-Id: <1507757851-12580-5-git-send-email-stefanb@linux.vnet.ibm.com> X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10432:, , definitions=2017-10-11_07:, , signatures=0 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 spamscore=0 suspectscore=3 malwarescore=0 phishscore=0 adultscore=0 bulkscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1707230000 definitions=main-1710110292 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x [generic] [fuzzy] X-Received-From: 148.163.156.1 Subject: [Qemu-devel] [RFC PATCH 4/4] tpm: extend TPM emulator and TIS with state migration support X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: amarnath.valluri@intel.com, marcandre.lureau@gmail.com, Stefan Berger Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Extend the TPM emulator and TPM TIS interface with state migration support. The external TPM emulator 'swtpm' provides a protocol over its control channel to retrieve its state blobs. We implement functions for getting and setting the different state blobs. Since we have an external TPM emulator, we need to make sure that we do not migrate the state for as long as it is busy processing a request. We need to wait for notification that the request has completed processing. Signed-off-by: Stefan Berger --- backends/tpm.c | 9 ++ hw/tpm/tpm_emulator.c | 310 +++++++++++++++++++++++++++++++++++++++= ++-- hw/tpm/tpm_tis.c | 138 ++++++++++++++++++- hw/tpm/tpm_tis.h | 2 + hw/tpm/tpm_util.c | 7 + hw/tpm/tpm_util.h | 2 + include/sysemu/tpm_backend.h | 8 ++ 7 files changed, 465 insertions(+), 11 deletions(-) diff --git a/backends/tpm.c b/backends/tpm.c index 334836b..be35ee2 100644 --- a/backends/tpm.c +++ b/backends/tpm.c @@ -68,6 +68,15 @@ void tpm_backend_cmd_completed(TPMBackend *s) qemu_mutex_unlock(&s->state_lock); } =20 +void tpm_backend_wait_cmd_completed(TPMBackend *s) +{ + qemu_mutex_lock(&s->state_lock); + if (s->tpm_busy) { + qemu_cond_wait(&s->cmd_complete, &s->state_lock); + } + qemu_mutex_unlock(&s->state_lock); +} + int tpm_backend_startup_tpm(TPMBackend *s) { int res =3D 0; diff --git a/hw/tpm/tpm_emulator.c b/hw/tpm/tpm_emulator.c index 556b8c8..3cafc55 100644 --- a/hw/tpm/tpm_emulator.c +++ b/hw/tpm/tpm_emulator.c @@ -63,6 +63,19 @@ static const TPMDriverOps tpm_emulator_driver; =20 /* data structures */ + +/* blobs from the TPM; part of VM state when migrating */ +typedef struct TPMBlobBuffers { + uint32_t permanent_flags; + TPMSizedBuffer permanent; + + uint32_t volatil_flags; + TPMSizedBuffer volatil; + + uint32_t savestate_flags; + TPMSizedBuffer savestate; +} TPMBlobBuffers; + typedef struct TPMEmulator { TPMBackend parent; =20 @@ -73,6 +86,8 @@ typedef struct TPMEmulator { ptm_cap caps; /* capabilities of the TPM */ uint8_t cur_locty_number; /* last set locality */ Error *migration_blocker; + + TPMBlobBuffers state_blobs; } TPMEmulator; =20 =20 @@ -260,13 +275,18 @@ static int tpm_emulator_check_caps(TPMEmulator *tpm_e= mu) return 0; } =20 -static int tpm_emulator_startup_tpm(TPMBackend *tb) +static int _tpm_emulator_startup_tpm(TPMBackend *tb, bool is_resume) { TPMEmulator *tpm_emu =3D TPM_EMULATOR(tb); ptm_init init; ptm_res res; =20 - DPRINTF("%s", __func__); + DPRINTF("%s is_resume: %d", __func__, is_resume); + + if (is_resume) { + init.u.req.init_flags =3D cpu_to_be32(PTM_INIT_FLAG_DELETE_VOLATIL= E); + } + if (tpm_emulator_ctrlcmd(&tpm_emu->ctrl_chr, CMD_INIT, &init, sizeof(i= nit), sizeof(init)) < 0) { error_report("tpm-emulator: could not send INIT: %s", @@ -285,6 +305,11 @@ err_exit: return -1; } =20 +static int tpm_emulator_startup_tpm(TPMBackend *tb) +{ + return _tpm_emulator_startup_tpm(tb, false); +} + static bool tpm_emulator_get_tpm_established_flag(TPMBackend *tb) { TPMEmulator *tpm_emu =3D TPM_EMULATOR(tb); @@ -363,16 +388,21 @@ static TPMVersion tpm_emulator_get_tpm_version(TPMBac= kend *tb) static int tpm_emulator_block_migration(TPMEmulator *tpm_emu) { Error *err =3D NULL; + ptm_cap caps =3D PTM_CAP_GET_STATEBLOB | PTM_CAP_SET_STATEBLOB | + PTM_CAP_STOP; =20 - error_setg(&tpm_emu->migration_blocker, - "Migration disabled: TPM emulator not yet migratable"); - migrate_add_blocker(tpm_emu->migration_blocker, &err); - if (err) { - error_report_err(err); - error_free(tpm_emu->migration_blocker); - tpm_emu->migration_blocker =3D NULL; + if (!TPM_EMULATOR_IMPLEMENTS_ALL_CAPS(tpm_emu, caps)) { + error_setg(&tpm_emu->migration_blocker, + "Migration disabled: TPM emulator does not support " + "migration"); + migrate_add_blocker(tpm_emu->migration_blocker, &err); + if (err) { + error_report_err(err); + error_free(tpm_emu->migration_blocker); + tpm_emu->migration_blocker =3D NULL; =20 - return -1; + return -1; + } } =20 return 0; @@ -521,13 +551,271 @@ static const TPMDriverOps tpm_emulator_driver =3D { .get_tpm_options =3D tpm_emulator_get_tpm_options, }; =20 +/* + * Transfer a TPM state blob from the TPM into a provided buffer. + * + * @tpm_emu: TPMEmulator + * @type: the type of blob to transfer + * @tsb: the TPMSizeBuffer to fill with the blob + * @flags: the flags to return to the caller + */ +static int tpm_emulator_get_state_blob(TPMEmulator *tpm_emu, + uint8_t type, + TPMSizedBuffer *tsb, + uint32_t *flags) +{ + ptm_getstate pgs; + ptm_res res; + ssize_t n; + uint32_t totlength, length; + + tpm_sized_buffer_reset(tsb); + + pgs.u.req.state_flags =3D cpu_to_be32(PTM_STATE_FLAG_DECRYPTED); + pgs.u.req.type =3D cpu_to_be32(type); + pgs.u.req.offset =3D 0; + + if (tpm_emulator_ctrlcmd(&tpm_emu->ctrl_chr, CMD_GET_STATEBLOB, + &pgs, sizeof(pgs.u.req), + offsetof(ptm_getstate, u.resp.data)) < 0) { + error_report("tpm-emulator: could not get state blob type %d : %s", + type, strerror(errno)); + return -1; + } + + res =3D be32_to_cpu(pgs.u.resp.tpm_result); + if (res !=3D 0 && (res & 0x800) =3D=3D 0) { + error_report("tpm-emulator: Getting the stateblob (type %d) failed= " + "with a TPM error 0x%x", type, res); + return -1; + } + + totlength =3D be32_to_cpu(pgs.u.resp.totlength); + if (totlength >=3D 32 * 1024) { + error_report("tpm-emulator: TPM state blob (type %d) with %d bytes= " + "too large to read", type, totlength); + return -1; + } + + length =3D be32_to_cpu(pgs.u.resp.length); + if (totlength !=3D length) { + error_report("tpm-emulator: Expecting to read %u bytes " + "but would get %u", totlength, length); + return -1; + } + + *flags =3D be32_to_cpu(pgs.u.resp.state_flags); + + tsb->buffer =3D g_malloc(totlength); + + n =3D qemu_chr_fe_read_all(&tpm_emu->ctrl_chr, tsb->buffer, totlength); + if (n !=3D totlength) { + error_report("tpm-emulator: Could not read stateblob (type %d) : %= s", + type, strerror(errno)); + return -1; + } + tsb->size =3D totlength; + + DPRINTF("got state blob type %d, %d bytes, flags 0x%08x\n", + type, tsb->size, *flags); + + return 0; +} + +static int tpm_emulator_get_state_blobs(TPMEmulator *tpm_emu) +{ + TPMBlobBuffers *state_blobs =3D &tpm_emu->state_blobs; + + if (tpm_emulator_get_state_blob(tpm_emu, PTM_BLOB_TYPE_PERMANENT, + &state_blobs->permanent, + &state_blobs->permanent_flags) || + tpm_emulator_get_state_blob(tpm_emu, PTM_BLOB_TYPE_VOLATILE, + &state_blobs->volatil, + &state_blobs->volatil_flags) || + tpm_emulator_get_state_blob(tpm_emu, PTM_BLOB_TYPE_SAVESTATE, + &state_blobs->savestate, + &state_blobs->savestate_flags)) { + goto err_exit; + } + + return 0; + + err_exit: + tpm_sized_buffer_reset(&state_blobs->volatil); + tpm_sized_buffer_reset(&state_blobs->permanent); + tpm_sized_buffer_reset(&state_blobs->savestate); + + return -1; +} + +/* + * Transfer a TPM state blob to the TPM emulator. + * + * @tpm_emu: TPMEmulator + * @type: the type of TPM state blob to transfer + * @tsb: TPMSizeBuffer containing the TPM state blob + * @flags: Flags describing the (encryption) state of the TPM state blob + */ +static int tpm_emulator_set_state_blob(TPMEmulator *tpm_emu, + uint32_t type, + TPMSizedBuffer *tsb, + uint32_t flags) +{ + uint32_t offset =3D 0; + ssize_t n; + ptm_setstate pss; + ptm_res tpm_result; + + if (tsb->size =3D=3D 0) { + return 0; + } + + pss =3D (ptm_setstate) { + .u.req.state_flags =3D cpu_to_be32(flags), + .u.req.type =3D cpu_to_be32(type), + .u.req.length =3D cpu_to_be32(tsb->size), + }; + + /* write the header only */ + if (tpm_emulator_ctrlcmd(&tpm_emu->ctrl_chr, CMD_SET_STATEBLOB, + &pss, + offsetof(ptm_setstate, u.req.data), 0) < 0) { + error_report("tpm-emulator: could not set state blob type %d : %s", + type, strerror(errno)); + return -1; + } + + /* now the body */ + n =3D qemu_chr_fe_write_all(&tpm_emu->ctrl_chr, + &tsb->buffer[offset], tsb->size); + if (n !=3D tsb->size) { + error_report("tpm-emulator: Writing the stateblob (type %d) " + "failed: %s", type, strerror(errno)); + return -1; + } + + /* now get the result */ + n =3D qemu_chr_fe_read_all(&tpm_emu->ctrl_chr, + (uint8_t *)&pss, sizeof(pss.u.resp)); + if (n !=3D sizeof(pss.u.resp)) { + error_report("tpm-emulator: Reading response from writing stateblo= b " + "(type %d) failed: %s", type, strerror(errno)); + return -1; + } + + tpm_result =3D be32_to_cpu(pss.u.resp.tpm_result); + if (tpm_result !=3D 0) { + error_report("tpm-emulator: Setting the stateblob (type %d) failed= " + "with a TPM error 0x%x", type, tpm_result); + return -1; + } + + DPRINTF("set the state blob type %d, %d bytes, flags 0x%08x\n", + type, tsb->size, flags); + + return 0; +} + +static int tpm_emulator_set_state_blobs(TPMEmulator *tpm_emu) +{ + ptm_res res; + TPMBlobBuffers *state_blobs =3D &tpm_emu->state_blobs; + + DPRINTF("%s: %d", __func__, __LINE__); + + if (tpm_emulator_ctrlcmd(&tpm_emu->ctrl_chr, CMD_STOP, &res, 0, + sizeof(res)) < 0) { + error_report("tpm-emulator: could not send STOP: %s", + strerror(errno)); + return -1; + } else if (res !=3D 0) { + error_report("tpm-emulator: Failed to stop TPM: 0x%x", + be32_to_cpu(res)); + return -1; + } + + if (tpm_emulator_set_state_blob(tpm_emu, PTM_BLOB_TYPE_PERMANENT, + &state_blobs->permanent, + state_blobs->permanent_flags) || + tpm_emulator_set_state_blob(tpm_emu, PTM_BLOB_TYPE_VOLATILE, + &state_blobs->volatil, + state_blobs->volatil_flags) || + tpm_emulator_set_state_blob(tpm_emu, PTM_BLOB_TYPE_SAVESTATE, + &state_blobs->savestate, + state_blobs->savestate_flags)) { + return -1; + } + + DPRINTF("DONE SETTING STATEBLOBS"); + + return 0; +} + +static int tpm_emulator_pre_save(void *opaque) +{ + TPMBackend *tb =3D opaque; + TPMEmulator *tpm_emu =3D TPM_EMULATOR(tb); + + DPRINTF("%s", __func__); + + tpm_backend_wait_cmd_completed(tb); + + /* get the state blobs from the TPM */ + return tpm_emulator_get_state_blobs(tpm_emu); +} + +static int tpm_emulator_post_load(void *opaque, + int version_id __attribute__((unused))) +{ + TPMBackend *tb =3D opaque; + + if (tpm_emulator_set_state_blobs(TPM_EMULATOR(tb))) { + return 1; + } + + return _tpm_emulator_startup_tpm(tb, true); +} + +static const VMStateDescription vmstate_tpm_emulator =3D { + .name =3D "tpm-emulator", + .version_id =3D 1, + .minimum_version_id =3D 0, + .minimum_version_id_old =3D 0, + .pre_save =3D tpm_emulator_pre_save, + .post_load =3D tpm_emulator_post_load, + .fields =3D (VMStateField[]) { + VMSTATE_UINT32(state_blobs.permanent_flags, TPMEmulator), + VMSTATE_UINT32(state_blobs.permanent.size, TPMEmulator), + VMSTATE_VBUFFER_ALLOC_UINT32(state_blobs.permanent.buffer, + TPMEmulator, 1, 0, + state_blobs.permanent.size), + + VMSTATE_UINT32(state_blobs.volatil_flags, TPMEmulator), + VMSTATE_UINT32(state_blobs.volatil.size, TPMEmulator), + VMSTATE_VBUFFER_ALLOC_UINT32(state_blobs.volatil.buffer, + TPMEmulator, 1, 0, + state_blobs.volatil.size), + + VMSTATE_UINT32(state_blobs.savestate_flags, TPMEmulator), + VMSTATE_UINT32(state_blobs.savestate.size, TPMEmulator), + VMSTATE_VBUFFER_ALLOC_UINT32(state_blobs.savestate.buffer, + TPMEmulator, 1, 0, + state_blobs.savestate.size), + + VMSTATE_END_OF_LIST() + } +}; + static void tpm_emulator_inst_init(Object *obj) { TPMEmulator *tpm_emu =3D TPM_EMULATOR(obj); =20 DPRINTF("%s", __func__); + tpm_emu->options =3D g_new0(TPMEmulatorOptions, 1); tpm_emu->cur_locty_number =3D ~0; + + vmstate_register(NULL, -1, &vmstate_tpm_emulator, obj); } =20 /* @@ -563,6 +851,8 @@ static void tpm_emulator_inst_finalize(Object *obj) migrate_del_blocker(tpm_emu->migration_blocker); error_free(tpm_emu->migration_blocker); } + + vmstate_unregister(NULL, &vmstate_tpm_emulator, obj); } =20 static void tpm_emulator_class_init(ObjectClass *klass, void *data) diff --git a/hw/tpm/tpm_tis.c b/hw/tpm/tpm_tis.c index b9b9a2f..1b23129 100644 --- a/hw/tpm/tpm_tis.c +++ b/hw/tpm/tpm_tis.c @@ -367,6 +367,8 @@ static void tpm_tis_receive_bh(void *opaque) TPMTISEmuState *tis =3D &s->s.tis; uint8_t locty =3D s->locty_number; =20 + tis->bh_scheduled =3D false; + qemu_mutex_lock(&s->state_lock); =20 tpm_tis_sts_set(&tis->loc[locty], @@ -416,6 +418,8 @@ static void tpm_tis_receive_cb(TPMState *s, uint8_t loc= ty, qemu_mutex_unlock(&s->state_lock); =20 qemu_bh_schedule(tis->bh); + + tis->bh_scheduled =3D true; } =20 /* @@ -1041,9 +1045,141 @@ static void tpm_tis_reset(DeviceState *dev) tpm_tis_do_startup_tpm(s); } =20 +/* persistent state handling */ + +static int tpm_tis_pre_save(void *opaque) +{ + TPMState *s =3D opaque; + TPMTISEmuState *tis =3D &s->s.tis; + uint8_t locty =3D tis->active_locty; + + DPRINTF("tpm_tis: suspend: locty =3D %d : r_offset =3D %d, w_offset = =3D %d\n", + locty, tis->loc[0].r_offset, tis->loc[0].w_offset); +#ifdef DEBUG_TIS + tpm_tis_dump_state(opaque, 0); +#endif + + qemu_mutex_lock(&s->state_lock); + + /* wait for outstanding request to complete */ + if (TPM_TIS_IS_VALID_LOCTY(locty) && + tis->loc[locty].state =3D=3D TPM_TIS_STATE_EXECUTION) { + /* + * If we get here when the bh is scheduled but did not run, + * we won't get notified... + */ + if (!tis->bh_scheduled) { + /* backend thread to notify us */ + qemu_cond_wait(&s->cmd_complete, &s->state_lock); + } + if (tis->loc[locty].state =3D=3D TPM_TIS_STATE_EXECUTION) { + /* bottom half did not run - run its function */ + qemu_mutex_unlock(&s->state_lock); + tpm_tis_receive_bh(opaque); + qemu_mutex_lock(&s->state_lock); + } + } + + qemu_mutex_unlock(&s->state_lock); + + /* copy current active read or write buffer into the buffer + written to disk */ + if (TPM_TIS_IS_VALID_LOCTY(locty)) { + switch (tis->loc[locty].state) { + case TPM_TIS_STATE_RECEPTION: + memcpy(tis->buf, + tis->loc[locty].w_buffer.buffer, + MIN(sizeof(tis->buf), + tis->loc[locty].w_buffer.size)); + tis->offset =3D tis->loc[locty].w_offset; + break; + case TPM_TIS_STATE_COMPLETION: + memcpy(tis->buf, + tis->loc[locty].r_buffer.buffer, + MIN(sizeof(tis->buf), + tis->loc[locty].r_buffer.size)); + tis->offset =3D tis->loc[locty].r_offset; + break; + default: + /* leak nothing */ + memset(tis->buf, 0x0, sizeof(tis->buf)); + break; + } + } + + return 0; +} + +static int tpm_tis_post_load(void *opaque, + int version_id __attribute__((unused))) +{ + TPMState *s =3D opaque; + TPMTISEmuState *tis =3D &s->s.tis; + + uint8_t locty =3D tis->active_locty; + + if (TPM_TIS_IS_VALID_LOCTY(locty)) { + switch (tis->loc[locty].state) { + case TPM_TIS_STATE_RECEPTION: + memcpy(tis->loc[locty].w_buffer.buffer, + tis->buf, + MIN(sizeof(tis->buf), + tis->loc[locty].w_buffer.size)); + tis->loc[locty].w_offset =3D tis->offset; + break; + case TPM_TIS_STATE_COMPLETION: + memcpy(tis->loc[locty].r_buffer.buffer, + tis->buf, + MIN(sizeof(tis->buf), + tis->loc[locty].r_buffer.size)); + tis->loc[locty].r_offset =3D tis->offset; + break; + default: + break; + } + } + + DPRINTF("tpm_tis: resume : locty =3D %d : r_offset =3D %d, w_offset = =3D %d\n", + locty, tis->loc[0].r_offset, tis->loc[0].w_offset); + + return 0; +} + +static const VMStateDescription vmstate_locty =3D { + .name =3D "loc", + .version_id =3D 1, + .minimum_version_id =3D 0, + .minimum_version_id_old =3D 0, + .fields =3D (VMStateField[]) { + VMSTATE_UINT32(state, TPMLocality), + VMSTATE_UINT32(inte, TPMLocality), + VMSTATE_UINT32(ints, TPMLocality), + VMSTATE_UINT8(access, TPMLocality), + VMSTATE_UINT32(sts, TPMLocality), + VMSTATE_UINT32(iface_id, TPMLocality), + VMSTATE_END_OF_LIST(), + } +}; + static const VMStateDescription vmstate_tpm_tis =3D { .name =3D "tpm", - .unmigratable =3D 1, + .version_id =3D 1, + .minimum_version_id =3D 0, + .minimum_version_id_old =3D 0, + .pre_save =3D tpm_tis_pre_save, + .post_load =3D tpm_tis_post_load, + .fields =3D (VMStateField[]) { + VMSTATE_UINT32(s.tis.offset, TPMState), + VMSTATE_BUFFER(s.tis.buf, TPMState), + VMSTATE_UINT8(s.tis.active_locty, TPMState), + VMSTATE_UINT8(s.tis.aborting_locty, TPMState), + VMSTATE_UINT8(s.tis.next_locty, TPMState), + + VMSTATE_STRUCT_ARRAY(s.tis.loc, TPMState, TPM_TIS_NUM_LOCALITIES, = 1, + vmstate_locty, TPMLocality), + + VMSTATE_END_OF_LIST() + } }; =20 static Property tpm_tis_properties[] =3D { diff --git a/hw/tpm/tpm_tis.h b/hw/tpm/tpm_tis.h index a1df41f..b7fc0ea 100644 --- a/hw/tpm/tpm_tis.h +++ b/hw/tpm/tpm_tis.h @@ -54,6 +54,8 @@ typedef struct TPMLocality { =20 typedef struct TPMTISEmuState { QEMUBH *bh; + bool bh_scheduled; /* bh scheduled but did not run yet */ + uint32_t offset; uint8_t buf[TPM_TIS_BUFFER_MAX]; =20 diff --git a/hw/tpm/tpm_util.c b/hw/tpm/tpm_util.c index 1129155..f496e39 100644 --- a/hw/tpm/tpm_util.c +++ b/hw/tpm/tpm_util.c @@ -150,3 +150,10 @@ int tpm_util_test_tpmdev(int tpm_fd, TPMVersion *tpm_v= ersion) =20 return 1; } + +void tpm_sized_buffer_reset(TPMSizedBuffer *tsb) +{ + g_free(tsb->buffer); + tsb->buffer =3D NULL; + tsb->size =3D 0; +} diff --git a/hw/tpm/tpm_util.h b/hw/tpm/tpm_util.h index 2f7c961..d394cb6 100644 --- a/hw/tpm/tpm_util.h +++ b/hw/tpm/tpm_util.h @@ -30,4 +30,6 @@ bool tpm_util_is_selftest(const uint8_t *in, uint32_t in_= len); =20 int tpm_util_test_tpmdev(int tpm_fd, TPMVersion *tpm_version); =20 +void tpm_sized_buffer_reset(TPMSizedBuffer *tsb); + #endif /* TPM_TPM_UTIL_H */ diff --git a/include/sysemu/tpm_backend.h b/include/sysemu/tpm_backend.h index cdc4742..250d763 100644 --- a/include/sysemu/tpm_backend.h +++ b/include/sysemu/tpm_backend.h @@ -227,6 +227,14 @@ TPMInfo *tpm_backend_query_tpm(TPMBackend *s); */ void tpm_backend_cmd_completed(TPMBackend *s); =20 +/** + * tpm_backend_wait_cmd_completed: + * @s: the backend + * + * Wait the backend to not be busy anymore + */ +void tpm_backend_wait_cmd_completed(TPMBackend *s); + TPMBackend *qemu_find_tpm(const char *id); =20 const TPMDriverOps *tpm_get_backend_driver(const char *type); --=20 2.5.5