[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Qemu-devel] [PATCH v2] QOM-ify the TPM support
From: |
Paolo Bonzini |
Subject: |
Re: [Qemu-devel] [PATCH v2] QOM-ify the TPM support |
Date: |
Wed, 27 Mar 2013 13:06:39 +0100 |
User-agent: |
Mozilla/5.0 (X11; Linux x86_64; rv:17.0) Gecko/20130311 Thunderbird/17.0.4 |
Il 26/03/2013 17:28, Stefan Berger ha scritto:
> QOM-ified the TPM support with much code borrowed from the rng implementation.
>
> What's missing may be that the tpm/tpm_passthrough.c be moved into backends/ .
>
> Signed-off-by: Stefan Berger <address@hidden>
>
> ---
> v1->v2:
> - followed to git revision e769bdc26
>
> ---
> backends/Makefile.objs | 2
> backends/tpm.c | 154 ++++++++++++++++++++++++++++++++++++++++++++
> include/qemu/tpm.h | 170
> +++++++++++++++++++++++++++++++++++++++++++++++++
I think these should be tpm_backend.[ch] (with the include file in
include/tpm). Can you rename the existing files with that name first?
Paolo
> include/tpm/tpm.h | 4 +
> tpm/tpm.c | 11 ++-
> tpm/tpm_int.h | 16 ----
> tpm/tpm_passthrough.c | 94 +++++++++++++++++----------
> tpm/tpm_tis.c | 21 +++---
> 8 files changed, 413 insertions(+), 59 deletions(-)
>
> Index: qemu-git.pt/backends/Makefile.objs
> ===================================================================
> --- qemu-git.pt.orig/backends/Makefile.objs
> +++ qemu-git.pt/backends/Makefile.objs
> @@ -4,3 +4,5 @@ common-obj-$(CONFIG_POSIX) += rng-random
> common-obj-y += msmouse.o
> common-obj-$(CONFIG_BRLAPI) += baum.o
> $(obj)/baum.o: QEMU_CFLAGS += $(SDL_CFLAGS)
> +
> +common-obj-$(CONFIG_TPM) += tpm.o
> Index: qemu-git.pt/backends/tpm.c
> ===================================================================
> --- /dev/null
> +++ qemu-git.pt/backends/tpm.c
> @@ -0,0 +1,154 @@
> +/*
> + * QEMU TPM Backend
> + *
> + * Copyright IBM, Corp. 2013
> + *
> + * Authors:
> + * Stefan Berger <address@hidden>
> + *
> + * This work is licensed under the terms of the GNU GPL, version 2 or later.
> + * See the COPYING file in the top-level directory.
> + *
> + * Based on backends/rng.c by Anthony Liguori
> + */
> +
> +#include "qemu/tpm.h"
> +#include "tpm/tpm_int.h"
> +#include "qapi/qmp/qerror.h"
> +
> +enum TpmType tpm_backend_get_type(TPMBackend *s)
> +{
> + TPMBackendClass *k = TPM_BACKEND_GET_CLASS(s);
> +
> + return k->ops->type;
> +}
> +
> +const char *tpm_backend_get_desc(TPMBackend *s)
> +{
> + TPMBackendClass *k = TPM_BACKEND_GET_CLASS(s);
> +
> + return k->ops->desc();
> +}
> +
> +void tpm_backend_destroy(TPMBackend *s)
> +{
> + TPMBackendClass *k = TPM_BACKEND_GET_CLASS(s);
> +
> + return k->ops->destroy(s);
> +}
> +
> +int tpm_backend_init(TPMBackend *s, TPMState *state,
> + TPMRecvDataCB *datacb)
> +{
> + TPMBackendClass *k = TPM_BACKEND_GET_CLASS(s);
> +
> + return k->ops->init(s, state, datacb);
> +}
> +
> +int tpm_backend_startup_tpm(TPMBackend *s)
> +{
> + TPMBackendClass *k = TPM_BACKEND_GET_CLASS(s);
> +
> + return k->ops->startup_tpm(s);
> +}
> +
> +bool tpm_backend_had_startup_error(TPMBackend *s)
> +{
> + TPMBackendClass *k = TPM_BACKEND_GET_CLASS(s);
> +
> + return k->ops->had_startup_error(s);
> +}
> +
> +size_t tpm_backend_realloc_buffer(TPMBackend *s, TPMSizedBuffer *sb)
> +{
> + TPMBackendClass *k = TPM_BACKEND_GET_CLASS(s);
> +
> + return k->ops->realloc_buffer(sb);
> +}
> +
> +void tpm_backend_deliver_request(TPMBackend *s)
> +{
> + TPMBackendClass *k = TPM_BACKEND_GET_CLASS(s);
> +
> + k->ops->deliver_request(s);
> +}
> +
> +void tpm_backend_reset(TPMBackend *s)
> +{
> + TPMBackendClass *k = TPM_BACKEND_GET_CLASS(s);
> +
> + k->ops->reset(s);
> +}
> +
> +void tpm_backend_cancel_cmd(TPMBackend *s)
> +{
> + TPMBackendClass *k = TPM_BACKEND_GET_CLASS(s);
> +
> + k->ops->cancel_cmd(s);
> +}
> +
> +bool tpm_backend_get_tpm_established_flag(TPMBackend *s)
> +{
> + TPMBackendClass *k = TPM_BACKEND_GET_CLASS(s);
> +
> + return k->ops->get_tpm_established_flag(s);
> +}
> +
> +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);
> +
> + if (value == s->opened) {
> + return;
> + }
> +
> + if (!value && s->opened) {
> + error_set(errp, QERR_PERMISSION_DENIED);
> + return;
> + }
> +
> + if (k->opened) {
> + k->opened(s, errp);
> + }
> +
> + if (!error_is_set(errp)) {
> + s->opened = value;
> + }
> +}
> +
> +static void tpm_backend_instance_init(Object *obj)
> +{
> + object_property_add_bool(obj, "opened",
> + tpm_backend_prop_get_opened,
> + tpm_backend_prop_set_opened,
> + NULL);
> +}
> +
> +static const TypeInfo tpm_backend_info = {
> + .name = TYPE_TPM_BACKEND,
> + .parent = TYPE_OBJECT,
> + .instance_size = sizeof(TPMBackend),
> + .instance_init = tpm_backend_instance_init,
> + .class_size = sizeof(TPMBackendClass),
> + .abstract = true,
> +};
> +
> +static void register_types(void)
> +{
> + type_register_static(&tpm_backend_info);
> +}
> +
> +type_init(register_types);
> Index: qemu-git.pt/include/qemu/tpm.h
> ===================================================================
> --- /dev/null
> +++ qemu-git.pt/include/qemu/tpm.h
> @@ -0,0 +1,170 @@
> +/*
> + * QEMU TPM Backend
> + *
> + * Copyright IBM, Corp. 2013
> + *
> + * Authors:
> + * Stefan Berger <address@hidden>
> + *
> + * This work is licensed under the terms of the GNU GPL, version 2 or later.
> + * See the COPYING file in the top-level directory.
> + */
> +
> +#ifndef _QEMU_TPM_H
> +#define _QEMU_TPM_H
> +
> +#include "qom/object.h"
> +#include "qemu-common.h"
> +#include "qapi/error.h"
> +#include "qapi-types.h"
> +#include "qemu/option.h"
> +#include "tpm/tpm.h"
> +
> +#define TYPE_TPM_BACKEND "tpm-backend"
> +#define TPM_BACKEND(obj) \
> + OBJECT_CHECK(TPMBackend, (obj), TYPE_TPM_BACKEND)
> +#define TPM_BACKEND_GET_CLASS(obj) \
> + OBJECT_GET_CLASS(TPMBackendClass, (obj), TYPE_TPM_BACKEND)
> +#define TPM_BACKEND_CLASS(klass) \
> + OBJECT_CLASS_CHECK(TPMBackendClass, (klass), TYPE_TPM_BACKEND)
> +
> +typedef struct TPMBackendClass TPMBackendClass;
> +typedef struct TPMBackend TPMBackend;
> +
> +typedef struct TPMDriverOps TPMDriverOps;
> +
> +struct TPMBackendClass {
> + ObjectClass parent_class;
> +
> + const TPMDriverOps *ops;
> +
> + void (*opened)(TPMBackend *s, Error **errp);
> +};
> +
> +struct TPMBackend {
> + Object parent;
> +
> + /*< protected >*/
> + bool opened;
> +
> + char *id;
> + enum TpmModel fe_model;
> + char *path;
> + char *cancel_path;
> + const TPMDriverOps *ops;
> +
> + QLIST_ENTRY(TPMBackend) list;
> +};
> +
> +
> +/**
> + * tpm_backend_get_type:
> + * @s: the backend
> + *
> + * Returns the TpmType of the backend.
> + */
> +enum TpmType tpm_backend_get_type(TPMBackend *s);
> +
> +/**
> + * tpm_backend_get_desc:
> + * @s: the backend
> + *
> + * Returns a human readable description of the backend.
> + */
> +const char *tpm_backend_get_desc(TPMBackend *s);
> +
> +/**
> + * tpm_backend_destroy:
> + * @s: the backend to destroy
> + */
> +void tpm_backend_destroy(TPMBackend *s);
> +
> +/**
> + * tpm_backend_init:
> + * @s: the backend to initialized
> + * @state: TPMState
> + * @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,
> + TPMRecvDataCB *datacb);
> +
> +/**
> + * tpm_backend_startup_tpm:
> + * @s: the backend whose TPM support is to be started
> + *
> + * Returns 0 on success.
> + */
> +int tpm_backend_startup_tpm(TPMBackend *s);
> +
> +/**
> + * tpm_backend_had_startup_error:
> + * @s: the backend to query for a statup error
> + *
> + * Check whether the backend had an error during startup. Returns
> + * false if no error occurred and the backend can be used, true
> + * otherwise.
> + */
> +bool tpm_backend_had_startup_error(TPMBackend *s);
> +
> +/**
> + * tpm_backend_realloc_buffer:
> + * @s: the backend
> + * @sb: the TPMSizedBuffer to re-allocated to the size suitable for the
> + * backend.
> + *
> + * This function returns the size of the allocated buffer
> + */
> +size_t tpm_backend_realloc_buffer(TPMBackend *s, TPMSizedBuffer *sb);
> +
> +/**
> + * tpm_backend_deliver_request:
> + * @s: the backend to send the request to
> + *
> + * Send a request to the backend. The backend will then send the request
> + * to the TPM implementation.
> + */
> +void tpm_backend_deliver_request(TPMBackend *s);
> +
> +/**
> + * tpm_backend_reset:
> + * @s: the backend to reset
> + *
> + * Reset the backend into a well defined state with all previous errors
> + * reset.
> + */
> +void tpm_backend_reset(TPMBackend *s);
> +
> +/**
> + * tpm_backend_cancel_cmd:
> + * @s: the backend
> + *
> + * Cancel any ongoing command being processed by the TPM implementation
> + * on behalf of the QEMU guest.
> + */
> +void tpm_backend_cancel_cmd(TPMBackend *s);
> +
> +/**
> + * tpm_backend_get_tpm_established_flag:
> + * @s: the backend
> + *
> + * Get the TPM establishment flag. This function may be called very
> + * frequently by the frontend since for example in the TIS implementation
> + * this flag is part of a register.
> + */
> +bool tpm_backend_get_tpm_established_flag(TPMBackend *s);
> +
> +/**
> + * 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);
> +
> +#endif
> Index: qemu-git.pt/tpm/tpm_passthrough.c
> ===================================================================
> --- qemu-git.pt.orig/tpm/tpm_passthrough.c
> +++ qemu-git.pt/tpm/tpm_passthrough.c
> @@ -27,6 +27,7 @@
> #include "qemu-common.h"
> #include "qapi/error.h"
> #include "qemu/sockets.h"
> +#include "qemu/tpm.h"
> #include "tpm_int.h"
> #include "hw/hw.h"
> #include "hw/pc.h"
> @@ -43,8 +44,11 @@
> do { } while (0)
> #endif
>
> -/* data structures */
> +#define TYPE_TPM_PASSTHROUGH "tpm-passthrough"
> +#define TPM_PASSTHROUGH(obj) \
> + OBJECT_CHECK(TPMPassthruState, (obj), TYPE_TPM_PASSTHROUGH)
>
> +/* data structures */
> typedef struct TPMPassthruThreadParams {
> TPMState *tpm_state;
>
> @@ -53,6 +57,8 @@ typedef struct TPMPassthruThreadParams {
> } TPMPassthruThreadParams;
>
> struct TPMPassthruState {
> + TPMBackend parent;
> +
> TPMBackendThread tbt;
>
> TPMPassthruThreadParams tpm_thread_params;
> @@ -65,6 +71,8 @@ struct TPMPassthruState {
> bool had_startup_error;
> };
>
> +typedef struct TPMPassthruState TPMPassthruState;
> +
> #define TPM_PASSTHROUGH_DEFAULT_DEVICE "/dev/tpm0"
>
> /* functions */
> @@ -149,7 +157,7 @@ static void tpm_passthrough_worker_threa
> gpointer user_data)
> {
> TPMPassthruThreadParams *thr_parms = user_data;
> - TPMPassthruState *tpm_pt = thr_parms->tb->s.tpm_pt;
> + TPMPassthruState *tpm_pt = TPM_PASSTHROUGH(thr_parms->tb);
> TPMBackendCmd cmd = (TPMBackendCmd)data;
>
> DPRINTF("tpm_passthrough: processing command type %d\n", cmd);
> @@ -176,21 +184,21 @@ static void tpm_passthrough_worker_threa
> */
> static int tpm_passthrough_startup_tpm(TPMBackend *tb)
> {
> - TPMPassthruState *tpm_pt = tb->s.tpm_pt;
> + TPMPassthruState *tpm_pt = TPM_PASSTHROUGH(tb);
>
> /* terminate a running TPM */
> tpm_backend_thread_end(&tpm_pt->tbt);
>
> tpm_backend_thread_create(&tpm_pt->tbt,
> tpm_passthrough_worker_thread,
> - &tb->s.tpm_pt->tpm_thread_params);
> + &tpm_pt->tpm_thread_params);
>
> return 0;
> }
>
> static void tpm_passthrough_reset(TPMBackend *tb)
> {
> - TPMPassthruState *tpm_pt = tb->s.tpm_pt;
> + TPMPassthruState *tpm_pt = TPM_PASSTHROUGH(tb);
>
> DPRINTF("tpm_passthrough: CALL TO TPM_RESET!\n");
>
> @@ -204,7 +212,7 @@ static void tpm_passthrough_reset(TPMBac
> static int tpm_passthrough_init(TPMBackend *tb, TPMState *s,
> TPMRecvDataCB *recv_data_cb)
> {
> - TPMPassthruState *tpm_pt = tb->s.tpm_pt;
> + TPMPassthruState *tpm_pt = TPM_PASSTHROUGH(tb);
>
> tpm_pt->tpm_thread_params.tpm_state = s;
> tpm_pt->tpm_thread_params.recv_data_callback = recv_data_cb;
> @@ -220,7 +228,7 @@ static bool tpm_passthrough_get_tpm_esta
>
> static bool tpm_passthrough_get_startup_error(TPMBackend *tb)
> {
> - TPMPassthruState *tpm_pt = tb->s.tpm_pt;
> + TPMPassthruState *tpm_pt = TPM_PASSTHROUGH(tb);
>
> return tpm_pt->had_startup_error;
> }
> @@ -238,14 +246,14 @@ static size_t tpm_passthrough_realloc_bu
>
> static void tpm_passthrough_deliver_request(TPMBackend *tb)
> {
> - TPMPassthruState *tpm_pt = tb->s.tpm_pt;
> + TPMPassthruState *tpm_pt = TPM_PASSTHROUGH(tb);
>
> tpm_backend_thread_deliver_request(&tpm_pt->tbt);
> }
>
> static void tpm_passthrough_cancel_cmd(TPMBackend *tb)
> {
> - TPMPassthruState *tpm_pt = tb->s.tpm_pt;
> + TPMPassthruState *tpm_pt = TPM_PASSTHROUGH(tb);
> int n;
>
> /*
> @@ -412,6 +420,7 @@ static int tpm_passthrough_open_sysfs_ca
>
> static int tpm_passthrough_handle_device_opts(QemuOpts *opts, TPMBackend *tb)
> {
> + TPMPassthruState *tpm_pt = TPM_PASSTHROUGH(tb);
> const char *value;
>
> value = qemu_opt_get(opts, "cancel-path");
> @@ -424,45 +433,45 @@ static int tpm_passthrough_handle_device
> value = TPM_PASSTHROUGH_DEFAULT_DEVICE;
> }
>
> - tb->s.tpm_pt->tpm_dev = g_strdup(value);
> + tpm_pt->tpm_dev = g_strdup(value);
>
> - tb->path = g_strdup(tb->s.tpm_pt->tpm_dev);
> + tb->path = g_strdup(tpm_pt->tpm_dev);
>
> - tb->s.tpm_pt->tpm_fd = qemu_open(tb->s.tpm_pt->tpm_dev, O_RDWR);
> - if (tb->s.tpm_pt->tpm_fd < 0) {
> + tpm_pt->tpm_fd = qemu_open(tpm_pt->tpm_dev, O_RDWR);
> + if (tpm_pt->tpm_fd < 0) {
> error_report("Cannot access TPM device using '%s': %s\n",
> - tb->s.tpm_pt->tpm_dev, strerror(errno));
> + tpm_pt->tpm_dev, strerror(errno));
> goto err_free_parameters;
> }
>
> - if (tpm_passthrough_test_tpmdev(tb->s.tpm_pt->tpm_fd)) {
> + if (tpm_passthrough_test_tpmdev(tpm_pt->tpm_fd)) {
> error_report("'%s' is not a TPM device.\n",
> - tb->s.tpm_pt->tpm_dev);
> + tpm_pt->tpm_dev);
> goto err_close_tpmdev;
> }
>
> return 0;
>
> err_close_tpmdev:
> - qemu_close(tb->s.tpm_pt->tpm_fd);
> - tb->s.tpm_pt->tpm_fd = -1;
> + qemu_close(tpm_pt->tpm_fd);
> + tpm_pt->tpm_fd = -1;
>
> err_free_parameters:
> g_free(tb->path);
> tb->path = NULL;
>
> - g_free(tb->s.tpm_pt->tpm_dev);
> - tb->s.tpm_pt->tpm_dev = NULL;
> + g_free(tpm_pt->tpm_dev);
> + tpm_pt->tpm_dev = NULL;
>
> return 1;
> }
>
> static TPMBackend *tpm_passthrough_create(QemuOpts *opts, const char *id)
> {
> - TPMBackend *tb;
> + Object *obj = object_new(TYPE_TPM_PASSTHROUGH);
> + TPMBackend *tb = TPM_BACKEND(obj);
> + TPMPassthruState *tpm_pt = TPM_PASSTHROUGH(tb);
>
> - tb = g_new0(TPMBackend, 1);
> - tb->s.tpm_pt = g_new0(TPMPassthruState, 1);
> tb->id = g_strdup(id);
> /* let frontend set the fe_model to proper value */
> tb->fe_model = -1;
> @@ -473,8 +482,8 @@ static TPMBackend *tpm_passthrough_creat
> goto err_exit;
> }
>
> - tb->s.tpm_pt->cancel_fd = tpm_passthrough_open_sysfs_cancel(tb);
> - if (tb->s.tpm_pt->cancel_fd < 0) {
> + tpm_pt->cancel_fd = tpm_passthrough_open_sysfs_cancel(tb);
> + if (tpm_pt->cancel_fd < 0) {
> goto err_exit;
> }
>
> @@ -482,29 +491,25 @@ static TPMBackend *tpm_passthrough_creat
>
> err_exit:
> g_free(tb->id);
> - g_free(tb->s.tpm_pt);
> - g_free(tb);
>
> return NULL;
> }
>
> static void tpm_passthrough_destroy(TPMBackend *tb)
> {
> - TPMPassthruState *tpm_pt = tb->s.tpm_pt;
> + TPMPassthruState *tpm_pt = TPM_PASSTHROUGH(tb);
>
> tpm_passthrough_cancel_cmd(tb);
>
> tpm_backend_thread_end(&tpm_pt->tbt);
>
> qemu_close(tpm_pt->tpm_fd);
> - qemu_close(tb->s.tpm_pt->cancel_fd);
> + qemu_close(tpm_pt->cancel_fd);
>
> g_free(tb->id);
> g_free(tb->path);
> g_free(tb->cancel_path);
> - g_free(tb->s.tpm_pt->tpm_dev);
> - g_free(tb->s.tpm_pt);
> - g_free(tb);
> + g_free(tpm_pt->tpm_dev);
> }
>
> const TPMDriverOps tpm_passthrough_driver = {
> @@ -522,8 +527,33 @@ const TPMDriverOps tpm_passthrough_drive
> .get_tpm_established_flag = tpm_passthrough_get_tpm_established_flag,
> };
>
> +static void tpm_passthrough_inst_init(Object *obj)
> +{
> +}
> +
> +static void tpm_passthrough_inst_finalize(Object *obj)
> +{
> +}
> +
> +static void tpm_passthrough_class_init(ObjectClass *klass, void *data)
> +{
> + TPMBackendClass *tbc = TPM_BACKEND_CLASS(klass);
> +
> + tbc->ops = &tpm_passthrough_driver;
> +}
> +
> +static const TypeInfo tpm_passthrough_info = {
> + .name = TYPE_TPM_PASSTHROUGH,
> + .parent = TYPE_TPM_BACKEND,
> + .instance_size = sizeof(TPMPassthruState),
> + .class_init = tpm_passthrough_class_init,
> + .instance_init = tpm_passthrough_inst_init,
> + .instance_finalize = tpm_passthrough_inst_finalize,
> +};
> +
> static void tpm_passthrough_register(void)
> {
> + type_register_static(&tpm_passthrough_info);
> tpm_register_driver(&tpm_passthrough_driver);
> }
>
> Index: qemu-git.pt/tpm/tpm_tis.c
> ===================================================================
> --- qemu-git.pt.orig/tpm/tpm_tis.c
> +++ qemu-git.pt/tpm/tpm_tis.c
> @@ -19,6 +19,7 @@
> * specification.
> */
>
> +#include "qemu/tpm.h"
> #include "tpm_int.h"
> #include "block/block.h"
> #include "exec/address-spaces.h"
> @@ -160,7 +161,7 @@ static void tpm_tis_tpm_send(TPMState *s
> */
> tis->loc[locty].state = TPM_TIS_STATE_EXECUTION;
>
> - s->be_driver->ops->deliver_request(s->be_driver);
> + tpm_backend_deliver_request(s->be_driver);
> }
>
> /* raise an interrupt if allowed */
> @@ -284,7 +285,7 @@ static void tpm_tis_prep_abort(TPMState
> * request the backend to cancel. Some backends may not
> * support it
> */
> - s->be_driver->ops->cancel_cmd(s->be_driver);
> + tpm_backend_cancel_cmd(s->be_driver);
> return;
> }
> }
> @@ -426,7 +427,7 @@ static uint64_t tpm_tis_mmio_read(void *
> uint8_t locty = tpm_tis_locality_from_addr(addr);
> uint32_t avail;
>
> - if (s->be_driver->ops->had_startup_error(s->be_driver)) {
> + if (tpm_backend_had_startup_error(s->be_driver)) {
> return val;
> }
>
> @@ -438,7 +439,7 @@ static uint64_t tpm_tis_mmio_read(void *
> if (tpm_tis_check_request_use_except(s, locty)) {
> val |= TPM_TIS_ACCESS_PENDING_REQUEST;
> }
> - val |= !s->be_driver->ops->get_tpm_established_flag(s->be_driver);
> + val |= !tpm_backend_get_tpm_established_flag(s->be_driver);
> break;
> case TPM_TIS_REG_INT_ENABLE:
> val = tis->loc[locty].inte;
> @@ -529,7 +530,7 @@ static void tpm_tis_mmio_write_intern(vo
> return;
> }
>
> - if (s->be_driver->ops->had_startup_error(s->be_driver)) {
> + if (tpm_backend_had_startup_error(s->be_driver)) {
> return;
> }
>
> @@ -804,7 +805,7 @@ static const MemoryRegionOps tpm_tis_mem
>
> static int tpm_tis_do_startup_tpm(TPMState *s)
> {
> - return s->be_driver->ops->startup_tpm(s->be_driver);
> + return tpm_backend_startup_tpm(s->be_driver);
> }
>
> /*
> @@ -817,7 +818,7 @@ static void tpm_tis_reset(DeviceState *d
> TPMTISEmuState *tis = &s->s.tis;
> int c;
>
> - s->be_driver->ops->reset(s->be_driver);
> + tpm_backend_reset(s->be_driver);
>
> tis->active_locty = TPM_TIS_NO_LOCALITY;
> tis->next_locty = TPM_TIS_NO_LOCALITY;
> @@ -831,9 +832,9 @@ static void tpm_tis_reset(DeviceState *d
> tis->loc[c].state = TPM_TIS_STATE_IDLE;
>
> tis->loc[c].w_offset = 0;
> - s->be_driver->ops->realloc_buffer(&tis->loc[c].w_buffer);
> + tpm_backend_realloc_buffer(s->be_driver, &tis->loc[c].w_buffer);
> tis->loc[c].r_offset = 0;
> - s->be_driver->ops->realloc_buffer(&tis->loc[c].r_buffer);
> + tpm_backend_realloc_buffer(s->be_driver, &tis->loc[c].r_buffer);
> }
>
> tpm_tis_do_startup_tpm(s);
> @@ -865,7 +866,7 @@ static void tpm_tis_realizefn(DeviceStat
>
> s->be_driver->fe_model = TPM_MODEL_TPM_TIS;
>
> - if (s->be_driver->ops->init(s->be_driver, s, tpm_tis_receive_cb)) {
> + if (tpm_backend_init(s->be_driver, s, tpm_tis_receive_cb)) {
> error_setg(errp, "tpm_tis: backend driver with id %s could not be "
> "initialized", s->backend);
> return;
> Index: qemu-git.pt/tpm/tpm_int.h
> ===================================================================
> --- qemu-git.pt.orig/tpm/tpm_int.h
> +++ qemu-git.pt/tpm/tpm_int.h
> @@ -18,22 +18,6 @@
> struct TPMDriverOps;
> typedef struct TPMDriverOps TPMDriverOps;
>
> -typedef struct TPMPassthruState TPMPassthruState;
> -
> -typedef struct TPMBackend {
> - char *id;
> - enum TpmModel fe_model;
> - char *path;
> - char *cancel_path;
> - const TPMDriverOps *ops;
> -
> - union {
> - TPMPassthruState *tpm_pt;
> - } s;
> -
> - QLIST_ENTRY(TPMBackend) list;
> -} TPMBackend;
> -
> /* overall state of the TPM interface */
> typedef struct TPMState {
> ISADevice busdev;
> Index: qemu-git.pt/tpm/tpm.c
> ===================================================================
> --- qemu-git.pt.orig/tpm/tpm.c
> +++ qemu-git.pt/tpm/tpm.c
> @@ -15,6 +15,7 @@
>
> #include "monitor/monitor.h"
> #include "qapi/qmp/qerror.h"
> +#include "qemu/tpm.h"
> #include "tpm_int.h"
> #include "tpm/tpm.h"
> #include "qemu/config-file.h"
> @@ -145,6 +146,7 @@ static int configure_tpm(QemuOpts *opts)
> const char *id;
> const TPMDriverOps *be;
> TPMBackend *drv;
> + Error *local_err = NULL;
>
> if (!QLIST_EMPTY(&tpm_backends)) {
> error_report("Only one TPM is allowed.\n");
> @@ -177,6 +179,13 @@ static int configure_tpm(QemuOpts *opts)
> return 1;
> }
>
> + tpm_backend_open(drv, &local_err);
> + if (local_err) {
> + qerror_report_err(local_err);
> + error_free(local_err);
> + return 1;
> + }
> +
> QLIST_INSERT_HEAD(&tpm_backends, drv, list);
>
> return 0;
> @@ -197,7 +206,7 @@ void tpm_cleanup(void)
>
> QLIST_FOREACH_SAFE(drv, &tpm_backends, list, next) {
> QLIST_REMOVE(drv, list);
> - drv->ops->destroy(drv);
> + tpm_backend_destroy(drv);
> }
> }
>
> Index: qemu-git.pt/include/tpm/tpm.h
> ===================================================================
> --- qemu-git.pt.orig/include/tpm/tpm.h
> +++ qemu-git.pt/include/tpm/tpm.h
> @@ -14,6 +14,10 @@
>
> #include "qemu/option.h"
>
> +typedef struct TPMState TPMState;
> +typedef struct TPMSizedBuffer TPMSizedBuffer;
> +typedef void (TPMRecvDataCB)(TPMState *, uint8_t locty);
> +
> int tpm_config_parse(QemuOptsList *opts_list, const char *optarg);
> int tpm_init(void);
> void tpm_cleanup(void);
>
>
>