mirror of
https://github.com/xemu-project/xemu.git
synced 2025-02-25 15:14:31 +00:00
tpm-backend: Move thread handling inside TPMBackend
Move thread handling inside TPMBackend, this way backend implementations need not to maintain their own thread life cycle, instead they needs to implement 'handle_request()' class method that always been called from a thread. This change made tpm_backend_int.h kind of useless, hence removed it. Signed-off-by: Amarnath Valluri <amarnath.valluri@intel.com> Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com> Reviewed-by: Stefan Berger <stefanb@linux.vnet.ibm.com> Signed-off-by: Stefan Berger <stefanb@linux.vnet.ibm.com>
This commit is contained in:
parent
fb4b0c6765
commit
b19a5eea5a
@ -18,7 +18,24 @@
|
|||||||
#include "qapi/qmp/qerror.h"
|
#include "qapi/qmp/qerror.h"
|
||||||
#include "sysemu/tpm.h"
|
#include "sysemu/tpm.h"
|
||||||
#include "qemu/thread.h"
|
#include "qemu/thread.h"
|
||||||
#include "sysemu/tpm_backend_int.h"
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void tpm_backend_thread_end(TPMBackend *s)
|
||||||
|
{
|
||||||
|
if (s->thread_pool) {
|
||||||
|
g_thread_pool_push(s->thread_pool, (gpointer)TPM_BACKEND_CMD_END, NULL);
|
||||||
|
g_thread_pool_free(s->thread_pool, FALSE, TRUE);
|
||||||
|
s->thread_pool = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
enum TpmType tpm_backend_get_type(TPMBackend *s)
|
enum TpmType tpm_backend_get_type(TPMBackend *s)
|
||||||
{
|
{
|
||||||
@ -39,6 +56,8 @@ void tpm_backend_destroy(TPMBackend *s)
|
|||||||
TPMBackendClass *k = TPM_BACKEND_GET_CLASS(s);
|
TPMBackendClass *k = TPM_BACKEND_GET_CLASS(s);
|
||||||
|
|
||||||
k->ops->destroy(s);
|
k->ops->destroy(s);
|
||||||
|
|
||||||
|
tpm_backend_thread_end(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
int tpm_backend_init(TPMBackend *s, TPMState *state,
|
int tpm_backend_init(TPMBackend *s, TPMState *state,
|
||||||
@ -46,13 +65,23 @@ int tpm_backend_init(TPMBackend *s, TPMState *state,
|
|||||||
{
|
{
|
||||||
TPMBackendClass *k = TPM_BACKEND_GET_CLASS(s);
|
TPMBackendClass *k = TPM_BACKEND_GET_CLASS(s);
|
||||||
|
|
||||||
return k->ops->init(s, state, datacb);
|
s->tpm_state = state;
|
||||||
|
s->recv_data_callback = datacb;
|
||||||
|
|
||||||
|
return k->ops->init(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
int tpm_backend_startup_tpm(TPMBackend *s)
|
int tpm_backend_startup_tpm(TPMBackend *s)
|
||||||
{
|
{
|
||||||
TPMBackendClass *k = TPM_BACKEND_GET_CLASS(s);
|
TPMBackendClass *k = TPM_BACKEND_GET_CLASS(s);
|
||||||
|
|
||||||
|
/* terminate a running TPM */
|
||||||
|
tpm_backend_thread_end(s);
|
||||||
|
|
||||||
|
s->thread_pool = g_thread_pool_new(tpm_backend_worker_thread, s, 1, TRUE,
|
||||||
|
NULL);
|
||||||
|
g_thread_pool_push(s->thread_pool, (gpointer)TPM_BACKEND_CMD_INIT, NULL);
|
||||||
|
|
||||||
return k->ops->startup_tpm(s);
|
return k->ops->startup_tpm(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -72,9 +101,8 @@ size_t tpm_backend_realloc_buffer(TPMBackend *s, TPMSizedBuffer *sb)
|
|||||||
|
|
||||||
void tpm_backend_deliver_request(TPMBackend *s)
|
void tpm_backend_deliver_request(TPMBackend *s)
|
||||||
{
|
{
|
||||||
TPMBackendClass *k = TPM_BACKEND_GET_CLASS(s);
|
g_thread_pool_push(s->thread_pool, (gpointer)TPM_BACKEND_CMD_PROCESS_CMD,
|
||||||
|
NULL);
|
||||||
k->ops->deliver_request(s);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void tpm_backend_reset(TPMBackend *s)
|
void tpm_backend_reset(TPMBackend *s)
|
||||||
@ -82,6 +110,8 @@ void tpm_backend_reset(TPMBackend *s)
|
|||||||
TPMBackendClass *k = TPM_BACKEND_GET_CLASS(s);
|
TPMBackendClass *k = TPM_BACKEND_GET_CLASS(s);
|
||||||
|
|
||||||
k->ops->reset(s);
|
k->ops->reset(s);
|
||||||
|
|
||||||
|
tpm_backend_thread_end(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
void tpm_backend_cancel_cmd(TPMBackend *s)
|
void tpm_backend_cancel_cmd(TPMBackend *s)
|
||||||
@ -156,29 +186,14 @@ static void tpm_backend_instance_init(Object *obj)
|
|||||||
tpm_backend_prop_get_opened,
|
tpm_backend_prop_get_opened,
|
||||||
tpm_backend_prop_set_opened,
|
tpm_backend_prop_set_opened,
|
||||||
NULL);
|
NULL);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void tpm_backend_thread_deliver_request(TPMBackendThread *tbt)
|
static void tpm_backend_instance_finalize(Object *obj)
|
||||||
{
|
{
|
||||||
g_thread_pool_push(tbt->pool, (gpointer)TPM_BACKEND_CMD_PROCESS_CMD, NULL);
|
TPMBackend *s = TPM_BACKEND(obj);
|
||||||
}
|
|
||||||
|
|
||||||
void tpm_backend_thread_create(TPMBackendThread *tbt,
|
tpm_backend_thread_end(s);
|
||||||
GFunc func, gpointer user_data)
|
|
||||||
{
|
|
||||||
if (!tbt->pool) {
|
|
||||||
tbt->pool = g_thread_pool_new(func, user_data, 1, TRUE, NULL);
|
|
||||||
g_thread_pool_push(tbt->pool, (gpointer)TPM_BACKEND_CMD_INIT, NULL);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void tpm_backend_thread_end(TPMBackendThread *tbt)
|
|
||||||
{
|
|
||||||
if (tbt->pool) {
|
|
||||||
g_thread_pool_push(tbt->pool, (gpointer)TPM_BACKEND_CMD_END, NULL);
|
|
||||||
g_thread_pool_free(tbt->pool, FALSE, TRUE);
|
|
||||||
tbt->pool = NULL;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static const TypeInfo tpm_backend_info = {
|
static const TypeInfo tpm_backend_info = {
|
||||||
@ -186,6 +201,7 @@ static const TypeInfo tpm_backend_info = {
|
|||||||
.parent = TYPE_OBJECT,
|
.parent = TYPE_OBJECT,
|
||||||
.instance_size = sizeof(TPMBackend),
|
.instance_size = sizeof(TPMBackend),
|
||||||
.instance_init = tpm_backend_instance_init,
|
.instance_init = tpm_backend_instance_init,
|
||||||
|
.instance_finalize = tpm_backend_instance_finalize,
|
||||||
.class_size = sizeof(TPMBackendClass),
|
.class_size = sizeof(TPMBackendClass),
|
||||||
.abstract = true,
|
.abstract = true,
|
||||||
};
|
};
|
||||||
|
@ -30,7 +30,6 @@
|
|||||||
#include "tpm_int.h"
|
#include "tpm_int.h"
|
||||||
#include "hw/hw.h"
|
#include "hw/hw.h"
|
||||||
#include "hw/i386/pc.h"
|
#include "hw/i386/pc.h"
|
||||||
#include "sysemu/tpm_backend_int.h"
|
|
||||||
#include "tpm_tis.h"
|
#include "tpm_tis.h"
|
||||||
#include "tpm_util.h"
|
#include "tpm_util.h"
|
||||||
|
|
||||||
@ -47,20 +46,9 @@
|
|||||||
OBJECT_CHECK(TPMPassthruState, (obj), TYPE_TPM_PASSTHROUGH)
|
OBJECT_CHECK(TPMPassthruState, (obj), TYPE_TPM_PASSTHROUGH)
|
||||||
|
|
||||||
/* data structures */
|
/* data structures */
|
||||||
typedef struct TPMPassthruThreadParams {
|
|
||||||
TPMState *tpm_state;
|
|
||||||
|
|
||||||
TPMRecvDataCB *recv_data_callback;
|
|
||||||
TPMBackend *tb;
|
|
||||||
} TPMPassthruThreadParams;
|
|
||||||
|
|
||||||
struct TPMPassthruState {
|
struct TPMPassthruState {
|
||||||
TPMBackend parent;
|
TPMBackend parent;
|
||||||
|
|
||||||
TPMBackendThread tbt;
|
|
||||||
|
|
||||||
TPMPassthruThreadParams tpm_thread_params;
|
|
||||||
|
|
||||||
char *tpm_dev;
|
char *tpm_dev;
|
||||||
int tpm_fd;
|
int tpm_fd;
|
||||||
bool tpm_executing;
|
bool tpm_executing;
|
||||||
@ -214,12 +202,9 @@ static int tpm_passthrough_unix_transfer(TPMPassthruState *tpm_pt,
|
|||||||
selftest_done);
|
selftest_done);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void tpm_passthrough_worker_thread(gpointer data,
|
static void tpm_passthrough_handle_request(TPMBackend *tb, TPMBackendCmd cmd)
|
||||||
gpointer user_data)
|
|
||||||
{
|
{
|
||||||
TPMPassthruThreadParams *thr_parms = user_data;
|
TPMPassthruState *tpm_pt = TPM_PASSTHROUGH(tb);
|
||||||
TPMPassthruState *tpm_pt = TPM_PASSTHROUGH(thr_parms->tb);
|
|
||||||
TPMBackendCmd cmd = (TPMBackendCmd)data;
|
|
||||||
bool selftest_done = false;
|
bool selftest_done = false;
|
||||||
|
|
||||||
DPRINTF("tpm_passthrough: processing command type %d\n", cmd);
|
DPRINTF("tpm_passthrough: processing command type %d\n", cmd);
|
||||||
@ -227,12 +212,12 @@ static void tpm_passthrough_worker_thread(gpointer data,
|
|||||||
switch (cmd) {
|
switch (cmd) {
|
||||||
case TPM_BACKEND_CMD_PROCESS_CMD:
|
case TPM_BACKEND_CMD_PROCESS_CMD:
|
||||||
tpm_passthrough_unix_transfer(tpm_pt,
|
tpm_passthrough_unix_transfer(tpm_pt,
|
||||||
thr_parms->tpm_state->locty_data,
|
tb->tpm_state->locty_data,
|
||||||
&selftest_done);
|
&selftest_done);
|
||||||
|
|
||||||
thr_parms->recv_data_callback(thr_parms->tpm_state,
|
tb->recv_data_callback(tb->tpm_state,
|
||||||
thr_parms->tpm_state->locty_number,
|
tb->tpm_state->locty_number,
|
||||||
selftest_done);
|
selftest_done);
|
||||||
break;
|
break;
|
||||||
case TPM_BACKEND_CMD_INIT:
|
case TPM_BACKEND_CMD_INIT:
|
||||||
case TPM_BACKEND_CMD_END:
|
case TPM_BACKEND_CMD_END:
|
||||||
@ -248,15 +233,6 @@ static void tpm_passthrough_worker_thread(gpointer data,
|
|||||||
*/
|
*/
|
||||||
static int tpm_passthrough_startup_tpm(TPMBackend *tb)
|
static int tpm_passthrough_startup_tpm(TPMBackend *tb)
|
||||||
{
|
{
|
||||||
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,
|
|
||||||
&tpm_pt->tpm_thread_params);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -268,20 +244,11 @@ static void tpm_passthrough_reset(TPMBackend *tb)
|
|||||||
|
|
||||||
tpm_passthrough_cancel_cmd(tb);
|
tpm_passthrough_cancel_cmd(tb);
|
||||||
|
|
||||||
tpm_backend_thread_end(&tpm_pt->tbt);
|
|
||||||
|
|
||||||
tpm_pt->had_startup_error = false;
|
tpm_pt->had_startup_error = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int tpm_passthrough_init(TPMBackend *tb, TPMState *s,
|
static int tpm_passthrough_init(TPMBackend *tb)
|
||||||
TPMRecvDataCB *recv_data_cb)
|
|
||||||
{
|
{
|
||||||
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;
|
|
||||||
tpm_pt->tpm_thread_params.tb = tb;
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -315,13 +282,6 @@ static size_t tpm_passthrough_realloc_buffer(TPMSizedBuffer *sb)
|
|||||||
return sb->size;
|
return sb->size;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void tpm_passthrough_deliver_request(TPMBackend *tb)
|
|
||||||
{
|
|
||||||
TPMPassthruState *tpm_pt = TPM_PASSTHROUGH(tb);
|
|
||||||
|
|
||||||
tpm_backend_thread_deliver_request(&tpm_pt->tbt);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void tpm_passthrough_cancel_cmd(TPMBackend *tb)
|
static void tpm_passthrough_cancel_cmd(TPMBackend *tb)
|
||||||
{
|
{
|
||||||
TPMPassthruState *tpm_pt = TPM_PASSTHROUGH(tb);
|
TPMPassthruState *tpm_pt = TPM_PASSTHROUGH(tb);
|
||||||
@ -483,8 +443,6 @@ static void tpm_passthrough_destroy(TPMBackend *tb)
|
|||||||
|
|
||||||
tpm_passthrough_cancel_cmd(tb);
|
tpm_passthrough_cancel_cmd(tb);
|
||||||
|
|
||||||
tpm_backend_thread_end(&tpm_pt->tbt);
|
|
||||||
|
|
||||||
qemu_close(tpm_pt->tpm_fd);
|
qemu_close(tpm_pt->tpm_fd);
|
||||||
qemu_close(tpm_pt->cancel_fd);
|
qemu_close(tpm_pt->cancel_fd);
|
||||||
|
|
||||||
@ -520,7 +478,6 @@ static const TPMDriverOps tpm_passthrough_driver = {
|
|||||||
.realloc_buffer = tpm_passthrough_realloc_buffer,
|
.realloc_buffer = tpm_passthrough_realloc_buffer,
|
||||||
.reset = tpm_passthrough_reset,
|
.reset = tpm_passthrough_reset,
|
||||||
.had_startup_error = tpm_passthrough_get_startup_error,
|
.had_startup_error = tpm_passthrough_get_startup_error,
|
||||||
.deliver_request = tpm_passthrough_deliver_request,
|
|
||||||
.cancel_cmd = tpm_passthrough_cancel_cmd,
|
.cancel_cmd = tpm_passthrough_cancel_cmd,
|
||||||
.get_tpm_established_flag = tpm_passthrough_get_tpm_established_flag,
|
.get_tpm_established_flag = tpm_passthrough_get_tpm_established_flag,
|
||||||
.reset_tpm_established_flag = tpm_passthrough_reset_tpm_established_flag,
|
.reset_tpm_established_flag = tpm_passthrough_reset_tpm_established_flag,
|
||||||
@ -540,6 +497,7 @@ static void tpm_passthrough_class_init(ObjectClass *klass, void *data)
|
|||||||
TPMBackendClass *tbc = TPM_BACKEND_CLASS(klass);
|
TPMBackendClass *tbc = TPM_BACKEND_CLASS(klass);
|
||||||
|
|
||||||
tbc->ops = &tpm_passthrough_driver;
|
tbc->ops = &tpm_passthrough_driver;
|
||||||
|
tbc->handle_request = tpm_passthrough_handle_request;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const TypeInfo tpm_passthrough_info = {
|
static const TypeInfo tpm_passthrough_info = {
|
||||||
|
@ -29,22 +29,24 @@
|
|||||||
|
|
||||||
typedef struct TPMBackendClass TPMBackendClass;
|
typedef struct TPMBackendClass TPMBackendClass;
|
||||||
typedef struct TPMBackend TPMBackend;
|
typedef struct TPMBackend TPMBackend;
|
||||||
|
|
||||||
typedef struct TPMDriverOps TPMDriverOps;
|
typedef struct TPMDriverOps TPMDriverOps;
|
||||||
|
typedef void (TPMRecvDataCB)(TPMState *, uint8_t locty, bool selftest_done);
|
||||||
|
|
||||||
struct TPMBackendClass {
|
typedef enum TPMBackendCmd {
|
||||||
ObjectClass parent_class;
|
TPM_BACKEND_CMD_INIT = 1,
|
||||||
|
TPM_BACKEND_CMD_PROCESS_CMD,
|
||||||
const TPMDriverOps *ops;
|
TPM_BACKEND_CMD_END,
|
||||||
|
TPM_BACKEND_CMD_TPM_RESET,
|
||||||
void (*opened)(TPMBackend *s, Error **errp);
|
} TPMBackendCmd;
|
||||||
};
|
|
||||||
|
|
||||||
struct TPMBackend {
|
struct TPMBackend {
|
||||||
Object parent;
|
Object parent;
|
||||||
|
|
||||||
/*< protected >*/
|
/*< protected >*/
|
||||||
bool opened;
|
bool opened;
|
||||||
|
TPMState *tpm_state;
|
||||||
|
GThreadPool *thread_pool;
|
||||||
|
TPMRecvDataCB *recv_data_callback;
|
||||||
|
|
||||||
char *id;
|
char *id;
|
||||||
enum TpmModel fe_model;
|
enum TpmModel fe_model;
|
||||||
@ -54,7 +56,15 @@ struct TPMBackend {
|
|||||||
QLIST_ENTRY(TPMBackend) list;
|
QLIST_ENTRY(TPMBackend) list;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef void (TPMRecvDataCB)(TPMState *, uint8_t locty, bool selftest_done);
|
struct TPMBackendClass {
|
||||||
|
ObjectClass parent_class;
|
||||||
|
|
||||||
|
const TPMDriverOps *ops;
|
||||||
|
|
||||||
|
void (*opened)(TPMBackend *s, Error **errp);
|
||||||
|
|
||||||
|
void (*handle_request)(TPMBackend *s, TPMBackendCmd cmd);
|
||||||
|
};
|
||||||
|
|
||||||
typedef struct TPMSizedBuffer {
|
typedef struct TPMSizedBuffer {
|
||||||
uint32_t size;
|
uint32_t size;
|
||||||
@ -71,7 +81,7 @@ struct TPMDriverOps {
|
|||||||
void (*destroy)(TPMBackend *t);
|
void (*destroy)(TPMBackend *t);
|
||||||
|
|
||||||
/* initialize the backend */
|
/* initialize the backend */
|
||||||
int (*init)(TPMBackend *t, TPMState *s, TPMRecvDataCB *datacb);
|
int (*init)(TPMBackend *t);
|
||||||
/* start up the TPM on the backend */
|
/* start up the TPM on the backend */
|
||||||
int (*startup_tpm)(TPMBackend *t);
|
int (*startup_tpm)(TPMBackend *t);
|
||||||
/* returns true if nothing will ever answer TPM requests */
|
/* returns true if nothing will ever answer TPM requests */
|
||||||
@ -79,8 +89,6 @@ struct TPMDriverOps {
|
|||||||
|
|
||||||
size_t (*realloc_buffer)(TPMSizedBuffer *sb);
|
size_t (*realloc_buffer)(TPMSizedBuffer *sb);
|
||||||
|
|
||||||
void (*deliver_request)(TPMBackend *t);
|
|
||||||
|
|
||||||
void (*reset)(TPMBackend *t);
|
void (*reset)(TPMBackend *t);
|
||||||
|
|
||||||
void (*cancel_cmd)(TPMBackend *t);
|
void (*cancel_cmd)(TPMBackend *t);
|
||||||
|
@ -1,41 +0,0 @@
|
|||||||
/*
|
|
||||||
* common TPM backend driver functions
|
|
||||||
*
|
|
||||||
* Copyright (c) 2012-2013 IBM Corporation
|
|
||||||
* Authors:
|
|
||||||
* Stefan Berger <stefanb@us.ibm.com>
|
|
||||||
*
|
|
||||||
* This library is free software; you can redistribute it and/or
|
|
||||||
* modify it under the terms of the GNU Lesser General Public
|
|
||||||
* License as published by the Free Software Foundation; either
|
|
||||||
* version 2 of the License, or (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This library is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
* Lesser General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Lesser General Public
|
|
||||||
* License along with this library; if not, see <http://www.gnu.org/licenses/>
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef TPM_BACKEND_INT_H
|
|
||||||
#define TPM_BACKEND_INT_H
|
|
||||||
|
|
||||||
typedef struct TPMBackendThread {
|
|
||||||
GThreadPool *pool;
|
|
||||||
} TPMBackendThread;
|
|
||||||
|
|
||||||
void tpm_backend_thread_deliver_request(TPMBackendThread *tbt);
|
|
||||||
void tpm_backend_thread_create(TPMBackendThread *tbt,
|
|
||||||
GFunc func, gpointer user_data);
|
|
||||||
void tpm_backend_thread_end(TPMBackendThread *tbt);
|
|
||||||
|
|
||||||
typedef enum TPMBackendCmd {
|
|
||||||
TPM_BACKEND_CMD_INIT = 1,
|
|
||||||
TPM_BACKEND_CMD_PROCESS_CMD,
|
|
||||||
TPM_BACKEND_CMD_END,
|
|
||||||
TPM_BACKEND_CMD_TPM_RESET,
|
|
||||||
} TPMBackendCmd;
|
|
||||||
|
|
||||||
#endif /* TPM_BACKEND_INT_H */
|
|
Loading…
x
Reference in New Issue
Block a user