summaryrefslogtreecommitdiff
path: root/tpm
diff options
context:
space:
mode:
authorStefan Berger <stefanb@linux.vnet.ibm.com>2013-03-28 07:26:21 -0400
committerAnthony Liguori <aliguori@us.ibm.com>2013-04-02 08:15:18 -0500
commit8f0605cc9caacbcc647a6df9ae541ed2da4b9bb0 (patch)
tree384017221d7b4dbf02fc246e314e0a89dcc32ca0 /tpm
parent684a096eafbe37ab6c9a1fdb5e0185f04098b166 (diff)
downloadqemu-8f0605cc9caacbcc647a6df9ae541ed2da4b9bb0.zip
QOM-ify the TPM support
QOM-ified the TPM support with much code borrowed from the rng implementation. All other TPM related code moves will be provided in a subsequent patch. Signed-off-by: Stefan Berger <stefanb@linux.vnet.ibm.com> Message-id: 1364469981.24703.1.camel@d941e-10 Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
Diffstat (limited to 'tpm')
-rw-r--r--tpm/tpm.c11
-rw-r--r--tpm/tpm_int.h16
-rw-r--r--tpm/tpm_passthrough.c94
-rw-r--r--tpm/tpm_tis.c21
4 files changed, 83 insertions, 59 deletions
diff --git a/tpm/tpm.c b/tpm/tpm.c
index ae00eae618..1f4ac8da00 100644
--- a/tpm/tpm.c
+++ b/tpm/tpm.c
@@ -15,6 +15,7 @@
#include "monitor/monitor.h"
#include "qapi/qmp/qerror.h"
+#include "backends/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);
}
}
diff --git a/tpm/tpm_int.h b/tpm/tpm_int.h
index f7056436cc..b4787ad27f 100644
--- a/tpm/tpm_int.h
+++ b/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;
diff --git a/tpm/tpm_passthrough.c b/tpm/tpm_passthrough.c
index 24aff4d69c..80a48d68cd 100644
--- a/tpm/tpm_passthrough.c
+++ b/tpm/tpm_passthrough.c
@@ -27,6 +27,7 @@
#include "qemu-common.h"
#include "qapi/error.h"
#include "qemu/sockets.h"
+#include "backends/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_thread(gpointer data,
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_thread(gpointer data,
*/
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(TPMBackend *tb)
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_established_flag(TPMBackend *tb)
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_buffer(TPMSizedBuffer *sb)
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_cancel(TPMBackend *tb)
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_opts(QemuOpts *opts, TPMBackend *tb)
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_create(QemuOpts *opts, const char *id)
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_create(QemuOpts *opts, const char *id)
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_driver = {
.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);
}
diff --git a/tpm/tpm_tis.c b/tpm/tpm_tis.c
index e93825eec1..367f734dc4 100644
--- a/tpm/tpm_tis.c
+++ b/tpm/tpm_tis.c
@@ -19,6 +19,7 @@
* specification.
*/
+#include "backends/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, uint8_t locty)
*/
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 *s, uint8_t locty, uint8_t newlocty)
* 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 *opaque, hwaddr addr,
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 *opaque, hwaddr addr,
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(void *opaque, hwaddr addr,
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_memory_ops = {
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 *dev)
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 *dev)
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(DeviceState *dev, Error **errp)
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;