Merge tpm 2022/09/13 v1
-----BEGIN PGP SIGNATURE----- iQEzBAABCAAdFiEEuBi5yt+QicLVzsZrda1lgCoLQhEFAmMgtKIACgkQda1lgCoL QhG/Zgf9Gs35w+hPwGQdsrwcDmCHiH6s4Eb7i4SgzPP4/EVR9kwYriKja4HoNvK2 GHQSXgYX5hazwgkRlNKNJSf2zckbZlr3OhPReZMab6YTVSi79xZRl4rWqKbMxk4K 82ueaUkLKm/RrCw69sM6ToSUQjbitseMVKorZ9NXVt9SVj+hwQv28o5U/+h8Q76T P3t1VraFV2vaiLhAyp4BY52djZ0AMrUox/27EdAYIPPi7om+fGeWcTQP4GsyWUv1 h8i+ZSU1QMJ5hF1szzP7bENwSzG7mSIiqMbrqtpysu/ET6r9WblLTSkRtojvms1S qb7NzQ3S4NwdCWGz0owEbF5kLmMniw== =XMPF -----END PGP SIGNATURE----- Merge tag 'tpm-pull-2022-09-13-1' of https://github.com/stefanberger/qemu-tpm into staging Merge tpm 2022/09/13 v1 # -----BEGIN PGP SIGNATURE----- # # iQEzBAABCAAdFiEEuBi5yt+QicLVzsZrda1lgCoLQhEFAmMgtKIACgkQda1lgCoL # QhG/Zgf9Gs35w+hPwGQdsrwcDmCHiH6s4Eb7i4SgzPP4/EVR9kwYriKja4HoNvK2 # GHQSXgYX5hazwgkRlNKNJSf2zckbZlr3OhPReZMab6YTVSi79xZRl4rWqKbMxk4K # 82ueaUkLKm/RrCw69sM6ToSUQjbitseMVKorZ9NXVt9SVj+hwQv28o5U/+h8Q76T # P3t1VraFV2vaiLhAyp4BY52djZ0AMrUox/27EdAYIPPi7om+fGeWcTQP4GsyWUv1 # h8i+ZSU1QMJ5hF1szzP7bENwSzG7mSIiqMbrqtpysu/ET6r9WblLTSkRtojvms1S # qb7NzQ3S4NwdCWGz0owEbF5kLmMniw== # =XMPF # -----END PGP SIGNATURE----- # gpg: Signature made Tue 13 Sep 2022 12:49:38 EDT # gpg: using RSA key B818B9CADF9089C2D5CEC66B75AD65802A0B4211 # gpg: Good signature from "Stefan Berger <stefanb@linux.vnet.ibm.com>" [unknown] # gpg: WARNING: This key is not certified with a trusted signature! # gpg: There is no indication that the signature belongs to the owner. # Primary key fingerprint: B818 B9CA DF90 89C2 D5CE C66B 75AD 6580 2A0B 4211 * tag 'tpm-pull-2022-09-13-1' of https://github.com/stefanberger/qemu-tpm: tpm_emulator: Have swtpm relock storage upon migration fall-back tpm_emulator: Use latest tpm_ioctl.h from swtpm project tpm_crb: Avoid backend startup just before shutdown under Xen tpm_emulator: Avoid double initialization during migration Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
This commit is contained in:
commit
92411fd91e
@ -32,8 +32,10 @@
|
||||
#include "qemu/sockets.h"
|
||||
#include "qemu/lockable.h"
|
||||
#include "io/channel-socket.h"
|
||||
#include "sysemu/runstate.h"
|
||||
#include "sysemu/tpm_backend.h"
|
||||
#include "sysemu/tpm_util.h"
|
||||
#include "sysemu/runstate.h"
|
||||
#include "tpm_int.h"
|
||||
#include "tpm_ioctl.h"
|
||||
#include "migration/blocker.h"
|
||||
@ -81,6 +83,9 @@ struct TPMEmulator {
|
||||
unsigned int established_flag_cached:1;
|
||||
|
||||
TPMBlobBuffers state_blobs;
|
||||
|
||||
bool relock_storage;
|
||||
VMChangeStateEntry *vmstate;
|
||||
};
|
||||
|
||||
struct tpm_error {
|
||||
@ -302,6 +307,35 @@ static int tpm_emulator_stop_tpm(TPMBackend *tb)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int tpm_emulator_lock_storage(TPMEmulator *tpm_emu)
|
||||
{
|
||||
ptm_lockstorage pls;
|
||||
|
||||
if (!TPM_EMULATOR_IMPLEMENTS_ALL_CAPS(tpm_emu, PTM_CAP_LOCK_STORAGE)) {
|
||||
trace_tpm_emulator_lock_storage_cmd_not_supt();
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* give failing side 300 * 10ms time to release lock */
|
||||
pls.u.req.retries = cpu_to_be32(300);
|
||||
if (tpm_emulator_ctrlcmd(tpm_emu, CMD_LOCK_STORAGE, &pls,
|
||||
sizeof(pls.u.req), sizeof(pls.u.resp)) < 0) {
|
||||
error_report("tpm-emulator: Could not lock storage within 3 seconds: "
|
||||
"%s", strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
pls.u.resp.tpm_result = be32_to_cpu(pls.u.resp.tpm_result);
|
||||
if (pls.u.resp.tpm_result != 0) {
|
||||
error_report("tpm-emulator: TPM result for CMD_LOCK_STORAGE: 0x%x %s",
|
||||
pls.u.resp.tpm_result,
|
||||
tpm_emulator_strerror(pls.u.resp.tpm_result));
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int tpm_emulator_set_buffer_size(TPMBackend *tb,
|
||||
size_t wanted_size,
|
||||
size_t *actual_size)
|
||||
@ -383,6 +417,15 @@ err_exit:
|
||||
|
||||
static int tpm_emulator_startup_tpm(TPMBackend *tb, size_t buffersize)
|
||||
{
|
||||
/* TPM startup will be done from post_load hook */
|
||||
if (runstate_check(RUN_STATE_INMIGRATE)) {
|
||||
if (buffersize != 0) {
|
||||
return tpm_emulator_set_buffer_size(tb, buffersize, NULL);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
return tpm_emulator_startup_tpm_resume(tb, buffersize, false);
|
||||
}
|
||||
|
||||
@ -843,13 +886,34 @@ static int tpm_emulator_pre_save(void *opaque)
|
||||
{
|
||||
TPMBackend *tb = opaque;
|
||||
TPMEmulator *tpm_emu = TPM_EMULATOR(tb);
|
||||
int ret;
|
||||
|
||||
trace_tpm_emulator_pre_save();
|
||||
|
||||
tpm_backend_finish_sync(tb);
|
||||
|
||||
/* get the state blobs from the TPM */
|
||||
return tpm_emulator_get_state_blobs(tpm_emu);
|
||||
ret = tpm_emulator_get_state_blobs(tpm_emu);
|
||||
|
||||
tpm_emu->relock_storage = ret == 0;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void tpm_emulator_vm_state_change(void *opaque, bool running,
|
||||
RunState state)
|
||||
{
|
||||
TPMBackend *tb = opaque;
|
||||
TPMEmulator *tpm_emu = TPM_EMULATOR(tb);
|
||||
|
||||
trace_tpm_emulator_vm_state_change(running, state);
|
||||
|
||||
if (!running || state != RUN_STATE_RUNNING || !tpm_emu->relock_storage) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* lock storage after migration fall-back */
|
||||
tpm_emulator_lock_storage(tpm_emu);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -911,6 +975,9 @@ static void tpm_emulator_inst_init(Object *obj)
|
||||
tpm_emu->options = g_new0(TPMEmulatorOptions, 1);
|
||||
tpm_emu->cur_locty_number = ~0;
|
||||
qemu_mutex_init(&tpm_emu->mutex);
|
||||
tpm_emu->vmstate =
|
||||
qemu_add_vm_change_state_handler(tpm_emulator_vm_state_change,
|
||||
tpm_emu);
|
||||
|
||||
vmstate_register(NULL, VMSTATE_INSTANCE_ID_ANY,
|
||||
&vmstate_tpm_emulator, obj);
|
||||
@ -960,6 +1027,7 @@ static void tpm_emulator_inst_finalize(Object *obj)
|
||||
tpm_sized_buffer_reset(&state_blobs->savestate);
|
||||
|
||||
qemu_mutex_destroy(&tpm_emu->mutex);
|
||||
qemu_del_vm_change_state_handler(tpm_emu->vmstate);
|
||||
|
||||
vmstate_unregister(NULL, &vmstate_tpm_emulator, obj);
|
||||
}
|
||||
|
@ -5,10 +5,15 @@
|
||||
*
|
||||
* This file is licensed under the terms of the 3-clause BSD license
|
||||
*/
|
||||
#ifndef _TPM_IOCTL_H_
|
||||
#define _TPM_IOCTL_H_
|
||||
|
||||
#ifndef TPM_IOCTL_H
|
||||
#define TPM_IOCTL_H
|
||||
#if defined(__CYGWIN__)
|
||||
# define __USE_LINUX_IOCTL_DEFS
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
#include <sys/types.h>
|
||||
#ifndef _WIN32
|
||||
#include <sys/uio.h>
|
||||
#include <sys/ioctl.h>
|
||||
@ -196,6 +201,48 @@ struct ptm_setbuffersize {
|
||||
} u;
|
||||
};
|
||||
|
||||
#define PTM_GETINFO_SIZE (3 * 1024)
|
||||
/*
|
||||
* PTM_GET_INFO: Get info about the TPM implementation (from libtpms)
|
||||
*
|
||||
* This request allows to indirectly call TPMLIB_GetInfo(flags) and
|
||||
* retrieve information from libtpms.
|
||||
* Only one transaction is currently necessary for returning results
|
||||
* to a client. Therefore, totlength and length will be the same if
|
||||
* offset is 0.
|
||||
*/
|
||||
struct ptm_getinfo {
|
||||
union {
|
||||
struct {
|
||||
uint64_t flags;
|
||||
uint32_t offset; /* offset from where to read */
|
||||
uint32_t pad; /* 32 bit arch */
|
||||
} req; /* request */
|
||||
struct {
|
||||
ptm_res tpm_result;
|
||||
uint32_t totlength;
|
||||
uint32_t length;
|
||||
char buffer[PTM_GETINFO_SIZE];
|
||||
} resp; /* response */
|
||||
} u;
|
||||
};
|
||||
|
||||
#define SWTPM_INFO_TPMSPECIFICATION ((uint64_t)1 << 0)
|
||||
#define SWTPM_INFO_TPMATTRIBUTES ((uint64_t)1 << 1)
|
||||
|
||||
/*
|
||||
* PTM_LOCK_STORAGE: Lock the storage and retry n times
|
||||
*/
|
||||
struct ptm_lockstorage {
|
||||
union {
|
||||
struct {
|
||||
uint32_t retries; /* number of retries */
|
||||
} req; /* request */
|
||||
struct {
|
||||
ptm_res tpm_result;
|
||||
} resp; /* reponse */
|
||||
} u;
|
||||
};
|
||||
|
||||
typedef uint64_t ptm_cap;
|
||||
typedef struct ptm_est ptm_est;
|
||||
@ -207,6 +254,8 @@ typedef struct ptm_getstate ptm_getstate;
|
||||
typedef struct ptm_setstate ptm_setstate;
|
||||
typedef struct ptm_getconfig ptm_getconfig;
|
||||
typedef struct ptm_setbuffersize ptm_setbuffersize;
|
||||
typedef struct ptm_getinfo ptm_getinfo;
|
||||
typedef struct ptm_lockstorage ptm_lockstorage;
|
||||
|
||||
/* capability flags returned by PTM_GET_CAPABILITY */
|
||||
#define PTM_CAP_INIT (1)
|
||||
@ -223,6 +272,9 @@ typedef struct ptm_setbuffersize ptm_setbuffersize;
|
||||
#define PTM_CAP_GET_CONFIG (1 << 11)
|
||||
#define PTM_CAP_SET_DATAFD (1 << 12)
|
||||
#define PTM_CAP_SET_BUFFERSIZE (1 << 13)
|
||||
#define PTM_CAP_GET_INFO (1 << 14)
|
||||
#define PTM_CAP_SEND_COMMAND_HEADER (1 << 15)
|
||||
#define PTM_CAP_LOCK_STORAGE (1 << 16)
|
||||
|
||||
#ifndef _WIN32
|
||||
enum {
|
||||
@ -243,6 +295,8 @@ enum {
|
||||
PTM_GET_CONFIG = _IOR('P', 14, ptm_getconfig),
|
||||
PTM_SET_DATAFD = _IOR('P', 15, ptm_res),
|
||||
PTM_SET_BUFFERSIZE = _IOWR('P', 16, ptm_setbuffersize),
|
||||
PTM_GET_INFO = _IOWR('P', 17, ptm_getinfo),
|
||||
PTM_LOCK_STORAGE = _IOWR('P', 18, ptm_lockstorage),
|
||||
};
|
||||
#endif
|
||||
|
||||
@ -257,23 +311,25 @@ enum {
|
||||
* and ptm_set_state:u.req.data) are 0xffffffff.
|
||||
*/
|
||||
enum {
|
||||
CMD_GET_CAPABILITY = 1,
|
||||
CMD_INIT,
|
||||
CMD_SHUTDOWN,
|
||||
CMD_GET_TPMESTABLISHED,
|
||||
CMD_SET_LOCALITY,
|
||||
CMD_HASH_START,
|
||||
CMD_HASH_DATA,
|
||||
CMD_HASH_END,
|
||||
CMD_CANCEL_TPM_CMD,
|
||||
CMD_STORE_VOLATILE,
|
||||
CMD_RESET_TPMESTABLISHED,
|
||||
CMD_GET_STATEBLOB,
|
||||
CMD_SET_STATEBLOB,
|
||||
CMD_STOP,
|
||||
CMD_GET_CONFIG,
|
||||
CMD_SET_DATAFD,
|
||||
CMD_SET_BUFFERSIZE,
|
||||
CMD_GET_CAPABILITY = 1, /* 0x01 */
|
||||
CMD_INIT, /* 0x02 */
|
||||
CMD_SHUTDOWN, /* 0x03 */
|
||||
CMD_GET_TPMESTABLISHED, /* 0x04 */
|
||||
CMD_SET_LOCALITY, /* 0x05 */
|
||||
CMD_HASH_START, /* 0x06 */
|
||||
CMD_HASH_DATA, /* 0x07 */
|
||||
CMD_HASH_END, /* 0x08 */
|
||||
CMD_CANCEL_TPM_CMD, /* 0x09 */
|
||||
CMD_STORE_VOLATILE, /* 0x0a */
|
||||
CMD_RESET_TPMESTABLISHED, /* 0x0b */
|
||||
CMD_GET_STATEBLOB, /* 0x0c */
|
||||
CMD_SET_STATEBLOB, /* 0x0d */
|
||||
CMD_STOP, /* 0x0e */
|
||||
CMD_GET_CONFIG, /* 0x0f */
|
||||
CMD_SET_DATAFD, /* 0x10 */
|
||||
CMD_SET_BUFFERSIZE, /* 0x11 */
|
||||
CMD_GET_INFO, /* 0x12 */
|
||||
CMD_LOCK_STORAGE, /* 0x13 */
|
||||
};
|
||||
|
||||
#endif /* TPM_IOCTL_H */
|
||||
#endif /* _TPM_IOCTL_H_ */
|
||||
|
@ -20,6 +20,8 @@ tpm_emulator_set_buffer_size(uint32_t buffersize, uint32_t minsize, uint32_t max
|
||||
tpm_emulator_startup_tpm_resume(bool is_resume, size_t buffersize) "is_resume: %d, buffer size: %zu"
|
||||
tpm_emulator_get_tpm_established_flag(uint8_t flag) "got established flag: %d"
|
||||
tpm_emulator_cancel_cmd_not_supt(void) "Backend does not support CANCEL_TPM_CMD"
|
||||
tpm_emulator_lock_storage_cmd_not_supt(void) "Backend does not support LOCK_STORAGE"
|
||||
tpm_emulator_vm_state_change(int running, int state) "state change to running %d state %d"
|
||||
tpm_emulator_handle_device_opts_tpm12(void) "TPM Version 1.2"
|
||||
tpm_emulator_handle_device_opts_tpm2(void) "TPM Version 2"
|
||||
tpm_emulator_handle_device_opts_unspec(void) "TPM Version Unspecified"
|
||||
|
@ -26,6 +26,7 @@
|
||||
#include "sysemu/tpm_backend.h"
|
||||
#include "sysemu/tpm_util.h"
|
||||
#include "sysemu/reset.h"
|
||||
#include "sysemu/xen.h"
|
||||
#include "tpm_prop.h"
|
||||
#include "tpm_ppi.h"
|
||||
#include "trace.h"
|
||||
@ -308,7 +309,11 @@ static void tpm_crb_realize(DeviceState *dev, Error **errp)
|
||||
TPM_PPI_ADDR_BASE, OBJECT(s));
|
||||
}
|
||||
|
||||
qemu_register_reset(tpm_crb_reset, dev);
|
||||
if (xen_enabled()) {
|
||||
tpm_crb_reset(dev);
|
||||
} else {
|
||||
qemu_register_reset(tpm_crb_reset, dev);
|
||||
}
|
||||
}
|
||||
|
||||
static void tpm_crb_class_init(ObjectClass *klass, void *data)
|
||||
|
Loading…
Reference in New Issue
Block a user