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;
|
||||
}
|
||||
|
||||
int tpm_backend_startup_tpm(TPMBackend *s)
|
||||
int tpm_backend_startup_tpm(TPMBackend *s, size_t buffersize)
|
||||
{
|
||||
int res = 0;
|
||||
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,
|
||||
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);
|
||||
|
||||
|
@ -232,13 +232,14 @@ static int tpm_emulator_check_caps(TPMEmulator *tpm_emu)
|
||||
switch (tpm_emu->tpm_version) {
|
||||
case TPM_VERSION_1_2:
|
||||
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";
|
||||
break;
|
||||
case TPM_VERSION_2_0:
|
||||
caps = PTM_CAP_INIT | PTM_CAP_SHUTDOWN | PTM_CAP_GET_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";
|
||||
break;
|
||||
case TPM_VERSION_UNSPEC:
|
||||
@ -255,12 +256,76 @@ static int tpm_emulator_check_caps(TPMEmulator *tpm_emu)
|
||||
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);
|
||||
ptm_init init;
|
||||
ptm_res res;
|
||||
|
||||
if (buffersize != 0 &&
|
||||
tpm_emulator_set_buffer_size(tb, buffersize, NULL) < 0) {
|
||||
goto err_exit;
|
||||
}
|
||||
|
||||
DPRINTF("%s", __func__);
|
||||
if (tpm_emulator_ctrlcmd(tpm_emu, CMD_INIT, &init, sizeof(init),
|
||||
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)
|
||||
{
|
||||
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)
|
||||
|
@ -169,6 +169,28 @@ struct ptm_getconfig {
|
||||
#define PTM_CONFIG_FLAG_FILE_KEY 0x1
|
||||
#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 struct ptm_est ptm_est;
|
||||
@ -179,6 +201,7 @@ typedef struct ptm_init ptm_init;
|
||||
typedef struct ptm_getstate ptm_getstate;
|
||||
typedef struct ptm_setstate ptm_setstate;
|
||||
typedef struct ptm_getconfig ptm_getconfig;
|
||||
typedef struct ptm_setbuffersize ptm_setbuffersize;
|
||||
|
||||
/* capability flags returned by PTM_GET_CAPABILITY */
|
||||
#define PTM_CAP_INIT (1)
|
||||
@ -194,6 +217,7 @@ typedef struct ptm_getconfig ptm_getconfig;
|
||||
#define PTM_CAP_STOP (1 << 10)
|
||||
#define PTM_CAP_GET_CONFIG (1 << 11)
|
||||
#define PTM_CAP_SET_DATAFD (1 << 12)
|
||||
#define PTM_CAP_SET_BUFFERSIZE (1 << 13)
|
||||
|
||||
enum {
|
||||
PTM_GET_CAPABILITY = _IOR('P', 0, ptm_cap),
|
||||
@ -212,6 +236,7 @@ enum {
|
||||
PTM_STOP = _IOR('P', 13, ptm_res),
|
||||
PTM_GET_CONFIG = _IOR('P', 14, ptm_getconfig),
|
||||
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_STOP,
|
||||
CMD_GET_CONFIG,
|
||||
CMD_SET_DATAFD
|
||||
CMD_SET_DATAFD,
|
||||
CMD_SET_BUFFERSIZE,
|
||||
};
|
||||
|
||||
#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,
|
||||
@ -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_do_startup_tpm(s);
|
||||
tpm_tis_do_startup_tpm(s, 0);
|
||||
}
|
||||
|
||||
static const VMStateDescription vmstate_tpm_tis = {
|
||||
|
@ -66,7 +66,7 @@ struct TPMBackendClass {
|
||||
TPMBackend *(*create)(QemuOpts *opts);
|
||||
|
||||
/* start up the TPM on the backend - optional */
|
||||
int (*startup_tpm)(TPMBackend *t);
|
||||
int (*startup_tpm)(TPMBackend *t, size_t buffersize);
|
||||
|
||||
/* optional */
|
||||
void (*reset)(TPMBackend *t);
|
||||
@ -112,10 +112,12 @@ int tpm_backend_init(TPMBackend *s, TPMIf *tpmif, Error **errp);
|
||||
/**
|
||||
* tpm_backend_startup_tpm:
|
||||
* @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.
|
||||
*/
|
||||
int tpm_backend_startup_tpm(TPMBackend *s);
|
||||
int tpm_backend_startup_tpm(TPMBackend *s, size_t buffersize);
|
||||
|
||||
/**
|
||||
* tpm_backend_had_startup_error:
|
||||
|
Loading…
Reference in New Issue
Block a user