tpm: tpm_emulator: get and set buffer size of device
Convert the tpm_emulator backend to get the current buffer size of the external device and set it to the buffer size that the frontend (TIS) requests. Signed-off-by: Stefan Berger <stefanb@linux.vnet.ibm.com> Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
This commit is contained in:
parent
abc5cda097
commit
9375c44fdf
@ -68,7 +68,7 @@ int tpm_backend_init(TPMBackend *s, TPMIf *tpmif, Error **errp)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int tpm_backend_startup_tpm(TPMBackend *s)
|
int tpm_backend_startup_tpm(TPMBackend *s, size_t buffersize)
|
||||||
{
|
{
|
||||||
int res = 0;
|
int res = 0;
|
||||||
TPMBackendClass *k = TPM_BACKEND_GET_CLASS(s);
|
TPMBackendClass *k = TPM_BACKEND_GET_CLASS(s);
|
||||||
@ -79,7 +79,7 @@ int tpm_backend_startup_tpm(TPMBackend *s)
|
|||||||
s->thread_pool = g_thread_pool_new(tpm_backend_worker_thread, s, 1, TRUE,
|
s->thread_pool = g_thread_pool_new(tpm_backend_worker_thread, s, 1, TRUE,
|
||||||
NULL);
|
NULL);
|
||||||
|
|
||||||
res = k->startup_tpm ? k->startup_tpm(s) : 0;
|
res = k->startup_tpm ? k->startup_tpm(s, buffersize) : 0;
|
||||||
|
|
||||||
s->had_startup_error = (res != 0);
|
s->had_startup_error = (res != 0);
|
||||||
|
|
||||||
|
@ -232,13 +232,14 @@ static int tpm_emulator_check_caps(TPMEmulator *tpm_emu)
|
|||||||
switch (tpm_emu->tpm_version) {
|
switch (tpm_emu->tpm_version) {
|
||||||
case TPM_VERSION_1_2:
|
case TPM_VERSION_1_2:
|
||||||
caps = PTM_CAP_INIT | PTM_CAP_SHUTDOWN | PTM_CAP_GET_TPMESTABLISHED |
|
caps = PTM_CAP_INIT | PTM_CAP_SHUTDOWN | PTM_CAP_GET_TPMESTABLISHED |
|
||||||
PTM_CAP_SET_LOCALITY | PTM_CAP_SET_DATAFD;
|
PTM_CAP_SET_LOCALITY | PTM_CAP_SET_DATAFD | PTM_CAP_STOP |
|
||||||
|
PTM_CAP_SET_BUFFERSIZE;
|
||||||
tpm = "1.2";
|
tpm = "1.2";
|
||||||
break;
|
break;
|
||||||
case TPM_VERSION_2_0:
|
case TPM_VERSION_2_0:
|
||||||
caps = PTM_CAP_INIT | PTM_CAP_SHUTDOWN | PTM_CAP_GET_TPMESTABLISHED |
|
caps = PTM_CAP_INIT | PTM_CAP_SHUTDOWN | PTM_CAP_GET_TPMESTABLISHED |
|
||||||
PTM_CAP_SET_LOCALITY | PTM_CAP_RESET_TPMESTABLISHED |
|
PTM_CAP_SET_LOCALITY | PTM_CAP_RESET_TPMESTABLISHED |
|
||||||
PTM_CAP_SET_DATAFD;
|
PTM_CAP_SET_DATAFD | PTM_CAP_STOP | PTM_CAP_SET_BUFFERSIZE;
|
||||||
tpm = "2";
|
tpm = "2";
|
||||||
break;
|
break;
|
||||||
case TPM_VERSION_UNSPEC:
|
case TPM_VERSION_UNSPEC:
|
||||||
@ -255,12 +256,76 @@ static int tpm_emulator_check_caps(TPMEmulator *tpm_emu)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int tpm_emulator_startup_tpm(TPMBackend *tb)
|
static int tpm_emulator_stop_tpm(TPMBackend *tb)
|
||||||
|
{
|
||||||
|
TPMEmulator *tpm_emu = TPM_EMULATOR(tb);
|
||||||
|
ptm_res res;
|
||||||
|
|
||||||
|
if (tpm_emulator_ctrlcmd(tpm_emu, CMD_STOP, &res, 0, sizeof(res)) < 0) {
|
||||||
|
error_report("tpm-emulator: Could not stop TPM: %s",
|
||||||
|
strerror(errno));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
res = be32_to_cpu(res);
|
||||||
|
if (res) {
|
||||||
|
error_report("tpm-emulator: TPM result for CMD_STOP: 0x%x", res);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int tpm_emulator_set_buffer_size(TPMBackend *tb,
|
||||||
|
size_t wanted_size,
|
||||||
|
size_t *actual_size)
|
||||||
|
{
|
||||||
|
TPMEmulator *tpm_emu = TPM_EMULATOR(tb);
|
||||||
|
ptm_setbuffersize psbs;
|
||||||
|
|
||||||
|
if (tpm_emulator_stop_tpm(tb) < 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
psbs.u.req.buffersize = cpu_to_be32(wanted_size);
|
||||||
|
|
||||||
|
if (tpm_emulator_ctrlcmd(tpm_emu, CMD_SET_BUFFERSIZE, &psbs,
|
||||||
|
sizeof(psbs.u.req), sizeof(psbs.u.resp)) < 0) {
|
||||||
|
error_report("tpm-emulator: Could not set buffer size: %s",
|
||||||
|
strerror(errno));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
psbs.u.resp.tpm_result = be32_to_cpu(psbs.u.resp.tpm_result);
|
||||||
|
if (psbs.u.resp.tpm_result != 0) {
|
||||||
|
error_report("tpm-emulator: TPM result for set buffer size : 0x%x",
|
||||||
|
psbs.u.resp.tpm_result);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (actual_size) {
|
||||||
|
*actual_size = be32_to_cpu(psbs.u.resp.buffersize);
|
||||||
|
}
|
||||||
|
|
||||||
|
DPRINTF("buffer size: %u, min: %u, max: %u\n",
|
||||||
|
be32_to_cpu(psbs.u.resp.buffersize),
|
||||||
|
be32_to_cpu(psbs.u.resp.minsize),
|
||||||
|
be32_to_cpu(psbs.u.resp.maxsize));
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int tpm_emulator_startup_tpm(TPMBackend *tb, size_t buffersize)
|
||||||
{
|
{
|
||||||
TPMEmulator *tpm_emu = TPM_EMULATOR(tb);
|
TPMEmulator *tpm_emu = TPM_EMULATOR(tb);
|
||||||
ptm_init init;
|
ptm_init init;
|
||||||
ptm_res res;
|
ptm_res res;
|
||||||
|
|
||||||
|
if (buffersize != 0 &&
|
||||||
|
tpm_emulator_set_buffer_size(tb, buffersize, NULL) < 0) {
|
||||||
|
goto err_exit;
|
||||||
|
}
|
||||||
|
|
||||||
DPRINTF("%s", __func__);
|
DPRINTF("%s", __func__);
|
||||||
if (tpm_emulator_ctrlcmd(tpm_emu, CMD_INIT, &init, sizeof(init),
|
if (tpm_emulator_ctrlcmd(tpm_emu, CMD_INIT, &init, sizeof(init),
|
||||||
sizeof(init)) < 0) {
|
sizeof(init)) < 0) {
|
||||||
@ -358,7 +423,13 @@ static TPMVersion tpm_emulator_get_tpm_version(TPMBackend *tb)
|
|||||||
|
|
||||||
static size_t tpm_emulator_get_buffer_size(TPMBackend *tb)
|
static size_t tpm_emulator_get_buffer_size(TPMBackend *tb)
|
||||||
{
|
{
|
||||||
return 4096;
|
size_t actual_size;
|
||||||
|
|
||||||
|
if (tpm_emulator_set_buffer_size(tb, 0, &actual_size) < 0) {
|
||||||
|
return 4096;
|
||||||
|
}
|
||||||
|
|
||||||
|
return actual_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int tpm_emulator_block_migration(TPMEmulator *tpm_emu)
|
static int tpm_emulator_block_migration(TPMEmulator *tpm_emu)
|
||||||
|
@ -169,6 +169,28 @@ struct ptm_getconfig {
|
|||||||
#define PTM_CONFIG_FLAG_FILE_KEY 0x1
|
#define PTM_CONFIG_FLAG_FILE_KEY 0x1
|
||||||
#define PTM_CONFIG_FLAG_MIGRATION_KEY 0x2
|
#define PTM_CONFIG_FLAG_MIGRATION_KEY 0x2
|
||||||
|
|
||||||
|
/*
|
||||||
|
* PTM_SET_BUFFERSIZE: Set the buffer size to be used by the TPM.
|
||||||
|
* A 0 on input queries for the current buffer size. Any other
|
||||||
|
* number will try to set the buffer size. The returned number is
|
||||||
|
* the buffer size that will be used, which can be larger than the
|
||||||
|
* requested one, if it was below the minimum, or smaller than the
|
||||||
|
* requested one, if it was above the maximum.
|
||||||
|
*/
|
||||||
|
struct ptm_setbuffersize {
|
||||||
|
union {
|
||||||
|
struct {
|
||||||
|
uint32_t buffersize; /* 0 to query for current buffer size */
|
||||||
|
} req; /* request */
|
||||||
|
struct {
|
||||||
|
ptm_res tpm_result;
|
||||||
|
uint32_t buffersize; /* buffer size in use */
|
||||||
|
uint32_t minsize; /* min. supported buffer size */
|
||||||
|
uint32_t maxsize; /* max. supported buffer size */
|
||||||
|
} resp; /* response */
|
||||||
|
} u;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
typedef uint64_t ptm_cap;
|
typedef uint64_t ptm_cap;
|
||||||
typedef struct ptm_est ptm_est;
|
typedef struct ptm_est ptm_est;
|
||||||
@ -179,6 +201,7 @@ typedef struct ptm_init ptm_init;
|
|||||||
typedef struct ptm_getstate ptm_getstate;
|
typedef struct ptm_getstate ptm_getstate;
|
||||||
typedef struct ptm_setstate ptm_setstate;
|
typedef struct ptm_setstate ptm_setstate;
|
||||||
typedef struct ptm_getconfig ptm_getconfig;
|
typedef struct ptm_getconfig ptm_getconfig;
|
||||||
|
typedef struct ptm_setbuffersize ptm_setbuffersize;
|
||||||
|
|
||||||
/* capability flags returned by PTM_GET_CAPABILITY */
|
/* capability flags returned by PTM_GET_CAPABILITY */
|
||||||
#define PTM_CAP_INIT (1)
|
#define PTM_CAP_INIT (1)
|
||||||
@ -194,6 +217,7 @@ typedef struct ptm_getconfig ptm_getconfig;
|
|||||||
#define PTM_CAP_STOP (1 << 10)
|
#define PTM_CAP_STOP (1 << 10)
|
||||||
#define PTM_CAP_GET_CONFIG (1 << 11)
|
#define PTM_CAP_GET_CONFIG (1 << 11)
|
||||||
#define PTM_CAP_SET_DATAFD (1 << 12)
|
#define PTM_CAP_SET_DATAFD (1 << 12)
|
||||||
|
#define PTM_CAP_SET_BUFFERSIZE (1 << 13)
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
PTM_GET_CAPABILITY = _IOR('P', 0, ptm_cap),
|
PTM_GET_CAPABILITY = _IOR('P', 0, ptm_cap),
|
||||||
@ -212,6 +236,7 @@ enum {
|
|||||||
PTM_STOP = _IOR('P', 13, ptm_res),
|
PTM_STOP = _IOR('P', 13, ptm_res),
|
||||||
PTM_GET_CONFIG = _IOR('P', 14, ptm_getconfig),
|
PTM_GET_CONFIG = _IOR('P', 14, ptm_getconfig),
|
||||||
PTM_SET_DATAFD = _IOR('P', 15, ptm_res),
|
PTM_SET_DATAFD = _IOR('P', 15, ptm_res),
|
||||||
|
PTM_SET_BUFFERSIZE = _IOWR('P', 16, ptm_setbuffersize),
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -240,7 +265,8 @@ enum {
|
|||||||
CMD_SET_STATEBLOB,
|
CMD_SET_STATEBLOB,
|
||||||
CMD_STOP,
|
CMD_STOP,
|
||||||
CMD_GET_CONFIG,
|
CMD_GET_CONFIG,
|
||||||
CMD_SET_DATAFD
|
CMD_SET_DATAFD,
|
||||||
|
CMD_SET_BUFFERSIZE,
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* _TPM_IOCTL_H */
|
#endif /* _TPM_IOCTL_H */
|
||||||
|
@ -974,9 +974,9 @@ static const MemoryRegionOps tpm_tis_memory_ops = {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
static int tpm_tis_do_startup_tpm(TPMState *s)
|
static int tpm_tis_do_startup_tpm(TPMState *s, uint32_t buffersize)
|
||||||
{
|
{
|
||||||
return tpm_backend_startup_tpm(s->be_driver);
|
return tpm_backend_startup_tpm(s->be_driver, buffersize);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void tpm_tis_realloc_buffer(TPMSizedBuffer *sb,
|
static void tpm_tis_realloc_buffer(TPMSizedBuffer *sb,
|
||||||
@ -1044,7 +1044,7 @@ static void tpm_tis_reset(DeviceState *dev)
|
|||||||
tpm_tis_realloc_buffer(&s->loc[c].r_buffer, s->be_buffer_size);
|
tpm_tis_realloc_buffer(&s->loc[c].r_buffer, s->be_buffer_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
tpm_tis_do_startup_tpm(s);
|
tpm_tis_do_startup_tpm(s, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const VMStateDescription vmstate_tpm_tis = {
|
static const VMStateDescription vmstate_tpm_tis = {
|
||||||
|
@ -66,7 +66,7 @@ struct TPMBackendClass {
|
|||||||
TPMBackend *(*create)(QemuOpts *opts);
|
TPMBackend *(*create)(QemuOpts *opts);
|
||||||
|
|
||||||
/* start up the TPM on the backend - optional */
|
/* start up the TPM on the backend - optional */
|
||||||
int (*startup_tpm)(TPMBackend *t);
|
int (*startup_tpm)(TPMBackend *t, size_t buffersize);
|
||||||
|
|
||||||
/* optional */
|
/* optional */
|
||||||
void (*reset)(TPMBackend *t);
|
void (*reset)(TPMBackend *t);
|
||||||
@ -112,10 +112,12 @@ int tpm_backend_init(TPMBackend *s, TPMIf *tpmif, Error **errp);
|
|||||||
/**
|
/**
|
||||||
* tpm_backend_startup_tpm:
|
* tpm_backend_startup_tpm:
|
||||||
* @s: the backend whose TPM support is to be started
|
* @s: the backend whose TPM support is to be started
|
||||||
|
* @buffersize: the buffer size the TPM is supposed to use,
|
||||||
|
* 0 to leave it as-is
|
||||||
*
|
*
|
||||||
* Returns 0 on success.
|
* Returns 0 on success.
|
||||||
*/
|
*/
|
||||||
int tpm_backend_startup_tpm(TPMBackend *s);
|
int tpm_backend_startup_tpm(TPMBackend *s, size_t buffersize);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* tpm_backend_had_startup_error:
|
* tpm_backend_had_startup_error:
|
||||||
|
Loading…
Reference in New Issue
Block a user