From 732a8e046948fd62b32cd1dd76a6798eb1caf4d6 Mon Sep 17 00:00:00 2001 From: Stefan Berger Date: Sat, 31 Dec 2016 11:23:32 -0500 Subject: [PATCH 3/4] Introduce condition in TPM backend for notification 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 Upstream-Status: Pending [https://lists.nongnu.org/archive/html/qemu-devel/2016-06/msg00252.html] Signed-off-by: Patrick Ohly --- hw/tpm/tpm_passthrough.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/hw/tpm/tpm_passthrough.c b/hw/tpm/tpm_passthrough.c index 050f2ba850..44739ebad2 100644 --- a/hw/tpm/tpm_passthrough.c +++ b/hw/tpm/tpm_passthrough.c @@ -75,6 +75,10 @@ struct TPMPassthruState { TPMVersion tpm_version; ptm_cap cuse_cap; /* capabilities of the CUSE TPM */ uint8_t cur_locty_number; /* last set locality */ + + QemuMutex state_lock; + QemuCond cmd_complete; /* singnaled once tpm_busy is false */ + bool tpm_busy; }; typedef struct TPMPassthruState TPMPassthruState; @@ -274,6 +278,11 @@ static void tpm_passthrough_worker_thread(gpointer data, thr_parms->recv_data_callback(thr_parms->tpm_state, thr_parms->tpm_state->locty_number, selftest_done); + /* result delivered */ + qemu_mutex_lock(&tpm_pt->state_lock); + tpm_pt->tpm_busy = false; + qemu_cond_signal(&tpm_pt->cmd_complete); + qemu_mutex_unlock(&tpm_pt->state_lock); break; case TPM_BACKEND_CMD_INIT: case TPM_BACKEND_CMD_END: @@ -401,6 +410,7 @@ static void tpm_passthrough_reset(TPMBackend *tb) tpm_backend_thread_end(&tpm_pt->tbt); tpm_pt->had_startup_error = false; + tpm_pt->tpm_busy = false; } static int tpm_passthrough_init(TPMBackend *tb, TPMState *s, @@ -478,6 +488,11 @@ static void tpm_passthrough_deliver_request(TPMBackend *tb) { TPMPassthruState *tpm_pt = TPM_PASSTHROUGH(tb); + /* TPM considered busy once TPM Request scheduled for processing */ + qemu_mutex_lock(&tpm_pt->state_lock); + tpm_pt->tpm_busy = true; + qemu_mutex_unlock(&tpm_pt->state_lock); + tpm_backend_thread_deliver_request(&tpm_pt->tbt); } @@ -746,6 +761,11 @@ static const TPMDriverOps tpm_passthrough_driver = { static void tpm_passthrough_inst_init(Object *obj) { + TPMBackend *tb = TPM_BACKEND(obj); + TPMPassthruState *tpm_pt = TPM_PASSTHROUGH(tb); + + qemu_mutex_init(&tpm_pt->state_lock); + qemu_cond_init(&tpm_pt->cmd_complete); } static void tpm_passthrough_inst_finalize(Object *obj) -- 2.11.0