From nobody Sun Feb 8 11:16:19 2026 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 1519934971596704.9208499084601; Thu, 1 Mar 2018 12:09:31 -0800 (PST) Received: from localhost ([::1]:59088 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1erUW7-0006W4-4X for importer@patchew.org; Thu, 01 Mar 2018 15:09:27 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:48879) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1erUMj-0006tX-7Z for qemu-devel@nongnu.org; Thu, 01 Mar 2018 14:59:48 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1erUMg-0002cq-58 for qemu-devel@nongnu.org; Thu, 01 Mar 2018 14:59:45 -0500 Received: from mx0b-001b2d01.pphosted.com ([148.163.158.5]:54014 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 1erUMf-0002cQ-TO for qemu-devel@nongnu.org; Thu, 01 Mar 2018 14:59:42 -0500 Received: from pps.filterd (m0098417.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.16.0.22/8.16.0.22) with SMTP id w21JxEBv147011 for ; Thu, 1 Mar 2018 14:59:41 -0500 Received: from e36.co.us.ibm.com (e36.co.us.ibm.com [32.97.110.154]) by mx0a-001b2d01.pphosted.com with ESMTP id 2gep8e4ukn-1 (version=TLSv1.2 cipher=AES256-SHA bits=256 verify=NOT) for ; Thu, 01 Mar 2018 14:59:40 -0500 Received: from localhost by e36.co.us.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Thu, 1 Mar 2018 12:59:40 -0700 Received: from b03cxnp07028.gho.boulder.ibm.com (9.17.130.15) by e36.co.us.ibm.com (192.168.1.136) with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted; Thu, 1 Mar 2018 12:59:38 -0700 Received: from b03ledav005.gho.boulder.ibm.com (b03ledav005.gho.boulder.ibm.com [9.17.130.236]) by b03cxnp07028.gho.boulder.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id w21Jxb2V13042122; Thu, 1 Mar 2018 12:59:37 -0700 Received: from b03ledav005.gho.boulder.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id C13B4BE03A; Thu, 1 Mar 2018 12:59:37 -0700 (MST) Received: from sbct-3.watson.ibm.com (unknown [9.47.158.153]) by b03ledav005.gho.boulder.ibm.com (Postfix) with ESMTP id 641A7BE039; Thu, 1 Mar 2018 12:59:37 -0700 (MST) From: Stefan Berger To: qemu-devel@nongnu.org Date: Thu, 1 Mar 2018 14:59:32 -0500 X-Mailer: git-send-email 2.5.5 In-Reply-To: <1519934373-3629-1-git-send-email-stefanb@linux.vnet.ibm.com> References: <1519934373-3629-1-git-send-email-stefanb@linux.vnet.ibm.com> X-TM-AS-GCONF: 00 x-cbid: 18030119-0020-0000-0000-00000D87EAB8 X-IBM-SpamModules-Scores: X-IBM-SpamModules-Versions: BY=3.00008609; HX=3.00000241; KW=3.00000007; PH=3.00000004; SC=3.00000254; SDB=6.00996930; UDB=6.00506869; IPR=6.00776248; MB=3.00019805; MTD=3.00000008; XFM=3.00000015; UTC=2018-03-01 19:59:39 X-IBM-AV-DETECTION: SAVI=unused REMOTE=unused XFE=unused x-cbparentid: 18030119-0021-0000-0000-00006053BE17 Message-Id: <1519934373-3629-2-git-send-email-stefanb@linux.vnet.ibm.com> X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10432:, , definitions=2018-03-01_10:, , signatures=0 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 priorityscore=1501 malwarescore=0 suspectscore=3 phishscore=0 bulkscore=0 spamscore=0 clxscore=1015 lowpriorityscore=0 impostorscore=0 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1709140000 definitions=main-1803010245 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x [generic] [fuzzy] X-Received-From: 148.163.158.5 Subject: [Qemu-devel] [PATCH v4 1/2] tpm: extend TPM emulator 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: marcandre.lureau@redhat.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 backend device 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. In case the setting of the state blobs fails, we return a negative errno code to fail the start of the VM. 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 Reviewed-by: Marc-Andr=C3=A9 Lureau --- hw/tpm/tpm_emulator.c | 312 ++++++++++++++++++++++++++++++++++++++++++++++= ++-- 1 file changed, 302 insertions(+), 10 deletions(-) diff --git a/hw/tpm/tpm_emulator.c b/hw/tpm/tpm_emulator.c index b787aee..da877e5 100644 --- a/hw/tpm/tpm_emulator.c +++ b/hw/tpm/tpm_emulator.c @@ -55,6 +55,19 @@ #define TPM_EMULATOR_IMPLEMENTS_ALL_CAPS(S, cap) (((S)->caps & (cap)) =3D= =3D (cap)) =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 @@ -70,6 +83,8 @@ typedef struct TPMEmulator { =20 unsigned int established_flag:1; unsigned int established_flag_cached:1; + + TPMBlobBuffers state_blobs; } TPMEmulator; =20 =20 @@ -301,7 +316,8 @@ static int tpm_emulator_set_buffer_size(TPMBackend *tb, return 0; } =20 -static int tpm_emulator_startup_tpm(TPMBackend *tb, size_t buffersize) +static int _tpm_emulator_startup_tpm(TPMBackend *tb, size_t buffersize, + bool is_resume) { TPMEmulator *tpm_emu =3D TPM_EMULATOR(tb); ptm_init init =3D { @@ -309,12 +325,17 @@ static int tpm_emulator_startup_tpm(TPMBackend *tb, s= ize_t buffersize) }; ptm_res res; =20 + DPRINTF("%s is_resume: %d", __func__, is_resume); + if (buffersize !=3D 0 && tpm_emulator_set_buffer_size(tb, buffersize, NULL) < 0) { goto err_exit; } =20 - DPRINTF("%s", __func__); + if (is_resume) { + init.u.req.init_flags =3D cpu_to_be32(PTM_INIT_FLAG_DELETE_VOLATIL= E); + } + if (tpm_emulator_ctrlcmd(tpm_emu, CMD_INIT, &init, sizeof(init), sizeof(init)) < 0) { error_report("tpm-emulator: could not send INIT: %s", @@ -333,6 +354,11 @@ err_exit: return -1; } =20 +static int tpm_emulator_startup_tpm(TPMBackend *tb, size_t buffersize) +{ + return _tpm_emulator_startup_tpm(tb, buffersize, false); +} + static bool tpm_emulator_get_tpm_established_flag(TPMBackend *tb) { TPMEmulator *tpm_emu =3D TPM_EMULATOR(tb); @@ -431,16 +457,21 @@ static size_t tpm_emulator_get_buffer_size(TPMBackend= *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; @@ -569,6 +600,263 @@ static const QemuOptDesc tpm_emulator_cmdline_opts[] = =3D { { /* end of list */ }, }; =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, 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); + 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) < 0 || + tpm_emulator_get_state_blob(tpm_emu, PTM_BLOB_TYPE_VOLATILE, + &state_blobs->volatil, + &state_blobs->volatil_flags) < 0 || + tpm_emulator_get_state_blob(tpm_emu, PTM_BLOB_TYPE_SAVESTATE, + &state_blobs->savestate, + &state_blobs->savestate_flags) < 0) { + 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, 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; +} + +/* + * Set all the TPM state blobs. + * + * Returns a negative errno code in case of error. + */ +static int tpm_emulator_set_state_blobs(TPMBackend *tb) +{ + TPMEmulator *tpm_emu =3D TPM_EMULATOR(tb); + TPMBlobBuffers *state_blobs =3D &tpm_emu->state_blobs; + + DPRINTF("%s: %d", __func__, __LINE__); + + if (tpm_emulator_stop_tpm(tb) < 0) { + return -EIO; + } + + if (tpm_emulator_set_state_blob(tpm_emu, PTM_BLOB_TYPE_PERMANENT, + &state_blobs->permanent, + state_blobs->permanent_flags) < 0 || + tpm_emulator_set_state_blob(tpm_emu, PTM_BLOB_TYPE_VOLATILE, + &state_blobs->volatil, + state_blobs->volatil_flags) < 0 || + tpm_emulator_set_state_blob(tpm_emu, PTM_BLOB_TYPE_SAVESTATE, + &state_blobs->savestate, + state_blobs->savestate_flags) < 0) { + return -EBADMSG; + } + + 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_finish_sync(tb); + + /* get the state blobs from the TPM */ + return tpm_emulator_get_state_blobs(tpm_emu); +} + +/* + * Load the TPM state blobs into the TPM. + * + * Returns negative errno codes in case of error. + */ +static int tpm_emulator_post_load(void *opaque, + int version_id __attribute__((unused))) +{ + TPMBackend *tb =3D opaque; + int ret; + + ret =3D tpm_emulator_set_state_blobs(tb); + if (ret < 0) { + return ret; + } + + if (_tpm_emulator_startup_tpm(tb, 0, true) < 0) { + return -EIO; + } + + return 0; +} + +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); @@ -577,6 +865,8 @@ static void tpm_emulator_inst_init(Object *obj) tpm_emu->options =3D g_new0(TPMEmulatorOptions, 1); tpm_emu->cur_locty_number =3D ~0; qemu_mutex_init(&tpm_emu->mutex); + + vmstate_register(NULL, -1, &vmstate_tpm_emulator, obj); } =20 /* @@ -613,6 +903,8 @@ static void tpm_emulator_inst_finalize(Object *obj) } =20 qemu_mutex_destroy(&tpm_emu->mutex); + + vmstate_unregister(NULL, &vmstate_tpm_emulator, obj); } =20 static void tpm_emulator_class_init(ObjectClass *klass, void *data) --=20 2.5.5 From nobody Sun Feb 8 11:16:19 2026 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 15199351077491007.0862676581933; Thu, 1 Mar 2018 12:11:47 -0800 (PST) Received: from localhost ([::1]:59103 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1erUYM-0008Qz-Ma for importer@patchew.org; Thu, 01 Mar 2018 15:11:46 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:48914) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1erUMm-0006v3-Tj for qemu-devel@nongnu.org; Thu, 01 Mar 2018 14:59:52 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1erUMj-0002eb-SH for qemu-devel@nongnu.org; Thu, 01 Mar 2018 14:59:48 -0500 Received: from mx0a-001b2d01.pphosted.com ([148.163.156.1]:53224) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1erUMj-0002e0-Jw for qemu-devel@nongnu.org; Thu, 01 Mar 2018 14:59:45 -0500 Received: from pps.filterd (m0098393.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.16.0.22/8.16.0.22) with SMTP id w21JxEX7124546 for ; Thu, 1 Mar 2018 14:59:44 -0500 Received: from e34.co.us.ibm.com (e34.co.us.ibm.com [32.97.110.152]) by mx0a-001b2d01.pphosted.com with ESMTP id 2geprxbkys-1 (version=TLSv1.2 cipher=AES256-SHA bits=256 verify=NOT) for ; Thu, 01 Mar 2018 14:59:43 -0500 Received: from localhost by e34.co.us.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Thu, 1 Mar 2018 12:59:43 -0700 Received: from b03cxnp08026.gho.boulder.ibm.com (9.17.130.18) by e34.co.us.ibm.com (192.168.1.134) with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted; Thu, 1 Mar 2018 12:59:39 -0700 Received: from b03ledav005.gho.boulder.ibm.com (b03ledav005.gho.boulder.ibm.com [9.17.130.236]) by b03cxnp08026.gho.boulder.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id w21JxdLn10617102; Thu, 1 Mar 2018 12:59:39 -0700 Received: from b03ledav005.gho.boulder.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 2F9DDBE03B; Thu, 1 Mar 2018 12:59:39 -0700 (MST) Received: from sbct-3.watson.ibm.com (unknown [9.47.158.153]) by b03ledav005.gho.boulder.ibm.com (Postfix) with ESMTP id D336EBE03A; Thu, 1 Mar 2018 12:59:38 -0700 (MST) From: Stefan Berger To: qemu-devel@nongnu.org Date: Thu, 1 Mar 2018 14:59:33 -0500 X-Mailer: git-send-email 2.5.5 In-Reply-To: <1519934373-3629-1-git-send-email-stefanb@linux.vnet.ibm.com> References: <1519934373-3629-1-git-send-email-stefanb@linux.vnet.ibm.com> X-TM-AS-GCONF: 00 x-cbid: 18030119-0016-0000-0000-000008551C5B X-IBM-SpamModules-Scores: X-IBM-SpamModules-Versions: BY=3.00008609; HX=3.00000241; KW=3.00000007; PH=3.00000004; SC=3.00000254; SDB=6.00996930; UDB=6.00506869; IPR=6.00776249; MB=3.00019805; MTD=3.00000008; XFM=3.00000015; UTC=2018-03-01 19:59:41 X-IBM-AV-DETECTION: SAVI=unused REMOTE=unused XFE=unused x-cbparentid: 18030119-0017-0000-0000-00003DAC3F2B Message-Id: <1519934373-3629-3-git-send-email-stefanb@linux.vnet.ibm.com> X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10432:, , definitions=2018-03-01_10:, , signatures=0 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 priorityscore=1501 malwarescore=0 suspectscore=1 phishscore=0 bulkscore=0 spamscore=0 clxscore=1015 lowpriorityscore=0 impostorscore=0 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1709140000 definitions=main-1803010245 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x [generic] [fuzzy] X-Received-From: 148.163.156.1 Subject: [Qemu-devel] [PATCH v4 2/2] tpm: extend TPM 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: marcandre.lureau@redhat.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 TIS interface with state migration support. We need to synchronize with the backend thread to make sure that a command being processed by the external TPM emulator has completed and its response been received. Signed-off-by: Stefan Berger --- hw/tpm/tpm_tis.c | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++++= +- 1 file changed, 53 insertions(+), 1 deletion(-) diff --git a/hw/tpm/tpm_tis.c b/hw/tpm/tpm_tis.c index 834eef7..5016d28 100644 --- a/hw/tpm/tpm_tis.c +++ b/hw/tpm/tpm_tis.c @@ -902,9 +902,61 @@ static void tpm_tis_reset(DeviceState *dev) tpm_backend_startup_tpm(s->be_driver, s->be_buffer_size); } =20 +/* persistent state handling */ + +static int tpm_tis_pre_save(void *opaque) +{ + TPMState *s =3D opaque; + uint8_t locty =3D s->active_locty; + + DPRINTF("tpm_tis: suspend: locty =3D %d : rw_offset =3D %u\n", + locty, s->rw_offset); +#ifdef DEBUG_TIS + tpm_tis_dump_state(opaque, 0); +#endif + + /* + * Synchronize with backend completion. + */ + tpm_backend_finish_sync(s->be_driver); + + 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, + .fields =3D (VMStateField[]) { + VMSTATE_BUFFER(buffer, TPMState), + VMSTATE_UINT16(rw_offset, TPMState), + VMSTATE_UINT8(active_locty, TPMState), + VMSTATE_UINT8(aborting_locty, TPMState), + VMSTATE_UINT8(next_locty, TPMState), + + VMSTATE_STRUCT_ARRAY(loc, TPMState, TPM_TIS_NUM_LOCALITIES, 1, + vmstate_locty, TPMLocality), + + VMSTATE_END_OF_LIST() + } }; =20 static Property tpm_tis_properties[] =3D { --=20 2.5.5