Record the last command sent to the TPM. Knowing the last command sent to a TPM 2 will allow us to determine whether we need to send a TPM2_Shutdown() command when the VM is reset.
Signed-off-by: Stefan Berger <stef...@linux.ibm.com> --- backends/tpm/tpm_emulator.c | 9 +++++++++ backends/tpm/tpm_util.c | 9 +++++++++ include/sysemu/tpm_util.h | 3 +++ 3 files changed, 21 insertions(+) diff --git a/backends/tpm/tpm_emulator.c b/backends/tpm/tpm_emulator.c index 87d061e9bb..89ecb04a2a 100644 --- a/backends/tpm/tpm_emulator.c +++ b/backends/tpm/tpm_emulator.c @@ -81,6 +81,8 @@ struct TPMEmulator { unsigned int established_flag_cached:1; TPMBlobBuffers state_blobs; + + uint32_t last_command; /* last command sent to TPM */ }; struct tpm_error { @@ -155,6 +157,12 @@ static int tpm_emulator_unix_tx_bufs(TPMEmulator *tpm_emu, { ssize_t ret; bool is_selftest = false; + uint32_t command; + + command = tpm_util_get_ordinal(in, in_len); + if (command != TPM_ORDINAL_NONE) { + tpm_emu->last_command = command; + } if (selftest_done) { *selftest_done = false; @@ -910,6 +918,7 @@ static void tpm_emulator_inst_init(Object *obj) tpm_emu->options = g_new0(TPMEmulatorOptions, 1); tpm_emu->cur_locty_number = ~0; + tpm_emu->last_command = TPM_ORDINAL_NONE; qemu_mutex_init(&tpm_emu->mutex); vmstate_register(NULL, VMSTATE_INSTANCE_ID_ANY, diff --git a/backends/tpm/tpm_util.c b/backends/tpm/tpm_util.c index a6e6d3e72f..28284940f0 100644 --- a/backends/tpm/tpm_util.c +++ b/backends/tpm/tpm_util.c @@ -103,6 +103,15 @@ bool tpm_util_is_selftest(const uint8_t *in, uint32_t in_len) return false; } +uint32_t tpm_util_get_ordinal(const uint8_t *in, uint32_t in_len) +{ + if (in_len >= sizeof(struct tpm_req_hdr)) { + return tpm_cmd_get_ordinal(in); + } + + return TPM_ORDINAL_NONE; +} + /* * Send request to a TPM device. We expect a response within one second. */ diff --git a/include/sysemu/tpm_util.h b/include/sysemu/tpm_util.h index 08f05172a7..7fc238b2a0 100644 --- a/include/sysemu/tpm_util.h +++ b/include/sysemu/tpm_util.h @@ -29,6 +29,9 @@ void tpm_util_write_fatal_error_response(uint8_t *out, uint32_t out_len); bool tpm_util_is_selftest(const uint8_t *in, uint32_t in_len); +uint32_t tpm_util_get_ordinal(const uint8_t *in, uint32_t in_len); +#define TPM_ORDINAL_NONE 0x0 + int tpm_util_test_tpmdev(int tpm_fd, TPMVersion *tpm_version); static inline uint16_t tpm_cmd_get_tag(const void *b) -- 2.35.3