From patchwork Thu Mar 21 01:23:56 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stefan Berger X-Patchwork-Id: 229526 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id D8CA92C00BF for ; Thu, 21 Mar 2013 12:24:32 +1100 (EST) Received: from localhost ([::1]:56340 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1UIUF5-0001Cm-0b for incoming@patchwork.ozlabs.org; Wed, 20 Mar 2013 21:24:31 -0400 Received: from eggs.gnu.org ([208.118.235.92]:49482) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1UIUEh-0001AK-N0 for qemu-devel@nongnu.org; Wed, 20 Mar 2013 21:24:10 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1UIUEe-0000Qy-QR for qemu-devel@nongnu.org; Wed, 20 Mar 2013 21:24:07 -0400 Received: from e37.co.us.ibm.com ([32.97.110.158]:53590) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1UIUEe-0000Qr-Es for qemu-devel@nongnu.org; Wed, 20 Mar 2013 21:24:04 -0400 Received: from /spool/local by e37.co.us.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Wed, 20 Mar 2013 19:24:03 -0600 Received: from d03dlp02.boulder.ibm.com (9.17.202.178) by e37.co.us.ibm.com (192.168.1.137) with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted; Wed, 20 Mar 2013 19:24:01 -0600 Received: from d03relay01.boulder.ibm.com (d03relay01.boulder.ibm.com [9.17.195.226]) by d03dlp02.boulder.ibm.com (Postfix) with ESMTP id AA76E3E40045 for ; Wed, 20 Mar 2013 19:23:49 -0600 (MDT) Received: from d03av04.boulder.ibm.com (d03av04.boulder.ibm.com [9.17.195.170]) by d03relay01.boulder.ibm.com (8.13.8/8.13.8/NCO v10.0) with ESMTP id r2L1NxLr125378 for ; Wed, 20 Mar 2013 19:23:59 -0600 Received: from d03av04.boulder.ibm.com (loopback [127.0.0.1]) by d03av04.boulder.ibm.com (8.14.4/8.13.1/NCO v10.0 AVout) with ESMTP id r2L1NvqY016328 for ; Wed, 20 Mar 2013 19:23:59 -0600 Received: from [9.2.141.150] (k-d941e-10.watson.ibm.com [9.2.141.150]) by d03av04.boulder.ibm.com (8.14.4/8.13.1/NCO v10.0 AVin) with ESMTP id r2L1Nu2q016258; Wed, 20 Mar 2013 19:23:57 -0600 Message-ID: <1363829036.14558.3.camel@d941e-10> From: Stefan Berger To: "qemu-devel@nongnu.org" Date: Wed, 20 Mar 2013 21:23:56 -0400 X-Mailer: Evolution 3.2.3 (3.2.3-3.fc16) Mime-Version: 1.0 X-TM-AS-MML: No X-Content-Scanned: Fidelis XPS MAILER x-cbid: 13032101-7408-0000-0000-00000E05964E X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.4.x-2.6.x [generic] X-Received-From: 32.97.110.158 Cc: coreyb@linux.vnet.ibm.com, armbru@redhat.com, anthony@codemonkey.ws, stefanb@linux.vnet.ibm.com Subject: [Qemu-devel] [PATCH] QOM-ify TPM X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org With much code borrowed from the rng QOM implementation. Signed-off-by: Stefan Berger --- backends/Makefile.objs | 2 backends/tpm.c | 154 ++++++++++++++++++++++++++++++++++++++++++++ include/qemu/tpm.h | 170 +++++++++++++++++++++++++++++++++++++++++++++++++ include/tpm/tpm.h | 4 + tpm/tpm.c | 13 +++ tpm/tpm_int.h | 16 ---- tpm/tpm_passthrough.c | 94 +++++++++++++++++---------- tpm/tpm_tis.c | 21 +++--- 8 files changed, 414 insertions(+), 60 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 + * + * 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 + * + * 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); } } @@ -257,7 +266,7 @@ static TPMInfo *qmp_query_tpm_inst(TPMBa res->id = g_strdup(drv->id); res->model = drv->fe_model; - res->type = drv->ops->type; + res->type = tpm_backend_get_type(drv); res->tpm_options = g_new0(TpmTypeOptions, 1); switch (res->type) { 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);