All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH v2 00/28] TPM: code cleanup (not 2.11)
@ 2017-11-06 18:38 Marc-André Lureau
  2017-11-06 18:38 ` [Qemu-devel] [PATCH v2 01/28] tpm-tis: remove unused locty_number Marc-André Lureau
                   ` (28 more replies)
  0 siblings, 29 replies; 44+ messages in thread
From: Marc-André Lureau @ 2017-11-06 18:38 UTC (permalink / raw)
  To: qemu-devel; +Cc: amarnath.valluri, stefanb, Marc-André Lureau

Hi,

Various code cleanups accumulated while doing reviews and implementing
a CRB device (postponed for later), aiming at a tpm-next development
branch for after qemu 2.11.

v2: after Stefan review
- rebased (half of v1 is merged upstream)
- add & use a DEFINE_PROP_TPMBE()
- remove tpm_register_model()
- fix wrong locty_number usage & regression
- tpm-tis: check that at most one TPM device exists
- I changed "tpm-passthrough: remove error cleanup from
  handle_device_opts" to "tpm-passthrough: simplify create()", it is
  mostly the same patch that Stefan didn't like much but with a
  different rationale to have code closer to tpm-emulator create().
- added some signed-offs

Marc-André Lureau (28):
  tpm-tis: remove unused locty_number
  tpm: move TpmIf in include/sysemu/tpm.h
  tpm-backend: store TPMIf interface, improve backend_init()
  tpm-tis: no longer expose TPMState
  tpm-be: call request_completed() out of thread
  tpm-be: report error instead of front-end
  tpm-be: ask model to the TPM interface
  tpm: remove unused opened code
  tpm-passthrough: don't save guessed cancel_path in options
  tpm-be: update optional function pointers
  tpm-passthrough: pass TPMPassthruState to handle_device_opts
  tpm-backend: move set 'id' to common code
  tpm-passthrough: make it safer to destroy after creation
  tpm-passthrough: simplify create()
  tpm-passthrough: workaround a possible race
  tpm-tis: simplify header inclusion
  tpm: rename qemu_find_tpm() -> qemu_find_tpm_be()
  tpm: lookup the the TPM interface instead of TIS device
  tpm: add TPM interface to lookup TPM version
  tpm: add tpm_cmd_get_size() to tpm_util
  acpi: change TPM TIS data conditions
  tpm-emulator: add a FIXME comment about blocking cancel
  tpm-tis: remove redundant 'tpm_tis:' in error messages
  tpm-tis: check that at most one TPM device exists
  tpm-emulator: protect concurrent ctrl_chr access
  qdev: add DEFINE_PROP_TPMBE
  tpm-tis: use DEFINE_PROP_TPMBE
  tpm: remove tpm_register_model()

 hw/tpm/tpm_int.h                 | 22 +----------
 hw/tpm/tpm_util.h                |  8 +++-
 include/hw/qdev-properties.h     |  3 ++
 include/sysemu/tpm.h             | 48 +++++++++++++++++------
 include/sysemu/tpm_backend.h     | 32 ++++++----------
 backends/tpm.c                   | 83 +++++++++++++---------------------------
 hw/core/qdev-properties-system.c | 64 +++++++++++++++++++++++++++++++
 hw/i386/acpi-build.c             | 14 ++++---
 hw/tpm/tpm_emulator.c            | 59 +++++++++++++++-------------
 hw/tpm/tpm_passthrough.c         | 66 +++++++++++---------------------
 hw/tpm/tpm_tis.c                 | 83 +++++++++++++++-------------------------
 tpm.c                            | 34 ++++++----------
 12 files changed, 255 insertions(+), 261 deletions(-)

-- 
2.15.0.rc0.40.gaefcc5f6f

^ permalink raw reply	[flat|nested] 44+ messages in thread

* [Qemu-devel] [PATCH v2 01/28] tpm-tis: remove unused locty_number
  2017-11-06 18:38 [Qemu-devel] [PATCH v2 00/28] TPM: code cleanup (not 2.11) Marc-André Lureau
@ 2017-11-06 18:38 ` Marc-André Lureau
  2017-11-06 18:57   ` Stefan Berger
  2017-11-06 18:38 ` [Qemu-devel] [PATCH v2 02/28] tpm: move TpmIf in include/sysemu/tpm.h Marc-André Lureau
                   ` (27 subsequent siblings)
  28 siblings, 1 reply; 44+ messages in thread
From: Marc-André Lureau @ 2017-11-06 18:38 UTC (permalink / raw)
  To: qemu-devel; +Cc: amarnath.valluri, stefanb, Marc-André Lureau

This field slipped in commit 5086bf9784.

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
 hw/tpm/tpm_tis.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/hw/tpm/tpm_tis.c b/hw/tpm/tpm_tis.c
index 7402528b25..c5c534d7f2 100644
--- a/hw/tpm/tpm_tis.c
+++ b/hw/tpm/tpm_tis.c
@@ -89,7 +89,6 @@ struct TPMState {
     qemu_irq irq;
     uint32_t irq_num;
 
-    uint8_t     locty_number;
     TPMBackendCmd cmd;
 
     char *backend;
-- 
2.15.0.rc0.40.gaefcc5f6f

^ permalink raw reply related	[flat|nested] 44+ messages in thread

* [Qemu-devel] [PATCH v2 02/28] tpm: move TpmIf in include/sysemu/tpm.h
  2017-11-06 18:38 [Qemu-devel] [PATCH v2 00/28] TPM: code cleanup (not 2.11) Marc-André Lureau
  2017-11-06 18:38 ` [Qemu-devel] [PATCH v2 01/28] tpm-tis: remove unused locty_number Marc-André Lureau
@ 2017-11-06 18:38 ` Marc-André Lureau
  2017-11-06 18:58   ` Stefan Berger
  2017-11-06 18:39 ` [Qemu-devel] [PATCH v2 03/28] tpm-backend: store TPMIf interface, improve backend_init() Marc-André Lureau
                   ` (26 subsequent siblings)
  28 siblings, 1 reply; 44+ messages in thread
From: Marc-André Lureau @ 2017-11-06 18:38 UTC (permalink / raw)
  To: qemu-devel; +Cc: amarnath.valluri, stefanb, Marc-André Lureau

This is a better location than hw/tpm, since we are going to use the
interface from outside hw/tpm.

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
 hw/tpm/tpm_int.h     | 22 +---------------------
 include/sysemu/tpm.h | 19 +++++++++++++++++++
 backends/tpm.c       |  1 -
 3 files changed, 20 insertions(+), 22 deletions(-)

diff --git a/hw/tpm/tpm_int.h b/hw/tpm/tpm_int.h
index 9c045b6691..1df5883f3c 100644
--- a/hw/tpm/tpm_int.h
+++ b/hw/tpm/tpm_int.h
@@ -13,28 +13,8 @@
 #define TPM_TPM_INT_H
 
 #include "qemu/osdep.h"
-#include "qom/object.h"
 
-#define TYPE_TPM_IF "tpm-if"
-#define TPM_IF_CLASS(klass) \
-    OBJECT_CLASS_CHECK(TPMIfClass, (klass), TYPE_TPM_IF)
-#define TPM_IF_GET_CLASS(obj) \
-    OBJECT_GET_CLASS(TPMIfClass, (obj), TYPE_TPM_IF)
-#define TPM_IF(obj) \
-    INTERFACE_CHECK(TPMIf, (obj), TYPE_TPM_IF)
-
-typedef struct TPMIf {
-    Object parent_obj;
-} TPMIf;
-
-typedef struct TPMIfClass {
-    InterfaceClass parent_class;
-
-    /* run in thread pool by backend */
-    void (*request_completed)(TPMIf *obj);
-} TPMIfClass;
-
-#define TPM_STANDARD_CMDLINE_OPTS               \
+#define TPM_STANDARD_CMDLINE_OPTS \
     { \
         .name = "type", \
         .type = QEMU_OPT_STRING, \
diff --git a/include/sysemu/tpm.h b/include/sysemu/tpm.h
index d7a2bd8556..452cdb9cb7 100644
--- a/include/sysemu/tpm.h
+++ b/include/sysemu/tpm.h
@@ -27,6 +27,25 @@ typedef enum  TPMVersion {
     TPM_VERSION_2_0 = 2,
 } TPMVersion;
 
+#define TYPE_TPM_IF "tpm-if"
+#define TPM_IF_CLASS(klass)                                 \
+    OBJECT_CLASS_CHECK(TPMIfClass, (klass), TYPE_TPM_IF)
+#define TPM_IF_GET_CLASS(obj)                           \
+    OBJECT_GET_CLASS(TPMIfClass, (obj), TYPE_TPM_IF)
+#define TPM_IF(obj)                             \
+    INTERFACE_CHECK(TPMIf, (obj), TYPE_TPM_IF)
+
+typedef struct TPMIf {
+    Object parent_obj;
+} TPMIf;
+
+typedef struct TPMIfClass {
+    InterfaceClass parent_class;
+
+    /* run in thread pool by backend */
+    void (*request_completed)(TPMIf *obj);
+} TPMIfClass;
+
 TPMVersion tpm_tis_get_tpm_version(Object *obj);
 
 #define TYPE_TPM_TIS                "tpm-tis"
diff --git a/backends/tpm.c b/backends/tpm.c
index 5763f6f369..1e416d7f90 100644
--- a/backends/tpm.c
+++ b/backends/tpm.c
@@ -17,7 +17,6 @@
 #include "qapi/error.h"
 #include "qapi/qmp/qerror.h"
 #include "sysemu/tpm.h"
-#include "hw/tpm/tpm_int.h"
 #include "qemu/thread.h"
 
 static void tpm_backend_worker_thread(gpointer data, gpointer user_data)
-- 
2.15.0.rc0.40.gaefcc5f6f

^ permalink raw reply related	[flat|nested] 44+ messages in thread

* [Qemu-devel] [PATCH v2 03/28] tpm-backend: store TPMIf interface, improve backend_init()
  2017-11-06 18:38 [Qemu-devel] [PATCH v2 00/28] TPM: code cleanup (not 2.11) Marc-André Lureau
  2017-11-06 18:38 ` [Qemu-devel] [PATCH v2 01/28] tpm-tis: remove unused locty_number Marc-André Lureau
  2017-11-06 18:38 ` [Qemu-devel] [PATCH v2 02/28] tpm: move TpmIf in include/sysemu/tpm.h Marc-André Lureau
@ 2017-11-06 18:39 ` Marc-André Lureau
  2017-11-06 19:02   ` Stefan Berger
  2017-11-06 18:39 ` [Qemu-devel] [PATCH v2 04/28] tpm-tis: no longer expose TPMState Marc-André Lureau
                   ` (25 subsequent siblings)
  28 siblings, 1 reply; 44+ messages in thread
From: Marc-André Lureau @ 2017-11-06 18:39 UTC (permalink / raw)
  To: qemu-devel; +Cc: amarnath.valluri, stefanb, Marc-André Lureau

Store the TPM interface, the actual object may be different from
TPMState. Keep a reference on the interface, and check the backend
wasn't already initialized.

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
 include/sysemu/tpm.h         |  2 +-
 include/sysemu/tpm_backend.h |  6 +++---
 backends/tpm.c               | 11 +++++++++--
 hw/tpm/tpm_emulator.c        |  4 ++--
 hw/tpm/tpm_passthrough.c     |  4 ++--
 hw/tpm/tpm_tis.c             |  2 +-
 6 files changed, 18 insertions(+), 11 deletions(-)

diff --git a/include/sysemu/tpm.h b/include/sysemu/tpm.h
index 452cdb9cb7..fb1719e5e4 100644
--- a/include/sysemu/tpm.h
+++ b/include/sysemu/tpm.h
@@ -12,8 +12,8 @@
 #ifndef QEMU_TPM_H
 #define QEMU_TPM_H
 
-#include "qemu/option.h"
 #include "qom/object.h"
+#include "qapi-types.h"
 
 typedef struct TPMState TPMState;
 
diff --git a/include/sysemu/tpm_backend.h b/include/sysemu/tpm_backend.h
index 03ea5a3400..b5f21ed8f1 100644
--- a/include/sysemu/tpm_backend.h
+++ b/include/sysemu/tpm_backend.h
@@ -43,8 +43,8 @@ struct TPMBackend {
     Object parent;
 
     /*< protected >*/
+    TPMIf *tpmif;
     bool opened;
-    TPMState *tpm_state;
     GThreadPool *thread_pool;
     bool had_startup_error;
 
@@ -96,14 +96,14 @@ enum TpmType tpm_backend_get_type(TPMBackend *s);
 /**
  * tpm_backend_init:
  * @s: the backend to initialized
- * @state: TPMState
+ * @tpmif: TPM interface
  * @datacb: callback for sending data to frontend
  *
  * Initialize the backend with the given variables.
  *
  * Returns 0 on success.
  */
-int tpm_backend_init(TPMBackend *s, TPMState *state);
+int tpm_backend_init(TPMBackend *s, TPMIf *tpmif);
 
 /**
  * tpm_backend_startup_tpm:
diff --git a/backends/tpm.c b/backends/tpm.c
index 1e416d7f90..86f0e7e915 100644
--- a/backends/tpm.c
+++ b/backends/tpm.c
@@ -43,9 +43,15 @@ enum TpmType tpm_backend_get_type(TPMBackend *s)
     return k->type;
 }
 
-int tpm_backend_init(TPMBackend *s, TPMState *state)
+int tpm_backend_init(TPMBackend *s, TPMIf *tpmif)
 {
-    s->tpm_state = state;
+    if (s->tpmif) {
+        return -1;
+    }
+
+    s->tpmif = tpmif;
+    object_ref(OBJECT(tpmif));
+
     s->had_startup_error = false;
 
     return 0;
@@ -193,6 +199,7 @@ static void tpm_backend_instance_finalize(Object *obj)
 {
     TPMBackend *s = TPM_BACKEND(obj);
 
+    object_unref(OBJECT(s->tpmif));
     g_free(s->id);
     tpm_backend_thread_end(s);
 }
diff --git a/hw/tpm/tpm_emulator.c b/hw/tpm/tpm_emulator.c
index 9aaec8e3ef..6bf025c7e2 100644
--- a/hw/tpm/tpm_emulator.c
+++ b/hw/tpm/tpm_emulator.c
@@ -176,7 +176,7 @@ static int tpm_emulator_set_locality(TPMEmulator *tpm_emu, uint8_t locty_number,
 static void tpm_emulator_handle_request(TPMBackend *tb, TPMBackendCmd *cmd)
 {
     TPMEmulator *tpm_emu = TPM_EMULATOR(tb);
-    TPMIfClass *tic = TPM_IF_GET_CLASS(tb->tpm_state);
+    TPMIfClass *tic = TPM_IF_GET_CLASS(tb->tpmif);
     Error *err = NULL;
 
     DPRINTF("processing TPM command");
@@ -191,7 +191,7 @@ static void tpm_emulator_handle_request(TPMBackend *tb, TPMBackendCmd *cmd)
         goto error;
     }
 
-    tic->request_completed(TPM_IF(tb->tpm_state));
+    tic->request_completed(tb->tpmif);
     return;
 
 error:
diff --git a/hw/tpm/tpm_passthrough.c b/hw/tpm/tpm_passthrough.c
index c440aff4b2..2ad74badca 100644
--- a/hw/tpm/tpm_passthrough.c
+++ b/hw/tpm/tpm_passthrough.c
@@ -139,14 +139,14 @@ err_exit:
 static void tpm_passthrough_handle_request(TPMBackend *tb, TPMBackendCmd *cmd)
 {
     TPMPassthruState *tpm_pt = TPM_PASSTHROUGH(tb);
-    TPMIfClass *tic = TPM_IF_GET_CLASS(tb->tpm_state);
+    TPMIfClass *tic = TPM_IF_GET_CLASS(tb->tpmif);
 
     DPRINTF("tpm_passthrough: processing command %p\n", cmd);
 
     tpm_passthrough_unix_tx_bufs(tpm_pt, cmd->in, cmd->in_len,
                                  cmd->out, cmd->out_len, &cmd->selftest_done);
 
-    tic->request_completed(TPM_IF(tb->tpm_state));
+    tic->request_completed(tb->tpmif);
 }
 
 static void tpm_passthrough_reset(TPMBackend *tb)
diff --git a/hw/tpm/tpm_tis.c b/hw/tpm/tpm_tis.c
index c5c534d7f2..34ceec91c3 100644
--- a/hw/tpm/tpm_tis.c
+++ b/hw/tpm/tpm_tis.c
@@ -1078,7 +1078,7 @@ static void tpm_tis_realizefn(DeviceState *dev, Error **errp)
 
     s->be_driver->fe_model = TPM_MODEL_TPM_TIS;
 
-    if (tpm_backend_init(s->be_driver, s)) {
+    if (tpm_backend_init(s->be_driver, TPM_IF(s))) {
         error_setg(errp, "tpm_tis: backend driver with id %s could not be "
                    "initialized", s->backend);
         return;
-- 
2.15.0.rc0.40.gaefcc5f6f

^ permalink raw reply related	[flat|nested] 44+ messages in thread

* [Qemu-devel] [PATCH v2 04/28] tpm-tis: no longer expose TPMState
  2017-11-06 18:38 [Qemu-devel] [PATCH v2 00/28] TPM: code cleanup (not 2.11) Marc-André Lureau
                   ` (2 preceding siblings ...)
  2017-11-06 18:39 ` [Qemu-devel] [PATCH v2 03/28] tpm-backend: store TPMIf interface, improve backend_init() Marc-André Lureau
@ 2017-11-06 18:39 ` Marc-André Lureau
  2017-11-06 18:39 ` [Qemu-devel] [PATCH v2 05/28] tpm-be: call request_completed() out of thread Marc-André Lureau
                   ` (24 subsequent siblings)
  28 siblings, 0 replies; 44+ messages in thread
From: Marc-André Lureau @ 2017-11-06 18:39 UTC (permalink / raw)
  To: qemu-devel; +Cc: amarnath.valluri, stefanb, Marc-André Lureau

Now that there is an interface instead.

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Reviewed-by: Stefan Berger <stefanb@linux.vnet.ibm.com>
---
 include/sysemu/tpm.h | 2 --
 hw/tpm/tpm_tis.c     | 4 ++--
 2 files changed, 2 insertions(+), 4 deletions(-)

diff --git a/include/sysemu/tpm.h b/include/sysemu/tpm.h
index fb1719e5e4..7a1713a81e 100644
--- a/include/sysemu/tpm.h
+++ b/include/sysemu/tpm.h
@@ -15,8 +15,6 @@
 #include "qom/object.h"
 #include "qapi-types.h"
 
-typedef struct TPMState TPMState;
-
 int tpm_config_parse(QemuOptsList *opts_list, const char *optarg);
 int tpm_init(void);
 void tpm_cleanup(void);
diff --git a/hw/tpm/tpm_tis.c b/hw/tpm/tpm_tis.c
index 34ceec91c3..4a8a2ffc79 100644
--- a/hw/tpm/tpm_tis.c
+++ b/hw/tpm/tpm_tis.c
@@ -72,7 +72,7 @@ typedef struct TPMLocality {
     TPMSizedBuffer r_buffer;
 } TPMLocality;
 
-struct TPMState {
+typedef struct TPMState {
     ISADevice busdev;
     MemoryRegion mmio;
 
@@ -94,7 +94,7 @@ struct TPMState {
     char *backend;
     TPMBackend *be_driver;
     TPMVersion be_tpm_version;
-};
+} TPMState;
 
 #define TPM(obj) OBJECT_CHECK(TPMState, (obj), TYPE_TPM_TIS)
 
-- 
2.15.0.rc0.40.gaefcc5f6f

^ permalink raw reply related	[flat|nested] 44+ messages in thread

* [Qemu-devel] [PATCH v2 05/28] tpm-be: call request_completed() out of thread
  2017-11-06 18:38 [Qemu-devel] [PATCH v2 00/28] TPM: code cleanup (not 2.11) Marc-André Lureau
                   ` (3 preceding siblings ...)
  2017-11-06 18:39 ` [Qemu-devel] [PATCH v2 04/28] tpm-tis: no longer expose TPMState Marc-André Lureau
@ 2017-11-06 18:39 ` Marc-André Lureau
  2017-11-06 19:22   ` Stefan Berger
  2017-11-06 18:39 ` [Qemu-devel] [PATCH v2 06/28] tpm-be: report error instead of front-end Marc-André Lureau
                   ` (23 subsequent siblings)
  28 siblings, 1 reply; 44+ messages in thread
From: Marc-André Lureau @ 2017-11-06 18:39 UTC (permalink / raw)
  To: qemu-devel; +Cc: amarnath.valluri, stefanb, Marc-André Lureau

Lift from the backend implementation the responsability to call the
request_completed() callback outside of thread context. This also
simplify frontend/interface work, as they no longer need to care
whether the callback is called from a different thread.

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
 include/sysemu/tpm.h         |  1 -
 include/sysemu/tpm_backend.h |  1 +
 backends/tpm.c               | 15 ++++++++++++++-
 hw/tpm/tpm_emulator.c        |  2 --
 hw/tpm/tpm_passthrough.c     |  3 ---
 hw/tpm/tpm_tis.c             | 34 ++++++++++++----------------------
 6 files changed, 27 insertions(+), 29 deletions(-)

diff --git a/include/sysemu/tpm.h b/include/sysemu/tpm.h
index 7a1713a81e..e0879620e7 100644
--- a/include/sysemu/tpm.h
+++ b/include/sysemu/tpm.h
@@ -40,7 +40,6 @@ typedef struct TPMIf {
 typedef struct TPMIfClass {
     InterfaceClass parent_class;
 
-    /* run in thread pool by backend */
     void (*request_completed)(TPMIf *obj);
 } TPMIfClass;
 
diff --git a/include/sysemu/tpm_backend.h b/include/sysemu/tpm_backend.h
index b5f21ed8f1..c5d1a6818a 100644
--- a/include/sysemu/tpm_backend.h
+++ b/include/sysemu/tpm_backend.h
@@ -47,6 +47,7 @@ struct TPMBackend {
     bool opened;
     GThreadPool *thread_pool;
     bool had_startup_error;
+    QEMUBH *bh;
 
     /* <public> */
     char *id;
diff --git a/backends/tpm.c b/backends/tpm.c
index 86f0e7e915..58f823d54c 100644
--- a/backends/tpm.c
+++ b/backends/tpm.c
@@ -18,14 +18,25 @@
 #include "qapi/qmp/qerror.h"
 #include "sysemu/tpm.h"
 #include "qemu/thread.h"
+#include "qemu/main-loop.h"
+
+static void tpm_backend_request_completed_bh(void *opaque)
+{
+    TPMBackend *s = TPM_BACKEND(opaque);
+    TPMIfClass *tic = TPM_IF_GET_CLASS(s->tpmif);
+
+    tic->request_completed(s->tpmif);
+}
 
 static void tpm_backend_worker_thread(gpointer data, gpointer user_data)
 {
     TPMBackend *s = TPM_BACKEND(user_data);
-    TPMBackendClass *k  = TPM_BACKEND_GET_CLASS(s);
+    TPMBackendClass *k = TPM_BACKEND_GET_CLASS(s);
 
     assert(k->handle_request != NULL);
     k->handle_request(s, (TPMBackendCmd *)data);
+
+    qemu_bh_schedule(s->bh);
 }
 
 static void tpm_backend_thread_end(TPMBackend *s)
@@ -193,6 +204,7 @@ static void tpm_backend_instance_init(Object *obj)
                              tpm_backend_prop_set_opened,
                              NULL);
     s->fe_model = -1;
+    s->bh = qemu_bh_new(tpm_backend_request_completed_bh, s);
 }
 
 static void tpm_backend_instance_finalize(Object *obj)
@@ -202,6 +214,7 @@ static void tpm_backend_instance_finalize(Object *obj)
     object_unref(OBJECT(s->tpmif));
     g_free(s->id);
     tpm_backend_thread_end(s);
+    qemu_bh_delete(s->bh);
 }
 
 static const TypeInfo tpm_backend_info = {
diff --git a/hw/tpm/tpm_emulator.c b/hw/tpm/tpm_emulator.c
index 6bf025c7e2..883e8c0c2d 100644
--- a/hw/tpm/tpm_emulator.c
+++ b/hw/tpm/tpm_emulator.c
@@ -176,7 +176,6 @@ static int tpm_emulator_set_locality(TPMEmulator *tpm_emu, uint8_t locty_number,
 static void tpm_emulator_handle_request(TPMBackend *tb, TPMBackendCmd *cmd)
 {
     TPMEmulator *tpm_emu = TPM_EMULATOR(tb);
-    TPMIfClass *tic = TPM_IF_GET_CLASS(tb->tpmif);
     Error *err = NULL;
 
     DPRINTF("processing TPM command");
@@ -191,7 +190,6 @@ static void tpm_emulator_handle_request(TPMBackend *tb, TPMBackendCmd *cmd)
         goto error;
     }
 
-    tic->request_completed(tb->tpmif);
     return;
 
 error:
diff --git a/hw/tpm/tpm_passthrough.c b/hw/tpm/tpm_passthrough.c
index 2ad74badca..8c002e4da6 100644
--- a/hw/tpm/tpm_passthrough.c
+++ b/hw/tpm/tpm_passthrough.c
@@ -139,14 +139,11 @@ err_exit:
 static void tpm_passthrough_handle_request(TPMBackend *tb, TPMBackendCmd *cmd)
 {
     TPMPassthruState *tpm_pt = TPM_PASSTHROUGH(tb);
-    TPMIfClass *tic = TPM_IF_GET_CLASS(tb->tpmif);
 
     DPRINTF("tpm_passthrough: processing command %p\n", cmd);
 
     tpm_passthrough_unix_tx_bufs(tpm_pt, cmd->in, cmd->in_len,
                                  cmd->out, cmd->out_len, &cmd->selftest_done);
-
-    tic->request_completed(tb->tpmif);
 }
 
 static void tpm_passthrough_reset(TPMBackend *tb)
diff --git a/hw/tpm/tpm_tis.c b/hw/tpm/tpm_tis.c
index 4a8a2ffc79..f81aaf10c3 100644
--- a/hw/tpm/tpm_tis.c
+++ b/hw/tpm/tpm_tis.c
@@ -76,7 +76,6 @@ typedef struct TPMState {
     ISADevice busdev;
     MemoryRegion mmio;
 
-    QEMUBH *bh;
     uint32_t offset;
     uint8_t buf[TPM_TIS_BUFFER_MAX];
 
@@ -410,10 +409,20 @@ static void tpm_tis_prep_abort(TPMState *s, uint8_t locty, uint8_t newlocty)
     tpm_tis_abort(s, locty);
 }
 
-static void tpm_tis_receive_bh(void *opaque)
+/*
+ * Callback from the TPM to indicate that the response was received.
+ */
+static void tpm_tis_request_completed(TPMIf *ti)
 {
-    TPMState *s = opaque;
+    TPMState *s = TPM(ti);
     uint8_t locty = s->cmd.locty;
+    uint8_t l;
+
+    if (s->cmd.selftest_done) {
+        for (l = 0; l < TPM_TIS_NUM_LOCALITIES; l++) {
+            s->loc[locty].sts |= TPM_TIS_STS_SELFTEST_DONE;
+        }
+    }
 
     tpm_tis_sts_set(&s->loc[locty],
                     TPM_TIS_STS_VALID | TPM_TIS_STS_DATA_AVAILABLE);
@@ -431,23 +440,6 @@ static void tpm_tis_receive_bh(void *opaque)
                       TPM_TIS_INT_DATA_AVAILABLE | TPM_TIS_INT_STS_VALID);
 }
 
-static void tpm_tis_request_completed(TPMIf *ti)
-{
-    TPMState *s = TPM(ti);
-
-    bool is_selftest_done = s->cmd.selftest_done;
-    uint8_t locty = s->cmd.locty;
-    uint8_t l;
-
-    if (is_selftest_done) {
-        for (l = 0; l < TPM_TIS_NUM_LOCALITIES; l++) {
-            s->loc[locty].sts |= TPM_TIS_STS_SELFTEST_DONE;
-        }
-    }
-
-    qemu_bh_schedule(s->bh);
-}
-
 /*
  * Read a byte of response data
  */
@@ -1090,8 +1082,6 @@ static void tpm_tis_realizefn(DeviceState *dev, Error **errp)
         return;
     }
 
-    s->bh = qemu_bh_new(tpm_tis_receive_bh, s);
-
     isa_init_irq(&s->busdev, &s->irq, s->irq_num);
 
     memory_region_add_subregion(isa_address_space(ISA_DEVICE(dev)),
-- 
2.15.0.rc0.40.gaefcc5f6f

^ permalink raw reply related	[flat|nested] 44+ messages in thread

* [Qemu-devel] [PATCH v2 06/28] tpm-be: report error instead of front-end
  2017-11-06 18:38 [Qemu-devel] [PATCH v2 00/28] TPM: code cleanup (not 2.11) Marc-André Lureau
                   ` (4 preceding siblings ...)
  2017-11-06 18:39 ` [Qemu-devel] [PATCH v2 05/28] tpm-be: call request_completed() out of thread Marc-André Lureau
@ 2017-11-06 18:39 ` Marc-André Lureau
  2017-11-06 18:39 ` [Qemu-devel] [PATCH v2 07/28] tpm-be: ask model to the TPM interface Marc-André Lureau
                   ` (22 subsequent siblings)
  28 siblings, 0 replies; 44+ messages in thread
From: Marc-André Lureau @ 2017-11-06 18:39 UTC (permalink / raw)
  To: qemu-devel; +Cc: amarnath.valluri, stefanb, Marc-André Lureau

Backend can give more accurate error description, and lift out the job
from the frontend.

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Reviewed-by: Stefan Berger <stefanb@linux.vnet.ibm.com>
---
 include/sysemu/tpm_backend.h | 3 ++-
 backends/tpm.c               | 3 ++-
 hw/tpm/tpm_tis.c             | 4 +---
 3 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/include/sysemu/tpm_backend.h b/include/sysemu/tpm_backend.h
index c5d1a6818a..df9ebd0e81 100644
--- a/include/sysemu/tpm_backend.h
+++ b/include/sysemu/tpm_backend.h
@@ -99,12 +99,13 @@ enum TpmType tpm_backend_get_type(TPMBackend *s);
  * @s: the backend to initialized
  * @tpmif: TPM interface
  * @datacb: callback for sending data to frontend
+ * @errp: a pointer to return the #Error object if an error occurs.
  *
  * Initialize the backend with the given variables.
  *
  * Returns 0 on success.
  */
-int tpm_backend_init(TPMBackend *s, TPMIf *tpmif);
+int tpm_backend_init(TPMBackend *s, TPMIf *tpmif, Error **errp);
 
 /**
  * tpm_backend_startup_tpm:
diff --git a/backends/tpm.c b/backends/tpm.c
index 58f823d54c..7b108bd5d8 100644
--- a/backends/tpm.c
+++ b/backends/tpm.c
@@ -54,9 +54,10 @@ enum TpmType tpm_backend_get_type(TPMBackend *s)
     return k->type;
 }
 
-int tpm_backend_init(TPMBackend *s, TPMIf *tpmif)
+int tpm_backend_init(TPMBackend *s, TPMIf *tpmif, Error **errp)
 {
     if (s->tpmif) {
+        error_setg(errp, "TPM backend '%s' is already initialized", s->id);
         return -1;
     }
 
diff --git a/hw/tpm/tpm_tis.c b/hw/tpm/tpm_tis.c
index f81aaf10c3..2febc8bd08 100644
--- a/hw/tpm/tpm_tis.c
+++ b/hw/tpm/tpm_tis.c
@@ -1070,9 +1070,7 @@ static void tpm_tis_realizefn(DeviceState *dev, Error **errp)
 
     s->be_driver->fe_model = TPM_MODEL_TPM_TIS;
 
-    if (tpm_backend_init(s->be_driver, TPM_IF(s))) {
-        error_setg(errp, "tpm_tis: backend driver with id %s could not be "
-                   "initialized", s->backend);
+    if (tpm_backend_init(s->be_driver, TPM_IF(s), errp)) {
         return;
     }
 
-- 
2.15.0.rc0.40.gaefcc5f6f

^ permalink raw reply related	[flat|nested] 44+ messages in thread

* [Qemu-devel] [PATCH v2 07/28] tpm-be: ask model to the TPM interface
  2017-11-06 18:38 [Qemu-devel] [PATCH v2 00/28] TPM: code cleanup (not 2.11) Marc-André Lureau
                   ` (5 preceding siblings ...)
  2017-11-06 18:39 ` [Qemu-devel] [PATCH v2 06/28] tpm-be: report error instead of front-end Marc-André Lureau
@ 2017-11-06 18:39 ` Marc-André Lureau
  2017-11-06 18:39 ` [Qemu-devel] [PATCH v2 08/28] tpm: remove unused opened code Marc-André Lureau
                   ` (21 subsequent siblings)
  28 siblings, 0 replies; 44+ messages in thread
From: Marc-André Lureau @ 2017-11-06 18:39 UTC (permalink / raw)
  To: qemu-devel; +Cc: amarnath.valluri, stefanb, Marc-André Lureau

No need to store the mode in the backend, or to let the frontend set
it itself.

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Reviewed-by: Stefan Berger <stefanb@linux.vnet.ibm.com>
---
 include/sysemu/tpm.h         | 1 +
 include/sysemu/tpm_backend.h | 1 -
 backends/tpm.c               | 4 ++--
 hw/tpm/tpm_tis.c             | 3 +--
 tpm.c                        | 3 ++-
 5 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/include/sysemu/tpm.h b/include/sysemu/tpm.h
index e0879620e7..7b407caf25 100644
--- a/include/sysemu/tpm.h
+++ b/include/sysemu/tpm.h
@@ -40,6 +40,7 @@ typedef struct TPMIf {
 typedef struct TPMIfClass {
     InterfaceClass parent_class;
 
+    enum TpmModel model;
     void (*request_completed)(TPMIf *obj);
 } TPMIfClass;
 
diff --git a/include/sysemu/tpm_backend.h b/include/sysemu/tpm_backend.h
index df9ebd0e81..665e807a73 100644
--- a/include/sysemu/tpm_backend.h
+++ b/include/sysemu/tpm_backend.h
@@ -51,7 +51,6 @@ struct TPMBackend {
 
     /* <public> */
     char *id;
-    enum TpmModel fe_model;
 
     QLIST_ENTRY(TPMBackend) list;
 };
diff --git a/backends/tpm.c b/backends/tpm.c
index 7b108bd5d8..0c48d18775 100644
--- a/backends/tpm.c
+++ b/backends/tpm.c
@@ -148,9 +148,10 @@ TPMInfo *tpm_backend_query_tpm(TPMBackend *s)
 {
     TPMInfo *info = g_new0(TPMInfo, 1);
     TPMBackendClass *k = TPM_BACKEND_GET_CLASS(s);
+    TPMIfClass *tic = TPM_IF_GET_CLASS(s->tpmif);
 
     info->id = g_strdup(s->id);
-    info->model = s->fe_model;
+    info->model = tic->model;
     if (k->get_tpm_options) {
         info->options = k->get_tpm_options(s);
     }
@@ -204,7 +205,6 @@ static void tpm_backend_instance_init(Object *obj)
                              tpm_backend_prop_get_opened,
                              tpm_backend_prop_set_opened,
                              NULL);
-    s->fe_model = -1;
     s->bh = qemu_bh_new(tpm_backend_request_completed_bh, s);
 }
 
diff --git a/hw/tpm/tpm_tis.c b/hw/tpm/tpm_tis.c
index 2febc8bd08..c1b738c29f 100644
--- a/hw/tpm/tpm_tis.c
+++ b/hw/tpm/tpm_tis.c
@@ -1068,8 +1068,6 @@ static void tpm_tis_realizefn(DeviceState *dev, Error **errp)
         return;
     }
 
-    s->be_driver->fe_model = TPM_MODEL_TPM_TIS;
-
     if (tpm_backend_init(s->be_driver, TPM_IF(s), errp)) {
         return;
     }
@@ -1104,6 +1102,7 @@ static void tpm_tis_class_init(ObjectClass *klass, void *data)
     dc->props = tpm_tis_properties;
     dc->reset = tpm_tis_reset;
     dc->vmsd  = &vmstate_tpm_tis;
+    tc->model = TPM_MODEL_TPM_TIS;
     tc->request_completed = tpm_tis_request_completed;
 }
 
diff --git a/tpm.c b/tpm.c
index ab5d29e91e..4320f44c9f 100644
--- a/tpm.c
+++ b/tpm.c
@@ -200,9 +200,10 @@ TPMInfoList *qmp_query_tpm(Error **errp)
     TPMInfoList *info, *head = NULL, *cur_item = NULL;
 
     QLIST_FOREACH(drv, &tpm_backends, list) {
-        if (!tpm_models[drv->fe_model]) {
+        if (!drv->tpmif) {
             continue;
         }
+
         info = g_new0(TPMInfoList, 1);
         info->value = tpm_backend_query_tpm(drv);
 
-- 
2.15.0.rc0.40.gaefcc5f6f

^ permalink raw reply related	[flat|nested] 44+ messages in thread

* [Qemu-devel] [PATCH v2 08/28] tpm: remove unused opened code
  2017-11-06 18:38 [Qemu-devel] [PATCH v2 00/28] TPM: code cleanup (not 2.11) Marc-André Lureau
                   ` (6 preceding siblings ...)
  2017-11-06 18:39 ` [Qemu-devel] [PATCH v2 07/28] tpm-be: ask model to the TPM interface Marc-André Lureau
@ 2017-11-06 18:39 ` Marc-André Lureau
  2017-11-06 18:39 ` [Qemu-devel] [PATCH v2 09/28] tpm-passthrough: don't save guessed cancel_path in options Marc-André Lureau
                   ` (20 subsequent siblings)
  28 siblings, 0 replies; 44+ messages in thread
From: Marc-André Lureau @ 2017-11-06 18:39 UTC (permalink / raw)
  To: qemu-devel; +Cc: amarnath.valluri, stefanb, Marc-André Lureau

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Reviewed-by: Stefan Berger <stefanb@linux.vnet.ibm.com>
---
 include/sysemu/tpm_backend.h | 12 ------------
 backends/tpm.c               | 42 ------------------------------------------
 tpm.c                        |  6 ------
 3 files changed, 60 deletions(-)

diff --git a/include/sysemu/tpm_backend.h b/include/sysemu/tpm_backend.h
index 665e807a73..904e5b1026 100644
--- a/include/sysemu/tpm_backend.h
+++ b/include/sysemu/tpm_backend.h
@@ -80,8 +80,6 @@ struct TPMBackendClass {
 
     TpmTypeOptions *(*get_tpm_options)(TPMBackend *t);
 
-    void (*opened)(TPMBackend *s, Error **errp);
-
     void (*handle_request)(TPMBackend *s, TPMBackendCmd *cmd);
 };
 
@@ -171,16 +169,6 @@ bool tpm_backend_get_tpm_established_flag(TPMBackend *s);
  */
 int tpm_backend_reset_tpm_established_flag(TPMBackend *s, uint8_t locty);
 
-/**
- * tpm_backend_open:
- * @s: the backend to open
- * @errp: a pointer to return the #Error object if an error occurs.
- *
- * This function will open the backend if it is not already open.  Calling this
- * function on an already opened backend will not result in an error.
- */
-void tpm_backend_open(TPMBackend *s, Error **errp);
-
 /**
  * tpm_backend_get_tpm_version:
  * @s: the backend to call into
diff --git a/backends/tpm.c b/backends/tpm.c
index 0c48d18775..7e636fbc7a 100644
--- a/backends/tpm.c
+++ b/backends/tpm.c
@@ -159,52 +159,10 @@ TPMInfo *tpm_backend_query_tpm(TPMBackend *s)
     return info;
 }
 
-static bool tpm_backend_prop_get_opened(Object *obj, Error **errp)
-{
-    TPMBackend *s = TPM_BACKEND(obj);
-
-    return s->opened;
-}
-
-void tpm_backend_open(TPMBackend *s, Error **errp)
-{
-    object_property_set_bool(OBJECT(s), true, "opened", errp);
-}
-
-static void tpm_backend_prop_set_opened(Object *obj, bool value, Error **errp)
-{
-    TPMBackend *s = TPM_BACKEND(obj);
-    TPMBackendClass *k = TPM_BACKEND_GET_CLASS(s);
-    Error *local_err = NULL;
-
-    if (value == s->opened) {
-        return;
-    }
-
-    if (!value && s->opened) {
-        error_setg(errp, QERR_PERMISSION_DENIED);
-        return;
-    }
-
-    if (k->opened) {
-        k->opened(s, &local_err);
-        if (local_err) {
-            error_propagate(errp, local_err);
-            return;
-        }
-    }
-
-    s->opened = true;
-}
-
 static void tpm_backend_instance_init(Object *obj)
 {
     TPMBackend *s = TPM_BACKEND(obj);
 
-    object_property_add_bool(obj, "opened",
-                             tpm_backend_prop_get_opened,
-                             tpm_backend_prop_set_opened,
-                             NULL);
     s->bh = qemu_bh_new(tpm_backend_request_completed_bh, s);
 }
 
diff --git a/tpm.c b/tpm.c
index 4320f44c9f..32d398aadf 100644
--- a/tpm.c
+++ b/tpm.c
@@ -132,12 +132,6 @@ static int tpm_init_tpmdev(void *dummy, QemuOpts *opts, Error **errp)
         return 1;
     }
 
-    tpm_backend_open(drv, &local_err);
-    if (local_err) {
-        error_report_err(local_err);
-        return 1;
-    }
-
     QLIST_INSERT_HEAD(&tpm_backends, drv, list);
 
     return 0;
-- 
2.15.0.rc0.40.gaefcc5f6f

^ permalink raw reply related	[flat|nested] 44+ messages in thread

* [Qemu-devel] [PATCH v2 09/28] tpm-passthrough: don't save guessed cancel_path in options
  2017-11-06 18:38 [Qemu-devel] [PATCH v2 00/28] TPM: code cleanup (not 2.11) Marc-André Lureau
                   ` (7 preceding siblings ...)
  2017-11-06 18:39 ` [Qemu-devel] [PATCH v2 08/28] tpm: remove unused opened code Marc-André Lureau
@ 2017-11-06 18:39 ` Marc-André Lureau
  2017-11-06 18:39 ` [Qemu-devel] [PATCH v2 10/28] tpm-be: update optional function pointers Marc-André Lureau
                   ` (19 subsequent siblings)
  28 siblings, 0 replies; 44+ messages in thread
From: Marc-André Lureau @ 2017-11-06 18:39 UTC (permalink / raw)
  To: qemu-devel; +Cc: amarnath.valluri, stefanb, Marc-André Lureau

The value is later unneeded, and may leak if the free visitor doesn't
consider it since has_cancel_path is false. And for consistency with
"path" it shouldn't be returned in get_tpm_options().

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Reviewed-by: Stefan Berger <stefanb@linux.vnet.ibm.com>
---
 hw/tpm/tpm_passthrough.c | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/hw/tpm/tpm_passthrough.c b/hw/tpm/tpm_passthrough.c
index 8c002e4da6..048edb1a1a 100644
--- a/hw/tpm/tpm_passthrough.c
+++ b/hw/tpm/tpm_passthrough.c
@@ -226,9 +226,7 @@ static int tpm_passthrough_open_sysfs_cancel(TPMPassthruState *tpm_pt)
         if (snprintf(path, sizeof(path), "/sys/class/misc/%s/device/cancel",
                      dev) < sizeof(path)) {
             fd = qemu_open(path, O_WRONLY);
-            if (fd >= 0) {
-                tpm_pt->options->cancel_path = g_strdup(path);
-            } else {
+            if (fd < 0) {
                 error_report("tpm_passthrough: Could not open TPM cancel "
                              "path %s : %s", path, strerror(errno));
             }
-- 
2.15.0.rc0.40.gaefcc5f6f

^ permalink raw reply related	[flat|nested] 44+ messages in thread

* [Qemu-devel] [PATCH v2 10/28] tpm-be: update optional function pointers
  2017-11-06 18:38 [Qemu-devel] [PATCH v2 00/28] TPM: code cleanup (not 2.11) Marc-André Lureau
                   ` (8 preceding siblings ...)
  2017-11-06 18:39 ` [Qemu-devel] [PATCH v2 09/28] tpm-passthrough: don't save guessed cancel_path in options Marc-André Lureau
@ 2017-11-06 18:39 ` Marc-André Lureau
  2017-11-06 18:39 ` [Qemu-devel] [PATCH v2 11/28] tpm-passthrough: pass TPMPassthruState to handle_device_opts Marc-André Lureau
                   ` (18 subsequent siblings)
  28 siblings, 0 replies; 44+ messages in thread
From: Marc-André Lureau @ 2017-11-06 18:39 UTC (permalink / raw)
  To: qemu-devel; +Cc: amarnath.valluri, stefanb, Marc-André Lureau

QEMU code doesn't generally have assert() for mandatory
callbacks/function pointers, probably because the crash is pretty
obvious. Document the methods instead of going into the code.

Make get_tpm_options() mandatory to implement (since all
backend implementation have it).

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Reviewed-by: Stefan Berger <stefanb@linux.vnet.ibm.com>
---
 include/sysemu/tpm_backend.h | 5 ++++-
 backends/tpm.c               | 9 +--------
 2 files changed, 5 insertions(+), 9 deletions(-)

diff --git a/include/sysemu/tpm_backend.h b/include/sysemu/tpm_backend.h
index 904e5b1026..ce8dee58cf 100644
--- a/include/sysemu/tpm_backend.h
+++ b/include/sysemu/tpm_backend.h
@@ -65,15 +65,18 @@ struct TPMBackendClass {
 
     TPMBackend *(*create)(QemuOpts *opts, const char *id);
 
-    /* start up the TPM on the backend */
+    /* start up the TPM on the backend - optional */
     int (*startup_tpm)(TPMBackend *t);
 
+    /* optional */
     void (*reset)(TPMBackend *t);
 
     void (*cancel_cmd)(TPMBackend *t);
 
+    /* optional */
     bool (*get_tpm_established_flag)(TPMBackend *t);
 
+    /* optional */
     int (*reset_tpm_established_flag)(TPMBackend *t, uint8_t locty);
 
     TPMVersion (*get_tpm_version)(TPMBackend *t);
diff --git a/backends/tpm.c b/backends/tpm.c
index 7e636fbc7a..7777467c44 100644
--- a/backends/tpm.c
+++ b/backends/tpm.c
@@ -33,7 +33,6 @@ static void tpm_backend_worker_thread(gpointer data, gpointer user_data)
     TPMBackend *s = TPM_BACKEND(user_data);
     TPMBackendClass *k = TPM_BACKEND_GET_CLASS(s);
 
-    assert(k->handle_request != NULL);
     k->handle_request(s, (TPMBackendCmd *)data);
 
     qemu_bh_schedule(s->bh);
@@ -114,8 +113,6 @@ void tpm_backend_cancel_cmd(TPMBackend *s)
 {
     TPMBackendClass *k = TPM_BACKEND_GET_CLASS(s);
 
-    assert(k->cancel_cmd);
-
     k->cancel_cmd(s);
 }
 
@@ -139,8 +136,6 @@ TPMVersion tpm_backend_get_tpm_version(TPMBackend *s)
 {
     TPMBackendClass *k = TPM_BACKEND_GET_CLASS(s);
 
-    assert(k->get_tpm_version);
-
     return k->get_tpm_version(s);
 }
 
@@ -152,9 +147,7 @@ TPMInfo *tpm_backend_query_tpm(TPMBackend *s)
 
     info->id = g_strdup(s->id);
     info->model = tic->model;
-    if (k->get_tpm_options) {
-        info->options = k->get_tpm_options(s);
-    }
+    info->options = k->get_tpm_options(s);
 
     return info;
 }
-- 
2.15.0.rc0.40.gaefcc5f6f

^ permalink raw reply related	[flat|nested] 44+ messages in thread

* [Qemu-devel] [PATCH v2 11/28] tpm-passthrough: pass TPMPassthruState to handle_device_opts
  2017-11-06 18:38 [Qemu-devel] [PATCH v2 00/28] TPM: code cleanup (not 2.11) Marc-André Lureau
                   ` (9 preceding siblings ...)
  2017-11-06 18:39 ` [Qemu-devel] [PATCH v2 10/28] tpm-be: update optional function pointers Marc-André Lureau
@ 2017-11-06 18:39 ` Marc-André Lureau
  2017-11-06 18:39 ` [Qemu-devel] [PATCH v2 12/28] tpm-backend: move set 'id' to common code Marc-André Lureau
                   ` (17 subsequent siblings)
  28 siblings, 0 replies; 44+ messages in thread
From: Marc-André Lureau @ 2017-11-06 18:39 UTC (permalink / raw)
  To: qemu-devel; +Cc: amarnath.valluri, stefanb, Marc-André Lureau

It doesn't need TPMBackend. Also reorder arguments for consistency.

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Reviewed-by: Stefan Berger <stefanb@linux.vnet.ibm.com>
---
 hw/tpm/tpm_passthrough.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/hw/tpm/tpm_passthrough.c b/hw/tpm/tpm_passthrough.c
index 048edb1a1a..9326cbfdc9 100644
--- a/hw/tpm/tpm_passthrough.c
+++ b/hw/tpm/tpm_passthrough.c
@@ -239,9 +239,9 @@ static int tpm_passthrough_open_sysfs_cancel(TPMPassthruState *tpm_pt)
     return fd;
 }
 
-static int tpm_passthrough_handle_device_opts(QemuOpts *opts, TPMBackend *tb)
+static int
+tpm_passthrough_handle_device_opts(TPMPassthruState *tpm_pt, QemuOpts *opts)
 {
-    TPMPassthruState *tpm_pt = TPM_PASSTHROUGH(tb);
     const char *value;
 
     value = qemu_opt_get(opts, "cancel-path");
@@ -292,7 +292,7 @@ static TPMBackend *tpm_passthrough_create(QemuOpts *opts, const char *id)
 
     tb->id = g_strdup(id);
 
-    if (tpm_passthrough_handle_device_opts(opts, tb)) {
+    if (tpm_passthrough_handle_device_opts(tpm_pt, opts)) {
         goto err_exit;
     }
 
-- 
2.15.0.rc0.40.gaefcc5f6f

^ permalink raw reply related	[flat|nested] 44+ messages in thread

* [Qemu-devel] [PATCH v2 12/28] tpm-backend: move set 'id' to common code
  2017-11-06 18:38 [Qemu-devel] [PATCH v2 00/28] TPM: code cleanup (not 2.11) Marc-André Lureau
                   ` (10 preceding siblings ...)
  2017-11-06 18:39 ` [Qemu-devel] [PATCH v2 11/28] tpm-passthrough: pass TPMPassthruState to handle_device_opts Marc-André Lureau
@ 2017-11-06 18:39 ` Marc-André Lureau
  2017-11-06 18:39 ` [Qemu-devel] [PATCH v2 13/28] tpm-passthrough: make it safer to destroy after creation Marc-André Lureau
                   ` (16 subsequent siblings)
  28 siblings, 0 replies; 44+ messages in thread
From: Marc-André Lureau @ 2017-11-06 18:39 UTC (permalink / raw)
  To: qemu-devel; +Cc: amarnath.valluri, stefanb, Marc-André Lureau

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Reviewed-by: Stefan Berger <stefanb@linux.vnet.ibm.com>
---
 include/sysemu/tpm_backend.h |  2 +-
 hw/tpm/tpm_emulator.c        | 12 +++---------
 hw/tpm/tpm_passthrough.c     |  9 +++------
 tpm.c                        |  3 ++-
 4 files changed, 9 insertions(+), 17 deletions(-)

diff --git a/include/sysemu/tpm_backend.h b/include/sysemu/tpm_backend.h
index ce8dee58cf..1ad27ec374 100644
--- a/include/sysemu/tpm_backend.h
+++ b/include/sysemu/tpm_backend.h
@@ -63,7 +63,7 @@ struct TPMBackendClass {
     /* get a descriptive text of the backend to display to the user */
     const char *desc;
 
-    TPMBackend *(*create)(QemuOpts *opts, const char *id);
+    TPMBackend *(*create)(QemuOpts *opts);
 
     /* start up the TPM on the backend - optional */
     int (*startup_tpm)(TPMBackend *t);
diff --git a/hw/tpm/tpm_emulator.c b/hw/tpm/tpm_emulator.c
index 883e8c0c2d..ff5fcbae03 100644
--- a/hw/tpm/tpm_emulator.c
+++ b/hw/tpm/tpm_emulator.c
@@ -453,22 +453,16 @@ err:
     return -1;
 }
 
-static TPMBackend *tpm_emulator_create(QemuOpts *opts, const char *id)
+static TPMBackend *tpm_emulator_create(QemuOpts *opts)
 {
     TPMBackend *tb = TPM_BACKEND(object_new(TYPE_TPM_EMULATOR));
 
-    tb->id = g_strdup(id);
-
     if (tpm_emulator_handle_device_opts(TPM_EMULATOR(tb), opts)) {
-        goto err_exit;
+        object_unref(OBJECT(tb));
+        return NULL;
     }
 
     return tb;
-
-err_exit:
-    object_unref(OBJECT(tb));
-
-    return NULL;
 }
 
 static TpmTypeOptions *tpm_emulator_get_tpm_options(TPMBackend *tb)
diff --git a/hw/tpm/tpm_passthrough.c b/hw/tpm/tpm_passthrough.c
index 9326cbfdc9..7371d50739 100644
--- a/hw/tpm/tpm_passthrough.c
+++ b/hw/tpm/tpm_passthrough.c
@@ -284,13 +284,10 @@ tpm_passthrough_handle_device_opts(TPMPassthruState *tpm_pt, QemuOpts *opts)
     return 1;
 }
 
-static TPMBackend *tpm_passthrough_create(QemuOpts *opts, const char *id)
+static TPMBackend *tpm_passthrough_create(QemuOpts *opts)
 {
     Object *obj = object_new(TYPE_TPM_PASSTHROUGH);
-    TPMBackend *tb = TPM_BACKEND(obj);
-    TPMPassthruState *tpm_pt = TPM_PASSTHROUGH(tb);
-
-    tb->id = g_strdup(id);
+    TPMPassthruState *tpm_pt = TPM_PASSTHROUGH(obj);
 
     if (tpm_passthrough_handle_device_opts(tpm_pt, opts)) {
         goto err_exit;
@@ -301,7 +298,7 @@ static TPMBackend *tpm_passthrough_create(QemuOpts *opts, const char *id)
         goto err_exit;
     }
 
-    return tb;
+    return TPM_BACKEND(obj);
 
 err_exit:
     object_unref(obj);
diff --git a/tpm.c b/tpm.c
index 32d398aadf..520f449234 100644
--- a/tpm.c
+++ b/tpm.c
@@ -127,11 +127,12 @@ static int tpm_init_tpmdev(void *dummy, QemuOpts *opts, Error **errp)
         return 1;
     }
 
-    drv = be->create(opts, id);
+    drv = be->create(opts);
     if (!drv) {
         return 1;
     }
 
+    drv->id = g_strdup(id);
     QLIST_INSERT_HEAD(&tpm_backends, drv, list);
 
     return 0;
-- 
2.15.0.rc0.40.gaefcc5f6f

^ permalink raw reply related	[flat|nested] 44+ messages in thread

* [Qemu-devel] [PATCH v2 13/28] tpm-passthrough: make it safer to destroy after creation
  2017-11-06 18:38 [Qemu-devel] [PATCH v2 00/28] TPM: code cleanup (not 2.11) Marc-André Lureau
                   ` (11 preceding siblings ...)
  2017-11-06 18:39 ` [Qemu-devel] [PATCH v2 12/28] tpm-backend: move set 'id' to common code Marc-André Lureau
@ 2017-11-06 18:39 ` Marc-André Lureau
  2017-11-06 18:39 ` [Qemu-devel] [PATCH v2 14/28] tpm-passthrough: simplify create() Marc-André Lureau
                   ` (15 subsequent siblings)
  28 siblings, 0 replies; 44+ messages in thread
From: Marc-André Lureau @ 2017-11-06 18:39 UTC (permalink / raw)
  To: qemu-devel; +Cc: amarnath.valluri, stefanb, Marc-André Lureau

Check fds values before closing, to avoid close(-1).

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Reviewed-by: Stefan Berger <stefanb@linux.vnet.ibm.com>
---
 hw/tpm/tpm_passthrough.c | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/hw/tpm/tpm_passthrough.c b/hw/tpm/tpm_passthrough.c
index 7371d50739..aa9167e3c6 100644
--- a/hw/tpm/tpm_passthrough.c
+++ b/hw/tpm/tpm_passthrough.c
@@ -347,8 +347,12 @@ static void tpm_passthrough_inst_finalize(Object *obj)
 
     tpm_passthrough_cancel_cmd(TPM_BACKEND(obj));
 
-    qemu_close(tpm_pt->tpm_fd);
-    qemu_close(tpm_pt->cancel_fd);
+    if (tpm_pt->tpm_fd >= 0) {
+        qemu_close(tpm_pt->tpm_fd);
+    }
+    if (tpm_pt->cancel_fd >= 0) {
+        qemu_close(tpm_pt->cancel_fd);
+    }
     qapi_free_TPMPassthroughOptions(tpm_pt->options);
 }
 
-- 
2.15.0.rc0.40.gaefcc5f6f

^ permalink raw reply related	[flat|nested] 44+ messages in thread

* [Qemu-devel] [PATCH v2 14/28] tpm-passthrough: simplify create()
  2017-11-06 18:38 [Qemu-devel] [PATCH v2 00/28] TPM: code cleanup (not 2.11) Marc-André Lureau
                   ` (12 preceding siblings ...)
  2017-11-06 18:39 ` [Qemu-devel] [PATCH v2 13/28] tpm-passthrough: make it safer to destroy after creation Marc-André Lureau
@ 2017-11-06 18:39 ` Marc-André Lureau
  2017-11-06 18:39 ` [Qemu-devel] [PATCH v2 15/28] tpm-passthrough: workaround a possible race Marc-André Lureau
                   ` (14 subsequent siblings)
  28 siblings, 0 replies; 44+ messages in thread
From: Marc-André Lureau @ 2017-11-06 18:39 UTC (permalink / raw)
  To: qemu-devel; +Cc: amarnath.valluri, stefanb, Marc-André Lureau

Use a similar code as tpm_emulator_create(), call handle_opts() and
handle failure cleanup with object_unref() in create().

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
 hw/tpm/tpm_passthrough.c | 36 ++++++++++--------------------------
 1 file changed, 10 insertions(+), 26 deletions(-)

diff --git a/hw/tpm/tpm_passthrough.c b/hw/tpm/tpm_passthrough.c
index aa9167e3c6..788be3847d 100644
--- a/hw/tpm/tpm_passthrough.c
+++ b/hw/tpm/tpm_passthrough.c
@@ -261,49 +261,33 @@ tpm_passthrough_handle_device_opts(TPMPassthruState *tpm_pt, QemuOpts *opts)
     if (tpm_pt->tpm_fd < 0) {
         error_report("Cannot access TPM device using '%s': %s",
                      tpm_pt->tpm_dev, strerror(errno));
-        goto err_free_parameters;
+        return -1;
     }
 
     if (tpm_util_test_tpmdev(tpm_pt->tpm_fd, &tpm_pt->tpm_version)) {
         error_report("'%s' is not a TPM device.",
                      tpm_pt->tpm_dev);
-        goto err_close_tpmdev;
+        return -1;
     }
 
-    return 0;
-
- err_close_tpmdev:
-    qemu_close(tpm_pt->tpm_fd);
-    tpm_pt->tpm_fd = -1;
-
- err_free_parameters:
-    qapi_free_TPMPassthroughOptions(tpm_pt->options);
-    tpm_pt->options = NULL;
-    tpm_pt->tpm_dev = NULL;
+    tpm_pt->cancel_fd = tpm_passthrough_open_sysfs_cancel(tpm_pt);
+    if (tpm_pt->cancel_fd < 0) {
+        return -1;
+    }
 
-    return 1;
+    return 0;
 }
 
 static TPMBackend *tpm_passthrough_create(QemuOpts *opts)
 {
     Object *obj = object_new(TYPE_TPM_PASSTHROUGH);
-    TPMPassthruState *tpm_pt = TPM_PASSTHROUGH(obj);
 
-    if (tpm_passthrough_handle_device_opts(tpm_pt, opts)) {
-        goto err_exit;
-    }
-
-    tpm_pt->cancel_fd = tpm_passthrough_open_sysfs_cancel(tpm_pt);
-    if (tpm_pt->cancel_fd < 0) {
-        goto err_exit;
+    if (tpm_passthrough_handle_device_opts(TPM_PASSTHROUGH(obj), opts)) {
+        object_unref(obj);
+        return NULL;
     }
 
     return TPM_BACKEND(obj);
-
-err_exit:
-    object_unref(obj);
-
-    return NULL;
 }
 
 static TpmTypeOptions *tpm_passthrough_get_tpm_options(TPMBackend *tb)
-- 
2.15.0.rc0.40.gaefcc5f6f

^ permalink raw reply related	[flat|nested] 44+ messages in thread

* [Qemu-devel] [PATCH v2 15/28] tpm-passthrough: workaround a possible race
  2017-11-06 18:38 [Qemu-devel] [PATCH v2 00/28] TPM: code cleanup (not 2.11) Marc-André Lureau
                   ` (13 preceding siblings ...)
  2017-11-06 18:39 ` [Qemu-devel] [PATCH v2 14/28] tpm-passthrough: simplify create() Marc-André Lureau
@ 2017-11-06 18:39 ` Marc-André Lureau
  2017-11-06 18:39 ` [Qemu-devel] [PATCH v2 16/28] tpm-tis: simplify header inclusion Marc-André Lureau
                   ` (13 subsequent siblings)
  28 siblings, 0 replies; 44+ messages in thread
From: Marc-André Lureau @ 2017-11-06 18:39 UTC (permalink / raw)
  To: qemu-devel; +Cc: amarnath.valluri, stefanb, Marc-André Lureau

The TPM backend processing thread has common shared variable race
issues. (they should not be so easy to reach since guest interaction
with the device is slow compared to host emulation)

An obvious one is setting op_cancelled from device thread after
calling write(cancel_fd). The backend thread may return before the
device thread has set the variable. Instead set it before
cancellation. Even if the write() failed, the end result is command
get possibly cancelled (even if cancellation came from external
sources it doesn't matter much).

It's worth to consider removing the backend processing thread for now.

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Reviewed-by: Stefan Berger <stefanb@linux.vnet.ibm.com>
---
 hw/tpm/tpm_passthrough.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/hw/tpm/tpm_passthrough.c b/hw/tpm/tpm_passthrough.c
index 788be3847d..73554aa792 100644
--- a/hw/tpm/tpm_passthrough.c
+++ b/hw/tpm/tpm_passthrough.c
@@ -89,6 +89,7 @@ static int tpm_passthrough_unix_tx_bufs(TPMPassthruState *tpm_pt,
     bool is_selftest;
     const struct tpm_resp_hdr *hdr;
 
+    /* FIXME: protect shared variables or use other sync mechanism */
     tpm_pt->tpm_op_canceled = false;
     tpm_pt->tpm_executing = true;
     *selftest_done = false;
@@ -178,12 +179,11 @@ static void tpm_passthrough_cancel_cmd(TPMBackend *tb)
      */
     if (tpm_pt->tpm_executing) {
         if (tpm_pt->cancel_fd >= 0) {
+            tpm_pt->tpm_op_canceled = true;
             n = write(tpm_pt->cancel_fd, "-", 1);
             if (n != 1) {
                 error_report("Canceling TPM command failed: %s",
                              strerror(errno));
-            } else {
-                tpm_pt->tpm_op_canceled = true;
             }
         } else {
             error_report("Cannot cancel TPM command due to missing "
-- 
2.15.0.rc0.40.gaefcc5f6f

^ permalink raw reply related	[flat|nested] 44+ messages in thread

* [Qemu-devel] [PATCH v2 16/28] tpm-tis: simplify header inclusion
  2017-11-06 18:38 [Qemu-devel] [PATCH v2 00/28] TPM: code cleanup (not 2.11) Marc-André Lureau
                   ` (14 preceding siblings ...)
  2017-11-06 18:39 ` [Qemu-devel] [PATCH v2 15/28] tpm-passthrough: workaround a possible race Marc-André Lureau
@ 2017-11-06 18:39 ` Marc-André Lureau
  2017-11-06 18:39 ` [Qemu-devel] [PATCH v2 17/28] tpm: rename qemu_find_tpm() -> qemu_find_tpm_be() Marc-André Lureau
                   ` (12 subsequent siblings)
  28 siblings, 0 replies; 44+ messages in thread
From: Marc-André Lureau @ 2017-11-06 18:39 UTC (permalink / raw)
  To: qemu-devel; +Cc: amarnath.valluri, stefanb, Marc-André Lureau

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Reviewed-by: Stefan Berger <stefanb@linux.vnet.ibm.com>
---
 hw/tpm/tpm_tis.c | 13 ++++---------
 1 file changed, 4 insertions(+), 9 deletions(-)

diff --git a/hw/tpm/tpm_tis.c b/hw/tpm/tpm_tis.c
index c1b738c29f..254f8bd6cb 100644
--- a/hw/tpm/tpm_tis.c
+++ b/hw/tpm/tpm_tis.c
@@ -24,17 +24,12 @@
 
 #include "qemu/osdep.h"
 #include "hw/isa/isa.h"
-#include "sysemu/tpm_backend.h"
-#include "tpm_int.h"
-#include "sysemu/block-backend.h"
-#include "exec/address-spaces.h"
-#include "hw/hw.h"
-#include "hw/i386/pc.h"
-#include "hw/pci/pci_ids.h"
 #include "qapi/error.h"
-#include "qemu-common.h"
-#include "qemu/main-loop.h"
+
 #include "hw/acpi/tpm.h"
+#include "hw/pci/pci_ids.h"
+#include "sysemu/tpm_backend.h"
+#include "tpm_int.h"
 
 #define TPM_TIS_NUM_LOCALITIES      5     /* per spec */
 #define TPM_TIS_LOCALITY_SHIFT      12
-- 
2.15.0.rc0.40.gaefcc5f6f

^ permalink raw reply related	[flat|nested] 44+ messages in thread

* [Qemu-devel] [PATCH v2 17/28] tpm: rename qemu_find_tpm() -> qemu_find_tpm_be()
  2017-11-06 18:38 [Qemu-devel] [PATCH v2 00/28] TPM: code cleanup (not 2.11) Marc-André Lureau
                   ` (15 preceding siblings ...)
  2017-11-06 18:39 ` [Qemu-devel] [PATCH v2 16/28] tpm-tis: simplify header inclusion Marc-André Lureau
@ 2017-11-06 18:39 ` Marc-André Lureau
  2017-11-06 18:39 ` [Qemu-devel] [PATCH v2 18/28] tpm: lookup the the TPM interface instead of TIS device Marc-André Lureau
                   ` (11 subsequent siblings)
  28 siblings, 0 replies; 44+ messages in thread
From: Marc-André Lureau @ 2017-11-06 18:39 UTC (permalink / raw)
  To: qemu-devel; +Cc: amarnath.valluri, stefanb, Marc-André Lureau

find_tpm() will be introduced to lookup the TPM device.

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Reviewed-by: Stefan Berger <stefanb@linux.vnet.ibm.com>
---
 include/sysemu/tpm_backend.h | 2 +-
 hw/tpm/tpm_tis.c             | 2 +-
 tpm.c                        | 2 +-
 3 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/include/sysemu/tpm_backend.h b/include/sysemu/tpm_backend.h
index 1ad27ec374..c42d83aaef 100644
--- a/include/sysemu/tpm_backend.h
+++ b/include/sysemu/tpm_backend.h
@@ -192,7 +192,7 @@ TPMVersion tpm_backend_get_tpm_version(TPMBackend *s);
  */
 TPMInfo *tpm_backend_query_tpm(TPMBackend *s);
 
-TPMBackend *qemu_find_tpm(const char *id);
+TPMBackend *qemu_find_tpm_be(const char *id);
 
 void tpm_register_model(enum TpmModel model);
 
diff --git a/hw/tpm/tpm_tis.c b/hw/tpm/tpm_tis.c
index 254f8bd6cb..1e846f1201 100644
--- a/hw/tpm/tpm_tis.c
+++ b/hw/tpm/tpm_tis.c
@@ -1056,7 +1056,7 @@ static void tpm_tis_realizefn(DeviceState *dev, Error **errp)
 {
     TPMState *s = TPM(dev);
 
-    s->be_driver = qemu_find_tpm(s->backend);
+    s->be_driver = qemu_find_tpm_be(s->backend);
     if (!s->be_driver) {
         error_setg(errp, "tpm_tis: backend driver with id %s could not be "
                    "found", s->backend);
diff --git a/tpm.c b/tpm.c
index 520f449234..4661dfc46e 100644
--- a/tpm.c
+++ b/tpm.c
@@ -69,7 +69,7 @@ static void tpm_display_backend_drivers(void)
 /*
  * Find the TPM with the given Id
  */
-TPMBackend *qemu_find_tpm(const char *id)
+TPMBackend *qemu_find_tpm_be(const char *id)
 {
     TPMBackend *drv;
 
-- 
2.15.0.rc0.40.gaefcc5f6f

^ permalink raw reply related	[flat|nested] 44+ messages in thread

* [Qemu-devel] [PATCH v2 18/28] tpm: lookup the the TPM interface instead of TIS device
  2017-11-06 18:38 [Qemu-devel] [PATCH v2 00/28] TPM: code cleanup (not 2.11) Marc-André Lureau
                   ` (16 preceding siblings ...)
  2017-11-06 18:39 ` [Qemu-devel] [PATCH v2 17/28] tpm: rename qemu_find_tpm() -> qemu_find_tpm_be() Marc-André Lureau
@ 2017-11-06 18:39 ` Marc-André Lureau
  2017-11-06 18:39 ` [Qemu-devel] [PATCH v2 19/28] tpm: add TPM interface to lookup TPM version Marc-André Lureau
                   ` (10 subsequent siblings)
  28 siblings, 0 replies; 44+ messages in thread
From: Marc-André Lureau @ 2017-11-06 18:39 UTC (permalink / raw)
  To: qemu-devel
  Cc: amarnath.valluri, stefanb, Marc-André Lureau,
	Michael S. Tsirkin, Igor Mammedov, Paolo Bonzini,
	Richard Henderson, Eduardo Habkost

This will allow to introduce new devices implementing TPM.

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Reviewed-by: Stefan Berger <stefanb@linux.vnet.ibm.com>
---
 include/sysemu/tpm.h | 25 +++++++++++++++----------
 hw/i386/acpi-build.c |  2 +-
 2 files changed, 16 insertions(+), 11 deletions(-)

diff --git a/include/sysemu/tpm.h b/include/sysemu/tpm.h
index 7b407caf25..2fe0f1e120 100644
--- a/include/sysemu/tpm.h
+++ b/include/sysemu/tpm.h
@@ -19,7 +19,7 @@ int tpm_config_parse(QemuOptsList *opts_list, const char *optarg);
 int tpm_init(void);
 void tpm_cleanup(void);
 
-typedef enum  TPMVersion {
+typedef enum TPMVersion {
     TPM_VERSION_UNSPEC = 0,
     TPM_VERSION_1_2 = 1,
     TPM_VERSION_2_0 = 2,
@@ -44,20 +44,25 @@ typedef struct TPMIfClass {
     void (*request_completed)(TPMIf *obj);
 } TPMIfClass;
 
-TPMVersion tpm_tis_get_tpm_version(Object *obj);
-
 #define TYPE_TPM_TIS                "tpm-tis"
 
-static inline TPMVersion tpm_get_version(void)
+/* returns NULL unless there is exactly one TPM device */
+static inline TPMIf *tpm_find(void)
 {
-#ifdef CONFIG_TPM
-    Object *obj = object_resolve_path_type("", TYPE_TPM_TIS, NULL);
+    Object *obj = object_resolve_path_type("", TYPE_TPM_IF, NULL);
+
+    return TPM_IF(obj);
+}
 
-    if (obj) {
-        return tpm_tis_get_tpm_version(obj);
+TPMVersion tpm_tis_get_tpm_version(Object *obj);
+
+static inline TPMVersion tpm_get_version(TPMIf *ti)
+{
+    if (!ti) {
+        return TPM_VERSION_UNSPEC;
     }
-#endif
-    return TPM_VERSION_UNSPEC;
+
+    return tpm_tis_get_tpm_version(OBJECT(ti));
 }
 
 #endif /* QEMU_TPM_H */
diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
index 73519ab3ac..cdb4aa9835 100644
--- a/hw/i386/acpi-build.c
+++ b/hw/i386/acpi-build.c
@@ -208,7 +208,7 @@ static void acpi_get_misc_info(AcpiMiscInfo *info)
     }
 
     info->has_hpet = hpet_find();
-    info->tpm_version = tpm_get_version();
+    info->tpm_version = tpm_get_version(tpm_find());
     info->pvpanic_port = pvpanic_port();
     info->applesmc_io_base = applesmc_port();
 }
-- 
2.15.0.rc0.40.gaefcc5f6f

^ permalink raw reply related	[flat|nested] 44+ messages in thread

* [Qemu-devel] [PATCH v2 19/28] tpm: add TPM interface to lookup TPM version
  2017-11-06 18:38 [Qemu-devel] [PATCH v2 00/28] TPM: code cleanup (not 2.11) Marc-André Lureau
                   ` (17 preceding siblings ...)
  2017-11-06 18:39 ` [Qemu-devel] [PATCH v2 18/28] tpm: lookup the the TPM interface instead of TIS device Marc-André Lureau
@ 2017-11-06 18:39 ` Marc-André Lureau
  2017-11-06 18:39 ` [Qemu-devel] [PATCH v2 20/28] tpm: add tpm_cmd_get_size() to tpm_util Marc-André Lureau
                   ` (9 subsequent siblings)
  28 siblings, 0 replies; 44+ messages in thread
From: Marc-André Lureau @ 2017-11-06 18:39 UTC (permalink / raw)
  To: qemu-devel; +Cc: amarnath.valluri, stefanb, Marc-André Lureau

Do not hardcode TPM device model to lookup version, use an interface
instead.

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Reviewed-by: Stefan Berger <stefanb@linux.vnet.ibm.com>
---
 include/sysemu/tpm.h | 5 ++---
 hw/tpm/tpm_tis.c     | 5 +++--
 2 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/include/sysemu/tpm.h b/include/sysemu/tpm.h
index 2fe0f1e120..650b4b8565 100644
--- a/include/sysemu/tpm.h
+++ b/include/sysemu/tpm.h
@@ -42,6 +42,7 @@ typedef struct TPMIfClass {
 
     enum TpmModel model;
     void (*request_completed)(TPMIf *obj);
+    enum TPMVersion (*get_version)(TPMIf *obj);
 } TPMIfClass;
 
 #define TYPE_TPM_TIS                "tpm-tis"
@@ -54,15 +55,13 @@ static inline TPMIf *tpm_find(void)
     return TPM_IF(obj);
 }
 
-TPMVersion tpm_tis_get_tpm_version(Object *obj);
-
 static inline TPMVersion tpm_get_version(TPMIf *ti)
 {
     if (!ti) {
         return TPM_VERSION_UNSPEC;
     }
 
-    return tpm_tis_get_tpm_version(OBJECT(ti));
+    return TPM_IF_GET_CLASS(ti)->get_version(ti);
 }
 
 #endif /* QEMU_TPM_H */
diff --git a/hw/tpm/tpm_tis.c b/hw/tpm/tpm_tis.c
index 1e846f1201..a0b39b6211 100644
--- a/hw/tpm/tpm_tis.c
+++ b/hw/tpm/tpm_tis.c
@@ -990,9 +990,9 @@ static void tpm_tis_realloc_buffer(TPMSizedBuffer *sb)
 /*
  * Get the TPMVersion of the backend device being used
  */
-TPMVersion tpm_tis_get_tpm_version(Object *obj)
+static enum TPMVersion tpm_tis_get_tpm_version(TPMIf *ti)
 {
-    TPMState *s = TPM(obj);
+    TPMState *s = TPM(ti);
 
     return tpm_backend_get_tpm_version(s->be_driver);
 }
@@ -1098,6 +1098,7 @@ static void tpm_tis_class_init(ObjectClass *klass, void *data)
     dc->reset = tpm_tis_reset;
     dc->vmsd  = &vmstate_tpm_tis;
     tc->model = TPM_MODEL_TPM_TIS;
+    tc->get_version = tpm_tis_get_tpm_version;
     tc->request_completed = tpm_tis_request_completed;
 }
 
-- 
2.15.0.rc0.40.gaefcc5f6f

^ permalink raw reply related	[flat|nested] 44+ messages in thread

* [Qemu-devel] [PATCH v2 20/28] tpm: add tpm_cmd_get_size() to tpm_util
  2017-11-06 18:38 [Qemu-devel] [PATCH v2 00/28] TPM: code cleanup (not 2.11) Marc-André Lureau
                   ` (18 preceding siblings ...)
  2017-11-06 18:39 ` [Qemu-devel] [PATCH v2 19/28] tpm: add TPM interface to lookup TPM version Marc-André Lureau
@ 2017-11-06 18:39 ` Marc-André Lureau
  2017-11-06 18:39 ` [Qemu-devel] [PATCH v2 21/28] acpi: change TPM TIS data conditions Marc-André Lureau
                   ` (8 subsequent siblings)
  28 siblings, 0 replies; 44+ messages in thread
From: Marc-André Lureau @ 2017-11-06 18:39 UTC (permalink / raw)
  To: qemu-devel; +Cc: amarnath.valluri, stefanb, Marc-André Lureau

The function is generally useful and used in the following patches.

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Reviewed-by: Stefan Berger <stefanb@linux.vnet.ibm.com>
---
 hw/tpm/tpm_util.h | 8 +++++++-
 hw/tpm/tpm_tis.c  | 3 ++-
 2 files changed, 9 insertions(+), 2 deletions(-)

diff --git a/hw/tpm/tpm_util.h b/hw/tpm/tpm_util.h
index 2f7c96146d..aca10c97bf 100644
--- a/hw/tpm/tpm_util.h
+++ b/hw/tpm/tpm_util.h
@@ -22,7 +22,8 @@
 #ifndef TPM_TPM_UTIL_H
 #define TPM_TPM_UTIL_H
 
-#include "sysemu/tpm_backend.h"
+#include "sysemu/tpm.h"
+#include "qemu/bswap.h"
 
 void tpm_util_write_fatal_error_response(uint8_t *out, uint32_t out_len);
 
@@ -30,4 +31,9 @@ bool tpm_util_is_selftest(const uint8_t *in, uint32_t in_len);
 
 int tpm_util_test_tpmdev(int tpm_fd, TPMVersion *tpm_version);
 
+static inline uint32_t tpm_cmd_get_size(const void *b)
+{
+    return be32_to_cpu(*(const uint32_t *)(b + 2));
+}
+
 #endif /* TPM_TPM_UTIL_H */
diff --git a/hw/tpm/tpm_tis.c b/hw/tpm/tpm_tis.c
index a0b39b6211..d313347144 100644
--- a/hw/tpm/tpm_tis.c
+++ b/hw/tpm/tpm_tis.c
@@ -30,6 +30,7 @@
 #include "hw/pci/pci_ids.h"
 #include "sysemu/tpm_backend.h"
 #include "tpm_int.h"
+#include "tpm_util.h"
 
 #define TPM_TIS_NUM_LOCALITIES      5     /* per spec */
 #define TPM_TIS_LOCALITY_SHIFT      12
@@ -215,7 +216,7 @@ static uint8_t tpm_tis_locality_from_addr(hwaddr addr)
 
 static uint32_t tpm_tis_get_size_from_buffer(const TPMSizedBuffer *sb)
 {
-    return be32_to_cpu(*(uint32_t *)&sb->buffer[2]);
+    return tpm_cmd_get_size(sb->buffer);
 }
 
 static void tpm_tis_show_buffer(const TPMSizedBuffer *sb, const char *string)
-- 
2.15.0.rc0.40.gaefcc5f6f

^ permalink raw reply related	[flat|nested] 44+ messages in thread

* [Qemu-devel] [PATCH v2 21/28] acpi: change TPM TIS data conditions
  2017-11-06 18:38 [Qemu-devel] [PATCH v2 00/28] TPM: code cleanup (not 2.11) Marc-André Lureau
                   ` (19 preceding siblings ...)
  2017-11-06 18:39 ` [Qemu-devel] [PATCH v2 20/28] tpm: add tpm_cmd_get_size() to tpm_util Marc-André Lureau
@ 2017-11-06 18:39 ` Marc-André Lureau
  2017-11-06 18:39 ` [Qemu-devel] [PATCH v2 22/28] tpm-emulator: add a FIXME comment about blocking cancel Marc-André Lureau
                   ` (7 subsequent siblings)
  28 siblings, 0 replies; 44+ messages in thread
From: Marc-André Lureau @ 2017-11-06 18:39 UTC (permalink / raw)
  To: qemu-devel
  Cc: amarnath.valluri, stefanb, Marc-André Lureau,
	Michael S. Tsirkin, Igor Mammedov, Paolo Bonzini,
	Richard Henderson, Eduardo Habkost

The device should be exposed if present. It shouldn't have an
undefined version (or else backend init failed, and device should fail
too). Finally, make the fields specific to TIS device model.

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Reviewed-by: Stefan Berger <stefanb@linux.vnet.ibm.com>
---
 include/sysemu/tpm.h |  3 +++
 hw/i386/acpi-build.c | 12 ++++++++----
 2 files changed, 11 insertions(+), 4 deletions(-)

diff --git a/include/sysemu/tpm.h b/include/sysemu/tpm.h
index 650b4b8565..852e02687c 100644
--- a/include/sysemu/tpm.h
+++ b/include/sysemu/tpm.h
@@ -47,6 +47,9 @@ typedef struct TPMIfClass {
 
 #define TYPE_TPM_TIS                "tpm-tis"
 
+#define TPM_IS_TIS(chr)                             \
+    object_dynamic_cast(OBJECT(chr), TYPE_TPM_TIS)
+
 /* returns NULL unless there is exactly one TPM device */
 static inline TPMIf *tpm_find(void)
 {
diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
index cdb4aa9835..dd1420b410 100644
--- a/hw/i386/acpi-build.c
+++ b/hw/i386/acpi-build.c
@@ -2038,7 +2038,7 @@ build_dsdt(GArray *table_data, BIOSLinker *linker,
         }
     }
 
-    if (misc->tpm_version != TPM_VERSION_UNSPEC) {
+    if (TPM_IS_TIS(tpm_find())) {
         aml_append(crs, aml_memory32_fixed(TPM_TIS_ADDR_BASE,
                    TPM_TIS_ADDR_SIZE, AML_READ_WRITE));
     }
@@ -2204,7 +2204,7 @@ build_dsdt(GArray *table_data, BIOSLinker *linker,
             /* Scan all PCI buses. Generate tables to support hotplug. */
             build_append_pci_bus_devices(scope, bus, pm->pcihp_bridge_en);
 
-            if (misc->tpm_version != TPM_VERSION_UNSPEC) {
+            if (TPM_IS_TIS(tpm_find())) {
                 dev = aml_device("ISA.TPM");
                 aml_append(dev, aml_name_decl("_HID", aml_eisaid("PNP0C31")));
                 aml_append(dev, aml_name_decl("_STA", aml_int(0xF)));
@@ -2281,8 +2281,12 @@ build_tpm2(GArray *table_data, BIOSLinker *linker)
     tpm2_ptr = acpi_data_push(table_data, sizeof *tpm2_ptr);
 
     tpm2_ptr->platform_class = cpu_to_le16(TPM2_ACPI_CLASS_CLIENT);
-    tpm2_ptr->control_area_address = cpu_to_le64(0);
-    tpm2_ptr->start_method = cpu_to_le32(TPM2_START_METHOD_MMIO);
+    if (TPM_IS_TIS(tpm_find())) {
+        tpm2_ptr->control_area_address = cpu_to_le64(0);
+        tpm2_ptr->start_method = cpu_to_le32(TPM2_START_METHOD_MMIO);
+    } else {
+        g_warn_if_reached();
+    }
 
     build_header(linker, table_data,
                  (void *)tpm2_ptr, "TPM2", sizeof(*tpm2_ptr), 4, NULL, NULL);
-- 
2.15.0.rc0.40.gaefcc5f6f

^ permalink raw reply related	[flat|nested] 44+ messages in thread

* [Qemu-devel] [PATCH v2 22/28] tpm-emulator: add a FIXME comment about blocking cancel
  2017-11-06 18:38 [Qemu-devel] [PATCH v2 00/28] TPM: code cleanup (not 2.11) Marc-André Lureau
                   ` (20 preceding siblings ...)
  2017-11-06 18:39 ` [Qemu-devel] [PATCH v2 21/28] acpi: change TPM TIS data conditions Marc-André Lureau
@ 2017-11-06 18:39 ` Marc-André Lureau
  2017-11-06 18:39 ` [Qemu-devel] [PATCH v2 23/28] tpm-tis: remove redundant 'tpm_tis:' in error messages Marc-André Lureau
                   ` (6 subsequent siblings)
  28 siblings, 0 replies; 44+ messages in thread
From: Marc-André Lureau @ 2017-11-06 18:39 UTC (permalink / raw)
  To: qemu-devel; +Cc: amarnath.valluri, stefanb, Marc-André Lureau

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Reviewed-by: Stefan Berger <stefanb@linux.vnet.ibm.com>
---
 hw/tpm/tpm_emulator.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/hw/tpm/tpm_emulator.c b/hw/tpm/tpm_emulator.c
index ff5fcbae03..b77c0238c7 100644
--- a/hw/tpm/tpm_emulator.c
+++ b/hw/tpm/tpm_emulator.c
@@ -328,6 +328,7 @@ static void tpm_emulator_cancel_cmd(TPMBackend *tb)
         return;
     }
 
+    /* FIXME: make the function non-blocking, or it may block a VCPU */
     if (tpm_emulator_ctrlcmd(&tpm_emu->ctrl_chr, CMD_CANCEL_TPM_CMD, &res, 0,
                              sizeof(res)) < 0) {
         error_report("tpm-emulator: Could not cancel command: %s",
-- 
2.15.0.rc0.40.gaefcc5f6f

^ permalink raw reply related	[flat|nested] 44+ messages in thread

* [Qemu-devel] [PATCH v2 23/28] tpm-tis: remove redundant 'tpm_tis:' in error messages
  2017-11-06 18:38 [Qemu-devel] [PATCH v2 00/28] TPM: code cleanup (not 2.11) Marc-André Lureau
                   ` (21 preceding siblings ...)
  2017-11-06 18:39 ` [Qemu-devel] [PATCH v2 22/28] tpm-emulator: add a FIXME comment about blocking cancel Marc-André Lureau
@ 2017-11-06 18:39 ` Marc-André Lureau
  2017-11-06 19:24   ` Stefan Berger
  2017-11-06 18:39 ` [Qemu-devel] [PATCH v2 24/28] tpm-tis: check that at most one TPM device exists Marc-André Lureau
                   ` (5 subsequent siblings)
  28 siblings, 1 reply; 44+ messages in thread
From: Marc-André Lureau @ 2017-11-06 18:39 UTC (permalink / raw)
  To: qemu-devel; +Cc: amarnath.valluri, stefanb, Marc-André Lureau

The reported error message is already prefixed with the -device
name & arguments.

Before:
qemu-system-x86_64: -device tpm-tis,id=foo,tpmdev=foo,irq=21: tpm_tis: IRQ 21 is outside valid range of 0 to 15

After:
qemu-system-x86_64: -device tpm-tis,id=foo,tpmdev=foo,irq=21: IRQ 21 is outside valid range of 0 to 15

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
 hw/tpm/tpm_tis.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/hw/tpm/tpm_tis.c b/hw/tpm/tpm_tis.c
index d313347144..175785b9c4 100644
--- a/hw/tpm/tpm_tis.c
+++ b/hw/tpm/tpm_tis.c
@@ -1059,8 +1059,8 @@ static void tpm_tis_realizefn(DeviceState *dev, Error **errp)
 
     s->be_driver = qemu_find_tpm_be(s->backend);
     if (!s->be_driver) {
-        error_setg(errp, "tpm_tis: backend driver with id %s could not be "
-                   "found", s->backend);
+        error_setg(errp, "backend driver with id %s could not be found",
+                   s->backend);
         return;
     }
 
@@ -1069,8 +1069,8 @@ static void tpm_tis_realizefn(DeviceState *dev, Error **errp)
     }
 
     if (s->irq_num > 15) {
-        error_setg(errp, "tpm_tis: IRQ %d for TPM TIS is outside valid range "
-                   "of 0 to 15", s->irq_num);
+        error_setg(errp, "IRQ %d is outside valid range of 0 to 15",
+                   s->irq_num);
         return;
     }
 
-- 
2.15.0.rc0.40.gaefcc5f6f

^ permalink raw reply related	[flat|nested] 44+ messages in thread

* [Qemu-devel] [PATCH v2 24/28] tpm-tis: check that at most one TPM device exists
  2017-11-06 18:38 [Qemu-devel] [PATCH v2 00/28] TPM: code cleanup (not 2.11) Marc-André Lureau
                   ` (22 preceding siblings ...)
  2017-11-06 18:39 ` [Qemu-devel] [PATCH v2 23/28] tpm-tis: remove redundant 'tpm_tis:' in error messages Marc-André Lureau
@ 2017-11-06 18:39 ` Marc-André Lureau
  2017-11-06 19:25   ` Stefan Berger
  2017-11-06 18:39 ` [Qemu-devel] [PATCH v2 25/28] tpm-emulator: protect concurrent ctrl_chr access Marc-André Lureau
                   ` (4 subsequent siblings)
  28 siblings, 1 reply; 44+ messages in thread
From: Marc-André Lureau @ 2017-11-06 18:39 UTC (permalink / raw)
  To: qemu-devel; +Cc: amarnath.valluri, stefanb, Marc-André Lureau

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
 hw/tpm/tpm_tis.c | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/hw/tpm/tpm_tis.c b/hw/tpm/tpm_tis.c
index 175785b9c4..dccc56ab09 100644
--- a/hw/tpm/tpm_tis.c
+++ b/hw/tpm/tpm_tis.c
@@ -1057,6 +1057,11 @@ static void tpm_tis_realizefn(DeviceState *dev, Error **errp)
 {
     TPMState *s = TPM(dev);
 
+    if (!tpm_find()) {
+        error_setg(errp, "at most one TPM device is permitted");
+        return;
+    }
+
     s->be_driver = qemu_find_tpm_be(s->backend);
     if (!s->be_driver) {
         error_setg(errp, "backend driver with id %s could not be found",
-- 
2.15.0.rc0.40.gaefcc5f6f

^ permalink raw reply related	[flat|nested] 44+ messages in thread

* [Qemu-devel] [PATCH v2 25/28] tpm-emulator: protect concurrent ctrl_chr access
  2017-11-06 18:38 [Qemu-devel] [PATCH v2 00/28] TPM: code cleanup (not 2.11) Marc-André Lureau
                   ` (23 preceding siblings ...)
  2017-11-06 18:39 ` [Qemu-devel] [PATCH v2 24/28] tpm-tis: check that at most one TPM device exists Marc-André Lureau
@ 2017-11-06 18:39 ` Marc-André Lureau
  2017-11-06 19:32   ` Stefan Berger
  2017-11-06 18:39 ` [Qemu-devel] [PATCH v2 26/28] qdev: add DEFINE_PROP_TPMBE Marc-André Lureau
                   ` (3 subsequent siblings)
  28 siblings, 1 reply; 44+ messages in thread
From: Marc-André Lureau @ 2017-11-06 18:39 UTC (permalink / raw)
  To: qemu-devel; +Cc: amarnath.valluri, stefanb, Marc-André Lureau

The control chardev is being used from the data thread to set the
locality of the next request. Altough the chr has a write mutex, we
may potentially read the reply from another thread request.

Add a mutex to protect from concurrent control commands.

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
 hw/tpm/tpm_emulator.c | 44 ++++++++++++++++++++++++++++----------------
 1 file changed, 28 insertions(+), 16 deletions(-)

diff --git a/hw/tpm/tpm_emulator.c b/hw/tpm/tpm_emulator.c
index b77c0238c7..24cb61162f 100644
--- a/hw/tpm/tpm_emulator.c
+++ b/hw/tpm/tpm_emulator.c
@@ -71,15 +71,21 @@ typedef struct TPMEmulator {
     ptm_cap caps; /* capabilities of the TPM */
     uint8_t cur_locty_number; /* last set locality */
     Error *migration_blocker;
+
+    QemuMutex mutex;
 } TPMEmulator;
 
 
-static int tpm_emulator_ctrlcmd(CharBackend *dev, unsigned long cmd, void *msg,
+static int tpm_emulator_ctrlcmd(TPMEmulator *tpm, unsigned long cmd, void *msg,
                                 size_t msg_len_in, size_t msg_len_out)
 {
+    CharBackend *dev = &tpm->ctrl_chr;
     uint32_t cmd_no = cpu_to_be32(cmd);
     ssize_t n = sizeof(uint32_t) + msg_len_in;
     uint8_t *buf = NULL;
+    int ret = -1;
+
+    qemu_mutex_lock(&tpm->mutex);
 
     buf = g_alloca(n);
     memcpy(buf, &cmd_no, sizeof(cmd_no));
@@ -87,17 +93,21 @@ static int tpm_emulator_ctrlcmd(CharBackend *dev, unsigned long cmd, void *msg,
 
     n = qemu_chr_fe_write_all(dev, buf, n);
     if (n <= 0) {
-        return -1;
+        goto end;
     }
 
     if (msg_len_out != 0) {
         n = qemu_chr_fe_read_all(dev, msg, msg_len_out);
         if (n <= 0) {
-            return -1;
+            goto end;
         }
     }
 
-    return 0;
+    ret = 0;
+
+end:
+    qemu_mutex_unlock(&tpm->mutex);
+    return ret;
 }
 
 static int tpm_emulator_unix_tx_bufs(TPMEmulator *tpm_emu,
@@ -154,7 +164,7 @@ static int tpm_emulator_set_locality(TPMEmulator *tpm_emu, uint8_t locty_number,
 
     DPRINTF("setting locality : 0x%x", locty_number);
     loc.u.req.loc = locty_number;
-    if (tpm_emulator_ctrlcmd(&tpm_emu->ctrl_chr, CMD_SET_LOCALITY, &loc,
+    if (tpm_emulator_ctrlcmd(tpm_emu, CMD_SET_LOCALITY, &loc,
                              sizeof(loc), sizeof(loc)) < 0) {
         error_setg(errp, "tpm-emulator: could not set locality : %s",
                    strerror(errno));
@@ -200,8 +210,8 @@ error:
 static int tpm_emulator_probe_caps(TPMEmulator *tpm_emu)
 {
     DPRINTF("%s", __func__);
-    if (tpm_emulator_ctrlcmd(&tpm_emu->ctrl_chr, CMD_GET_CAPABILITY,
-                         &tpm_emu->caps, 0, sizeof(tpm_emu->caps)) < 0) {
+    if (tpm_emulator_ctrlcmd(tpm_emu, CMD_GET_CAPABILITY,
+                             &tpm_emu->caps, 0, sizeof(tpm_emu->caps)) < 0) {
         error_report("tpm-emulator: probing failed : %s", strerror(errno));
         return -1;
     }
@@ -252,8 +262,8 @@ static int tpm_emulator_startup_tpm(TPMBackend *tb)
     ptm_res res;
 
     DPRINTF("%s", __func__);
-    if (tpm_emulator_ctrlcmd(&tpm_emu->ctrl_chr, CMD_INIT, &init, sizeof(init),
-                         sizeof(init)) < 0) {
+    if (tpm_emulator_ctrlcmd(tpm_emu, CMD_INIT, &init, sizeof(init),
+                             sizeof(init)) < 0) {
         error_report("tpm-emulator: could not send INIT: %s",
                      strerror(errno));
         goto err_exit;
@@ -276,7 +286,7 @@ static bool tpm_emulator_get_tpm_established_flag(TPMBackend *tb)
     ptm_est est;
 
     DPRINTF("%s", __func__);
-    if (tpm_emulator_ctrlcmd(&tpm_emu->ctrl_chr, CMD_GET_TPMESTABLISHED, &est,
+    if (tpm_emulator_ctrlcmd(tpm_emu, CMD_GET_TPMESTABLISHED, &est,
                              0, sizeof(est)) < 0) {
         error_report("tpm-emulator: Could not get the TPM established flag: %s",
                      strerror(errno));
@@ -300,7 +310,7 @@ static int tpm_emulator_reset_tpm_established_flag(TPMBackend *tb,
     }
 
     reset_est.u.req.loc = tpm_emu->cur_locty_number;
-    if (tpm_emulator_ctrlcmd(&tpm_emu->ctrl_chr, CMD_RESET_TPMESTABLISHED,
+    if (tpm_emulator_ctrlcmd(tpm_emu, CMD_RESET_TPMESTABLISHED,
                              &reset_est, sizeof(reset_est),
                              sizeof(reset_est)) < 0) {
         error_report("tpm-emulator: Could not reset the establishment bit: %s",
@@ -329,7 +339,7 @@ static void tpm_emulator_cancel_cmd(TPMBackend *tb)
     }
 
     /* FIXME: make the function non-blocking, or it may block a VCPU */
-    if (tpm_emulator_ctrlcmd(&tpm_emu->ctrl_chr, CMD_CANCEL_TPM_CMD, &res, 0,
+    if (tpm_emulator_ctrlcmd(tpm_emu, CMD_CANCEL_TPM_CMD, &res, 0,
                              sizeof(res)) < 0) {
         error_report("tpm-emulator: Could not cancel command: %s",
                      strerror(errno));
@@ -377,8 +387,8 @@ static int tpm_emulator_prepare_data_fd(TPMEmulator *tpm_emu)
 
     qemu_chr_fe_set_msgfds(&tpm_emu->ctrl_chr, fds + 1, 1);
 
-    if (tpm_emulator_ctrlcmd(&tpm_emu->ctrl_chr, CMD_SET_DATAFD, &res, 0,
-                    sizeof(res)) || res != 0) {
+    if (tpm_emulator_ctrlcmd(tpm_emu, CMD_SET_DATAFD, &res, 0,
+                             sizeof(res)) < 0 || res != 0) {
         error_report("tpm-emulator: Failed to send CMD_SET_DATAFD: %s",
                      strerror(errno));
         goto err_exit;
@@ -494,6 +504,7 @@ static void tpm_emulator_inst_init(Object *obj)
     DPRINTF("%s", __func__);
     tpm_emu->options = g_new0(TPMEmulatorOptions, 1);
     tpm_emu->cur_locty_number = ~0;
+    qemu_mutex_init(&tpm_emu->mutex);
 }
 
 /*
@@ -503,8 +514,7 @@ static void tpm_emulator_shutdown(TPMEmulator *tpm_emu)
 {
     ptm_res res;
 
-    if (tpm_emulator_ctrlcmd(&tpm_emu->ctrl_chr, CMD_SHUTDOWN, &res, 0,
-                             sizeof(res)) < 0) {
+    if (tpm_emulator_ctrlcmd(tpm_emu, CMD_SHUTDOWN, &res, 0, sizeof(res)) < 0) {
         error_report("tpm-emulator: Could not cleanly shutdown the TPM: %s",
                      strerror(errno));
     } else if (res != 0) {
@@ -529,6 +539,8 @@ static void tpm_emulator_inst_finalize(Object *obj)
         migrate_del_blocker(tpm_emu->migration_blocker);
         error_free(tpm_emu->migration_blocker);
     }
+
+    qemu_mutex_destroy(&tpm_emu->mutex);
 }
 
 static void tpm_emulator_class_init(ObjectClass *klass, void *data)
-- 
2.15.0.rc0.40.gaefcc5f6f

^ permalink raw reply related	[flat|nested] 44+ messages in thread

* [Qemu-devel] [PATCH v2 26/28] qdev: add DEFINE_PROP_TPMBE
  2017-11-06 18:38 [Qemu-devel] [PATCH v2 00/28] TPM: code cleanup (not 2.11) Marc-André Lureau
                   ` (24 preceding siblings ...)
  2017-11-06 18:39 ` [Qemu-devel] [PATCH v2 25/28] tpm-emulator: protect concurrent ctrl_chr access Marc-André Lureau
@ 2017-11-06 18:39 ` Marc-André Lureau
  2017-11-06 20:31   ` Stefan Berger
  2017-11-06 18:39 ` [Qemu-devel] [PATCH v2 27/28] tpm-tis: use DEFINE_PROP_TPMBE Marc-André Lureau
                   ` (2 subsequent siblings)
  28 siblings, 1 reply; 44+ messages in thread
From: Marc-André Lureau @ 2017-11-06 18:39 UTC (permalink / raw)
  To: qemu-devel; +Cc: amarnath.valluri, stefanb, Marc-André Lureau

A property to lookup a tpm backend.

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
 include/hw/qdev-properties.h     |  3 ++
 hw/core/qdev-properties-system.c | 64 ++++++++++++++++++++++++++++++++++++++++
 2 files changed, 67 insertions(+)

diff --git a/include/hw/qdev-properties.h b/include/hw/qdev-properties.h
index e2321f1cc1..4d24cdf8d6 100644
--- a/include/hw/qdev-properties.h
+++ b/include/hw/qdev-properties.h
@@ -17,6 +17,7 @@ extern const PropertyInfo qdev_prop_int64;
 extern const PropertyInfo qdev_prop_size;
 extern const PropertyInfo qdev_prop_string;
 extern const PropertyInfo qdev_prop_chr;
+extern const PropertyInfo qdev_prop_tpm;
 extern const PropertyInfo qdev_prop_ptr;
 extern const PropertyInfo qdev_prop_macaddr;
 extern const PropertyInfo qdev_prop_on_off_auto;
@@ -186,6 +187,8 @@ extern const PropertyInfo qdev_prop_link;
 
 #define DEFINE_PROP_CHR(_n, _s, _f)             \
     DEFINE_PROP(_n, _s, _f, qdev_prop_chr, CharBackend)
+#define DEFINE_PROP_TPMBE(_n, _s, _f)                     \
+    DEFINE_PROP(_n, _s, _f, qdev_prop_tpm, TPMBackend *)
 #define DEFINE_PROP_STRING(_n, _s, _f)             \
     DEFINE_PROP(_n, _s, _f, qdev_prop_string, char*)
 #define DEFINE_PROP_NETDEV(_n, _s, _f)             \
diff --git a/hw/core/qdev-properties-system.c b/hw/core/qdev-properties-system.c
index ec10da7424..c17364655c 100644
--- a/hw/core/qdev-properties-system.c
+++ b/hw/core/qdev-properties-system.c
@@ -21,6 +21,7 @@
 #include "net/hub.h"
 #include "qapi/visitor.h"
 #include "chardev/char-fe.h"
+#include "sysemu/tpm_backend.h"
 #include "sysemu/iothread.h"
 
 static void get_pointer(Object *obj, Visitor *v, Property *prop,
@@ -236,6 +237,69 @@ const PropertyInfo qdev_prop_chr = {
     .release = release_chr,
 };
 
+/* --- character device --- */
+
+static void get_tpm(Object *obj, Visitor *v, const char *name, void *opaque,
+                    Error **errp)
+{
+    DeviceState *dev = DEVICE(obj);
+    TPMBackend **be = qdev_get_prop_ptr(dev, opaque);
+    char *p;
+
+    p = g_strdup(*be ? (*be)->id : "");
+    visit_type_str(v, name, &p, errp);
+    g_free(p);
+}
+
+static void set_tpm(Object *obj, Visitor *v, const char *name, void *opaque,
+                    Error **errp)
+{
+    DeviceState *dev = DEVICE(obj);
+    Error *local_err = NULL;
+    Property *prop = opaque;
+    TPMBackend *s, **be = qdev_get_prop_ptr(dev, prop);
+    char *str;
+
+    if (dev->realized) {
+        qdev_prop_set_after_realize(dev, name, errp);
+        return;
+    }
+
+    visit_type_str(v, name, &str, &local_err);
+    if (local_err) {
+        error_propagate(errp, local_err);
+        return;
+    }
+
+    s = qemu_find_tpm_be(str);
+    if (s == NULL) {
+        error_setg(errp, "Property '%s.%s' can't find value '%s'",
+                   object_get_typename(obj), prop->name, str);
+    } else if (tpm_backend_init(s, TPM_IF(obj), errp) == 0) {
+        *be = s; /* weak reference, avoid cyclic ref */
+    }
+    g_free(str);
+}
+
+static void release_tpm(Object *obj, const char *name, void *opaque)
+{
+    DeviceState *dev = DEVICE(obj);
+    Property *prop = opaque;
+    TPMBackend **be = qdev_get_prop_ptr(dev, prop);
+
+    if (*be) {
+        tpm_backend_reset(*be);
+    }
+}
+
+const PropertyInfo qdev_prop_tpm = {
+    .name  = "str",
+    .description = "ID of a tpm to use as a backend",
+    .get   = get_tpm,
+    .set   = set_tpm,
+    .release = release_tpm,
+};
+
 /* --- netdev device --- */
 static void get_netdev(Object *obj, Visitor *v, const char *name,
                        void *opaque, Error **errp)
-- 
2.15.0.rc0.40.gaefcc5f6f

^ permalink raw reply related	[flat|nested] 44+ messages in thread

* [Qemu-devel] [PATCH v2 27/28] tpm-tis: use DEFINE_PROP_TPMBE
  2017-11-06 18:38 [Qemu-devel] [PATCH v2 00/28] TPM: code cleanup (not 2.11) Marc-André Lureau
                   ` (25 preceding siblings ...)
  2017-11-06 18:39 ` [Qemu-devel] [PATCH v2 26/28] qdev: add DEFINE_PROP_TPMBE Marc-André Lureau
@ 2017-11-06 18:39 ` Marc-André Lureau
  2017-11-06 20:31   ` Stefan Berger
  2017-11-06 18:39 ` [Qemu-devel] [PATCH v2 28/28] tpm: remove tpm_register_model() Marc-André Lureau
  2017-11-07  1:05 ` [Qemu-devel] [PATCH v2 00/28] TPM: code cleanup (not 2.11) Stefan Berger
  28 siblings, 1 reply; 44+ messages in thread
From: Marc-André Lureau @ 2017-11-06 18:39 UTC (permalink / raw)
  To: qemu-devel; +Cc: amarnath.valluri, stefanb, Marc-André Lureau

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
 hw/tpm/tpm_tis.c | 12 ++----------
 1 file changed, 2 insertions(+), 10 deletions(-)

diff --git a/hw/tpm/tpm_tis.c b/hw/tpm/tpm_tis.c
index dccc56ab09..a00779f3aa 100644
--- a/hw/tpm/tpm_tis.c
+++ b/hw/tpm/tpm_tis.c
@@ -86,7 +86,6 @@ typedef struct TPMState {
 
     TPMBackendCmd cmd;
 
-    char *backend;
     TPMBackend *be_driver;
     TPMVersion be_tpm_version;
 } TPMState;
@@ -1049,7 +1048,7 @@ static const VMStateDescription vmstate_tpm_tis = {
 
 static Property tpm_tis_properties[] = {
     DEFINE_PROP_UINT32("irq", TPMState, irq_num, TPM_TIS_IRQ),
-    DEFINE_PROP_STRING("tpmdev", TPMState, backend),
+    DEFINE_PROP_TPMBE("tpmdev", TPMState, be_driver),
     DEFINE_PROP_END_OF_LIST(),
 };
 
@@ -1062,17 +1061,10 @@ static void tpm_tis_realizefn(DeviceState *dev, Error **errp)
         return;
     }
 
-    s->be_driver = qemu_find_tpm_be(s->backend);
     if (!s->be_driver) {
-        error_setg(errp, "backend driver with id %s could not be found",
-                   s->backend);
+        error_setg(errp, "'tpmdev' property is required");
         return;
     }
-
-    if (tpm_backend_init(s->be_driver, TPM_IF(s), errp)) {
-        return;
-    }
-
     if (s->irq_num > 15) {
         error_setg(errp, "IRQ %d is outside valid range of 0 to 15",
                    s->irq_num);
-- 
2.15.0.rc0.40.gaefcc5f6f

^ permalink raw reply related	[flat|nested] 44+ messages in thread

* [Qemu-devel] [PATCH v2 28/28] tpm: remove tpm_register_model()
  2017-11-06 18:38 [Qemu-devel] [PATCH v2 00/28] TPM: code cleanup (not 2.11) Marc-André Lureau
                   ` (26 preceding siblings ...)
  2017-11-06 18:39 ` [Qemu-devel] [PATCH v2 27/28] tpm-tis: use DEFINE_PROP_TPMBE Marc-André Lureau
@ 2017-11-06 18:39 ` Marc-André Lureau
  2017-11-06 20:33   ` Stefan Berger
  2017-11-07  1:05 ` [Qemu-devel] [PATCH v2 00/28] TPM: code cleanup (not 2.11) Stefan Berger
  28 siblings, 1 reply; 44+ messages in thread
From: Marc-André Lureau @ 2017-11-06 18:39 UTC (permalink / raw)
  To: qemu-devel; +Cc: amarnath.valluri, stefanb, Marc-André Lureau

Query object classes that implements TPMIf instead.

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
 include/sysemu/tpm_backend.h |  2 --
 hw/tpm/tpm_tis.c             |  1 -
 tpm.c                        | 20 ++++++--------------
 3 files changed, 6 insertions(+), 17 deletions(-)

diff --git a/include/sysemu/tpm_backend.h b/include/sysemu/tpm_backend.h
index c42d83aaef..590e8b42de 100644
--- a/include/sysemu/tpm_backend.h
+++ b/include/sysemu/tpm_backend.h
@@ -194,6 +194,4 @@ TPMInfo *tpm_backend_query_tpm(TPMBackend *s);
 
 TPMBackend *qemu_find_tpm_be(const char *id);
 
-void tpm_register_model(enum TpmModel model);
-
 #endif
diff --git a/hw/tpm/tpm_tis.c b/hw/tpm/tpm_tis.c
index a00779f3aa..cc32fcde36 100644
--- a/hw/tpm/tpm_tis.c
+++ b/hw/tpm/tpm_tis.c
@@ -1115,7 +1115,6 @@ static const TypeInfo tpm_tis_info = {
 static void tpm_tis_register(void)
 {
     type_register_static(&tpm_tis_info);
-    tpm_register_model(TPM_MODEL_TPM_TIS);
 }
 
 type_init(tpm_tis_register)
diff --git a/tpm.c b/tpm.c
index 4661dfc46e..61a434185a 100644
--- a/tpm.c
+++ b/tpm.c
@@ -23,13 +23,6 @@
 static QLIST_HEAD(, TPMBackend) tpm_backends =
     QLIST_HEAD_INITIALIZER(tpm_backends);
 
-static bool tpm_models[TPM_MODEL__MAX];
-
-void tpm_register_model(enum TpmModel model)
-{
-    tpm_models[model] = true;
-}
-
 static const TPMBackendClass *
 tpm_be_find_by_type(enum TpmType type)
 {
@@ -236,18 +229,16 @@ TpmTypeList *qmp_query_tpm_types(Error **errp)
 
     return head;
 }
-
 TpmModelList *qmp_query_tpm_models(Error **errp)
 {
-    unsigned int i = 0;
     TpmModelList *head = NULL, *prev = NULL, *cur_item;
+    GSList *e, *l = object_class_get_list(TYPE_TPM_IF, false);
+
+    for (e = l; e; e = e->next) {
+        TPMIfClass *c = TPM_IF_CLASS(e->data);
 
-    for (i = 0; i < TPM_MODEL__MAX; i++) {
-        if (!tpm_models[i]) {
-            continue;
-        }
         cur_item = g_new0(TpmModelList, 1);
-        cur_item->value = i;
+        cur_item->value = c->model;
 
         if (prev) {
             prev->next = cur_item;
@@ -257,6 +248,7 @@ TpmModelList *qmp_query_tpm_models(Error **errp)
         }
         prev = cur_item;
     }
+    g_slist_free(l);
 
     return head;
 }
-- 
2.15.0.rc0.40.gaefcc5f6f

^ permalink raw reply related	[flat|nested] 44+ messages in thread

* Re: [Qemu-devel] [PATCH v2 01/28] tpm-tis: remove unused locty_number
  2017-11-06 18:38 ` [Qemu-devel] [PATCH v2 01/28] tpm-tis: remove unused locty_number Marc-André Lureau
@ 2017-11-06 18:57   ` Stefan Berger
  0 siblings, 0 replies; 44+ messages in thread
From: Stefan Berger @ 2017-11-06 18:57 UTC (permalink / raw)
  To: Marc-André Lureau, qemu-devel; +Cc: amarnath.valluri

On 11/06/2017 01:38 PM, Marc-André Lureau wrote:
> This field slipped in commit 5086bf9784.
>
> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>

Reviewed-by: Stefan Berger <stefanb@linux.vnet.ibm.com>

> ---
>   hw/tpm/tpm_tis.c | 1 -
>   1 file changed, 1 deletion(-)
>
> diff --git a/hw/tpm/tpm_tis.c b/hw/tpm/tpm_tis.c
> index 7402528b25..c5c534d7f2 100644
> --- a/hw/tpm/tpm_tis.c
> +++ b/hw/tpm/tpm_tis.c
> @@ -89,7 +89,6 @@ struct TPMState {
>       qemu_irq irq;
>       uint32_t irq_num;
>
> -    uint8_t     locty_number;
>       TPMBackendCmd cmd;
>
>       char *backend;

^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: [Qemu-devel] [PATCH v2 02/28] tpm: move TpmIf in include/sysemu/tpm.h
  2017-11-06 18:38 ` [Qemu-devel] [PATCH v2 02/28] tpm: move TpmIf in include/sysemu/tpm.h Marc-André Lureau
@ 2017-11-06 18:58   ` Stefan Berger
  0 siblings, 0 replies; 44+ messages in thread
From: Stefan Berger @ 2017-11-06 18:58 UTC (permalink / raw)
  To: Marc-André Lureau, qemu-devel; +Cc: amarnath.valluri

On 11/06/2017 01:38 PM, Marc-André Lureau wrote:
> This is a better location than hw/tpm, since we are going to use the
> interface from outside hw/tpm.
>
> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>

Reviewed-by: Stefan Berger <stefanb@linux.vnet.ibm.com>

> ---
>   hw/tpm/tpm_int.h     | 22 +---------------------
>   include/sysemu/tpm.h | 19 +++++++++++++++++++
>   backends/tpm.c       |  1 -
>   3 files changed, 20 insertions(+), 22 deletions(-)
>
> diff --git a/hw/tpm/tpm_int.h b/hw/tpm/tpm_int.h
> index 9c045b6691..1df5883f3c 100644
> --- a/hw/tpm/tpm_int.h
> +++ b/hw/tpm/tpm_int.h
> @@ -13,28 +13,8 @@
>   #define TPM_TPM_INT_H
>
>   #include "qemu/osdep.h"
> -#include "qom/object.h"
>
> -#define TYPE_TPM_IF "tpm-if"
> -#define TPM_IF_CLASS(klass) \
> -    OBJECT_CLASS_CHECK(TPMIfClass, (klass), TYPE_TPM_IF)
> -#define TPM_IF_GET_CLASS(obj) \
> -    OBJECT_GET_CLASS(TPMIfClass, (obj), TYPE_TPM_IF)
> -#define TPM_IF(obj) \
> -    INTERFACE_CHECK(TPMIf, (obj), TYPE_TPM_IF)
> -
> -typedef struct TPMIf {
> -    Object parent_obj;
> -} TPMIf;
> -
> -typedef struct TPMIfClass {
> -    InterfaceClass parent_class;
> -
> -    /* run in thread pool by backend */
> -    void (*request_completed)(TPMIf *obj);
> -} TPMIfClass;
> -
> -#define TPM_STANDARD_CMDLINE_OPTS               \
> +#define TPM_STANDARD_CMDLINE_OPTS \
>       { \
>           .name = "type", \
>           .type = QEMU_OPT_STRING, \
> diff --git a/include/sysemu/tpm.h b/include/sysemu/tpm.h
> index d7a2bd8556..452cdb9cb7 100644
> --- a/include/sysemu/tpm.h
> +++ b/include/sysemu/tpm.h
> @@ -27,6 +27,25 @@ typedef enum  TPMVersion {
>       TPM_VERSION_2_0 = 2,
>   } TPMVersion;
>
> +#define TYPE_TPM_IF "tpm-if"
> +#define TPM_IF_CLASS(klass)                                 \
> +    OBJECT_CLASS_CHECK(TPMIfClass, (klass), TYPE_TPM_IF)
> +#define TPM_IF_GET_CLASS(obj)                           \
> +    OBJECT_GET_CLASS(TPMIfClass, (obj), TYPE_TPM_IF)
> +#define TPM_IF(obj)                             \
> +    INTERFACE_CHECK(TPMIf, (obj), TYPE_TPM_IF)
> +
> +typedef struct TPMIf {
> +    Object parent_obj;
> +} TPMIf;
> +
> +typedef struct TPMIfClass {
> +    InterfaceClass parent_class;
> +
> +    /* run in thread pool by backend */
> +    void (*request_completed)(TPMIf *obj);
> +} TPMIfClass;
> +
>   TPMVersion tpm_tis_get_tpm_version(Object *obj);
>
>   #define TYPE_TPM_TIS                "tpm-tis"
> diff --git a/backends/tpm.c b/backends/tpm.c
> index 5763f6f369..1e416d7f90 100644
> --- a/backends/tpm.c
> +++ b/backends/tpm.c
> @@ -17,7 +17,6 @@
>   #include "qapi/error.h"
>   #include "qapi/qmp/qerror.h"
>   #include "sysemu/tpm.h"
> -#include "hw/tpm/tpm_int.h"
>   #include "qemu/thread.h"
>
>   static void tpm_backend_worker_thread(gpointer data, gpointer user_data)

^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: [Qemu-devel] [PATCH v2 03/28] tpm-backend: store TPMIf interface, improve backend_init()
  2017-11-06 18:39 ` [Qemu-devel] [PATCH v2 03/28] tpm-backend: store TPMIf interface, improve backend_init() Marc-André Lureau
@ 2017-11-06 19:02   ` Stefan Berger
  0 siblings, 0 replies; 44+ messages in thread
From: Stefan Berger @ 2017-11-06 19:02 UTC (permalink / raw)
  To: Marc-André Lureau, qemu-devel; +Cc: amarnath.valluri

On 11/06/2017 01:39 PM, Marc-André Lureau wrote:
> Store the TPM interface, the actual object may be different from
> TPMState. Keep a reference on the interface, and check the backend
> wasn't already initialized.
>
> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>

Reviewed-by: Stefan Berger <stefanb@linux.vnet.ibm.com>


> ---
>   include/sysemu/tpm.h         |  2 +-
>   include/sysemu/tpm_backend.h |  6 +++---
>   backends/tpm.c               | 11 +++++++++--
>   hw/tpm/tpm_emulator.c        |  4 ++--
>   hw/tpm/tpm_passthrough.c     |  4 ++--
>   hw/tpm/tpm_tis.c             |  2 +-
>   6 files changed, 18 insertions(+), 11 deletions(-)
>
> diff --git a/include/sysemu/tpm.h b/include/sysemu/tpm.h
> index 452cdb9cb7..fb1719e5e4 100644
> --- a/include/sysemu/tpm.h
> +++ b/include/sysemu/tpm.h
> @@ -12,8 +12,8 @@
>   #ifndef QEMU_TPM_H
>   #define QEMU_TPM_H
>
> -#include "qemu/option.h"
>   #include "qom/object.h"
> +#include "qapi-types.h"
>
>   typedef struct TPMState TPMState;
>
> diff --git a/include/sysemu/tpm_backend.h b/include/sysemu/tpm_backend.h
> index 03ea5a3400..b5f21ed8f1 100644
> --- a/include/sysemu/tpm_backend.h
> +++ b/include/sysemu/tpm_backend.h
> @@ -43,8 +43,8 @@ struct TPMBackend {
>       Object parent;
>
>       /*< protected >*/
> +    TPMIf *tpmif;
>       bool opened;
> -    TPMState *tpm_state;
>       GThreadPool *thread_pool;
>       bool had_startup_error;
>
> @@ -96,14 +96,14 @@ enum TpmType tpm_backend_get_type(TPMBackend *s);
>   /**
>    * tpm_backend_init:
>    * @s: the backend to initialized
> - * @state: TPMState
> + * @tpmif: TPM interface
>    * @datacb: callback for sending data to frontend
>    *
>    * Initialize the backend with the given variables.
>    *
>    * Returns 0 on success.
>    */
> -int tpm_backend_init(TPMBackend *s, TPMState *state);
> +int tpm_backend_init(TPMBackend *s, TPMIf *tpmif);
>
>   /**
>    * tpm_backend_startup_tpm:
> diff --git a/backends/tpm.c b/backends/tpm.c
> index 1e416d7f90..86f0e7e915 100644
> --- a/backends/tpm.c
> +++ b/backends/tpm.c
> @@ -43,9 +43,15 @@ enum TpmType tpm_backend_get_type(TPMBackend *s)
>       return k->type;
>   }
>
> -int tpm_backend_init(TPMBackend *s, TPMState *state)
> +int tpm_backend_init(TPMBackend *s, TPMIf *tpmif)
>   {
> -    s->tpm_state = state;
> +    if (s->tpmif) {
> +        return -1;
> +    }
> +
> +    s->tpmif = tpmif;
> +    object_ref(OBJECT(tpmif));
> +
>       s->had_startup_error = false;
>
>       return 0;
> @@ -193,6 +199,7 @@ static void tpm_backend_instance_finalize(Object *obj)
>   {
>       TPMBackend *s = TPM_BACKEND(obj);
>
> +    object_unref(OBJECT(s->tpmif));
>       g_free(s->id);
>       tpm_backend_thread_end(s);
>   }
> diff --git a/hw/tpm/tpm_emulator.c b/hw/tpm/tpm_emulator.c
> index 9aaec8e3ef..6bf025c7e2 100644
> --- a/hw/tpm/tpm_emulator.c
> +++ b/hw/tpm/tpm_emulator.c
> @@ -176,7 +176,7 @@ static int tpm_emulator_set_locality(TPMEmulator *tpm_emu, uint8_t locty_number,
>   static void tpm_emulator_handle_request(TPMBackend *tb, TPMBackendCmd *cmd)
>   {
>       TPMEmulator *tpm_emu = TPM_EMULATOR(tb);
> -    TPMIfClass *tic = TPM_IF_GET_CLASS(tb->tpm_state);
> +    TPMIfClass *tic = TPM_IF_GET_CLASS(tb->tpmif);
>       Error *err = NULL;
>
>       DPRINTF("processing TPM command");
> @@ -191,7 +191,7 @@ static void tpm_emulator_handle_request(TPMBackend *tb, TPMBackendCmd *cmd)
>           goto error;
>       }
>
> -    tic->request_completed(TPM_IF(tb->tpm_state));
> +    tic->request_completed(tb->tpmif);
>       return;
>
>   error:
> diff --git a/hw/tpm/tpm_passthrough.c b/hw/tpm/tpm_passthrough.c
> index c440aff4b2..2ad74badca 100644
> --- a/hw/tpm/tpm_passthrough.c
> +++ b/hw/tpm/tpm_passthrough.c
> @@ -139,14 +139,14 @@ err_exit:
>   static void tpm_passthrough_handle_request(TPMBackend *tb, TPMBackendCmd *cmd)
>   {
>       TPMPassthruState *tpm_pt = TPM_PASSTHROUGH(tb);
> -    TPMIfClass *tic = TPM_IF_GET_CLASS(tb->tpm_state);
> +    TPMIfClass *tic = TPM_IF_GET_CLASS(tb->tpmif);
>
>       DPRINTF("tpm_passthrough: processing command %p\n", cmd);
>
>       tpm_passthrough_unix_tx_bufs(tpm_pt, cmd->in, cmd->in_len,
>                                    cmd->out, cmd->out_len, &cmd->selftest_done);
>
> -    tic->request_completed(TPM_IF(tb->tpm_state));
> +    tic->request_completed(tb->tpmif);
>   }
>
>   static void tpm_passthrough_reset(TPMBackend *tb)
> diff --git a/hw/tpm/tpm_tis.c b/hw/tpm/tpm_tis.c
> index c5c534d7f2..34ceec91c3 100644
> --- a/hw/tpm/tpm_tis.c
> +++ b/hw/tpm/tpm_tis.c
> @@ -1078,7 +1078,7 @@ static void tpm_tis_realizefn(DeviceState *dev, Error **errp)
>
>       s->be_driver->fe_model = TPM_MODEL_TPM_TIS;
>
> -    if (tpm_backend_init(s->be_driver, s)) {
> +    if (tpm_backend_init(s->be_driver, TPM_IF(s))) {
>           error_setg(errp, "tpm_tis: backend driver with id %s could not be "
>                      "initialized", s->backend);
>           return;

^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: [Qemu-devel] [PATCH v2 05/28] tpm-be: call request_completed() out of thread
  2017-11-06 18:39 ` [Qemu-devel] [PATCH v2 05/28] tpm-be: call request_completed() out of thread Marc-André Lureau
@ 2017-11-06 19:22   ` Stefan Berger
  0 siblings, 0 replies; 44+ messages in thread
From: Stefan Berger @ 2017-11-06 19:22 UTC (permalink / raw)
  To: Marc-André Lureau, qemu-devel; +Cc: amarnath.valluri

On 11/06/2017 01:39 PM, Marc-André Lureau wrote:
> Lift from the backend implementation the responsability to call the
> request_completed() callback outside of thread context. This also
> simplify frontend/interface work, as they no longer need to care
> whether the callback is called from a different thread.
>
> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>

Reviewed-by: Stefan Berger <stefanb@linux.vnet.ibm.com>



> ---
>   include/sysemu/tpm.h         |  1 -
>   include/sysemu/tpm_backend.h |  1 +
>   backends/tpm.c               | 15 ++++++++++++++-
>   hw/tpm/tpm_emulator.c        |  2 --
>   hw/tpm/tpm_passthrough.c     |  3 ---
>   hw/tpm/tpm_tis.c             | 34 ++++++++++++----------------------
>   6 files changed, 27 insertions(+), 29 deletions(-)
>
> diff --git a/include/sysemu/tpm.h b/include/sysemu/tpm.h
> index 7a1713a81e..e0879620e7 100644
> --- a/include/sysemu/tpm.h
> +++ b/include/sysemu/tpm.h
> @@ -40,7 +40,6 @@ typedef struct TPMIf {
>   typedef struct TPMIfClass {
>       InterfaceClass parent_class;
>   
> -    /* run in thread pool by backend */
>       void (*request_completed)(TPMIf *obj);
>   } TPMIfClass;
>   
> diff --git a/include/sysemu/tpm_backend.h b/include/sysemu/tpm_backend.h
> index b5f21ed8f1..c5d1a6818a 100644
> --- a/include/sysemu/tpm_backend.h
> +++ b/include/sysemu/tpm_backend.h
> @@ -47,6 +47,7 @@ struct TPMBackend {
>       bool opened;
>       GThreadPool *thread_pool;
>       bool had_startup_error;
> +    QEMUBH *bh;
>   
>       /* <public> */
>       char *id;
> diff --git a/backends/tpm.c b/backends/tpm.c
> index 86f0e7e915..58f823d54c 100644
> --- a/backends/tpm.c
> +++ b/backends/tpm.c
> @@ -18,14 +18,25 @@
>   #include "qapi/qmp/qerror.h"
>   #include "sysemu/tpm.h"
>   #include "qemu/thread.h"
> +#include "qemu/main-loop.h"
> +
> +static void tpm_backend_request_completed_bh(void *opaque)
> +{
> +    TPMBackend *s = TPM_BACKEND(opaque);
> +    TPMIfClass *tic = TPM_IF_GET_CLASS(s->tpmif);
> +
> +    tic->request_completed(s->tpmif);
> +}
>   
>   static void tpm_backend_worker_thread(gpointer data, gpointer user_data)
>   {
>       TPMBackend *s = TPM_BACKEND(user_data);
> -    TPMBackendClass *k  = TPM_BACKEND_GET_CLASS(s);
> +    TPMBackendClass *k = TPM_BACKEND_GET_CLASS(s);
>   
>       assert(k->handle_request != NULL);
>       k->handle_request(s, (TPMBackendCmd *)data);
> +
> +    qemu_bh_schedule(s->bh);
>   }
>   
>   static void tpm_backend_thread_end(TPMBackend *s)
> @@ -193,6 +204,7 @@ static void tpm_backend_instance_init(Object *obj)
>                                tpm_backend_prop_set_opened,
>                                NULL);
>       s->fe_model = -1;
> +    s->bh = qemu_bh_new(tpm_backend_request_completed_bh, s);
>   }
>   
>   static void tpm_backend_instance_finalize(Object *obj)
> @@ -202,6 +214,7 @@ static void tpm_backend_instance_finalize(Object *obj)
>       object_unref(OBJECT(s->tpmif));
>       g_free(s->id);
>       tpm_backend_thread_end(s);
> +    qemu_bh_delete(s->bh);
>   }
>   
>   static const TypeInfo tpm_backend_info = {
> diff --git a/hw/tpm/tpm_emulator.c b/hw/tpm/tpm_emulator.c
> index 6bf025c7e2..883e8c0c2d 100644
> --- a/hw/tpm/tpm_emulator.c
> +++ b/hw/tpm/tpm_emulator.c
> @@ -176,7 +176,6 @@ static int tpm_emulator_set_locality(TPMEmulator *tpm_emu, uint8_t locty_number,
>   static void tpm_emulator_handle_request(TPMBackend *tb, TPMBackendCmd *cmd)
>   {
>       TPMEmulator *tpm_emu = TPM_EMULATOR(tb);
> -    TPMIfClass *tic = TPM_IF_GET_CLASS(tb->tpmif);
>       Error *err = NULL;
>   
>       DPRINTF("processing TPM command");
> @@ -191,7 +190,6 @@ static void tpm_emulator_handle_request(TPMBackend *tb, TPMBackendCmd *cmd)
>           goto error;
>       }
>   
> -    tic->request_completed(tb->tpmif);
>       return;
>   
>   error:
> diff --git a/hw/tpm/tpm_passthrough.c b/hw/tpm/tpm_passthrough.c
> index 2ad74badca..8c002e4da6 100644
> --- a/hw/tpm/tpm_passthrough.c
> +++ b/hw/tpm/tpm_passthrough.c
> @@ -139,14 +139,11 @@ err_exit:
>   static void tpm_passthrough_handle_request(TPMBackend *tb, TPMBackendCmd *cmd)
>   {
>       TPMPassthruState *tpm_pt = TPM_PASSTHROUGH(tb);
> -    TPMIfClass *tic = TPM_IF_GET_CLASS(tb->tpmif);
>   
>       DPRINTF("tpm_passthrough: processing command %p\n", cmd);
>   
>       tpm_passthrough_unix_tx_bufs(tpm_pt, cmd->in, cmd->in_len,
>                                    cmd->out, cmd->out_len, &cmd->selftest_done);
> -
> -    tic->request_completed(tb->tpmif);
>   }
>   
>   static void tpm_passthrough_reset(TPMBackend *tb)
> diff --git a/hw/tpm/tpm_tis.c b/hw/tpm/tpm_tis.c
> index 4a8a2ffc79..f81aaf10c3 100644
> --- a/hw/tpm/tpm_tis.c
> +++ b/hw/tpm/tpm_tis.c
> @@ -76,7 +76,6 @@ typedef struct TPMState {
>       ISADevice busdev;
>       MemoryRegion mmio;
>   
> -    QEMUBH *bh;
>       uint32_t offset;
>       uint8_t buf[TPM_TIS_BUFFER_MAX];
>   
> @@ -410,10 +409,20 @@ static void tpm_tis_prep_abort(TPMState *s, uint8_t locty, uint8_t newlocty)
>       tpm_tis_abort(s, locty);
>   }
>   
> -static void tpm_tis_receive_bh(void *opaque)
> +/*
> + * Callback from the TPM to indicate that the response was received.
> + */
> +static void tpm_tis_request_completed(TPMIf *ti)
>   {
> -    TPMState *s = opaque;
> +    TPMState *s = TPM(ti);
>       uint8_t locty = s->cmd.locty;
> +    uint8_t l;
> +
> +    if (s->cmd.selftest_done) {
> +        for (l = 0; l < TPM_TIS_NUM_LOCALITIES; l++) {
> +            s->loc[locty].sts |= TPM_TIS_STS_SELFTEST_DONE;
> +        }
> +    }
>   
>       tpm_tis_sts_set(&s->loc[locty],
>                       TPM_TIS_STS_VALID | TPM_TIS_STS_DATA_AVAILABLE);
> @@ -431,23 +440,6 @@ static void tpm_tis_receive_bh(void *opaque)
>                         TPM_TIS_INT_DATA_AVAILABLE | TPM_TIS_INT_STS_VALID);
>   }
>   
> -static void tpm_tis_request_completed(TPMIf *ti)
> -{
> -    TPMState *s = TPM(ti);
> -
> -    bool is_selftest_done = s->cmd.selftest_done;
> -    uint8_t locty = s->cmd.locty;
> -    uint8_t l;
> -
> -    if (is_selftest_done) {
> -        for (l = 0; l < TPM_TIS_NUM_LOCALITIES; l++) {
> -            s->loc[locty].sts |= TPM_TIS_STS_SELFTEST_DONE;
> -        }
> -    }
> -
> -    qemu_bh_schedule(s->bh);
> -}
> -
>   /*
>    * Read a byte of response data
>    */
> @@ -1090,8 +1082,6 @@ static void tpm_tis_realizefn(DeviceState *dev, Error **errp)
>           return;
>       }
>   
> -    s->bh = qemu_bh_new(tpm_tis_receive_bh, s);
> -
>       isa_init_irq(&s->busdev, &s->irq, s->irq_num);
>   
>       memory_region_add_subregion(isa_address_space(ISA_DEVICE(dev)),

^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: [Qemu-devel] [PATCH v2 23/28] tpm-tis: remove redundant 'tpm_tis:' in error messages
  2017-11-06 18:39 ` [Qemu-devel] [PATCH v2 23/28] tpm-tis: remove redundant 'tpm_tis:' in error messages Marc-André Lureau
@ 2017-11-06 19:24   ` Stefan Berger
  0 siblings, 0 replies; 44+ messages in thread
From: Stefan Berger @ 2017-11-06 19:24 UTC (permalink / raw)
  To: Marc-André Lureau, qemu-devel; +Cc: amarnath.valluri

On 11/06/2017 01:39 PM, Marc-André Lureau wrote:
> The reported error message is already prefixed with the -device
> name & arguments.
>
> Before:
> qemu-system-x86_64: -device tpm-tis,id=foo,tpmdev=foo,irq=21: tpm_tis: IRQ 21 is outside valid range of 0 to 15
>
> After:
> qemu-system-x86_64: -device tpm-tis,id=foo,tpmdev=foo,irq=21: IRQ 21 is outside valid range of 0 to 15
>
> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>

Reviewed-by: Stefan Berger <stefanb@linux.vnet.ibm.com>

> ---
>   hw/tpm/tpm_tis.c | 8 ++++----
>   1 file changed, 4 insertions(+), 4 deletions(-)
>
> diff --git a/hw/tpm/tpm_tis.c b/hw/tpm/tpm_tis.c
> index d313347144..175785b9c4 100644
> --- a/hw/tpm/tpm_tis.c
> +++ b/hw/tpm/tpm_tis.c
> @@ -1059,8 +1059,8 @@ static void tpm_tis_realizefn(DeviceState *dev, Error **errp)
>
>       s->be_driver = qemu_find_tpm_be(s->backend);
>       if (!s->be_driver) {
> -        error_setg(errp, "tpm_tis: backend driver with id %s could not be "
> -                   "found", s->backend);
> +        error_setg(errp, "backend driver with id %s could not be found",
> +                   s->backend);
>           return;
>       }
>
> @@ -1069,8 +1069,8 @@ static void tpm_tis_realizefn(DeviceState *dev, Error **errp)
>       }
>
>       if (s->irq_num > 15) {
> -        error_setg(errp, "tpm_tis: IRQ %d for TPM TIS is outside valid range "
> -                   "of 0 to 15", s->irq_num);
> +        error_setg(errp, "IRQ %d is outside valid range of 0 to 15",
> +                   s->irq_num);
>           return;
>       }
>

^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: [Qemu-devel] [PATCH v2 24/28] tpm-tis: check that at most one TPM device exists
  2017-11-06 18:39 ` [Qemu-devel] [PATCH v2 24/28] tpm-tis: check that at most one TPM device exists Marc-André Lureau
@ 2017-11-06 19:25   ` Stefan Berger
  0 siblings, 0 replies; 44+ messages in thread
From: Stefan Berger @ 2017-11-06 19:25 UTC (permalink / raw)
  To: Marc-André Lureau, qemu-devel; +Cc: amarnath.valluri

On 11/06/2017 01:39 PM, Marc-André Lureau wrote:
> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>

Reviewed-by: Stefan Berger <stefanb@linux.vnet.ibm.com>

> ---
>   hw/tpm/tpm_tis.c | 5 +++++
>   1 file changed, 5 insertions(+)
>
> diff --git a/hw/tpm/tpm_tis.c b/hw/tpm/tpm_tis.c
> index 175785b9c4..dccc56ab09 100644
> --- a/hw/tpm/tpm_tis.c
> +++ b/hw/tpm/tpm_tis.c
> @@ -1057,6 +1057,11 @@ static void tpm_tis_realizefn(DeviceState *dev, Error **errp)
>   {
>       TPMState *s = TPM(dev);
>
> +    if (!tpm_find()) {
> +        error_setg(errp, "at most one TPM device is permitted");
> +        return;
> +    }
> +
>       s->be_driver = qemu_find_tpm_be(s->backend);
>       if (!s->be_driver) {
>           error_setg(errp, "backend driver with id %s could not be found",

^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: [Qemu-devel] [PATCH v2 25/28] tpm-emulator: protect concurrent ctrl_chr access
  2017-11-06 18:39 ` [Qemu-devel] [PATCH v2 25/28] tpm-emulator: protect concurrent ctrl_chr access Marc-André Lureau
@ 2017-11-06 19:32   ` Stefan Berger
  2017-11-06 22:11     ` Marc-André Lureau
  0 siblings, 1 reply; 44+ messages in thread
From: Stefan Berger @ 2017-11-06 19:32 UTC (permalink / raw)
  To: Marc-André Lureau, qemu-devel; +Cc: amarnath.valluri

On 11/06/2017 01:39 PM, Marc-André Lureau wrote:
> The control chardev is being used from the data thread to set the
> locality of the next request. Altough the chr has a write mutex, we
> may potentially read the reply from another thread request.

Right, so there may be concurrency with the CMD_RESET/GET_TPMESTABLISHED 
commands. All the other ones shouldn't be affected. It sound like a bug 
in existing code.

>
> Add a mutex to protect from concurrent control commands.
>
> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>

Reviewed-by: Stefan Berger <stefanb@linux.vnet.ibm.com>


> ---
>   hw/tpm/tpm_emulator.c | 44 ++++++++++++++++++++++++++++----------------
>   1 file changed, 28 insertions(+), 16 deletions(-)
>
> diff --git a/hw/tpm/tpm_emulator.c b/hw/tpm/tpm_emulator.c
> index b77c0238c7..24cb61162f 100644
> --- a/hw/tpm/tpm_emulator.c
> +++ b/hw/tpm/tpm_emulator.c
> @@ -71,15 +71,21 @@ typedef struct TPMEmulator {
>       ptm_cap caps; /* capabilities of the TPM */
>       uint8_t cur_locty_number; /* last set locality */
>       Error *migration_blocker;
> +
> +    QemuMutex mutex;
>   } TPMEmulator;
>
>
> -static int tpm_emulator_ctrlcmd(CharBackend *dev, unsigned long cmd, void *msg,
> +static int tpm_emulator_ctrlcmd(TPMEmulator *tpm, unsigned long cmd, void *msg,
>                                   size_t msg_len_in, size_t msg_len_out)
>   {
> +    CharBackend *dev = &tpm->ctrl_chr;
>       uint32_t cmd_no = cpu_to_be32(cmd);
>       ssize_t n = sizeof(uint32_t) + msg_len_in;
>       uint8_t *buf = NULL;
> +    int ret = -1;
> +
> +    qemu_mutex_lock(&tpm->mutex);
>
>       buf = g_alloca(n);
>       memcpy(buf, &cmd_no, sizeof(cmd_no));
> @@ -87,17 +93,21 @@ static int tpm_emulator_ctrlcmd(CharBackend *dev, unsigned long cmd, void *msg,
>
>       n = qemu_chr_fe_write_all(dev, buf, n);
>       if (n <= 0) {
> -        return -1;
> +        goto end;
>       }
>
>       if (msg_len_out != 0) {
>           n = qemu_chr_fe_read_all(dev, msg, msg_len_out);
>           if (n <= 0) {
> -            return -1;
> +            goto end;
>           }
>       }
>
> -    return 0;
> +    ret = 0;
> +
> +end:
> +    qemu_mutex_unlock(&tpm->mutex);
> +    return ret;
>   }
>
>   static int tpm_emulator_unix_tx_bufs(TPMEmulator *tpm_emu,
> @@ -154,7 +164,7 @@ static int tpm_emulator_set_locality(TPMEmulator *tpm_emu, uint8_t locty_number,
>
>       DPRINTF("setting locality : 0x%x", locty_number);
>       loc.u.req.loc = locty_number;
> -    if (tpm_emulator_ctrlcmd(&tpm_emu->ctrl_chr, CMD_SET_LOCALITY, &loc,
> +    if (tpm_emulator_ctrlcmd(tpm_emu, CMD_SET_LOCALITY, &loc,
>                                sizeof(loc), sizeof(loc)) < 0) {
>           error_setg(errp, "tpm-emulator: could not set locality : %s",
>                      strerror(errno));
> @@ -200,8 +210,8 @@ error:
>   static int tpm_emulator_probe_caps(TPMEmulator *tpm_emu)
>   {
>       DPRINTF("%s", __func__);
> -    if (tpm_emulator_ctrlcmd(&tpm_emu->ctrl_chr, CMD_GET_CAPABILITY,
> -                         &tpm_emu->caps, 0, sizeof(tpm_emu->caps)) < 0) {
> +    if (tpm_emulator_ctrlcmd(tpm_emu, CMD_GET_CAPABILITY,
> +                             &tpm_emu->caps, 0, sizeof(tpm_emu->caps)) < 0) {
>           error_report("tpm-emulator: probing failed : %s", strerror(errno));
>           return -1;
>       }
> @@ -252,8 +262,8 @@ static int tpm_emulator_startup_tpm(TPMBackend *tb)
>       ptm_res res;
>
>       DPRINTF("%s", __func__);
> -    if (tpm_emulator_ctrlcmd(&tpm_emu->ctrl_chr, CMD_INIT, &init, sizeof(init),
> -                         sizeof(init)) < 0) {
> +    if (tpm_emulator_ctrlcmd(tpm_emu, CMD_INIT, &init, sizeof(init),
> +                             sizeof(init)) < 0) {
>           error_report("tpm-emulator: could not send INIT: %s",
>                        strerror(errno));
>           goto err_exit;
> @@ -276,7 +286,7 @@ static bool tpm_emulator_get_tpm_established_flag(TPMBackend *tb)
>       ptm_est est;
>
>       DPRINTF("%s", __func__);
> -    if (tpm_emulator_ctrlcmd(&tpm_emu->ctrl_chr, CMD_GET_TPMESTABLISHED, &est,
> +    if (tpm_emulator_ctrlcmd(tpm_emu, CMD_GET_TPMESTABLISHED, &est,
>                                0, sizeof(est)) < 0) {
>           error_report("tpm-emulator: Could not get the TPM established flag: %s",
>                        strerror(errno));
> @@ -300,7 +310,7 @@ static int tpm_emulator_reset_tpm_established_flag(TPMBackend *tb,
>       }
>
>       reset_est.u.req.loc = tpm_emu->cur_locty_number;
> -    if (tpm_emulator_ctrlcmd(&tpm_emu->ctrl_chr, CMD_RESET_TPMESTABLISHED,
> +    if (tpm_emulator_ctrlcmd(tpm_emu, CMD_RESET_TPMESTABLISHED,
>                                &reset_est, sizeof(reset_est),
>                                sizeof(reset_est)) < 0) {
>           error_report("tpm-emulator: Could not reset the establishment bit: %s",
> @@ -329,7 +339,7 @@ static void tpm_emulator_cancel_cmd(TPMBackend *tb)
>       }
>
>       /* FIXME: make the function non-blocking, or it may block a VCPU */
> -    if (tpm_emulator_ctrlcmd(&tpm_emu->ctrl_chr, CMD_CANCEL_TPM_CMD, &res, 0,
> +    if (tpm_emulator_ctrlcmd(tpm_emu, CMD_CANCEL_TPM_CMD, &res, 0,
>                                sizeof(res)) < 0) {
>           error_report("tpm-emulator: Could not cancel command: %s",
>                        strerror(errno));
> @@ -377,8 +387,8 @@ static int tpm_emulator_prepare_data_fd(TPMEmulator *tpm_emu)
>
>       qemu_chr_fe_set_msgfds(&tpm_emu->ctrl_chr, fds + 1, 1);
>
> -    if (tpm_emulator_ctrlcmd(&tpm_emu->ctrl_chr, CMD_SET_DATAFD, &res, 0,
> -                    sizeof(res)) || res != 0) {
> +    if (tpm_emulator_ctrlcmd(tpm_emu, CMD_SET_DATAFD, &res, 0,
> +                             sizeof(res)) < 0 || res != 0) {
>           error_report("tpm-emulator: Failed to send CMD_SET_DATAFD: %s",
>                        strerror(errno));
>           goto err_exit;
> @@ -494,6 +504,7 @@ static void tpm_emulator_inst_init(Object *obj)
>       DPRINTF("%s", __func__);
>       tpm_emu->options = g_new0(TPMEmulatorOptions, 1);
>       tpm_emu->cur_locty_number = ~0;
> +    qemu_mutex_init(&tpm_emu->mutex);
>   }
>
>   /*
> @@ -503,8 +514,7 @@ static void tpm_emulator_shutdown(TPMEmulator *tpm_emu)
>   {
>       ptm_res res;
>
> -    if (tpm_emulator_ctrlcmd(&tpm_emu->ctrl_chr, CMD_SHUTDOWN, &res, 0,
> -                             sizeof(res)) < 0) {
> +    if (tpm_emulator_ctrlcmd(tpm_emu, CMD_SHUTDOWN, &res, 0, sizeof(res)) < 0) {
>           error_report("tpm-emulator: Could not cleanly shutdown the TPM: %s",
>                        strerror(errno));
>       } else if (res != 0) {
> @@ -529,6 +539,8 @@ static void tpm_emulator_inst_finalize(Object *obj)
>           migrate_del_blocker(tpm_emu->migration_blocker);
>           error_free(tpm_emu->migration_blocker);
>       }
> +
> +    qemu_mutex_destroy(&tpm_emu->mutex);
>   }
>
>   static void tpm_emulator_class_init(ObjectClass *klass, void *data)

^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: [Qemu-devel] [PATCH v2 26/28] qdev: add DEFINE_PROP_TPMBE
  2017-11-06 18:39 ` [Qemu-devel] [PATCH v2 26/28] qdev: add DEFINE_PROP_TPMBE Marc-André Lureau
@ 2017-11-06 20:31   ` Stefan Berger
  2017-11-07 10:58     ` Marc-André Lureau
  0 siblings, 1 reply; 44+ messages in thread
From: Stefan Berger @ 2017-11-06 20:31 UTC (permalink / raw)
  To: Marc-André Lureau, qemu-devel; +Cc: amarnath.valluri

On 11/06/2017 01:39 PM, Marc-André Lureau wrote:
> A property to lookup a tpm backend.
>
> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
> ---
>   include/hw/qdev-properties.h     |  3 ++
>   hw/core/qdev-properties-system.c | 64 ++++++++++++++++++++++++++++++++++++++++
>   2 files changed, 67 insertions(+)
>
> diff --git a/include/hw/qdev-properties.h b/include/hw/qdev-properties.h
> index e2321f1cc1..4d24cdf8d6 100644
> --- a/include/hw/qdev-properties.h
> +++ b/include/hw/qdev-properties.h
> @@ -17,6 +17,7 @@ extern const PropertyInfo qdev_prop_int64;
>   extern const PropertyInfo qdev_prop_size;
>   extern const PropertyInfo qdev_prop_string;
>   extern const PropertyInfo qdev_prop_chr;
> +extern const PropertyInfo qdev_prop_tpm;
>   extern const PropertyInfo qdev_prop_ptr;
>   extern const PropertyInfo qdev_prop_macaddr;
>   extern const PropertyInfo qdev_prop_on_off_auto;
> @@ -186,6 +187,8 @@ extern const PropertyInfo qdev_prop_link;
>
>   #define DEFINE_PROP_CHR(_n, _s, _f)             \
>       DEFINE_PROP(_n, _s, _f, qdev_prop_chr, CharBackend)
> +#define DEFINE_PROP_TPMBE(_n, _s, _f)                     \
> +    DEFINE_PROP(_n, _s, _f, qdev_prop_tpm, TPMBackend *)
>   #define DEFINE_PROP_STRING(_n, _s, _f)             \
>       DEFINE_PROP(_n, _s, _f, qdev_prop_string, char*)
>   #define DEFINE_PROP_NETDEV(_n, _s, _f)             \
> diff --git a/hw/core/qdev-properties-system.c b/hw/core/qdev-properties-system.c
> index ec10da7424..c17364655c 100644
> --- a/hw/core/qdev-properties-system.c
> +++ b/hw/core/qdev-properties-system.c
> @@ -21,6 +21,7 @@
>   #include "net/hub.h"
>   #include "qapi/visitor.h"
>   #include "chardev/char-fe.h"
> +#include "sysemu/tpm_backend.h"
>   #include "sysemu/iothread.h"
>
>   static void get_pointer(Object *obj, Visitor *v, Property *prop,
> @@ -236,6 +237,69 @@ const PropertyInfo qdev_prop_chr = {
>       .release = release_chr,
>   };
>
> +/* --- character device --- */
> +
> +static void get_tpm(Object *obj, Visitor *v, const char *name, void *opaque,
> +                    Error **errp)
> +{
> +    DeviceState *dev = DEVICE(obj);
> +    TPMBackend **be = qdev_get_prop_ptr(dev, opaque);
> +    char *p;
> +
> +    p = g_strdup(*be ? (*be)->id : "");
> +    visit_type_str(v, name, &p, errp);
> +    g_free(p);
> +}
> +
> +static void set_tpm(Object *obj, Visitor *v, const char *name, void *opaque,
> +                    Error **errp)
> +{
> +    DeviceState *dev = DEVICE(obj);
> +    Error *local_err = NULL;
> +    Property *prop = opaque;
> +    TPMBackend *s, **be = qdev_get_prop_ptr(dev, prop);
> +    char *str;
> +
> +    if (dev->realized) {
> +        qdev_prop_set_after_realize(dev, name, errp);
> +        return;
> +    }
> +
> +    visit_type_str(v, name, &str, &local_err);
> +    if (local_err) {
> +        error_propagate(errp, local_err);
> +        return;
> +    }
> +
> +    s = qemu_find_tpm_be(str);
> +    if (s == NULL) {
> +        error_setg(errp, "Property '%s.%s' can't find value '%s'",
> +                   object_get_typename(obj), prop->name, str);
> +    } else if (tpm_backend_init(s, TPM_IF(obj), errp) == 0) {
> +        *be = s; /* weak reference, avoid cyclic ref */

I suppose this is the reason why you need **be rather than *be, but why 
do you need this here?

Reviewed-by: Stefan Berger <stefanb@linux.vnet.ibm.com>

     Stefan

> +    }
> +    g_free(str);
> +}
> +
> +static void release_tpm(Object *obj, const char *name, void *opaque)
> +{
> +    DeviceState *dev = DEVICE(obj);
> +    Property *prop = opaque;
> +    TPMBackend **be = qdev_get_prop_ptr(dev, prop);
> +
> +    if (*be) {
> +        tpm_backend_reset(*be);
> +    }
> +}
> +
> +const PropertyInfo qdev_prop_tpm = {
> +    .name  = "str",
> +    .description = "ID of a tpm to use as a backend",
> +    .get   = get_tpm,
> +    .set   = set_tpm,
> +    .release = release_tpm,
> +};
> +
>   /* --- netdev device --- */
>   static void get_netdev(Object *obj, Visitor *v, const char *name,
>                          void *opaque, Error **errp)

^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: [Qemu-devel] [PATCH v2 27/28] tpm-tis: use DEFINE_PROP_TPMBE
  2017-11-06 18:39 ` [Qemu-devel] [PATCH v2 27/28] tpm-tis: use DEFINE_PROP_TPMBE Marc-André Lureau
@ 2017-11-06 20:31   ` Stefan Berger
  0 siblings, 0 replies; 44+ messages in thread
From: Stefan Berger @ 2017-11-06 20:31 UTC (permalink / raw)
  To: Marc-André Lureau, qemu-devel; +Cc: amarnath.valluri

On 11/06/2017 01:39 PM, Marc-André Lureau wrote:
> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>

Reviewed-by: Stefan Berger <stefanb@linux.vnet.ibm.com>

> ---
>   hw/tpm/tpm_tis.c | 12 ++----------
>   1 file changed, 2 insertions(+), 10 deletions(-)
>
> diff --git a/hw/tpm/tpm_tis.c b/hw/tpm/tpm_tis.c
> index dccc56ab09..a00779f3aa 100644
> --- a/hw/tpm/tpm_tis.c
> +++ b/hw/tpm/tpm_tis.c
> @@ -86,7 +86,6 @@ typedef struct TPMState {
>
>       TPMBackendCmd cmd;
>
> -    char *backend;
>       TPMBackend *be_driver;
>       TPMVersion be_tpm_version;
>   } TPMState;
> @@ -1049,7 +1048,7 @@ static const VMStateDescription vmstate_tpm_tis = {
>
>   static Property tpm_tis_properties[] = {
>       DEFINE_PROP_UINT32("irq", TPMState, irq_num, TPM_TIS_IRQ),
> -    DEFINE_PROP_STRING("tpmdev", TPMState, backend),
> +    DEFINE_PROP_TPMBE("tpmdev", TPMState, be_driver),
>       DEFINE_PROP_END_OF_LIST(),
>   };
>
> @@ -1062,17 +1061,10 @@ static void tpm_tis_realizefn(DeviceState *dev, Error **errp)
>           return;
>       }
>
> -    s->be_driver = qemu_find_tpm_be(s->backend);
>       if (!s->be_driver) {
> -        error_setg(errp, "backend driver with id %s could not be found",
> -                   s->backend);
> +        error_setg(errp, "'tpmdev' property is required");
>           return;
>       }
> -
> -    if (tpm_backend_init(s->be_driver, TPM_IF(s), errp)) {
> -        return;
> -    }
> -
>       if (s->irq_num > 15) {
>           error_setg(errp, "IRQ %d is outside valid range of 0 to 15",
>                      s->irq_num);

^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: [Qemu-devel] [PATCH v2 28/28] tpm: remove tpm_register_model()
  2017-11-06 18:39 ` [Qemu-devel] [PATCH v2 28/28] tpm: remove tpm_register_model() Marc-André Lureau
@ 2017-11-06 20:33   ` Stefan Berger
  0 siblings, 0 replies; 44+ messages in thread
From: Stefan Berger @ 2017-11-06 20:33 UTC (permalink / raw)
  To: qemu-devel

On 11/06/2017 01:39 PM, Marc-André Lureau wrote:
> Query object classes that implements TPMIf instead.
>
> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>

Reviewed-by: Stefan Berger <stefanb@linux.vnet.ibm.com>

> ---
>   include/sysemu/tpm_backend.h |  2 --
>   hw/tpm/tpm_tis.c             |  1 -
>   tpm.c                        | 20 ++++++--------------
>   3 files changed, 6 insertions(+), 17 deletions(-)
>
> diff --git a/include/sysemu/tpm_backend.h b/include/sysemu/tpm_backend.h
> index c42d83aaef..590e8b42de 100644
> --- a/include/sysemu/tpm_backend.h
> +++ b/include/sysemu/tpm_backend.h
> @@ -194,6 +194,4 @@ TPMInfo *tpm_backend_query_tpm(TPMBackend *s);
>   
>   TPMBackend *qemu_find_tpm_be(const char *id);
>   
> -void tpm_register_model(enum TpmModel model);
> -
>   #endif
> diff --git a/hw/tpm/tpm_tis.c b/hw/tpm/tpm_tis.c
> index a00779f3aa..cc32fcde36 100644
> --- a/hw/tpm/tpm_tis.c
> +++ b/hw/tpm/tpm_tis.c
> @@ -1115,7 +1115,6 @@ static const TypeInfo tpm_tis_info = {
>   static void tpm_tis_register(void)
>   {
>       type_register_static(&tpm_tis_info);
> -    tpm_register_model(TPM_MODEL_TPM_TIS);
>   }
>   
>   type_init(tpm_tis_register)
> diff --git a/tpm.c b/tpm.c
> index 4661dfc46e..61a434185a 100644
> --- a/tpm.c
> +++ b/tpm.c
> @@ -23,13 +23,6 @@
>   static QLIST_HEAD(, TPMBackend) tpm_backends =
>       QLIST_HEAD_INITIALIZER(tpm_backends);
>   
> -static bool tpm_models[TPM_MODEL__MAX];
> -
> -void tpm_register_model(enum TpmModel model)
> -{
> -    tpm_models[model] = true;
> -}
> -
>   static const TPMBackendClass *
>   tpm_be_find_by_type(enum TpmType type)
>   {
> @@ -236,18 +229,16 @@ TpmTypeList *qmp_query_tpm_types(Error **errp)
>   
>       return head;
>   }
> -
>   TpmModelList *qmp_query_tpm_models(Error **errp)
>   {
> -    unsigned int i = 0;
>       TpmModelList *head = NULL, *prev = NULL, *cur_item;
> +    GSList *e, *l = object_class_get_list(TYPE_TPM_IF, false);
> +
> +    for (e = l; e; e = e->next) {
> +        TPMIfClass *c = TPM_IF_CLASS(e->data);
>   
> -    for (i = 0; i < TPM_MODEL__MAX; i++) {
> -        if (!tpm_models[i]) {
> -            continue;
> -        }
>           cur_item = g_new0(TpmModelList, 1);
> -        cur_item->value = i;
> +        cur_item->value = c->model;
>   
>           if (prev) {
>               prev->next = cur_item;
> @@ -257,6 +248,7 @@ TpmModelList *qmp_query_tpm_models(Error **errp)
>           }
>           prev = cur_item;
>       }
> +    g_slist_free(l);
>   
>       return head;
>   }

^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: [Qemu-devel] [PATCH v2 25/28] tpm-emulator: protect concurrent ctrl_chr access
  2017-11-06 19:32   ` Stefan Berger
@ 2017-11-06 22:11     ` Marc-André Lureau
  2017-11-07  1:11       ` Stefan Berger
  0 siblings, 1 reply; 44+ messages in thread
From: Marc-André Lureau @ 2017-11-06 22:11 UTC (permalink / raw)
  To: Stefan Berger; +Cc: qemu-devel, amarnath valluri

Hi

----- Original Message -----
> On 11/06/2017 01:39 PM, Marc-André Lureau wrote:
> > The control chardev is being used from the data thread to set the
> > locality of the next request. Altough the chr has a write mutex, we
> > may potentially read the reply from another thread request.
> 
> Right, so there may be concurrency with the CMD_RESET/GET_TPMESTABLISHED
> commands. All the other ones shouldn't be affected. It sound like a bug
> in existing code.
> 

I think so too, I'll rebase on master for 2.11, unless you can trivially cherry-pick it.

> > Add a mutex to protect from concurrent control commands.
> >
> > Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
> 
> Reviewed-by: Stefan Berger <stefanb@linux.vnet.ibm.com>
> 
> 

thanks

> > ---
> >   hw/tpm/tpm_emulator.c | 44 ++++++++++++++++++++++++++++----------------
> >   1 file changed, 28 insertions(+), 16 deletions(-)
> >
> > diff --git a/hw/tpm/tpm_emulator.c b/hw/tpm/tpm_emulator.c
> > index b77c0238c7..24cb61162f 100644
> > --- a/hw/tpm/tpm_emulator.c
> > +++ b/hw/tpm/tpm_emulator.c
> > @@ -71,15 +71,21 @@ typedef struct TPMEmulator {
> >       ptm_cap caps; /* capabilities of the TPM */
> >       uint8_t cur_locty_number; /* last set locality */
> >       Error *migration_blocker;
> > +
> > +    QemuMutex mutex;
> >   } TPMEmulator;
> >
> >
> > -static int tpm_emulator_ctrlcmd(CharBackend *dev, unsigned long cmd, void
> > *msg,
> > +static int tpm_emulator_ctrlcmd(TPMEmulator *tpm, unsigned long cmd, void
> > *msg,
> >                                   size_t msg_len_in, size_t msg_len_out)
> >   {
> > +    CharBackend *dev = &tpm->ctrl_chr;
> >       uint32_t cmd_no = cpu_to_be32(cmd);
> >       ssize_t n = sizeof(uint32_t) + msg_len_in;
> >       uint8_t *buf = NULL;
> > +    int ret = -1;
> > +
> > +    qemu_mutex_lock(&tpm->mutex);
> >
> >       buf = g_alloca(n);
> >       memcpy(buf, &cmd_no, sizeof(cmd_no));
> > @@ -87,17 +93,21 @@ static int tpm_emulator_ctrlcmd(CharBackend *dev,
> > unsigned long cmd, void *msg,
> >
> >       n = qemu_chr_fe_write_all(dev, buf, n);
> >       if (n <= 0) {
> > -        return -1;
> > +        goto end;
> >       }
> >
> >       if (msg_len_out != 0) {
> >           n = qemu_chr_fe_read_all(dev, msg, msg_len_out);
> >           if (n <= 0) {
> > -            return -1;
> > +            goto end;
> >           }
> >       }
> >
> > -    return 0;
> > +    ret = 0;
> > +
> > +end:
> > +    qemu_mutex_unlock(&tpm->mutex);
> > +    return ret;
> >   }
> >
> >   static int tpm_emulator_unix_tx_bufs(TPMEmulator *tpm_emu,
> > @@ -154,7 +164,7 @@ static int tpm_emulator_set_locality(TPMEmulator
> > *tpm_emu, uint8_t locty_number,
> >
> >       DPRINTF("setting locality : 0x%x", locty_number);
> >       loc.u.req.loc = locty_number;
> > -    if (tpm_emulator_ctrlcmd(&tpm_emu->ctrl_chr, CMD_SET_LOCALITY, &loc,
> > +    if (tpm_emulator_ctrlcmd(tpm_emu, CMD_SET_LOCALITY, &loc,
> >                                sizeof(loc), sizeof(loc)) < 0) {
> >           error_setg(errp, "tpm-emulator: could not set locality : %s",
> >                      strerror(errno));
> > @@ -200,8 +210,8 @@ error:
> >   static int tpm_emulator_probe_caps(TPMEmulator *tpm_emu)
> >   {
> >       DPRINTF("%s", __func__);
> > -    if (tpm_emulator_ctrlcmd(&tpm_emu->ctrl_chr, CMD_GET_CAPABILITY,
> > -                         &tpm_emu->caps, 0, sizeof(tpm_emu->caps)) < 0) {
> > +    if (tpm_emulator_ctrlcmd(tpm_emu, CMD_GET_CAPABILITY,
> > +                             &tpm_emu->caps, 0, sizeof(tpm_emu->caps)) <
> > 0) {
> >           error_report("tpm-emulator: probing failed : %s",
> >           strerror(errno));
> >           return -1;
> >       }
> > @@ -252,8 +262,8 @@ static int tpm_emulator_startup_tpm(TPMBackend *tb)
> >       ptm_res res;
> >
> >       DPRINTF("%s", __func__);
> > -    if (tpm_emulator_ctrlcmd(&tpm_emu->ctrl_chr, CMD_INIT, &init,
> > sizeof(init),
> > -                         sizeof(init)) < 0) {
> > +    if (tpm_emulator_ctrlcmd(tpm_emu, CMD_INIT, &init, sizeof(init),
> > +                             sizeof(init)) < 0) {
> >           error_report("tpm-emulator: could not send INIT: %s",
> >                        strerror(errno));
> >           goto err_exit;
> > @@ -276,7 +286,7 @@ static bool
> > tpm_emulator_get_tpm_established_flag(TPMBackend *tb)
> >       ptm_est est;
> >
> >       DPRINTF("%s", __func__);
> > -    if (tpm_emulator_ctrlcmd(&tpm_emu->ctrl_chr, CMD_GET_TPMESTABLISHED,
> > &est,
> > +    if (tpm_emulator_ctrlcmd(tpm_emu, CMD_GET_TPMESTABLISHED, &est,
> >                                0, sizeof(est)) < 0) {
> >           error_report("tpm-emulator: Could not get the TPM established
> >           flag: %s",
> >                        strerror(errno));
> > @@ -300,7 +310,7 @@ static int
> > tpm_emulator_reset_tpm_established_flag(TPMBackend *tb,
> >       }
> >
> >       reset_est.u.req.loc = tpm_emu->cur_locty_number;
> > -    if (tpm_emulator_ctrlcmd(&tpm_emu->ctrl_chr, CMD_RESET_TPMESTABLISHED,
> > +    if (tpm_emulator_ctrlcmd(tpm_emu, CMD_RESET_TPMESTABLISHED,
> >                                &reset_est, sizeof(reset_est),
> >                                sizeof(reset_est)) < 0) {
> >           error_report("tpm-emulator: Could not reset the establishment
> >           bit: %s",
> > @@ -329,7 +339,7 @@ static void tpm_emulator_cancel_cmd(TPMBackend *tb)
> >       }
> >
> >       /* FIXME: make the function non-blocking, or it may block a VCPU */
> > -    if (tpm_emulator_ctrlcmd(&tpm_emu->ctrl_chr, CMD_CANCEL_TPM_CMD, &res,
> > 0,
> > +    if (tpm_emulator_ctrlcmd(tpm_emu, CMD_CANCEL_TPM_CMD, &res, 0,
> >                                sizeof(res)) < 0) {
> >           error_report("tpm-emulator: Could not cancel command: %s",
> >                        strerror(errno));
> > @@ -377,8 +387,8 @@ static int tpm_emulator_prepare_data_fd(TPMEmulator
> > *tpm_emu)
> >
> >       qemu_chr_fe_set_msgfds(&tpm_emu->ctrl_chr, fds + 1, 1);
> >
> > -    if (tpm_emulator_ctrlcmd(&tpm_emu->ctrl_chr, CMD_SET_DATAFD, &res, 0,
> > -                    sizeof(res)) || res != 0) {
> > +    if (tpm_emulator_ctrlcmd(tpm_emu, CMD_SET_DATAFD, &res, 0,
> > +                             sizeof(res)) < 0 || res != 0) {
> >           error_report("tpm-emulator: Failed to send CMD_SET_DATAFD: %s",
> >                        strerror(errno));
> >           goto err_exit;
> > @@ -494,6 +504,7 @@ static void tpm_emulator_inst_init(Object *obj)
> >       DPRINTF("%s", __func__);
> >       tpm_emu->options = g_new0(TPMEmulatorOptions, 1);
> >       tpm_emu->cur_locty_number = ~0;
> > +    qemu_mutex_init(&tpm_emu->mutex);
> >   }
> >
> >   /*
> > @@ -503,8 +514,7 @@ static void tpm_emulator_shutdown(TPMEmulator *tpm_emu)
> >   {
> >       ptm_res res;
> >
> > -    if (tpm_emulator_ctrlcmd(&tpm_emu->ctrl_chr, CMD_SHUTDOWN, &res, 0,
> > -                             sizeof(res)) < 0) {
> > +    if (tpm_emulator_ctrlcmd(tpm_emu, CMD_SHUTDOWN, &res, 0, sizeof(res))
> > < 0) {
> >           error_report("tpm-emulator: Could not cleanly shutdown the TPM:
> >           %s",
> >                        strerror(errno));
> >       } else if (res != 0) {
> > @@ -529,6 +539,8 @@ static void tpm_emulator_inst_finalize(Object *obj)
> >           migrate_del_blocker(tpm_emu->migration_blocker);
> >           error_free(tpm_emu->migration_blocker);
> >       }
> > +
> > +    qemu_mutex_destroy(&tpm_emu->mutex);
> >   }
> >
> >   static void tpm_emulator_class_init(ObjectClass *klass, void *data)
> 
> 
> 

^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: [Qemu-devel] [PATCH v2 00/28] TPM: code cleanup (not 2.11)
  2017-11-06 18:38 [Qemu-devel] [PATCH v2 00/28] TPM: code cleanup (not 2.11) Marc-André Lureau
                   ` (27 preceding siblings ...)
  2017-11-06 18:39 ` [Qemu-devel] [PATCH v2 28/28] tpm: remove tpm_register_model() Marc-André Lureau
@ 2017-11-07  1:05 ` Stefan Berger
  28 siblings, 0 replies; 44+ messages in thread
From: Stefan Berger @ 2017-11-07  1:05 UTC (permalink / raw)
  To: Marc-André Lureau, qemu-devel; +Cc: amarnath.valluri

On 11/06/2017 01:38 PM, Marc-André Lureau wrote:
> Hi,
>
> Various code cleanups accumulated while doing reviews and implementing
> a CRB device (postponed for later), aiming at a tpm-next development
> branch for after qemu 2.11.

I put all of these now into a tpm-next branch here.

https://github.com/stefanberger/qemu-tpm/commits/tpm-next

This includes 25/28 until I rebase tpm-next on a later 2.11.

All my tests succeeded.

    Stefan


>
> v2: after Stefan review
> - rebased (half of v1 is merged upstream)
> - add & use a DEFINE_PROP_TPMBE()
> - remove tpm_register_model()
> - fix wrong locty_number usage & regression
> - tpm-tis: check that at most one TPM device exists
> - I changed "tpm-passthrough: remove error cleanup from
>    handle_device_opts" to "tpm-passthrough: simplify create()", it is
>    mostly the same patch that Stefan didn't like much but with a
>    different rationale to have code closer to tpm-emulator create().
> - added some signed-offs
>
> Marc-André Lureau (28):
>    tpm-tis: remove unused locty_number
>    tpm: move TpmIf in include/sysemu/tpm.h
>    tpm-backend: store TPMIf interface, improve backend_init()
>    tpm-tis: no longer expose TPMState
>    tpm-be: call request_completed() out of thread
>    tpm-be: report error instead of front-end
>    tpm-be: ask model to the TPM interface
>    tpm: remove unused opened code
>    tpm-passthrough: don't save guessed cancel_path in options
>    tpm-be: update optional function pointers
>    tpm-passthrough: pass TPMPassthruState to handle_device_opts
>    tpm-backend: move set 'id' to common code
>    tpm-passthrough: make it safer to destroy after creation
>    tpm-passthrough: simplify create()
>    tpm-passthrough: workaround a possible race
>    tpm-tis: simplify header inclusion
>    tpm: rename qemu_find_tpm() -> qemu_find_tpm_be()
>    tpm: lookup the the TPM interface instead of TIS device
>    tpm: add TPM interface to lookup TPM version
>    tpm: add tpm_cmd_get_size() to tpm_util
>    acpi: change TPM TIS data conditions
>    tpm-emulator: add a FIXME comment about blocking cancel
>    tpm-tis: remove redundant 'tpm_tis:' in error messages
>    tpm-tis: check that at most one TPM device exists
>    tpm-emulator: protect concurrent ctrl_chr access
>    qdev: add DEFINE_PROP_TPMBE
>    tpm-tis: use DEFINE_PROP_TPMBE
>    tpm: remove tpm_register_model()
>
>   hw/tpm/tpm_int.h                 | 22 +----------
>   hw/tpm/tpm_util.h                |  8 +++-
>   include/hw/qdev-properties.h     |  3 ++
>   include/sysemu/tpm.h             | 48 +++++++++++++++++------
>   include/sysemu/tpm_backend.h     | 32 ++++++----------
>   backends/tpm.c                   | 83 +++++++++++++---------------------------
>   hw/core/qdev-properties-system.c | 64 +++++++++++++++++++++++++++++++
>   hw/i386/acpi-build.c             | 14 ++++---
>   hw/tpm/tpm_emulator.c            | 59 +++++++++++++++-------------
>   hw/tpm/tpm_passthrough.c         | 66 +++++++++++---------------------
>   hw/tpm/tpm_tis.c                 | 83 +++++++++++++++-------------------------
>   tpm.c                            | 34 ++++++----------
>   12 files changed, 255 insertions(+), 261 deletions(-)
>

^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: [Qemu-devel] [PATCH v2 25/28] tpm-emulator: protect concurrent ctrl_chr access
  2017-11-06 22:11     ` Marc-André Lureau
@ 2017-11-07  1:11       ` Stefan Berger
  2017-11-07 11:08         ` Marc-André Lureau
  0 siblings, 1 reply; 44+ messages in thread
From: Stefan Berger @ 2017-11-07  1:11 UTC (permalink / raw)
  To: Marc-André Lureau; +Cc: qemu-devel, amarnath valluri

On 11/06/2017 05:11 PM, Marc-André Lureau wrote:
> Hi
>
> ----- Original Message -----
>> On 11/06/2017 01:39 PM, Marc-André Lureau wrote:
>>> The control chardev is being used from the data thread to set the
>>> locality of the next request. Altough the chr has a write mutex, we
>>> may potentially read the reply from another thread request.
>> Right, so there may be concurrency with the CMD_RESET/GET_TPMESTABLISHED
>> commands. All the other ones shouldn't be affected. It sound like a bug
>> in existing code.
>>
> I think so too, I'll rebase on master for 2.11, unless you can trivially cherry-pick it.

I could trivially cherry-pick it. Now can I send it as a pull request ?

    Stefan

>
>>> Add a mutex to protect from concurrent control commands.
>>>
>>> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
>> Reviewed-by: Stefan Berger <stefanb@linux.vnet.ibm.com>
>>
>>
> thanks
>
>>> ---
>>>    hw/tpm/tpm_emulator.c | 44 ++++++++++++++++++++++++++++----------------
>>>    1 file changed, 28 insertions(+), 16 deletions(-)
>>>
>>> diff --git a/hw/tpm/tpm_emulator.c b/hw/tpm/tpm_emulator.c
>>> index b77c0238c7..24cb61162f 100644
>>> --- a/hw/tpm/tpm_emulator.c
>>> +++ b/hw/tpm/tpm_emulator.c
>>> @@ -71,15 +71,21 @@ typedef struct TPMEmulator {
>>>        ptm_cap caps; /* capabilities of the TPM */
>>>        uint8_t cur_locty_number; /* last set locality */
>>>        Error *migration_blocker;
>>> +
>>> +    QemuMutex mutex;
>>>    } TPMEmulator;
>>>
>>>
>>> -static int tpm_emulator_ctrlcmd(CharBackend *dev, unsigned long cmd, void
>>> *msg,
>>> +static int tpm_emulator_ctrlcmd(TPMEmulator *tpm, unsigned long cmd, void
>>> *msg,
>>>                                    size_t msg_len_in, size_t msg_len_out)
>>>    {
>>> +    CharBackend *dev = &tpm->ctrl_chr;
>>>        uint32_t cmd_no = cpu_to_be32(cmd);
>>>        ssize_t n = sizeof(uint32_t) + msg_len_in;
>>>        uint8_t *buf = NULL;
>>> +    int ret = -1;
>>> +
>>> +    qemu_mutex_lock(&tpm->mutex);
>>>
>>>        buf = g_alloca(n);
>>>        memcpy(buf, &cmd_no, sizeof(cmd_no));
>>> @@ -87,17 +93,21 @@ static int tpm_emulator_ctrlcmd(CharBackend *dev,
>>> unsigned long cmd, void *msg,
>>>
>>>        n = qemu_chr_fe_write_all(dev, buf, n);
>>>        if (n <= 0) {
>>> -        return -1;
>>> +        goto end;
>>>        }
>>>
>>>        if (msg_len_out != 0) {
>>>            n = qemu_chr_fe_read_all(dev, msg, msg_len_out);
>>>            if (n <= 0) {
>>> -            return -1;
>>> +            goto end;
>>>            }
>>>        }
>>>
>>> -    return 0;
>>> +    ret = 0;
>>> +
>>> +end:
>>> +    qemu_mutex_unlock(&tpm->mutex);
>>> +    return ret;
>>>    }
>>>
>>>    static int tpm_emulator_unix_tx_bufs(TPMEmulator *tpm_emu,
>>> @@ -154,7 +164,7 @@ static int tpm_emulator_set_locality(TPMEmulator
>>> *tpm_emu, uint8_t locty_number,
>>>
>>>        DPRINTF("setting locality : 0x%x", locty_number);
>>>        loc.u.req.loc = locty_number;
>>> -    if (tpm_emulator_ctrlcmd(&tpm_emu->ctrl_chr, CMD_SET_LOCALITY, &loc,
>>> +    if (tpm_emulator_ctrlcmd(tpm_emu, CMD_SET_LOCALITY, &loc,
>>>                                 sizeof(loc), sizeof(loc)) < 0) {
>>>            error_setg(errp, "tpm-emulator: could not set locality : %s",
>>>                       strerror(errno));
>>> @@ -200,8 +210,8 @@ error:
>>>    static int tpm_emulator_probe_caps(TPMEmulator *tpm_emu)
>>>    {
>>>        DPRINTF("%s", __func__);
>>> -    if (tpm_emulator_ctrlcmd(&tpm_emu->ctrl_chr, CMD_GET_CAPABILITY,
>>> -                         &tpm_emu->caps, 0, sizeof(tpm_emu->caps)) < 0) {
>>> +    if (tpm_emulator_ctrlcmd(tpm_emu, CMD_GET_CAPABILITY,
>>> +                             &tpm_emu->caps, 0, sizeof(tpm_emu->caps)) <
>>> 0) {
>>>            error_report("tpm-emulator: probing failed : %s",
>>>            strerror(errno));
>>>            return -1;
>>>        }
>>> @@ -252,8 +262,8 @@ static int tpm_emulator_startup_tpm(TPMBackend *tb)
>>>        ptm_res res;
>>>
>>>        DPRINTF("%s", __func__);
>>> -    if (tpm_emulator_ctrlcmd(&tpm_emu->ctrl_chr, CMD_INIT, &init,
>>> sizeof(init),
>>> -                         sizeof(init)) < 0) {
>>> +    if (tpm_emulator_ctrlcmd(tpm_emu, CMD_INIT, &init, sizeof(init),
>>> +                             sizeof(init)) < 0) {
>>>            error_report("tpm-emulator: could not send INIT: %s",
>>>                         strerror(errno));
>>>            goto err_exit;
>>> @@ -276,7 +286,7 @@ static bool
>>> tpm_emulator_get_tpm_established_flag(TPMBackend *tb)
>>>        ptm_est est;
>>>
>>>        DPRINTF("%s", __func__);
>>> -    if (tpm_emulator_ctrlcmd(&tpm_emu->ctrl_chr, CMD_GET_TPMESTABLISHED,
>>> &est,
>>> +    if (tpm_emulator_ctrlcmd(tpm_emu, CMD_GET_TPMESTABLISHED, &est,
>>>                                 0, sizeof(est)) < 0) {
>>>            error_report("tpm-emulator: Could not get the TPM established
>>>            flag: %s",
>>>                         strerror(errno));
>>> @@ -300,7 +310,7 @@ static int
>>> tpm_emulator_reset_tpm_established_flag(TPMBackend *tb,
>>>        }
>>>
>>>        reset_est.u.req.loc = tpm_emu->cur_locty_number;
>>> -    if (tpm_emulator_ctrlcmd(&tpm_emu->ctrl_chr, CMD_RESET_TPMESTABLISHED,
>>> +    if (tpm_emulator_ctrlcmd(tpm_emu, CMD_RESET_TPMESTABLISHED,
>>>                                 &reset_est, sizeof(reset_est),
>>>                                 sizeof(reset_est)) < 0) {
>>>            error_report("tpm-emulator: Could not reset the establishment
>>>            bit: %s",
>>> @@ -329,7 +339,7 @@ static void tpm_emulator_cancel_cmd(TPMBackend *tb)
>>>        }
>>>
>>>        /* FIXME: make the function non-blocking, or it may block a VCPU */
>>> -    if (tpm_emulator_ctrlcmd(&tpm_emu->ctrl_chr, CMD_CANCEL_TPM_CMD, &res,
>>> 0,
>>> +    if (tpm_emulator_ctrlcmd(tpm_emu, CMD_CANCEL_TPM_CMD, &res, 0,
>>>                                 sizeof(res)) < 0) {
>>>            error_report("tpm-emulator: Could not cancel command: %s",
>>>                         strerror(errno));
>>> @@ -377,8 +387,8 @@ static int tpm_emulator_prepare_data_fd(TPMEmulator
>>> *tpm_emu)
>>>
>>>        qemu_chr_fe_set_msgfds(&tpm_emu->ctrl_chr, fds + 1, 1);
>>>
>>> -    if (tpm_emulator_ctrlcmd(&tpm_emu->ctrl_chr, CMD_SET_DATAFD, &res, 0,
>>> -                    sizeof(res)) || res != 0) {
>>> +    if (tpm_emulator_ctrlcmd(tpm_emu, CMD_SET_DATAFD, &res, 0,
>>> +                             sizeof(res)) < 0 || res != 0) {
>>>            error_report("tpm-emulator: Failed to send CMD_SET_DATAFD: %s",
>>>                         strerror(errno));
>>>            goto err_exit;
>>> @@ -494,6 +504,7 @@ static void tpm_emulator_inst_init(Object *obj)
>>>        DPRINTF("%s", __func__);
>>>        tpm_emu->options = g_new0(TPMEmulatorOptions, 1);
>>>        tpm_emu->cur_locty_number = ~0;
>>> +    qemu_mutex_init(&tpm_emu->mutex);
>>>    }
>>>
>>>    /*
>>> @@ -503,8 +514,7 @@ static void tpm_emulator_shutdown(TPMEmulator *tpm_emu)
>>>    {
>>>        ptm_res res;
>>>
>>> -    if (tpm_emulator_ctrlcmd(&tpm_emu->ctrl_chr, CMD_SHUTDOWN, &res, 0,
>>> -                             sizeof(res)) < 0) {
>>> +    if (tpm_emulator_ctrlcmd(tpm_emu, CMD_SHUTDOWN, &res, 0, sizeof(res))
>>> < 0) {
>>>            error_report("tpm-emulator: Could not cleanly shutdown the TPM:
>>>            %s",
>>>                         strerror(errno));
>>>        } else if (res != 0) {
>>> @@ -529,6 +539,8 @@ static void tpm_emulator_inst_finalize(Object *obj)
>>>            migrate_del_blocker(tpm_emu->migration_blocker);
>>>            error_free(tpm_emu->migration_blocker);
>>>        }
>>> +
>>> +    qemu_mutex_destroy(&tpm_emu->mutex);
>>>    }
>>>
>>>    static void tpm_emulator_class_init(ObjectClass *klass, void *data)
>>
>>

^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: [Qemu-devel] [PATCH v2 26/28] qdev: add DEFINE_PROP_TPMBE
  2017-11-06 20:31   ` Stefan Berger
@ 2017-11-07 10:58     ` Marc-André Lureau
  0 siblings, 0 replies; 44+ messages in thread
From: Marc-André Lureau @ 2017-11-07 10:58 UTC (permalink / raw)
  To: Stefan Berger; +Cc: QEMU, Amarnath Valluri

On Mon, Nov 6, 2017 at 9:31 PM, Stefan Berger
<stefanb@linux.vnet.ibm.com> wrote:
> On 11/06/2017 01:39 PM, Marc-André Lureau wrote:
>>
>> A property to lookup a tpm backend.
>>
>> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
>> ---
>>   include/hw/qdev-properties.h     |  3 ++
>>   hw/core/qdev-properties-system.c | 64
>> ++++++++++++++++++++++++++++++++++++++++
>>   2 files changed, 67 insertions(+)
>>
>> diff --git a/include/hw/qdev-properties.h b/include/hw/qdev-properties.h
>> index e2321f1cc1..4d24cdf8d6 100644
>> --- a/include/hw/qdev-properties.h
>> +++ b/include/hw/qdev-properties.h
>> @@ -17,6 +17,7 @@ extern const PropertyInfo qdev_prop_int64;
>>   extern const PropertyInfo qdev_prop_size;
>>   extern const PropertyInfo qdev_prop_string;
>>   extern const PropertyInfo qdev_prop_chr;
>> +extern const PropertyInfo qdev_prop_tpm;
>>   extern const PropertyInfo qdev_prop_ptr;
>>   extern const PropertyInfo qdev_prop_macaddr;
>>   extern const PropertyInfo qdev_prop_on_off_auto;
>> @@ -186,6 +187,8 @@ extern const PropertyInfo qdev_prop_link;
>>
>>   #define DEFINE_PROP_CHR(_n, _s, _f)             \
>>       DEFINE_PROP(_n, _s, _f, qdev_prop_chr, CharBackend)
>> +#define DEFINE_PROP_TPMBE(_n, _s, _f)                     \
>> +    DEFINE_PROP(_n, _s, _f, qdev_prop_tpm, TPMBackend *)
>>   #define DEFINE_PROP_STRING(_n, _s, _f)             \
>>       DEFINE_PROP(_n, _s, _f, qdev_prop_string, char*)
>>   #define DEFINE_PROP_NETDEV(_n, _s, _f)             \
>> diff --git a/hw/core/qdev-properties-system.c
>> b/hw/core/qdev-properties-system.c
>> index ec10da7424..c17364655c 100644
>> --- a/hw/core/qdev-properties-system.c
>> +++ b/hw/core/qdev-properties-system.c
>> @@ -21,6 +21,7 @@
>>   #include "net/hub.h"
>>   #include "qapi/visitor.h"
>>   #include "chardev/char-fe.h"
>> +#include "sysemu/tpm_backend.h"
>>   #include "sysemu/iothread.h"
>>
>>   static void get_pointer(Object *obj, Visitor *v, Property *prop,
>> @@ -236,6 +237,69 @@ const PropertyInfo qdev_prop_chr = {
>>       .release = release_chr,
>>   };
>>
>> +/* --- character device --- */
>> +
>> +static void get_tpm(Object *obj, Visitor *v, const char *name, void
>> *opaque,
>> +                    Error **errp)
>> +{
>> +    DeviceState *dev = DEVICE(obj);
>> +    TPMBackend **be = qdev_get_prop_ptr(dev, opaque);
>> +    char *p;
>> +
>> +    p = g_strdup(*be ? (*be)->id : "");
>> +    visit_type_str(v, name, &p, errp);
>> +    g_free(p);
>> +}
>> +
>> +static void set_tpm(Object *obj, Visitor *v, const char *name, void
>> *opaque,
>> +                    Error **errp)
>> +{
>> +    DeviceState *dev = DEVICE(obj);
>> +    Error *local_err = NULL;
>> +    Property *prop = opaque;
>> +    TPMBackend *s, **be = qdev_get_prop_ptr(dev, prop);
>> +    char *str;
>> +
>> +    if (dev->realized) {
>> +        qdev_prop_set_after_realize(dev, name, errp);
>> +        return;
>> +    }
>> +
>> +    visit_type_str(v, name, &str, &local_err);
>> +    if (local_err) {
>> +        error_propagate(errp, local_err);
>> +        return;
>> +    }
>> +
>> +    s = qemu_find_tpm_be(str);
>> +    if (s == NULL) {
>> +        error_setg(errp, "Property '%s.%s' can't find value '%s'",
>> +                   object_get_typename(obj), prop->name, str);
>> +    } else if (tpm_backend_init(s, TPM_IF(obj), errp) == 0) {
>> +        *be = s; /* weak reference, avoid cyclic ref */
>
>
> I suppose this is the reason why you need **be rather than *be, but why do
> you need this here?
>

**be is because we have a pointer to the pointer property. This is
similar to PROP_PTR for example.

tpm_backend_init() takes a refrence to the TpmIf, so we only take a
weak reference to the backend. Otherwise we would need extra calls to
break the reference loop. (I am not convinced this is the best design,
we would need to think about destruction order if there is an issue
left)

thanks

> Reviewed-by: Stefan Berger <stefanb@linux.vnet.ibm.com>
>
>     Stefan
>
>
>> +    }
>> +    g_free(str);
>> +}
>> +
>> +static void release_tpm(Object *obj, const char *name, void *opaque)
>> +{
>> +    DeviceState *dev = DEVICE(obj);
>> +    Property *prop = opaque;
>> +    TPMBackend **be = qdev_get_prop_ptr(dev, prop);
>> +
>> +    if (*be) {
>> +        tpm_backend_reset(*be);
>> +    }
>> +}
>> +
>> +const PropertyInfo qdev_prop_tpm = {
>> +    .name  = "str",
>> +    .description = "ID of a tpm to use as a backend",
>> +    .get   = get_tpm,
>> +    .set   = set_tpm,
>> +    .release = release_tpm,
>> +};
>> +
>>   /* --- netdev device --- */
>>   static void get_netdev(Object *obj, Visitor *v, const char *name,
>>                          void *opaque, Error **errp)
>
>
>
>



-- 
Marc-André Lureau

^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: [Qemu-devel] [PATCH v2 25/28] tpm-emulator: protect concurrent ctrl_chr access
  2017-11-07  1:11       ` Stefan Berger
@ 2017-11-07 11:08         ` Marc-André Lureau
  0 siblings, 0 replies; 44+ messages in thread
From: Marc-André Lureau @ 2017-11-07 11:08 UTC (permalink / raw)
  To: Stefan Berger; +Cc: amarnath valluri, QEMU

Hi

On Tue, Nov 7, 2017 at 2:11 AM, Stefan Berger
<stefanb@linux.vnet.ibm.com> wrote:
> On 11/06/2017 05:11 PM, Marc-André Lureau wrote:
>>
>> Hi
>>
>> ----- Original Message -----
>>>
>>> On 11/06/2017 01:39 PM, Marc-André Lureau wrote:
>>>>
>>>> The control chardev is being used from the data thread to set the
>>>> locality of the next request. Altough the chr has a write mutex, we
>>>> may potentially read the reply from another thread request.
>>>
>>> Right, so there may be concurrency with the CMD_RESET/GET_TPMESTABLISHED
>>> commands. All the other ones shouldn't be affected. It sound like a bug
>>> in existing code.
>>>
>> I think so too, I'll rebase on master for 2.11, unless you can trivially
>> cherry-pick it.
>
>
> I could trivially cherry-pick it. Now can I send it as a pull request ?
>

Sure, thanks!


>    Stefan
>
>
>>
>>>> Add a mutex to protect from concurrent control commands.
>>>>
>>>> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
>>>
>>> Reviewed-by: Stefan Berger <stefanb@linux.vnet.ibm.com>
>>>
>>>
>> thanks
>>
>>>> ---
>>>>    hw/tpm/tpm_emulator.c | 44
>>>> ++++++++++++++++++++++++++++----------------
>>>>    1 file changed, 28 insertions(+), 16 deletions(-)
>>>>
>>>> diff --git a/hw/tpm/tpm_emulator.c b/hw/tpm/tpm_emulator.c
>>>> index b77c0238c7..24cb61162f 100644
>>>> --- a/hw/tpm/tpm_emulator.c
>>>> +++ b/hw/tpm/tpm_emulator.c
>>>> @@ -71,15 +71,21 @@ typedef struct TPMEmulator {
>>>>        ptm_cap caps; /* capabilities of the TPM */
>>>>        uint8_t cur_locty_number; /* last set locality */
>>>>        Error *migration_blocker;
>>>> +
>>>> +    QemuMutex mutex;
>>>>    } TPMEmulator;
>>>>
>>>>
>>>> -static int tpm_emulator_ctrlcmd(CharBackend *dev, unsigned long cmd,
>>>> void
>>>> *msg,
>>>> +static int tpm_emulator_ctrlcmd(TPMEmulator *tpm, unsigned long cmd,
>>>> void
>>>> *msg,
>>>>                                    size_t msg_len_in, size_t
>>>> msg_len_out)
>>>>    {
>>>> +    CharBackend *dev = &tpm->ctrl_chr;
>>>>        uint32_t cmd_no = cpu_to_be32(cmd);
>>>>        ssize_t n = sizeof(uint32_t) + msg_len_in;
>>>>        uint8_t *buf = NULL;
>>>> +    int ret = -1;
>>>> +
>>>> +    qemu_mutex_lock(&tpm->mutex);
>>>>
>>>>        buf = g_alloca(n);
>>>>        memcpy(buf, &cmd_no, sizeof(cmd_no));
>>>> @@ -87,17 +93,21 @@ static int tpm_emulator_ctrlcmd(CharBackend *dev,
>>>> unsigned long cmd, void *msg,
>>>>
>>>>        n = qemu_chr_fe_write_all(dev, buf, n);
>>>>        if (n <= 0) {
>>>> -        return -1;
>>>> +        goto end;
>>>>        }
>>>>
>>>>        if (msg_len_out != 0) {
>>>>            n = qemu_chr_fe_read_all(dev, msg, msg_len_out);
>>>>            if (n <= 0) {
>>>> -            return -1;
>>>> +            goto end;
>>>>            }
>>>>        }
>>>>
>>>> -    return 0;
>>>> +    ret = 0;
>>>> +
>>>> +end:
>>>> +    qemu_mutex_unlock(&tpm->mutex);
>>>> +    return ret;
>>>>    }
>>>>
>>>>    static int tpm_emulator_unix_tx_bufs(TPMEmulator *tpm_emu,
>>>> @@ -154,7 +164,7 @@ static int tpm_emulator_set_locality(TPMEmulator
>>>> *tpm_emu, uint8_t locty_number,
>>>>
>>>>        DPRINTF("setting locality : 0x%x", locty_number);
>>>>        loc.u.req.loc = locty_number;
>>>> -    if (tpm_emulator_ctrlcmd(&tpm_emu->ctrl_chr, CMD_SET_LOCALITY,
>>>> &loc,
>>>> +    if (tpm_emulator_ctrlcmd(tpm_emu, CMD_SET_LOCALITY, &loc,
>>>>                                 sizeof(loc), sizeof(loc)) < 0) {
>>>>            error_setg(errp, "tpm-emulator: could not set locality : %s",
>>>>                       strerror(errno));
>>>> @@ -200,8 +210,8 @@ error:
>>>>    static int tpm_emulator_probe_caps(TPMEmulator *tpm_emu)
>>>>    {
>>>>        DPRINTF("%s", __func__);
>>>> -    if (tpm_emulator_ctrlcmd(&tpm_emu->ctrl_chr, CMD_GET_CAPABILITY,
>>>> -                         &tpm_emu->caps, 0, sizeof(tpm_emu->caps)) < 0)
>>>> {
>>>> +    if (tpm_emulator_ctrlcmd(tpm_emu, CMD_GET_CAPABILITY,
>>>> +                             &tpm_emu->caps, 0, sizeof(tpm_emu->caps))
>>>> <
>>>> 0) {
>>>>            error_report("tpm-emulator: probing failed : %s",
>>>>            strerror(errno));
>>>>            return -1;
>>>>        }
>>>> @@ -252,8 +262,8 @@ static int tpm_emulator_startup_tpm(TPMBackend *tb)
>>>>        ptm_res res;
>>>>
>>>>        DPRINTF("%s", __func__);
>>>> -    if (tpm_emulator_ctrlcmd(&tpm_emu->ctrl_chr, CMD_INIT, &init,
>>>> sizeof(init),
>>>> -                         sizeof(init)) < 0) {
>>>> +    if (tpm_emulator_ctrlcmd(tpm_emu, CMD_INIT, &init, sizeof(init),
>>>> +                             sizeof(init)) < 0) {
>>>>            error_report("tpm-emulator: could not send INIT: %s",
>>>>                         strerror(errno));
>>>>            goto err_exit;
>>>> @@ -276,7 +286,7 @@ static bool
>>>> tpm_emulator_get_tpm_established_flag(TPMBackend *tb)
>>>>        ptm_est est;
>>>>
>>>>        DPRINTF("%s", __func__);
>>>> -    if (tpm_emulator_ctrlcmd(&tpm_emu->ctrl_chr,
>>>> CMD_GET_TPMESTABLISHED,
>>>> &est,
>>>> +    if (tpm_emulator_ctrlcmd(tpm_emu, CMD_GET_TPMESTABLISHED, &est,
>>>>                                 0, sizeof(est)) < 0) {
>>>>            error_report("tpm-emulator: Could not get the TPM established
>>>>            flag: %s",
>>>>                         strerror(errno));
>>>> @@ -300,7 +310,7 @@ static int
>>>> tpm_emulator_reset_tpm_established_flag(TPMBackend *tb,
>>>>        }
>>>>
>>>>        reset_est.u.req.loc = tpm_emu->cur_locty_number;
>>>> -    if (tpm_emulator_ctrlcmd(&tpm_emu->ctrl_chr,
>>>> CMD_RESET_TPMESTABLISHED,
>>>> +    if (tpm_emulator_ctrlcmd(tpm_emu, CMD_RESET_TPMESTABLISHED,
>>>>                                 &reset_est, sizeof(reset_est),
>>>>                                 sizeof(reset_est)) < 0) {
>>>>            error_report("tpm-emulator: Could not reset the establishment
>>>>            bit: %s",
>>>> @@ -329,7 +339,7 @@ static void tpm_emulator_cancel_cmd(TPMBackend *tb)
>>>>        }
>>>>
>>>>        /* FIXME: make the function non-blocking, or it may block a VCPU
>>>> */
>>>> -    if (tpm_emulator_ctrlcmd(&tpm_emu->ctrl_chr, CMD_CANCEL_TPM_CMD,
>>>> &res,
>>>> 0,
>>>> +    if (tpm_emulator_ctrlcmd(tpm_emu, CMD_CANCEL_TPM_CMD, &res, 0,
>>>>                                 sizeof(res)) < 0) {
>>>>            error_report("tpm-emulator: Could not cancel command: %s",
>>>>                         strerror(errno));
>>>> @@ -377,8 +387,8 @@ static int tpm_emulator_prepare_data_fd(TPMEmulator
>>>> *tpm_emu)
>>>>
>>>>        qemu_chr_fe_set_msgfds(&tpm_emu->ctrl_chr, fds + 1, 1);
>>>>
>>>> -    if (tpm_emulator_ctrlcmd(&tpm_emu->ctrl_chr, CMD_SET_DATAFD, &res,
>>>> 0,
>>>> -                    sizeof(res)) || res != 0) {
>>>> +    if (tpm_emulator_ctrlcmd(tpm_emu, CMD_SET_DATAFD, &res, 0,
>>>> +                             sizeof(res)) < 0 || res != 0) {
>>>>            error_report("tpm-emulator: Failed to send CMD_SET_DATAFD:
>>>> %s",
>>>>                         strerror(errno));
>>>>            goto err_exit;
>>>> @@ -494,6 +504,7 @@ static void tpm_emulator_inst_init(Object *obj)
>>>>        DPRINTF("%s", __func__);
>>>>        tpm_emu->options = g_new0(TPMEmulatorOptions, 1);
>>>>        tpm_emu->cur_locty_number = ~0;
>>>> +    qemu_mutex_init(&tpm_emu->mutex);
>>>>    }
>>>>
>>>>    /*
>>>> @@ -503,8 +514,7 @@ static void tpm_emulator_shutdown(TPMEmulator
>>>> *tpm_emu)
>>>>    {
>>>>        ptm_res res;
>>>>
>>>> -    if (tpm_emulator_ctrlcmd(&tpm_emu->ctrl_chr, CMD_SHUTDOWN, &res, 0,
>>>> -                             sizeof(res)) < 0) {
>>>> +    if (tpm_emulator_ctrlcmd(tpm_emu, CMD_SHUTDOWN, &res, 0,
>>>> sizeof(res))
>>>> < 0) {
>>>>            error_report("tpm-emulator: Could not cleanly shutdown the
>>>> TPM:
>>>>            %s",
>>>>                         strerror(errno));
>>>>        } else if (res != 0) {
>>>> @@ -529,6 +539,8 @@ static void tpm_emulator_inst_finalize(Object *obj)
>>>>            migrate_del_blocker(tpm_emu->migration_blocker);
>>>>            error_free(tpm_emu->migration_blocker);
>>>>        }
>>>> +
>>>> +    qemu_mutex_destroy(&tpm_emu->mutex);
>>>>    }
>>>>
>>>>    static void tpm_emulator_class_init(ObjectClass *klass, void *data)
>>>
>>>
>>>
>
>



-- 
Marc-André Lureau

^ permalink raw reply	[flat|nested] 44+ messages in thread

end of thread, other threads:[~2017-11-07 11:08 UTC | newest]

Thread overview: 44+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-11-06 18:38 [Qemu-devel] [PATCH v2 00/28] TPM: code cleanup (not 2.11) Marc-André Lureau
2017-11-06 18:38 ` [Qemu-devel] [PATCH v2 01/28] tpm-tis: remove unused locty_number Marc-André Lureau
2017-11-06 18:57   ` Stefan Berger
2017-11-06 18:38 ` [Qemu-devel] [PATCH v2 02/28] tpm: move TpmIf in include/sysemu/tpm.h Marc-André Lureau
2017-11-06 18:58   ` Stefan Berger
2017-11-06 18:39 ` [Qemu-devel] [PATCH v2 03/28] tpm-backend: store TPMIf interface, improve backend_init() Marc-André Lureau
2017-11-06 19:02   ` Stefan Berger
2017-11-06 18:39 ` [Qemu-devel] [PATCH v2 04/28] tpm-tis: no longer expose TPMState Marc-André Lureau
2017-11-06 18:39 ` [Qemu-devel] [PATCH v2 05/28] tpm-be: call request_completed() out of thread Marc-André Lureau
2017-11-06 19:22   ` Stefan Berger
2017-11-06 18:39 ` [Qemu-devel] [PATCH v2 06/28] tpm-be: report error instead of front-end Marc-André Lureau
2017-11-06 18:39 ` [Qemu-devel] [PATCH v2 07/28] tpm-be: ask model to the TPM interface Marc-André Lureau
2017-11-06 18:39 ` [Qemu-devel] [PATCH v2 08/28] tpm: remove unused opened code Marc-André Lureau
2017-11-06 18:39 ` [Qemu-devel] [PATCH v2 09/28] tpm-passthrough: don't save guessed cancel_path in options Marc-André Lureau
2017-11-06 18:39 ` [Qemu-devel] [PATCH v2 10/28] tpm-be: update optional function pointers Marc-André Lureau
2017-11-06 18:39 ` [Qemu-devel] [PATCH v2 11/28] tpm-passthrough: pass TPMPassthruState to handle_device_opts Marc-André Lureau
2017-11-06 18:39 ` [Qemu-devel] [PATCH v2 12/28] tpm-backend: move set 'id' to common code Marc-André Lureau
2017-11-06 18:39 ` [Qemu-devel] [PATCH v2 13/28] tpm-passthrough: make it safer to destroy after creation Marc-André Lureau
2017-11-06 18:39 ` [Qemu-devel] [PATCH v2 14/28] tpm-passthrough: simplify create() Marc-André Lureau
2017-11-06 18:39 ` [Qemu-devel] [PATCH v2 15/28] tpm-passthrough: workaround a possible race Marc-André Lureau
2017-11-06 18:39 ` [Qemu-devel] [PATCH v2 16/28] tpm-tis: simplify header inclusion Marc-André Lureau
2017-11-06 18:39 ` [Qemu-devel] [PATCH v2 17/28] tpm: rename qemu_find_tpm() -> qemu_find_tpm_be() Marc-André Lureau
2017-11-06 18:39 ` [Qemu-devel] [PATCH v2 18/28] tpm: lookup the the TPM interface instead of TIS device Marc-André Lureau
2017-11-06 18:39 ` [Qemu-devel] [PATCH v2 19/28] tpm: add TPM interface to lookup TPM version Marc-André Lureau
2017-11-06 18:39 ` [Qemu-devel] [PATCH v2 20/28] tpm: add tpm_cmd_get_size() to tpm_util Marc-André Lureau
2017-11-06 18:39 ` [Qemu-devel] [PATCH v2 21/28] acpi: change TPM TIS data conditions Marc-André Lureau
2017-11-06 18:39 ` [Qemu-devel] [PATCH v2 22/28] tpm-emulator: add a FIXME comment about blocking cancel Marc-André Lureau
2017-11-06 18:39 ` [Qemu-devel] [PATCH v2 23/28] tpm-tis: remove redundant 'tpm_tis:' in error messages Marc-André Lureau
2017-11-06 19:24   ` Stefan Berger
2017-11-06 18:39 ` [Qemu-devel] [PATCH v2 24/28] tpm-tis: check that at most one TPM device exists Marc-André Lureau
2017-11-06 19:25   ` Stefan Berger
2017-11-06 18:39 ` [Qemu-devel] [PATCH v2 25/28] tpm-emulator: protect concurrent ctrl_chr access Marc-André Lureau
2017-11-06 19:32   ` Stefan Berger
2017-11-06 22:11     ` Marc-André Lureau
2017-11-07  1:11       ` Stefan Berger
2017-11-07 11:08         ` Marc-André Lureau
2017-11-06 18:39 ` [Qemu-devel] [PATCH v2 26/28] qdev: add DEFINE_PROP_TPMBE Marc-André Lureau
2017-11-06 20:31   ` Stefan Berger
2017-11-07 10:58     ` Marc-André Lureau
2017-11-06 18:39 ` [Qemu-devel] [PATCH v2 27/28] tpm-tis: use DEFINE_PROP_TPMBE Marc-André Lureau
2017-11-06 20:31   ` Stefan Berger
2017-11-06 18:39 ` [Qemu-devel] [PATCH v2 28/28] tpm: remove tpm_register_model() Marc-André Lureau
2017-11-06 20:33   ` Stefan Berger
2017-11-07  1:05 ` [Qemu-devel] [PATCH v2 00/28] TPM: code cleanup (not 2.11) Stefan Berger

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.