Skip to content

Commit

Permalink
bhyve: do not hold CRB mutex when executing TPM commands
Browse files Browse the repository at this point in the history
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
  • Loading branch information
ckoehne committed Jul 25, 2023
1 parent b9b8a47 commit f0124ab
Showing 1 changed file with 20 additions and 3 deletions.
23 changes: 20 additions & 3 deletions usr.sbin/bhyve/tpm_intf_crb.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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
Expand All @@ -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);

Expand Down

0 comments on commit f0124ab

Please sign in to comment.