diff --git a/usr.sbin/bhyve/tpm_intf_crb.c b/usr.sbin/bhyve/tpm_intf_crb.c --- a/usr.sbin/bhyve/tpm_intf_crb.c +++ b/usr.sbin/bhyve/tpm_intf_crb.c @@ -208,6 +208,16 @@ 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 +231,10 @@ * 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);