Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 25 Jul 2023 06:50:59 GMT
From:      =?utf-8?Q?Corvin=20K=C3=B6hne?= <corvink@FreeBSD.org>
To:        src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org
Subject:   git: f0124ab11122 - main - bhyve: do not hold CRB mutex when executing TPM commands
Message-ID:  <202307250650.36P6oxmu081412@gitrepo.freebsd.org>

next in thread | raw e-mail | index | archive | help
The branch main has been updated by corvink:

URL: https://cgit.FreeBSD.org/src/commit/?id=f0124ab11122c24166fe83ae6898f629721a7894

commit f0124ab11122c24166fe83ae6898f629721a7894
Author:     Corvin Köhne <corvink@FreeBSD.org>
AuthorDate: 2023-06-23 06:31:38 +0000
Commit:     Corvin Köhne <corvink@FreeBSD.org>
CommitDate: 2023-07-25 06:50:23 +0000

    bhyve: do not hold CRB mutex when executing TPM commands
    
    TPM commands can take up to several seconds to execute. If we hold the
    CRB mutex while executing the command, MMIO accesses could be blocked
    for a long time. Therefore, just copy all required values and work on
    the copied values.
    
    Reviewed by:            markj
    MFC after:              1 week
    Sponsored by:           Beckhoff Automation GmbH & Co. KG
    Differential Revision:  https://reviews.freebsd.org/D40724
---
 usr.sbin/bhyve/tpm_intf_crb.c | 23 ++++++++++++++++++++---
 1 file changed, 20 insertions(+), 3 deletions(-)

diff --git a/usr.sbin/bhyve/tpm_intf_crb.c b/usr.sbin/bhyve/tpm_intf_crb.c
index a8e84f911c8d..c4bfaa19958d 100644
--- a/usr.sbin/bhyve/tpm_intf_crb.c
+++ b/usr.sbin/bhyve/tpm_intf_crb.c
@@ -184,6 +184,13 @@ tpm_crb_thread(void *const arg)
 
 	pthread_mutex_lock(&crb->mutex);
 	for (;;) {
+		/*
+		 * We're releasing the lock after wake up. Therefore, we have to
+		 * check the closing condition before and after going to sleep.
+		 */
+		if (crb->closing)
+			break;
+
 		pthread_cond_wait(&crb->cond, &crb->mutex);
 
 		if (crb->closing)
@@ -208,6 +215,16 @@ tpm_crb_thread(void *const arg)
 			break;
 		}
 
+		uint8_t cmd[TPM_CRB_DATA_BUFFER_SIZE];
+		memcpy(cmd, crb->regs.data_buffer, TPM_CRB_DATA_BUFFER_SIZE);
+
+		/*
+		 * A TPM command can take multiple seconds to execute. As we've
+		 * copied all required values and buffers at this point, we can
+		 * release the mutex.
+		 */
+		pthread_mutex_unlock(&crb->mutex);
+
 		/*
 		 * The command response buffer interface uses a single buffer
 		 * for sending a command to and receiving a response from the
@@ -221,10 +238,10 @@ tpm_crb_thread(void *const arg)
 		 * response.
 		 */
 		uint8_t rsp[TPM_CRB_DATA_BUFFER_SIZE] = { 0 };
-		crb->emul->execute_cmd(crb->emul_sc,
-		    &crb->regs.data_buffer[cmd_off], cmd_size, &rsp[rsp_off],
-		    rsp_size);
+		crb->emul->execute_cmd(crb->emul_sc, &cmd[cmd_off], cmd_size,
+		    &rsp[rsp_off], rsp_size);
 
+		pthread_mutex_lock(&crb->mutex);
 		memset(crb->regs.data_buffer, 0, TPM_CRB_DATA_BUFFER_SIZE);
 		memcpy(&crb->regs.data_buffer[rsp_off], &rsp[rsp_off], rsp_size);
 



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202307250650.36P6oxmu081412>