aboutsummaryrefslogtreecommitdiff
path: root/hw
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2020-06-24 21:19:53 +0100
committerPeter Maydell <peter.maydell@linaro.org>2020-06-24 21:19:53 +0100
commit27c77b1f55323fae772699e05cd5107aa32f9e9a (patch)
tree3ed67330e72f694e5b2548a0940d943bea0ee2ac /hw
parentd4b78317b7cf8c0c635b70086503813f79ff21ec (diff)
parentca64b08638e259c313a3e7c3da106116b59be8e9 (diff)
downloadqemu-27c77b1f55323fae772699e05cd5107aa32f9e9a.zip
qemu-27c77b1f55323fae772699e05cd5107aa32f9e9a.tar.gz
qemu-27c77b1f55323fae772699e05cd5107aa32f9e9a.tar.bz2
Merge remote-tracking branch 'remotes/stefanberger/tags/pull-tpm-2020-06-23-1' into staging
Merge tpm 2020/06/23 v1 # gpg: Signature made Tue 23 Jun 2020 12:35:03 BST # 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 * remotes/stefanberger/tags/pull-tpm-2020-06-23-1: tpm: Move backend code under the 'backends/' directory hw/tpm: Make 'tpm_util.h' publicly accessible as "sysemu/tpm_util.h" hw/tpm: Move DEFINE_PROP_TPMBE() macro to 'tmp_prop.h' local header hw/tpm: Move few declarations from 'tpm_util.h' to 'tpm_int.h' hw/tpm: Make TRACE_TPM_UTIL_SHOW_BUFFER check local to tpm_util.c hw/tpm: Remove unnecessary 'tpm_int.h' header inclusion hw/tpm: Move 'hw/acpi/tpm.h' inclusion from header to sources hw/tpm: Include missing 'qemu/option.h' header hw/tpm: Do not include 'qemu/osdep.h' in header hw/tpm: Rename TPMDEV as TPM_BACKEND in Kconfig backends: Add TPM files into their own directory docs/specs/tpm: Correct header path name Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'hw')
-rw-r--r--hw/tpm/Kconfig21
-rw-r--r--hw/tpm/Makefile.objs3
-rw-r--r--hw/tpm/tpm_crb.c4
-rw-r--r--hw/tpm/tpm_emulator.c997
-rw-r--r--hw/tpm/tpm_int.h75
-rw-r--r--hw/tpm/tpm_ioctl.h271
-rw-r--r--hw/tpm/tpm_passthrough.c405
-rw-r--r--hw/tpm/tpm_ppi.c1
-rw-r--r--hw/tpm/tpm_ppi.h1
-rw-r--r--hw/tpm/tpm_prop.h31
-rw-r--r--hw/tpm/tpm_spapr.c4
-rw-r--r--hw/tpm/tpm_tis.h1
-rw-r--r--hw/tpm/tpm_tis_common.c11
-rw-r--r--hw/tpm/tpm_tis_isa.c3
-rw-r--r--hw/tpm/tpm_tis_sysbus.c3
-rw-r--r--hw/tpm/tpm_util.c377
-rw-r--r--hw/tpm/tpm_util.h85
-rw-r--r--hw/tpm/trace-events34
18 files changed, 47 insertions, 2280 deletions
diff --git a/hw/tpm/Kconfig b/hw/tpm/Kconfig
index 4794e7f..29e82f3 100644
--- a/hw/tpm/Kconfig
+++ b/hw/tpm/Kconfig
@@ -1,7 +1,3 @@
-config TPMDEV
- bool
- depends on TPM
-
config TPM_TIS_ISA
bool
depends on TPM && ISA_BUS
@@ -15,26 +11,15 @@ config TPM_TIS_SYSBUS
config TPM_TIS
bool
depends on TPM
- select TPMDEV
+ select TPM_BACKEND
config TPM_CRB
bool
depends on TPM && PC
- select TPMDEV
-
-config TPM_PASSTHROUGH
- bool
- default y
- # FIXME: should check for x86 host as well
- depends on TPMDEV && LINUX
-
-config TPM_EMULATOR
- bool
- default y
- depends on TPMDEV
+ select TPM_BACKEND
config TPM_SPAPR
bool
default y
depends on TPM && PSERIES
- select TPMDEV
+ select TPM_BACKEND
diff --git a/hw/tpm/Makefile.objs b/hw/tpm/Makefile.objs
index f1ec4be..6fc05be 100644
--- a/hw/tpm/Makefile.objs
+++ b/hw/tpm/Makefile.objs
@@ -1,9 +1,6 @@
-common-obj-$(CONFIG_TPM) += tpm_util.o
obj-$(call lor,$(CONFIG_TPM_TIS),$(CONFIG_TPM_CRB)) += tpm_ppi.o
common-obj-$(CONFIG_TPM_TIS_ISA) += tpm_tis_isa.o
common-obj-$(CONFIG_TPM_TIS_SYSBUS) += tpm_tis_sysbus.o
common-obj-$(CONFIG_TPM_TIS) += tpm_tis_common.o
common-obj-$(CONFIG_TPM_CRB) += tpm_crb.o
-common-obj-$(CONFIG_TPM_PASSTHROUGH) += tpm_passthrough.o
-common-obj-$(CONFIG_TPM_EMULATOR) += tpm_emulator.o
obj-$(CONFIG_TPM_SPAPR) += tpm_spapr.o
diff --git a/hw/tpm/tpm_crb.c b/hw/tpm/tpm_crb.c
index cd004e7..6024729 100644
--- a/hw/tpm/tpm_crb.c
+++ b/hw/tpm/tpm_crb.c
@@ -24,9 +24,9 @@
#include "hw/acpi/tpm.h"
#include "migration/vmstate.h"
#include "sysemu/tpm_backend.h"
+#include "sysemu/tpm_util.h"
#include "sysemu/reset.h"
-#include "tpm_int.h"
-#include "tpm_util.h"
+#include "tpm_prop.h"
#include "tpm_ppi.h"
#include "trace.h"
diff --git a/hw/tpm/tpm_emulator.c b/hw/tpm/tpm_emulator.c
deleted file mode 100644
index 3a0fc44..0000000
--- a/hw/tpm/tpm_emulator.c
+++ /dev/null
@@ -1,997 +0,0 @@
-/*
- * Emulator TPM driver
- *
- * Copyright (c) 2017 Intel Corporation
- * Author: Amarnath Valluri <amarnath.valluri@intel.com>
- *
- * Copyright (c) 2010 - 2013, 2018 IBM Corporation
- * Authors:
- * Stefan Berger <stefanb@us.ibm.com>
- *
- * Copyright (C) 2011 IAIK, Graz University of Technology
- * Author: Andreas Niederl
- *
- * 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/>
- *
- */
-
-#include "qemu/osdep.h"
-#include "qemu/error-report.h"
-#include "qemu/module.h"
-#include "qemu/sockets.h"
-#include "io/channel-socket.h"
-#include "sysemu/tpm_backend.h"
-#include "tpm_int.h"
-#include "tpm_util.h"
-#include "tpm_ioctl.h"
-#include "migration/blocker.h"
-#include "migration/vmstate.h"
-#include "qapi/error.h"
-#include "qapi/clone-visitor.h"
-#include "qapi/qapi-visit-tpm.h"
-#include "chardev/char-fe.h"
-#include "trace.h"
-
-#define TYPE_TPM_EMULATOR "tpm-emulator"
-#define TPM_EMULATOR(obj) \
- OBJECT_CHECK(TPMEmulator, (obj), TYPE_TPM_EMULATOR)
-
-#define TPM_EMULATOR_IMPLEMENTS_ALL_CAPS(S, cap) (((S)->caps & (cap)) == (cap))
-
-/* data structures */
-
-/* blobs from the TPM; part of VM state when migrating */
-typedef struct TPMBlobBuffers {
- uint32_t permanent_flags;
- TPMSizedBuffer permanent;
-
- uint32_t volatil_flags;
- TPMSizedBuffer volatil;
-
- uint32_t savestate_flags;
- TPMSizedBuffer savestate;
-} TPMBlobBuffers;
-
-typedef struct TPMEmulator {
- TPMBackend parent;
-
- TPMEmulatorOptions *options;
- CharBackend ctrl_chr;
- QIOChannel *data_ioc;
- TPMVersion tpm_version;
- ptm_cap caps; /* capabilities of the TPM */
- uint8_t cur_locty_number; /* last set locality */
- Error *migration_blocker;
-
- QemuMutex mutex;
-
- unsigned int established_flag:1;
- unsigned int established_flag_cached:1;
-
- TPMBlobBuffers state_blobs;
-} TPMEmulator;
-
-struct tpm_error {
- uint32_t tpm_result;
- const char *string;
-};
-
-static const struct tpm_error tpm_errors[] = {
- /* TPM 1.2 error codes */
- { TPM_BAD_PARAMETER , "a parameter is bad" },
- { TPM_FAIL , "operation failed" },
- { TPM_KEYNOTFOUND , "key could not be found" },
- { TPM_BAD_PARAM_SIZE , "bad parameter size"},
- { TPM_ENCRYPT_ERROR , "encryption error" },
- { TPM_DECRYPT_ERROR , "decryption error" },
- { TPM_BAD_KEY_PROPERTY, "bad key property" },
- { TPM_BAD_MODE , "bad (encryption) mode" },
- { TPM_BAD_VERSION , "bad version identifier" },
- { TPM_BAD_LOCALITY , "bad locality" },
- /* TPM 2 error codes */
- { TPM_RC_FAILURE , "operation failed" },
- { TPM_RC_LOCALITY , "bad locality" },
- { TPM_RC_INSUFFICIENT, "insufficient amount of data" },
-};
-
-static const char *tpm_emulator_strerror(uint32_t tpm_result)
-{
- size_t i;
-
- for (i = 0; i < ARRAY_SIZE(tpm_errors); i++) {
- if (tpm_errors[i].tpm_result == tpm_result) {
- return tpm_errors[i].string;
- }
- }
- return "";
-}
-
-static int tpm_emulator_ctrlcmd(TPMEmulator *tpm, unsigned long cmd, void *msg,
- size_t msg_len_in, size_t msg_len_out)
-{
- CharBackend *dev = &tpm->ctrl_chr;
- uint32_t cmd_no = cpu_to_be32(cmd);
- ssize_t n = sizeof(uint32_t) + msg_len_in;
- uint8_t *buf = NULL;
- int ret = -1;
-
- qemu_mutex_lock(&tpm->mutex);
-
- buf = g_alloca(n);
- memcpy(buf, &cmd_no, sizeof(cmd_no));
- memcpy(buf + sizeof(cmd_no), msg, msg_len_in);
-
- n = qemu_chr_fe_write_all(dev, buf, n);
- if (n <= 0) {
- goto end;
- }
-
- if (msg_len_out != 0) {
- n = qemu_chr_fe_read_all(dev, msg, msg_len_out);
- if (n <= 0) {
- goto end;
- }
- }
-
- ret = 0;
-
-end:
- qemu_mutex_unlock(&tpm->mutex);
- return ret;
-}
-
-static int tpm_emulator_unix_tx_bufs(TPMEmulator *tpm_emu,
- const uint8_t *in, uint32_t in_len,
- uint8_t *out, uint32_t out_len,
- bool *selftest_done,
- Error **errp)
-{
- ssize_t ret;
- bool is_selftest = false;
-
- if (selftest_done) {
- *selftest_done = false;
- is_selftest = tpm_util_is_selftest(in, in_len);
- }
-
- ret = qio_channel_write_all(tpm_emu->data_ioc, (char *)in, in_len, errp);
- if (ret != 0) {
- return -1;
- }
-
- ret = qio_channel_read_all(tpm_emu->data_ioc, (char *)out,
- sizeof(struct tpm_resp_hdr), errp);
- if (ret != 0) {
- return -1;
- }
-
- ret = qio_channel_read_all(tpm_emu->data_ioc,
- (char *)out + sizeof(struct tpm_resp_hdr),
- tpm_cmd_get_size(out) - sizeof(struct tpm_resp_hdr), errp);
- if (ret != 0) {
- return -1;
- }
-
- if (is_selftest) {
- *selftest_done = tpm_cmd_get_errcode(out) == 0;
- }
-
- return 0;
-}
-
-static int tpm_emulator_set_locality(TPMEmulator *tpm_emu, uint8_t locty_number,
- Error **errp)
-{
- ptm_loc loc;
-
- if (tpm_emu->cur_locty_number == locty_number) {
- return 0;
- }
-
- trace_tpm_emulator_set_locality(locty_number);
-
- memset(&loc, 0, sizeof(loc));
- loc.u.req.loc = locty_number;
- if (tpm_emulator_ctrlcmd(tpm_emu, CMD_SET_LOCALITY, &loc,
- sizeof(loc), sizeof(loc)) < 0) {
- error_setg(errp, "tpm-emulator: could not set locality : %s",
- strerror(errno));
- return -1;
- }
-
- loc.u.resp.tpm_result = be32_to_cpu(loc.u.resp.tpm_result);
- if (loc.u.resp.tpm_result != 0) {
- error_setg(errp, "tpm-emulator: TPM result for set locality : 0x%x",
- loc.u.resp.tpm_result);
- return -1;
- }
-
- tpm_emu->cur_locty_number = locty_number;
-
- return 0;
-}
-
-static void tpm_emulator_handle_request(TPMBackend *tb, TPMBackendCmd *cmd,
- Error **errp)
-{
- TPMEmulator *tpm_emu = TPM_EMULATOR(tb);
-
- trace_tpm_emulator_handle_request();
-
- if (tpm_emulator_set_locality(tpm_emu, cmd->locty, errp) < 0 ||
- tpm_emulator_unix_tx_bufs(tpm_emu, cmd->in, cmd->in_len,
- cmd->out, cmd->out_len,
- &cmd->selftest_done, errp) < 0) {
- tpm_util_write_fatal_error_response(cmd->out, cmd->out_len);
- }
-}
-
-static int tpm_emulator_probe_caps(TPMEmulator *tpm_emu)
-{
- if (tpm_emulator_ctrlcmd(tpm_emu, CMD_GET_CAPABILITY,
- &tpm_emu->caps, 0, sizeof(tpm_emu->caps)) < 0) {
- error_report("tpm-emulator: probing failed : %s", strerror(errno));
- return -1;
- }
-
- tpm_emu->caps = be64_to_cpu(tpm_emu->caps);
-
- trace_tpm_emulator_probe_caps(tpm_emu->caps);
-
- return 0;
-}
-
-static int tpm_emulator_check_caps(TPMEmulator *tpm_emu)
-{
- ptm_cap caps = 0;
- const char *tpm = NULL;
-
- /* check for min. required capabilities */
- 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_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_STOP | PTM_CAP_SET_BUFFERSIZE;
- tpm = "2";
- break;
- case TPM_VERSION_UNSPEC:
- error_report("tpm-emulator: TPM version has not been set");
- return -1;
- }
-
- if (!TPM_EMULATOR_IMPLEMENTS_ALL_CAPS(tpm_emu, caps)) {
- error_report("tpm-emulator: TPM does not implement minimum set of "
- "required capabilities for TPM %s (0x%x)", tpm, (int)caps);
- return -1;
- }
-
- return 0;
-}
-
-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 %s", res,
- tpm_emulator_strerror(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 %s",
- psbs.u.resp.tpm_result,
- tpm_emulator_strerror(psbs.u.resp.tpm_result));
- return -1;
- }
-
- if (actual_size) {
- *actual_size = be32_to_cpu(psbs.u.resp.buffersize);
- }
-
- trace_tpm_emulator_set_buffer_size(
- 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_resume(TPMBackend *tb, size_t buffersize,
- bool is_resume)
-{
- TPMEmulator *tpm_emu = TPM_EMULATOR(tb);
- ptm_init init = {
- .u.req.init_flags = 0,
- };
- ptm_res res;
-
- trace_tpm_emulator_startup_tpm_resume(is_resume, buffersize);
-
- if (buffersize != 0 &&
- tpm_emulator_set_buffer_size(tb, buffersize, NULL) < 0) {
- goto err_exit;
- }
-
- if (is_resume) {
- init.u.req.init_flags |= cpu_to_be32(PTM_INIT_FLAG_DELETE_VOLATILE);
- }
-
- if (tpm_emulator_ctrlcmd(tpm_emu, CMD_INIT, &init, sizeof(init),
- sizeof(init)) < 0) {
- error_report("tpm-emulator: could not send INIT: %s",
- strerror(errno));
- goto err_exit;
- }
-
- res = be32_to_cpu(init.u.resp.tpm_result);
- if (res) {
- error_report("tpm-emulator: TPM result for CMD_INIT: 0x%x %s", res,
- tpm_emulator_strerror(res));
- goto err_exit;
- }
- return 0;
-
-err_exit:
- return -1;
-}
-
-static int tpm_emulator_startup_tpm(TPMBackend *tb, size_t buffersize)
-{
- return tpm_emulator_startup_tpm_resume(tb, buffersize, false);
-}
-
-static bool tpm_emulator_get_tpm_established_flag(TPMBackend *tb)
-{
- TPMEmulator *tpm_emu = TPM_EMULATOR(tb);
- ptm_est est;
-
- if (tpm_emu->established_flag_cached) {
- return tpm_emu->established_flag;
- }
-
- if (tpm_emulator_ctrlcmd(tpm_emu, CMD_GET_TPMESTABLISHED, &est,
- 0, sizeof(est)) < 0) {
- error_report("tpm-emulator: Could not get the TPM established flag: %s",
- strerror(errno));
- return false;
- }
- trace_tpm_emulator_get_tpm_established_flag(est.u.resp.bit);
-
- tpm_emu->established_flag_cached = 1;
- tpm_emu->established_flag = (est.u.resp.bit != 0);
-
- return tpm_emu->established_flag;
-}
-
-static int tpm_emulator_reset_tpm_established_flag(TPMBackend *tb,
- uint8_t locty)
-{
- TPMEmulator *tpm_emu = TPM_EMULATOR(tb);
- ptm_reset_est reset_est;
- ptm_res res;
-
- /* only a TPM 2.0 will support this */
- if (tpm_emu->tpm_version != TPM_VERSION_2_0) {
- return 0;
- }
-
- reset_est.u.req.loc = tpm_emu->cur_locty_number;
- if (tpm_emulator_ctrlcmd(tpm_emu, CMD_RESET_TPMESTABLISHED,
- &reset_est, sizeof(reset_est),
- sizeof(reset_est)) < 0) {
- error_report("tpm-emulator: Could not reset the establishment bit: %s",
- strerror(errno));
- return -1;
- }
-
- res = be32_to_cpu(reset_est.u.resp.tpm_result);
- if (res) {
- error_report(
- "tpm-emulator: TPM result for rest established flag: 0x%x %s",
- res, tpm_emulator_strerror(res));
- return -1;
- }
-
- tpm_emu->established_flag_cached = 0;
-
- return 0;
-}
-
-static void tpm_emulator_cancel_cmd(TPMBackend *tb)
-{
- TPMEmulator *tpm_emu = TPM_EMULATOR(tb);
- ptm_res res;
-
- if (!TPM_EMULATOR_IMPLEMENTS_ALL_CAPS(tpm_emu, PTM_CAP_CANCEL_TPM_CMD)) {
- trace_tpm_emulator_cancel_cmd_not_supt();
- return;
- }
-
- /* FIXME: make the function non-blocking, or it may block a VCPU */
- if (tpm_emulator_ctrlcmd(tpm_emu, CMD_CANCEL_TPM_CMD, &res, 0,
- sizeof(res)) < 0) {
- error_report("tpm-emulator: Could not cancel command: %s",
- strerror(errno));
- } else if (res != 0) {
- error_report("tpm-emulator: Failed to cancel TPM: 0x%x",
- be32_to_cpu(res));
- }
-}
-
-static TPMVersion tpm_emulator_get_tpm_version(TPMBackend *tb)
-{
- TPMEmulator *tpm_emu = TPM_EMULATOR(tb);
-
- return tpm_emu->tpm_version;
-}
-
-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)
-{
- Error *err = NULL;
- ptm_cap caps = PTM_CAP_GET_STATEBLOB | PTM_CAP_SET_STATEBLOB |
- PTM_CAP_STOP;
-
- if (!TPM_EMULATOR_IMPLEMENTS_ALL_CAPS(tpm_emu, caps)) {
- error_setg(&tpm_emu->migration_blocker,
- "Migration disabled: TPM emulator does not support "
- "migration");
- migrate_add_blocker(tpm_emu->migration_blocker, &err);
- if (err) {
- error_report_err(err);
- error_free(tpm_emu->migration_blocker);
- tpm_emu->migration_blocker = NULL;
-
- return -1;
- }
- }
-
- return 0;
-}
-
-static int tpm_emulator_prepare_data_fd(TPMEmulator *tpm_emu)
-{
- ptm_res res;
- Error *err = NULL;
- int fds[2] = { -1, -1 };
-
- if (socketpair(AF_UNIX, SOCK_STREAM, 0, fds) < 0) {
- error_report("tpm-emulator: Failed to create socketpair");
- return -1;
- }
-
- qemu_chr_fe_set_msgfds(&tpm_emu->ctrl_chr, fds + 1, 1);
-
- if (tpm_emulator_ctrlcmd(tpm_emu, CMD_SET_DATAFD, &res, 0,
- sizeof(res)) < 0 || res != 0) {
- error_report("tpm-emulator: Failed to send CMD_SET_DATAFD: %s",
- strerror(errno));
- goto err_exit;
- }
-
- tpm_emu->data_ioc = QIO_CHANNEL(qio_channel_socket_new_fd(fds[0], &err));
- if (err) {
- error_prepend(&err, "tpm-emulator: Failed to create io channel: ");
- error_report_err(err);
- goto err_exit;
- }
-
- closesocket(fds[1]);
-
- return 0;
-
-err_exit:
- closesocket(fds[0]);
- closesocket(fds[1]);
- return -1;
-}
-
-static int tpm_emulator_handle_device_opts(TPMEmulator *tpm_emu, QemuOpts *opts)
-{
- const char *value;
-
- value = qemu_opt_get(opts, "chardev");
- if (value) {
- Error *err = NULL;
- Chardev *dev = qemu_chr_find(value);
-
- if (!dev) {
- error_report("tpm-emulator: tpm chardev '%s' not found.", value);
- goto err;
- }
-
- if (!qemu_chr_fe_init(&tpm_emu->ctrl_chr, dev, &err)) {
- error_prepend(&err, "tpm-emulator: No valid chardev found at '%s':",
- value);
- error_report_err(err);
- goto err;
- }
-
- tpm_emu->options->chardev = g_strdup(value);
- }
-
- if (tpm_emulator_prepare_data_fd(tpm_emu) < 0) {
- goto err;
- }
-
- /* FIXME: tpm_util_test_tpmdev() accepts only on socket fd, as it also used
- * by passthrough driver, which not yet using GIOChannel.
- */
- if (tpm_util_test_tpmdev(QIO_CHANNEL_SOCKET(tpm_emu->data_ioc)->fd,
- &tpm_emu->tpm_version)) {
- error_report("'%s' is not emulating TPM device. Error: %s",
- tpm_emu->options->chardev, strerror(errno));
- goto err;
- }
-
- switch (tpm_emu->tpm_version) {
- case TPM_VERSION_1_2:
- trace_tpm_emulator_handle_device_opts_tpm12();
- break;
- case TPM_VERSION_2_0:
- trace_tpm_emulator_handle_device_opts_tpm2();
- break;
- default:
- trace_tpm_emulator_handle_device_opts_unspec();
- }
-
- if (tpm_emulator_probe_caps(tpm_emu) ||
- tpm_emulator_check_caps(tpm_emu)) {
- goto err;
- }
-
- return tpm_emulator_block_migration(tpm_emu);
-
-err:
- trace_tpm_emulator_handle_device_opts_startup_error();
-
- return -1;
-}
-
-static TPMBackend *tpm_emulator_create(QemuOpts *opts)
-{
- TPMBackend *tb = TPM_BACKEND(object_new(TYPE_TPM_EMULATOR));
-
- if (tpm_emulator_handle_device_opts(TPM_EMULATOR(tb), opts)) {
- object_unref(OBJECT(tb));
- return NULL;
- }
-
- return tb;
-}
-
-static TpmTypeOptions *tpm_emulator_get_tpm_options(TPMBackend *tb)
-{
- TPMEmulator *tpm_emu = TPM_EMULATOR(tb);
- TpmTypeOptions *options = g_new0(TpmTypeOptions, 1);
-
- options->type = TPM_TYPE_OPTIONS_KIND_EMULATOR;
- options->u.emulator.data = QAPI_CLONE(TPMEmulatorOptions, tpm_emu->options);
-
- return options;
-}
-
-static const QemuOptDesc tpm_emulator_cmdline_opts[] = {
- TPM_STANDARD_CMDLINE_OPTS,
- {
- .name = "chardev",
- .type = QEMU_OPT_STRING,
- .help = "Character device to use for out-of-band control messages",
- },
- { /* end of list */ },
-};
-
-/*
- * Transfer a TPM state blob from the TPM into a provided buffer.
- *
- * @tpm_emu: TPMEmulator
- * @type: the type of blob to transfer
- * @tsb: the TPMSizeBuffer to fill with the blob
- * @flags: the flags to return to the caller
- */
-static int tpm_emulator_get_state_blob(TPMEmulator *tpm_emu,
- uint8_t type,
- TPMSizedBuffer *tsb,
- uint32_t *flags)
-{
- ptm_getstate pgs;
- ptm_res res;
- ssize_t n;
- uint32_t totlength, length;
-
- tpm_sized_buffer_reset(tsb);
-
- pgs.u.req.state_flags = cpu_to_be32(PTM_STATE_FLAG_DECRYPTED);
- pgs.u.req.type = cpu_to_be32(type);
- pgs.u.req.offset = 0;
-
- if (tpm_emulator_ctrlcmd(tpm_emu, CMD_GET_STATEBLOB,
- &pgs, sizeof(pgs.u.req),
- offsetof(ptm_getstate, u.resp.data)) < 0) {
- error_report("tpm-emulator: could not get state blob type %d : %s",
- type, strerror(errno));
- return -1;
- }
-
- res = be32_to_cpu(pgs.u.resp.tpm_result);
- if (res != 0 && (res & 0x800) == 0) {
- error_report("tpm-emulator: Getting the stateblob (type %d) failed "
- "with a TPM error 0x%x %s", type, res,
- tpm_emulator_strerror(res));
- return -1;
- }
-
- totlength = be32_to_cpu(pgs.u.resp.totlength);
- length = be32_to_cpu(pgs.u.resp.length);
- if (totlength != length) {
- error_report("tpm-emulator: Expecting to read %u bytes "
- "but would get %u", totlength, length);
- return -1;
- }
-
- *flags = be32_to_cpu(pgs.u.resp.state_flags);
-
- if (totlength > 0) {
- tsb->buffer = g_try_malloc(totlength);
- if (!tsb->buffer) {
- error_report("tpm-emulator: Out of memory allocating %u bytes",
- totlength);
- return -1;
- }
-
- n = qemu_chr_fe_read_all(&tpm_emu->ctrl_chr, tsb->buffer, totlength);
- if (n != totlength) {
- error_report("tpm-emulator: Could not read stateblob (type %d); "
- "expected %u bytes, got %zd",
- type, totlength, n);
- return -1;
- }
- }
- tsb->size = totlength;
-
- trace_tpm_emulator_get_state_blob(type, tsb->size, *flags);
-
- return 0;
-}
-
-static int tpm_emulator_get_state_blobs(TPMEmulator *tpm_emu)
-{
- TPMBlobBuffers *state_blobs = &tpm_emu->state_blobs;
-
- if (tpm_emulator_get_state_blob(tpm_emu, PTM_BLOB_TYPE_PERMANENT,
- &state_blobs->permanent,
- &state_blobs->permanent_flags) < 0 ||
- tpm_emulator_get_state_blob(tpm_emu, PTM_BLOB_TYPE_VOLATILE,
- &state_blobs->volatil,
- &state_blobs->volatil_flags) < 0 ||
- tpm_emulator_get_state_blob(tpm_emu, PTM_BLOB_TYPE_SAVESTATE,
- &state_blobs->savestate,
- &state_blobs->savestate_flags) < 0) {
- goto err_exit;
- }
-
- return 0;
-
- err_exit:
- tpm_sized_buffer_reset(&state_blobs->volatil);
- tpm_sized_buffer_reset(&state_blobs->permanent);
- tpm_sized_buffer_reset(&state_blobs->savestate);
-
- return -1;
-}
-
-/*
- * Transfer a TPM state blob to the TPM emulator.
- *
- * @tpm_emu: TPMEmulator
- * @type: the type of TPM state blob to transfer
- * @tsb: TPMSizedBuffer containing the TPM state blob
- * @flags: Flags describing the (encryption) state of the TPM state blob
- */
-static int tpm_emulator_set_state_blob(TPMEmulator *tpm_emu,
- uint32_t type,
- TPMSizedBuffer *tsb,
- uint32_t flags)
-{
- ssize_t n;
- ptm_setstate pss;
- ptm_res tpm_result;
-
- if (tsb->size == 0) {
- return 0;
- }
-
- pss = (ptm_setstate) {
- .u.req.state_flags = cpu_to_be32(flags),
- .u.req.type = cpu_to_be32(type),
- .u.req.length = cpu_to_be32(tsb->size),
- };
-
- /* write the header only */
- if (tpm_emulator_ctrlcmd(tpm_emu, CMD_SET_STATEBLOB, &pss,
- offsetof(ptm_setstate, u.req.data), 0) < 0) {
- error_report("tpm-emulator: could not set state blob type %d : %s",
- type, strerror(errno));
- return -1;
- }
-
- /* now the body */
- n = qemu_chr_fe_write_all(&tpm_emu->ctrl_chr, tsb->buffer, tsb->size);
- if (n != tsb->size) {
- error_report("tpm-emulator: Writing the stateblob (type %d) "
- "failed; could not write %u bytes, but only %zd",
- type, tsb->size, n);
- return -1;
- }
-
- /* now get the result */
- n = qemu_chr_fe_read_all(&tpm_emu->ctrl_chr,
- (uint8_t *)&pss, sizeof(pss.u.resp));
- if (n != sizeof(pss.u.resp)) {
- error_report("tpm-emulator: Reading response from writing stateblob "
- "(type %d) failed; expected %zu bytes, got %zd", type,
- sizeof(pss.u.resp), n);
- return -1;
- }
-
- tpm_result = be32_to_cpu(pss.u.resp.tpm_result);
- if (tpm_result != 0) {
- error_report("tpm-emulator: Setting the stateblob (type %d) failed "
- "with a TPM error 0x%x %s", type, tpm_result,
- tpm_emulator_strerror(tpm_result));
- return -1;
- }
-
- trace_tpm_emulator_set_state_blob(type, tsb->size, flags);
-
- return 0;
-}
-
-/*
- * Set all the TPM state blobs.
- *
- * Returns a negative errno code in case of error.
- */
-static int tpm_emulator_set_state_blobs(TPMBackend *tb)
-{
- TPMEmulator *tpm_emu = TPM_EMULATOR(tb);
- TPMBlobBuffers *state_blobs = &tpm_emu->state_blobs;
-
- trace_tpm_emulator_set_state_blobs();
-
- if (tpm_emulator_stop_tpm(tb) < 0) {
- trace_tpm_emulator_set_state_blobs_error("Could not stop TPM");
- return -EIO;
- }
-
- if (tpm_emulator_set_state_blob(tpm_emu, PTM_BLOB_TYPE_PERMANENT,
- &state_blobs->permanent,
- state_blobs->permanent_flags) < 0 ||
- tpm_emulator_set_state_blob(tpm_emu, PTM_BLOB_TYPE_VOLATILE,
- &state_blobs->volatil,
- state_blobs->volatil_flags) < 0 ||
- tpm_emulator_set_state_blob(tpm_emu, PTM_BLOB_TYPE_SAVESTATE,
- &state_blobs->savestate,
- state_blobs->savestate_flags) < 0) {
- return -EIO;
- }
-
- trace_tpm_emulator_set_state_blobs_done();
-
- return 0;
-}
-
-static int tpm_emulator_pre_save(void *opaque)
-{
- TPMBackend *tb = opaque;
- TPMEmulator *tpm_emu = TPM_EMULATOR(tb);
-
- 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);
-}
-
-/*
- * Load the TPM state blobs into the TPM.
- *
- * Returns negative errno codes in case of error.
- */
-static int tpm_emulator_post_load(void *opaque, int version_id)
-{
- TPMBackend *tb = opaque;
- int ret;
-
- ret = tpm_emulator_set_state_blobs(tb);
- if (ret < 0) {
- return ret;
- }
-
- if (tpm_emulator_startup_tpm_resume(tb, 0, true) < 0) {
- return -EIO;
- }
-
- return 0;
-}
-
-static const VMStateDescription vmstate_tpm_emulator = {
- .name = "tpm-emulator",
- .version_id = 0,
- .pre_save = tpm_emulator_pre_save,
- .post_load = tpm_emulator_post_load,
- .fields = (VMStateField[]) {
- VMSTATE_UINT32(state_blobs.permanent_flags, TPMEmulator),
- VMSTATE_UINT32(state_blobs.permanent.size, TPMEmulator),
- VMSTATE_VBUFFER_ALLOC_UINT32(state_blobs.permanent.buffer,
- TPMEmulator, 0, 0,
- state_blobs.permanent.size),
-
- VMSTATE_UINT32(state_blobs.volatil_flags, TPMEmulator),
- VMSTATE_UINT32(state_blobs.volatil.size, TPMEmulator),
- VMSTATE_VBUFFER_ALLOC_UINT32(state_blobs.volatil.buffer,
- TPMEmulator, 0, 0,
- state_blobs.volatil.size),
-
- VMSTATE_UINT32(state_blobs.savestate_flags, TPMEmulator),
- VMSTATE_UINT32(state_blobs.savestate.size, TPMEmulator),
- VMSTATE_VBUFFER_ALLOC_UINT32(state_blobs.savestate.buffer,
- TPMEmulator, 0, 0,
- state_blobs.savestate.size),
-
- VMSTATE_END_OF_LIST()
- }
-};
-
-static void tpm_emulator_inst_init(Object *obj)
-{
- TPMEmulator *tpm_emu = TPM_EMULATOR(obj);
-
- trace_tpm_emulator_inst_init();
-
- tpm_emu->options = g_new0(TPMEmulatorOptions, 1);
- tpm_emu->cur_locty_number = ~0;
- qemu_mutex_init(&tpm_emu->mutex);
-
- vmstate_register(NULL, VMSTATE_INSTANCE_ID_ANY,
- &vmstate_tpm_emulator, obj);
-}
-
-/*
- * Gracefully shut down the external TPM
- */
-static void tpm_emulator_shutdown(TPMEmulator *tpm_emu)
-{
- ptm_res res;
-
- if (tpm_emulator_ctrlcmd(tpm_emu, CMD_SHUTDOWN, &res, 0, sizeof(res)) < 0) {
- error_report("tpm-emulator: Could not cleanly shutdown the TPM: %s",
- strerror(errno));
- } else if (res != 0) {
- error_report("tpm-emulator: TPM result for shutdown: 0x%x %s",
- be32_to_cpu(res), tpm_emulator_strerror(be32_to_cpu(res)));
- }
-}
-
-static void tpm_emulator_inst_finalize(Object *obj)
-{
- TPMEmulator *tpm_emu = TPM_EMULATOR(obj);
- TPMBlobBuffers *state_blobs = &tpm_emu->state_blobs;
-
- tpm_emulator_shutdown(tpm_emu);
-
- object_unref(OBJECT(tpm_emu->data_ioc));
-
- qemu_chr_fe_deinit(&tpm_emu->ctrl_chr, false);
-
- qapi_free_TPMEmulatorOptions(tpm_emu->options);
-
- if (tpm_emu->migration_blocker) {
- migrate_del_blocker(tpm_emu->migration_blocker);
- error_free(tpm_emu->migration_blocker);
- }
-
- tpm_sized_buffer_reset(&state_blobs->volatil);
- tpm_sized_buffer_reset(&state_blobs->permanent);
- tpm_sized_buffer_reset(&state_blobs->savestate);
-
- qemu_mutex_destroy(&tpm_emu->mutex);
-
- vmstate_unregister(NULL, &vmstate_tpm_emulator, obj);
-}
-
-static void tpm_emulator_class_init(ObjectClass *klass, void *data)
-{
- TPMBackendClass *tbc = TPM_BACKEND_CLASS(klass);
-
- tbc->type = TPM_TYPE_EMULATOR;
- tbc->opts = tpm_emulator_cmdline_opts;
- tbc->desc = "TPM emulator backend driver";
- tbc->create = tpm_emulator_create;
- tbc->startup_tpm = tpm_emulator_startup_tpm;
- tbc->cancel_cmd = tpm_emulator_cancel_cmd;
- tbc->get_tpm_established_flag = tpm_emulator_get_tpm_established_flag;
- tbc->reset_tpm_established_flag = tpm_emulator_reset_tpm_established_flag;
- tbc->get_tpm_version = tpm_emulator_get_tpm_version;
- tbc->get_buffer_size = tpm_emulator_get_buffer_size;
- tbc->get_tpm_options = tpm_emulator_get_tpm_options;
-
- tbc->handle_request = tpm_emulator_handle_request;
-}
-
-static const TypeInfo tpm_emulator_info = {
- .name = TYPE_TPM_EMULATOR,
- .parent = TYPE_TPM_BACKEND,
- .instance_size = sizeof(TPMEmulator),
- .class_init = tpm_emulator_class_init,
- .instance_init = tpm_emulator_inst_init,
- .instance_finalize = tpm_emulator_inst_finalize,
-};
-
-static void tpm_emulator_register(void)
-{
- type_register_static(&tpm_emulator_info);
-}
-
-type_init(tpm_emulator_register)
diff --git a/hw/tpm/tpm_int.h b/hw/tpm/tpm_int.h
deleted file mode 100644
index 3fb28a9..0000000
--- a/hw/tpm/tpm_int.h
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * TPM configuration
- *
- * Copyright (C) 2011-2013 IBM Corporation
- *
- * Authors:
- * Stefan Berger <stefanb@us.ibm.com>
- *
- * This work is licensed under the terms of the GNU GPL, version 2 or later.
- * See the COPYING file in the top-level directory.
- */
-#ifndef TPM_TPM_INT_H
-#define TPM_TPM_INT_H
-
-#define TPM_STANDARD_CMDLINE_OPTS \
- { \
- .name = "type", \
- .type = QEMU_OPT_STRING, \
- .help = "Type of TPM backend", \
- }
-
-struct tpm_req_hdr {
- uint16_t tag;
- uint32_t len;
- uint32_t ordinal;
-} QEMU_PACKED;
-
-struct tpm_resp_hdr {
- uint16_t tag;
- uint32_t len;
- uint32_t errcode;
-} QEMU_PACKED;
-
-#define TPM_TAG_RQU_COMMAND 0xc1
-#define TPM_TAG_RQU_AUTH1_COMMAND 0xc2
-#define TPM_TAG_RQU_AUTH2_COMMAND 0xc3
-
-#define TPM_TAG_RSP_COMMAND 0xc4
-#define TPM_TAG_RSP_AUTH1_COMMAND 0xc5
-#define TPM_TAG_RSP_AUTH2_COMMAND 0xc6
-
-#define TPM_BAD_PARAMETER 3
-#define TPM_FAIL 9
-#define TPM_KEYNOTFOUND 13
-#define TPM_BAD_PARAM_SIZE 25
-#define TPM_ENCRYPT_ERROR 32
-#define TPM_DECRYPT_ERROR 33
-#define TPM_BAD_KEY_PROPERTY 40
-#define TPM_BAD_MODE 44
-#define TPM_BAD_VERSION 46
-#define TPM_BAD_LOCALITY 61
-
-#define TPM_ORD_ContinueSelfTest 0x53
-#define TPM_ORD_GetTicks 0xf1
-#define TPM_ORD_GetCapability 0x65
-
-#define TPM_CAP_PROPERTY 0x05
-
-#define TPM_CAP_PROP_INPUT_BUFFER 0x124
-
-/* TPM2 defines */
-#define TPM2_ST_NO_SESSIONS 0x8001
-
-#define TPM2_CC_ReadClock 0x00000181
-#define TPM2_CC_GetCapability 0x0000017a
-
-#define TPM2_CAP_TPM_PROPERTIES 0x6
-
-#define TPM2_PT_MAX_COMMAND_SIZE 0x11e
-
-#define TPM_RC_INSUFFICIENT 0x9a
-#define TPM_RC_FAILURE 0x101
-#define TPM_RC_LOCALITY 0x907
-
-#endif /* TPM_TPM_INT_H */
diff --git a/hw/tpm/tpm_ioctl.h b/hw/tpm/tpm_ioctl.h
deleted file mode 100644
index f5f5c55..0000000
--- a/hw/tpm/tpm_ioctl.h
+++ /dev/null
@@ -1,271 +0,0 @@
-/*
- * tpm_ioctl.h
- *
- * (c) Copyright IBM Corporation 2014, 2015.
- *
- * This file is licensed under the terms of the 3-clause BSD license
- */
-
-#ifndef TPM_IOCTL_H
-#define TPM_IOCTL_H
-
-#include <sys/uio.h>
-#include <sys/ioctl.h>
-
-/*
- * Every response from a command involving a TPM command execution must hold
- * the ptm_res as the first element.
- * ptm_res corresponds to the error code of a command executed by the TPM.
- */
-
-typedef uint32_t ptm_res;
-
-/* PTM_GET_TPMESTABLISHED: get the establishment bit */
-struct ptm_est {
- union {
- struct {
- ptm_res tpm_result;
- unsigned char bit; /* TPM established bit */
- } resp; /* response */
- } u;
-};
-
-/* PTM_RESET_TPMESTABLISHED: reset establishment bit */
-struct ptm_reset_est {
- union {
- struct {
- uint8_t loc; /* locality to use */
- } req; /* request */
- struct {
- ptm_res tpm_result;
- } resp; /* response */
- } u;
-};
-
-/* PTM_INIT */
-struct ptm_init {
- union {
- struct {
- uint32_t init_flags; /* see definitions below */
- } req; /* request */
- struct {
- ptm_res tpm_result;
- } resp; /* response */
- } u;
-};
-
-/* above init_flags */
-#define PTM_INIT_FLAG_DELETE_VOLATILE (1 << 0)
- /* delete volatile state file after reading it */
-
-/* PTM_SET_LOCALITY */
-struct ptm_loc {
- union {
- struct {
- uint8_t loc; /* locality to set */
- } req; /* request */
- struct {
- ptm_res tpm_result;
- } resp; /* response */
- } u;
-};
-
-/* PTM_HASH_DATA: hash given data */
-struct ptm_hdata {
- union {
- struct {
- uint32_t length;
- uint8_t data[4096];
- } req; /* request */
- struct {
- ptm_res tpm_result;
- } resp; /* response */
- } u;
-};
-
-/*
- * size of the TPM state blob to transfer; x86_64 can handle 8k,
- * ppc64le only ~7k; keep the response below a 4k page size
- */
-#define PTM_STATE_BLOB_SIZE (3 * 1024)
-
-/*
- * The following is the data structure to get state blobs from the TPM.
- * If the size of the state blob exceeds the PTM_STATE_BLOB_SIZE, multiple reads
- * with this ioctl and with adjusted offset are necessary. All bytes
- * must be transferred and the transfer is done once the last byte has been
- * returned.
- * It is possible to use the read() interface for reading the data; however, the
- * first bytes of the state blob will be part of the response to the ioctl(); a
- * subsequent read() is only necessary if the total length (totlength) exceeds
- * the number of received bytes. seek() is not supported.
- */
-struct ptm_getstate {
- union {
- struct {
- uint32_t state_flags; /* may be: PTM_STATE_FLAG_DECRYPTED */
- uint32_t type; /* which blob to pull */
- uint32_t offset; /* offset from where to read */
- } req; /* request */
- struct {
- ptm_res tpm_result;
- uint32_t state_flags; /* may be: PTM_STATE_FLAG_ENCRYPTED */
- uint32_t totlength; /* total length that will be transferred */
- uint32_t length; /* number of bytes in following buffer */
- uint8_t data[PTM_STATE_BLOB_SIZE];
- } resp; /* response */
- } u;
-};
-
-/* TPM state blob types */
-#define PTM_BLOB_TYPE_PERMANENT 1
-#define PTM_BLOB_TYPE_VOLATILE 2
-#define PTM_BLOB_TYPE_SAVESTATE 3
-
-/* state_flags above : */
-#define PTM_STATE_FLAG_DECRYPTED 1 /* on input: get decrypted state */
-#define PTM_STATE_FLAG_ENCRYPTED 2 /* on output: state is encrypted */
-
-/*
- * The following is the data structure to set state blobs in the TPM.
- * If the size of the state blob exceeds the PTM_STATE_BLOB_SIZE, multiple
- * 'writes' using this ioctl are necessary. The last packet is indicated
- * by the length being smaller than the PTM_STATE_BLOB_SIZE.
- * The very first packet may have a length indicator of '0' enabling
- * a write() with all the bytes from a buffer. If the write() interface
- * is used, a final ioctl with a non-full buffer must be made to indicate
- * that all data were transferred (a write with 0 bytes would not work).
- */
-struct ptm_setstate {
- union {
- struct {
- uint32_t state_flags; /* may be PTM_STATE_FLAG_ENCRYPTED */
- uint32_t type; /* which blob to set */
- uint32_t length; /* length of the data;
- use 0 on the first packet to
- transfer using write() */
- uint8_t data[PTM_STATE_BLOB_SIZE];
- } req; /* request */
- struct {
- ptm_res tpm_result;
- } resp; /* response */
- } u;
-};
-
-/*
- * PTM_GET_CONFIG: Data structure to get runtime configuration information
- * such as which keys are applied.
- */
-struct ptm_getconfig {
- union {
- struct {
- ptm_res tpm_result;
- uint32_t flags;
- } resp; /* response */
- } u;
-};
-
-#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;
-typedef struct ptm_reset_est ptm_reset_est;
-typedef struct ptm_loc ptm_loc;
-typedef struct ptm_hdata ptm_hdata;
-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)
-#define PTM_CAP_SHUTDOWN (1 << 1)
-#define PTM_CAP_GET_TPMESTABLISHED (1 << 2)
-#define PTM_CAP_SET_LOCALITY (1 << 3)
-#define PTM_CAP_HASHING (1 << 4)
-#define PTM_CAP_CANCEL_TPM_CMD (1 << 5)
-#define PTM_CAP_STORE_VOLATILE (1 << 6)
-#define PTM_CAP_RESET_TPMESTABLISHED (1 << 7)
-#define PTM_CAP_GET_STATEBLOB (1 << 8)
-#define PTM_CAP_SET_STATEBLOB (1 << 9)
-#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),
- PTM_INIT = _IOWR('P', 1, ptm_init),
- PTM_SHUTDOWN = _IOR('P', 2, ptm_res),
- PTM_GET_TPMESTABLISHED = _IOR('P', 3, ptm_est),
- PTM_SET_LOCALITY = _IOWR('P', 4, ptm_loc),
- PTM_HASH_START = _IOR('P', 5, ptm_res),
- PTM_HASH_DATA = _IOWR('P', 6, ptm_hdata),
- PTM_HASH_END = _IOR('P', 7, ptm_res),
- PTM_CANCEL_TPM_CMD = _IOR('P', 8, ptm_res),
- PTM_STORE_VOLATILE = _IOR('P', 9, ptm_res),
- PTM_RESET_TPMESTABLISHED = _IOWR('P', 10, ptm_reset_est),
- PTM_GET_STATEBLOB = _IOWR('P', 11, ptm_getstate),
- PTM_SET_STATEBLOB = _IOWR('P', 12, ptm_setstate),
- 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),
-};
-
-/*
- * Commands used by the non-CUSE TPMs
- *
- * All messages container big-endian data.
- *
- * The return messages only contain the 'resp' part of the unions
- * in the data structures above. Besides that the limits in the
- * buffers above (ptm_hdata:u.req.data and ptm_get_state:u.resp.data
- * 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,
-};
-
-#endif /* TPM_IOCTL_H */
diff --git a/hw/tpm/tpm_passthrough.c b/hw/tpm/tpm_passthrough.c
deleted file mode 100644
index f67244b..0000000
--- a/hw/tpm/tpm_passthrough.c
+++ /dev/null
@@ -1,405 +0,0 @@
-/*
- * passthrough TPM driver
- *
- * Copyright (c) 2010 - 2013 IBM Corporation
- * Authors:
- * Stefan Berger <stefanb@us.ibm.com>
- *
- * Copyright (C) 2011 IAIK, Graz University of Technology
- * Author: Andreas Niederl
- *
- * 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/>
- */
-
-#include "qemu/osdep.h"
-#include "qemu-common.h"
-#include "qemu/error-report.h"
-#include "qemu/module.h"
-#include "qemu/sockets.h"
-#include "sysemu/tpm_backend.h"
-#include "tpm_int.h"
-#include "qapi/clone-visitor.h"
-#include "qapi/qapi-visit-tpm.h"
-#include "tpm_util.h"
-#include "trace.h"
-
-#define TYPE_TPM_PASSTHROUGH "tpm-passthrough"
-#define TPM_PASSTHROUGH(obj) \
- OBJECT_CHECK(TPMPassthruState, (obj), TYPE_TPM_PASSTHROUGH)
-
-/* data structures */
-struct TPMPassthruState {
- TPMBackend parent;
-
- TPMPassthroughOptions *options;
- const char *tpm_dev;
- int tpm_fd;
- bool tpm_executing;
- bool tpm_op_canceled;
- int cancel_fd;
-
- TPMVersion tpm_version;
- size_t tpm_buffersize;
-};
-
-typedef struct TPMPassthruState TPMPassthruState;
-
-#define TPM_PASSTHROUGH_DEFAULT_DEVICE "/dev/tpm0"
-
-/* functions */
-
-static void tpm_passthrough_cancel_cmd(TPMBackend *tb);
-
-static int tpm_passthrough_unix_read(int fd, uint8_t *buf, uint32_t len)
-{
- int ret;
- reread:
- ret = read(fd, buf, len);
- if (ret < 0) {
- if (errno != EINTR && errno != EAGAIN) {
- return -1;
- }
- goto reread;
- }
- return ret;
-}
-
-static void tpm_passthrough_unix_tx_bufs(TPMPassthruState *tpm_pt,
- const uint8_t *in, uint32_t in_len,
- uint8_t *out, uint32_t out_len,
- bool *selftest_done, Error **errp)
-{
- ssize_t ret;
- bool is_selftest;
-
- /* FIXME: protect shared variables or use other sync mechanism */
- tpm_pt->tpm_op_canceled = false;
- tpm_pt->tpm_executing = true;
- *selftest_done = false;
-
- is_selftest = tpm_util_is_selftest(in, in_len);
-
- ret = qemu_write_full(tpm_pt->tpm_fd, in, in_len);
- if (ret != in_len) {
- if (!tpm_pt->tpm_op_canceled || errno != ECANCELED) {
- error_setg_errno(errp, errno, "tpm_passthrough: error while "
- "transmitting data to TPM");
- }
- goto err_exit;
- }
-
- tpm_pt->tpm_executing = false;
-
- ret = tpm_passthrough_unix_read(tpm_pt->tpm_fd, out, out_len);
- if (ret < 0) {
- if (!tpm_pt->tpm_op_canceled || errno != ECANCELED) {
- error_setg_errno(errp, errno, "tpm_passthrough: error while "
- "reading data from TPM");
- }
- } else if (ret < sizeof(struct tpm_resp_hdr) ||
- tpm_cmd_get_size(out) != ret) {
- ret = -1;
- error_setg_errno(errp, errno, "tpm_passthrough: received invalid "
- "response packet from TPM");
- }
-
- if (is_selftest && (ret >= sizeof(struct tpm_resp_hdr))) {
- *selftest_done = tpm_cmd_get_errcode(out) == 0;
- }
-
-err_exit:
- if (ret < 0) {
- tpm_util_write_fatal_error_response(out, out_len);
- }
-
- tpm_pt->tpm_executing = false;
-}
-
-static void tpm_passthrough_handle_request(TPMBackend *tb, TPMBackendCmd *cmd,
- Error **errp)
-{
- TPMPassthruState *tpm_pt = TPM_PASSTHROUGH(tb);
-
- trace_tpm_passthrough_handle_request(cmd);
-
- tpm_passthrough_unix_tx_bufs(tpm_pt, cmd->in, cmd->in_len,
- cmd->out, cmd->out_len, &cmd->selftest_done,
- errp);
-}
-
-static void tpm_passthrough_reset(TPMBackend *tb)
-{
- trace_tpm_passthrough_reset();
-
- tpm_passthrough_cancel_cmd(tb);
-}
-
-static bool tpm_passthrough_get_tpm_established_flag(TPMBackend *tb)
-{
- return false;
-}
-
-static int tpm_passthrough_reset_tpm_established_flag(TPMBackend *tb,
- uint8_t locty)
-{
- /* only a TPM 2.0 will support this */
- return 0;
-}
-
-static void tpm_passthrough_cancel_cmd(TPMBackend *tb)
-{
- TPMPassthruState *tpm_pt = TPM_PASSTHROUGH(tb);
- int n;
-
- /*
- * As of Linux 3.7 the tpm_tis driver does not properly cancel
- * commands on all TPM manufacturers' TPMs.
- * Only cancel if we're busy so we don't cancel someone else's
- * command, e.g., a command executed on the host.
- */
- if (tpm_pt->tpm_executing) {
- if (tpm_pt->cancel_fd >= 0) {
- tpm_pt->tpm_op_canceled = true;
- n = write(tpm_pt->cancel_fd, "-", 1);
- if (n != 1) {
- error_report("Canceling TPM command failed: %s",
- strerror(errno));
- }
- } else {
- error_report("Cannot cancel TPM command due to missing "
- "TPM sysfs cancel entry");
- }
- }
-}
-
-static TPMVersion tpm_passthrough_get_tpm_version(TPMBackend *tb)
-{
- TPMPassthruState *tpm_pt = TPM_PASSTHROUGH(tb);
-
- return tpm_pt->tpm_version;
-}
-
-static size_t tpm_passthrough_get_buffer_size(TPMBackend *tb)
-{
- TPMPassthruState *tpm_pt = TPM_PASSTHROUGH(tb);
- int ret;
-
- ret = tpm_util_get_buffer_size(tpm_pt->tpm_fd, tpm_pt->tpm_version,
- &tpm_pt->tpm_buffersize);
- if (ret < 0) {
- tpm_pt->tpm_buffersize = 4096;
- }
- return tpm_pt->tpm_buffersize;
-}
-
-/*
- * Unless path or file descriptor set has been provided by user,
- * determine the sysfs cancel file following kernel documentation
- * in Documentation/ABI/stable/sysfs-class-tpm.
- * From /dev/tpm0 create /sys/class/tpm/tpm0/device/cancel
- * before 4.0: /sys/class/misc/tpm0/device/cancel
- */
-static int tpm_passthrough_open_sysfs_cancel(TPMPassthruState *tpm_pt)
-{
- int fd = -1;
- char *dev;
- char path[PATH_MAX];
-
- if (tpm_pt->options->cancel_path) {
- fd = qemu_open(tpm_pt->options->cancel_path, O_WRONLY);
- if (fd < 0) {
- error_report("tpm_passthrough: Could not open TPM cancel path: %s",
- strerror(errno));
- }
- return fd;
- }
-
- dev = strrchr(tpm_pt->tpm_dev, '/');
- if (!dev) {
- error_report("tpm_passthrough: Bad TPM device path %s",
- tpm_pt->tpm_dev);
- return -1;
- }
-
- dev++;
- if (snprintf(path, sizeof(path), "/sys/class/tpm/%s/device/cancel",
- dev) < sizeof(path)) {
- fd = qemu_open(path, O_WRONLY);
- if (fd < 0) {
- if (snprintf(path, sizeof(path), "/sys/class/misc/%s/device/cancel",
- dev) < sizeof(path)) {
- fd = qemu_open(path, O_WRONLY);
- }
- }
- }
-
- if (fd < 0) {
- error_report("tpm_passthrough: Could not guess TPM cancel path");
- } else {
- tpm_pt->options->cancel_path = g_strdup(path);
- }
-
- return fd;
-}
-
-static int
-tpm_passthrough_handle_device_opts(TPMPassthruState *tpm_pt, QemuOpts *opts)
-{
- const char *value;
-
- value = qemu_opt_get(opts, "cancel-path");
- if (value) {
- tpm_pt->options->cancel_path = g_strdup(value);
- tpm_pt->options->has_cancel_path = true;
- }
-
- value = qemu_opt_get(opts, "path");
- if (value) {
- tpm_pt->options->has_path = true;
- tpm_pt->options->path = g_strdup(value);
- }
-
- tpm_pt->tpm_dev = value ? value : TPM_PASSTHROUGH_DEFAULT_DEVICE;
- tpm_pt->tpm_fd = qemu_open(tpm_pt->tpm_dev, O_RDWR);
- if (tpm_pt->tpm_fd < 0) {
- error_report("Cannot access TPM device using '%s': %s",
- tpm_pt->tpm_dev, strerror(errno));
- return -1;
- }
-
- if (tpm_util_test_tpmdev(tpm_pt->tpm_fd, &tpm_pt->tpm_version)) {
- error_report("'%s' is not a TPM device.",
- tpm_pt->tpm_dev);
- return -1;
- }
-
- tpm_pt->cancel_fd = tpm_passthrough_open_sysfs_cancel(tpm_pt);
- if (tpm_pt->cancel_fd < 0) {
- return -1;
- }
-
- return 0;
-}
-
-static TPMBackend *tpm_passthrough_create(QemuOpts *opts)
-{
- Object *obj = object_new(TYPE_TPM_PASSTHROUGH);
-
- if (tpm_passthrough_handle_device_opts(TPM_PASSTHROUGH(obj), opts)) {
- object_unref(obj);
- return NULL;
- }
-
- return TPM_BACKEND(obj);
-}
-
-static int tpm_passthrough_startup_tpm(TPMBackend *tb, size_t buffersize)
-{
- TPMPassthruState *tpm_pt = TPM_PASSTHROUGH(tb);
-
- if (buffersize && buffersize < tpm_pt->tpm_buffersize) {
- error_report("Requested buffer size of %zu is smaller than host TPM's "
- "fixed buffer size of %zu",
- buffersize, tpm_pt->tpm_buffersize);
- return -1;
- }
-
- return 0;
-}
-
-static TpmTypeOptions *tpm_passthrough_get_tpm_options(TPMBackend *tb)
-{
- TpmTypeOptions *options = g_new0(TpmTypeOptions, 1);
-
- options->type = TPM_TYPE_OPTIONS_KIND_PASSTHROUGH;
- options->u.passthrough.data = QAPI_CLONE(TPMPassthroughOptions,
- TPM_PASSTHROUGH(tb)->options);
-
- return options;
-}
-
-static const QemuOptDesc tpm_passthrough_cmdline_opts[] = {
- TPM_STANDARD_CMDLINE_OPTS,
- {
- .name = "cancel-path",
- .type = QEMU_OPT_STRING,
- .help = "Sysfs file entry for canceling TPM commands",
- },
- {
- .name = "path",
- .type = QEMU_OPT_STRING,
- .help = "Path to TPM device on the host",
- },
- { /* end of list */ },
-};
-
-static void tpm_passthrough_inst_init(Object *obj)
-{
- TPMPassthruState *tpm_pt = TPM_PASSTHROUGH(obj);
-
- tpm_pt->options = g_new0(TPMPassthroughOptions, 1);
- tpm_pt->tpm_fd = -1;
- tpm_pt->cancel_fd = -1;
-}
-
-static void tpm_passthrough_inst_finalize(Object *obj)
-{
- TPMPassthruState *tpm_pt = TPM_PASSTHROUGH(obj);
-
- tpm_passthrough_cancel_cmd(TPM_BACKEND(obj));
-
- if (tpm_pt->tpm_fd >= 0) {
- qemu_close(tpm_pt->tpm_fd);
- }
- if (tpm_pt->cancel_fd >= 0) {
- qemu_close(tpm_pt->cancel_fd);
- }
- qapi_free_TPMPassthroughOptions(tpm_pt->options);
-}
-
-static void tpm_passthrough_class_init(ObjectClass *klass, void *data)
-{
- TPMBackendClass *tbc = TPM_BACKEND_CLASS(klass);
-
- tbc->type = TPM_TYPE_PASSTHROUGH;
- tbc->opts = tpm_passthrough_cmdline_opts;
- tbc->desc = "Passthrough TPM backend driver";
- tbc->create = tpm_passthrough_create;
- tbc->startup_tpm = tpm_passthrough_startup_tpm;
- tbc->reset = tpm_passthrough_reset;
- tbc->cancel_cmd = tpm_passthrough_cancel_cmd;
- tbc->get_tpm_established_flag = tpm_passthrough_get_tpm_established_flag;
- tbc->reset_tpm_established_flag =
- tpm_passthrough_reset_tpm_established_flag;
- tbc->get_tpm_version = tpm_passthrough_get_tpm_version;
- tbc->get_buffer_size = tpm_passthrough_get_buffer_size;
- tbc->get_tpm_options = tpm_passthrough_get_tpm_options;
- tbc->handle_request = tpm_passthrough_handle_request;
-}
-
-static const TypeInfo tpm_passthrough_info = {
- .name = TYPE_TPM_PASSTHROUGH,
- .parent = TYPE_TPM_BACKEND,
- .instance_size = sizeof(TPMPassthruState),
- .class_init = tpm_passthrough_class_init,
- .instance_init = tpm_passthrough_inst_init,
- .instance_finalize = tpm_passthrough_inst_finalize,
-};
-
-static void tpm_passthrough_register(void)
-{
- type_register_static(&tpm_passthrough_info);
-}
-
-type_init(tpm_passthrough_register)
diff --git a/hw/tpm/tpm_ppi.c b/hw/tpm/tpm_ppi.c
index 6d9c1a3..72d7a3d 100644
--- a/hw/tpm/tpm_ppi.c
+++ b/hw/tpm/tpm_ppi.c
@@ -17,6 +17,7 @@
#include "cpu.h"
#include "sysemu/memory_mapping.h"
#include "migration/vmstate.h"
+#include "hw/acpi/tpm.h"
#include "tpm_ppi.h"
#include "trace.h"
diff --git a/hw/tpm/tpm_ppi.h b/hw/tpm/tpm_ppi.h
index d33ef27..6f773c2 100644
--- a/hw/tpm/tpm_ppi.h
+++ b/hw/tpm/tpm_ppi.h
@@ -12,7 +12,6 @@
#ifndef TPM_TPM_PPI_H
#define TPM_TPM_PPI_H
-#include "hw/acpi/tpm.h"
#include "exec/address-spaces.h"
typedef struct TPMPPI {
diff --git a/hw/tpm/tpm_prop.h b/hw/tpm/tpm_prop.h
new file mode 100644
index 0000000..85e1ae5
--- /dev/null
+++ b/hw/tpm/tpm_prop.h
@@ -0,0 +1,31 @@
+/*
+ * TPM utility functions
+ *
+ * Copyright (c) 2010 - 2015 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 HW_TPM_PROP_H
+#define HW_TPM_PROP_H
+
+#include "sysemu/tpm_backend.h"
+#include "hw/qdev-properties.h"
+
+#define DEFINE_PROP_TPMBE(_n, _s, _f) \
+ DEFINE_PROP(_n, _s, _f, qdev_prop_tpm, TPMBackend *)
+
+#endif /* HW_TPM_PROP_H */
diff --git a/hw/tpm/tpm_spapr.c b/hw/tpm/tpm_spapr.c
index ce65eb2..cb4dfd1 100644
--- a/hw/tpm/tpm_spapr.c
+++ b/hw/tpm/tpm_spapr.c
@@ -20,8 +20,8 @@
#include "migration/vmstate.h"
#include "sysemu/tpm_backend.h"
-#include "tpm_int.h"
-#include "tpm_util.h"
+#include "sysemu/tpm_util.h"
+#include "tpm_prop.h"
#include "hw/ppc/spapr.h"
#include "hw/ppc/spapr_vio.h"
diff --git a/hw/tpm/tpm_tis.h b/hw/tpm/tpm_tis.h
index 5554989..f6b5872 100644
--- a/hw/tpm/tpm_tis.h
+++ b/hw/tpm/tpm_tis.h
@@ -24,7 +24,6 @@
#ifndef TPM_TPM_TIS_H
#define TPM_TPM_TIS_H
-#include "qemu/osdep.h"
#include "sysemu/tpm_backend.h"
#include "tpm_ppi.h"
diff --git a/hw/tpm/tpm_tis_common.c b/hw/tpm/tpm_tis_common.c
index 1af4bce..e700d82 100644
--- a/hw/tpm/tpm_tis_common.c
+++ b/hw/tpm/tpm_tis_common.c
@@ -33,8 +33,7 @@
#include "hw/qdev-properties.h"
#include "migration/vmstate.h"
#include "sysemu/tpm_backend.h"
-#include "tpm_int.h"
-#include "tpm_util.h"
+#include "sysemu/tpm_util.h"
#include "tpm_ppi.h"
#include "trace.h"
@@ -79,9 +78,7 @@ static void tpm_tis_sts_set(TPMLocality *l, uint32_t flags)
*/
static void tpm_tis_tpm_send(TPMState *s, uint8_t locty)
{
- if (trace_event_get_state_backends(TRACE_TPM_UTIL_SHOW_BUFFER)) {
- tpm_util_show_buffer(s->buffer, s->be_buffer_size, "To TPM");
- }
+ tpm_util_show_buffer(s->buffer, s->be_buffer_size, "To TPM");
/*
* rw_offset serves as length indicator for length of data;
@@ -247,9 +244,7 @@ void tpm_tis_request_completed(TPMState *s, int ret)
s->loc[locty].state = TPM_TIS_STATE_COMPLETION;
s->rw_offset = 0;
- if (trace_event_get_state_backends(TRACE_TPM_UTIL_SHOW_BUFFER)) {
- tpm_util_show_buffer(s->buffer, s->be_buffer_size, "From TPM");
- }
+ tpm_util_show_buffer(s->buffer, s->be_buffer_size, "From TPM");
if (TPM_TIS_IS_VALID_LOCTY(s->next_locty)) {
tpm_tis_abort(s);
diff --git a/hw/tpm/tpm_tis_isa.c b/hw/tpm/tpm_tis_isa.c
index 30ba370..5faf623 100644
--- a/hw/tpm/tpm_tis_isa.c
+++ b/hw/tpm/tpm_tis_isa.c
@@ -26,7 +26,8 @@
#include "hw/isa/isa.h"
#include "hw/qdev-properties.h"
#include "migration/vmstate.h"
-#include "tpm_util.h"
+#include "hw/acpi/tpm.h"
+#include "tpm_prop.h"
#include "tpm_tis.h"
typedef struct TPMStateISA {
diff --git a/hw/tpm/tpm_tis_sysbus.c b/hw/tpm/tpm_tis_sysbus.c
index eced1fc..4a3bc70 100644
--- a/hw/tpm/tpm_tis_sysbus.c
+++ b/hw/tpm/tpm_tis_sysbus.c
@@ -25,7 +25,8 @@
#include "qemu/osdep.h"
#include "hw/qdev-properties.h"
#include "migration/vmstate.h"
-#include "tpm_util.h"
+#include "hw/acpi/tpm.h"
+#include "tpm_prop.h"
#include "hw/sysbus.h"
#include "tpm_tis.h"
diff --git a/hw/tpm/tpm_util.c b/hw/tpm/tpm_util.c
deleted file mode 100644
index c0a0f3d..0000000
--- a/hw/tpm/tpm_util.c
+++ /dev/null
@@ -1,377 +0,0 @@
-/*
- * TPM utility functions
- *
- * Copyright (c) 2010 - 2015 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/>
- */
-
-#include "qemu/osdep.h"
-#include "qemu/error-report.h"
-#include "qapi/error.h"
-#include "qapi/visitor.h"
-#include "tpm_util.h"
-#include "tpm_int.h"
-#include "exec/memory.h"
-#include "hw/qdev-properties.h"
-#include "sysemu/tpm_backend.h"
-#include "trace.h"
-
-/* tpm backend property */
-
-static void get_tpm(Object *obj, Visitor *v, const char *name, void *opaque,
- Error **errp)
-{
- DeviceState *dev = DEVICE(obj);
- TPMBackend **be = qdev_get_prop_ptr(dev, opaque);
- char *p;
-
- p = g_strdup(*be ? (*be)->id : "");
- visit_type_str(v, name, &p, errp);
- g_free(p);
-}
-
-static void set_tpm(Object *obj, Visitor *v, const char *name, void *opaque,
- Error **errp)
-{
- DeviceState *dev = DEVICE(obj);
- Error *local_err = NULL;
- Property *prop = opaque;
- TPMBackend *s, **be = qdev_get_prop_ptr(dev, prop);
- char *str;
-
- if (dev->realized) {
- qdev_prop_set_after_realize(dev, name, errp);
- return;
- }
-
- visit_type_str(v, name, &str, &local_err);
- if (local_err) {
- error_propagate(errp, local_err);
- return;
- }
-
- s = qemu_find_tpm_be(str);
- if (s == NULL) {
- error_setg(errp, "Property '%s.%s' can't find value '%s'",
- object_get_typename(obj), prop->name, str);
- } else if (tpm_backend_init(s, TPM_IF(obj), errp) == 0) {
- *be = s; /* weak reference, avoid cyclic ref */
- }
- g_free(str);
-}
-
-static void release_tpm(Object *obj, const char *name, void *opaque)
-{
- DeviceState *dev = DEVICE(obj);
- Property *prop = opaque;
- TPMBackend **be = qdev_get_prop_ptr(dev, prop);
-
- if (*be) {
- tpm_backend_reset(*be);
- }
-}
-
-const PropertyInfo qdev_prop_tpm = {
- .name = "str",
- .description = "ID of a tpm to use as a backend",
- .get = get_tpm,
- .set = set_tpm,
- .release = release_tpm,
-};
-
-/*
- * Write an error message in the given output buffer.
- */
-void tpm_util_write_fatal_error_response(uint8_t *out, uint32_t out_len)
-{
- if (out_len >= sizeof(struct tpm_resp_hdr)) {
- tpm_cmd_set_tag(out, TPM_TAG_RSP_COMMAND);
- tpm_cmd_set_size(out, sizeof(struct tpm_resp_hdr));
- tpm_cmd_set_error(out, TPM_FAIL);
- }
-}
-
-bool tpm_util_is_selftest(const uint8_t *in, uint32_t in_len)
-{
- if (in_len >= sizeof(struct tpm_req_hdr)) {
- return tpm_cmd_get_ordinal(in) == TPM_ORD_ContinueSelfTest;
- }
-
- return false;
-}
-
-/*
- * Send request to a TPM device. We expect a response within one second.
- */
-static int tpm_util_request(int fd,
- const void *request,
- size_t requestlen,
- void *response,
- size_t responselen)
-{
- fd_set readfds;
- int n;
- struct timeval tv = {
- .tv_sec = 1,
- .tv_usec = 0,
- };
-
- n = write(fd, request, requestlen);
- if (n < 0) {
- return -errno;
- }
- if (n != requestlen) {
- return -EFAULT;
- }
-
- FD_ZERO(&readfds);
- FD_SET(fd, &readfds);
-
- /* wait for a second */
- n = select(fd + 1, &readfds, NULL, NULL, &tv);
- if (n != 1) {
- return -errno;
- }
-
- n = read(fd, response, responselen);
- if (n < sizeof(struct tpm_resp_hdr)) {
- return -EFAULT;
- }
-
- /* check the header */
- if (tpm_cmd_get_size(response) != n) {
- return -EMSGSIZE;
- }
-
- return 0;
-}
-
-/*
- * A basic test of a TPM device. We expect a well formatted response header
- * (error response is fine).
- */
-static int tpm_util_test(int fd,
- const void *request,
- size_t requestlen,
- uint16_t *return_tag)
-{
- char buf[1024];
- ssize_t ret;
-
- ret = tpm_util_request(fd, request, requestlen,
- buf, sizeof(buf));
- if (ret < 0) {
- return ret;
- }
-
- *return_tag = tpm_cmd_get_tag(buf);
-
- return 0;
-}
-
-/*
- * Probe for the TPM device in the back
- * Returns 0 on success with the version of the probed TPM set, 1 on failure.
- */
-int tpm_util_test_tpmdev(int tpm_fd, TPMVersion *tpm_version)
-{
- /*
- * Sending a TPM1.2 command to a TPM2 should return a TPM1.2
- * header (tag = 0xc4) and error code (TPM_BADTAG = 0x1e)
- *
- * Sending a TPM2 command to a TPM 2 will give a TPM 2 tag in the
- * header.
- * Sending a TPM2 command to a TPM 1.2 will give a TPM 1.2 tag
- * in the header and an error code.
- */
- const struct tpm_req_hdr test_req = {
- .tag = cpu_to_be16(TPM_TAG_RQU_COMMAND),
- .len = cpu_to_be32(sizeof(test_req)),
- .ordinal = cpu_to_be32(TPM_ORD_GetTicks),
- };
-
- const struct tpm_req_hdr test_req_tpm2 = {
- .tag = cpu_to_be16(TPM2_ST_NO_SESSIONS),
- .len = cpu_to_be32(sizeof(test_req_tpm2)),
- .ordinal = cpu_to_be32(TPM2_CC_ReadClock),
- };
- uint16_t return_tag;
- int ret;
-
- /* Send TPM 2 command */
- ret = tpm_util_test(tpm_fd, &test_req_tpm2,
- sizeof(test_req_tpm2), &return_tag);
- /* TPM 2 would respond with a tag of TPM2_ST_NO_SESSIONS */
- if (!ret && return_tag == TPM2_ST_NO_SESSIONS) {
- *tpm_version = TPM_VERSION_2_0;
- return 0;
- }
-
- /* Send TPM 1.2 command */
- ret = tpm_util_test(tpm_fd, &test_req,
- sizeof(test_req), &return_tag);
- if (!ret && return_tag == TPM_TAG_RSP_COMMAND) {
- *tpm_version = TPM_VERSION_1_2;
- /* this is a TPM 1.2 */
- return 0;
- }
-
- *tpm_version = TPM_VERSION_UNSPEC;
-
- return 1;
-}
-
-int tpm_util_get_buffer_size(int tpm_fd, TPMVersion tpm_version,
- size_t *buffersize)
-{
- int ret;
-
- switch (tpm_version) {
- case TPM_VERSION_1_2: {
- const struct tpm_req_get_buffer_size {
- struct tpm_req_hdr hdr;
- uint32_t capability;
- uint32_t len;
- uint32_t subcap;
- } QEMU_PACKED tpm_get_buffer_size = {
- .hdr = {
- .tag = cpu_to_be16(TPM_TAG_RQU_COMMAND),
- .len = cpu_to_be32(sizeof(tpm_get_buffer_size)),
- .ordinal = cpu_to_be32(TPM_ORD_GetCapability),
- },
- .capability = cpu_to_be32(TPM_CAP_PROPERTY),
- .len = cpu_to_be32(sizeof(uint32_t)),
- .subcap = cpu_to_be32(TPM_CAP_PROP_INPUT_BUFFER),
- };
- struct tpm_resp_get_buffer_size {
- struct tpm_resp_hdr hdr;
- uint32_t len;
- uint32_t buffersize;
- } QEMU_PACKED tpm_resp;
-
- ret = tpm_util_request(tpm_fd, &tpm_get_buffer_size,
- sizeof(tpm_get_buffer_size),
- &tpm_resp, sizeof(tpm_resp));
- if (ret < 0) {
- return ret;
- }
-
- if (be32_to_cpu(tpm_resp.hdr.len) != sizeof(tpm_resp) ||
- be32_to_cpu(tpm_resp.len) != sizeof(uint32_t)) {
- trace_tpm_util_get_buffer_size_hdr_len(
- be32_to_cpu(tpm_resp.hdr.len),
- sizeof(tpm_resp));
- trace_tpm_util_get_buffer_size_len(be32_to_cpu(tpm_resp.len),
- sizeof(uint32_t));
- error_report("tpm_util: Got unexpected response to "
- "TPM_GetCapability; errcode: 0x%x",
- be32_to_cpu(tpm_resp.hdr.errcode));
- return -EFAULT;
- }
- *buffersize = be32_to_cpu(tpm_resp.buffersize);
- break;
- }
- case TPM_VERSION_2_0: {
- const struct tpm2_req_get_buffer_size {
- struct tpm_req_hdr hdr;
- uint32_t capability;
- uint32_t property;
- uint32_t count;
- } QEMU_PACKED tpm2_get_buffer_size = {
- .hdr = {
- .tag = cpu_to_be16(TPM2_ST_NO_SESSIONS),
- .len = cpu_to_be32(sizeof(tpm2_get_buffer_size)),
- .ordinal = cpu_to_be32(TPM2_CC_GetCapability),
- },
- .capability = cpu_to_be32(TPM2_CAP_TPM_PROPERTIES),
- .property = cpu_to_be32(TPM2_PT_MAX_COMMAND_SIZE),
- .count = cpu_to_be32(2), /* also get TPM2_PT_MAX_RESPONSE_SIZE */
- };
- struct tpm2_resp_get_buffer_size {
- struct tpm_resp_hdr hdr;
- uint8_t more;
- uint32_t capability;
- uint32_t count;
- uint32_t property1;
- uint32_t value1;
- uint32_t property2;
- uint32_t value2;
- } QEMU_PACKED tpm2_resp;
-
- ret = tpm_util_request(tpm_fd, &tpm2_get_buffer_size,
- sizeof(tpm2_get_buffer_size),
- &tpm2_resp, sizeof(tpm2_resp));
- if (ret < 0) {
- return ret;
- }
-
- if (be32_to_cpu(tpm2_resp.hdr.len) != sizeof(tpm2_resp) ||
- be32_to_cpu(tpm2_resp.count) != 2) {
- trace_tpm_util_get_buffer_size_hdr_len2(
- be32_to_cpu(tpm2_resp.hdr.len),
- sizeof(tpm2_resp));
- trace_tpm_util_get_buffer_size_len2(
- be32_to_cpu(tpm2_resp.count), 2);
- error_report("tpm_util: Got unexpected response to "
- "TPM2_GetCapability; errcode: 0x%x",
- be32_to_cpu(tpm2_resp.hdr.errcode));
- return -EFAULT;
- }
- *buffersize = MAX(be32_to_cpu(tpm2_resp.value1),
- be32_to_cpu(tpm2_resp.value2));
- break;
- }
- case TPM_VERSION_UNSPEC:
- return -EFAULT;
- }
-
- trace_tpm_util_get_buffer_size(*buffersize);
-
- return 0;
-}
-
-void tpm_sized_buffer_reset(TPMSizedBuffer *tsb)
-{
- g_free(tsb->buffer);
- tsb->buffer = NULL;
- tsb->size = 0;
-}
-
-void tpm_util_show_buffer(const unsigned char *buffer,
- size_t buffer_size, const char *string)
-{
- size_t len, i;
- char *line_buffer, *p;
-
- len = MIN(tpm_cmd_get_size(buffer), buffer_size);
-
- /*
- * allocate enough room for 3 chars per buffer entry plus a
- * newline after every 16 chars and a final null terminator.
- */
- line_buffer = g_malloc(len * 3 + (len / 16) + 1);
-
- for (i = 0, p = line_buffer; i < len; i++) {
- if (i && !(i % 16)) {
- p += sprintf(p, "\n");
- }
- p += sprintf(p, "%.2X ", buffer[i]);
- }
- trace_tpm_util_show_buffer(string, len, line_buffer);
-
- g_free(line_buffer);
-}
diff --git a/hw/tpm/tpm_util.h b/hw/tpm/tpm_util.h
deleted file mode 100644
index 7889081..0000000
--- a/hw/tpm/tpm_util.h
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * TPM utility functions
- *
- * Copyright (c) 2010 - 2015 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_TPM_UTIL_H
-#define TPM_TPM_UTIL_H
-
-#include "sysemu/tpm.h"
-#include "qemu/bswap.h"
-
-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);
-
-int tpm_util_test_tpmdev(int tpm_fd, TPMVersion *tpm_version);
-
-static inline uint16_t tpm_cmd_get_tag(const void *b)
-{
- return lduw_be_p(b);
-}
-
-static inline void tpm_cmd_set_tag(void *b, uint16_t tag)
-{
- stw_be_p(b, tag);
-}
-
-static inline uint32_t tpm_cmd_get_size(const void *b)
-{
- return ldl_be_p(b + 2);
-}
-
-static inline void tpm_cmd_set_size(void *b, uint32_t size)
-{
- stl_be_p(b + 2, size);
-}
-
-static inline uint32_t tpm_cmd_get_ordinal(const void *b)
-{
- return ldl_be_p(b + 6);
-}
-
-static inline uint32_t tpm_cmd_get_errcode(const void *b)
-{
- return ldl_be_p(b + 6);
-}
-
-static inline void tpm_cmd_set_error(void *b, uint32_t error)
-{
- stl_be_p(b + 6, error);
-}
-
-int tpm_util_get_buffer_size(int tpm_fd, TPMVersion tpm_version,
- size_t *buffersize);
-
-#define DEFINE_PROP_TPMBE(_n, _s, _f) \
- DEFINE_PROP(_n, _s, _f, qdev_prop_tpm, TPMBackend *)
-
-typedef struct TPMSizedBuffer {
- uint32_t size;
- uint8_t *buffer;
-} TPMSizedBuffer;
-
-void tpm_sized_buffer_reset(TPMSizedBuffer *tsb);
-
-void tpm_util_show_buffer(const unsigned char *buffer,
- size_t buffer_size, const char *string);
-
-#endif /* TPM_TPM_UTIL_H */
diff --git a/hw/tpm/trace-events b/hw/tpm/trace-events
index 439e514..de9bf1e 100644
--- a/hw/tpm/trace-events
+++ b/hw/tpm/trace-events
@@ -4,38 +4,6 @@
tpm_crb_mmio_read(uint64_t addr, unsigned size, uint32_t val) "CRB read 0x%016" PRIx64 " len:%u val: 0x%" PRIx32
tpm_crb_mmio_write(uint64_t addr, unsigned size, uint32_t val) "CRB write 0x%016" PRIx64 " len:%u val: 0x%" PRIx32
-# tpm_passthrough.c
-tpm_passthrough_handle_request(void *cmd) "processing command %p"
-tpm_passthrough_reset(void) "reset"
-
-# tpm_util.c
-tpm_util_get_buffer_size_hdr_len(uint32_t len, size_t expected) "tpm_resp->hdr.len = %u, expected = %zu"
-tpm_util_get_buffer_size_len(uint32_t len, size_t expected) "tpm_resp->len = %u, expected = %zu"
-tpm_util_get_buffer_size_hdr_len2(uint32_t len, size_t expected) "tpm2_resp->hdr.len = %u, expected = %zu"
-tpm_util_get_buffer_size_len2(uint32_t len, size_t expected) "tpm2_resp->len = %u, expected = %zu"
-tpm_util_get_buffer_size(size_t len) "buffersize of device: %zu"
-tpm_util_show_buffer(const char *direction, size_t len, const char *buf) "direction: %s len: %zu\n%s"
-
-# tpm_emulator.c
-tpm_emulator_set_locality(uint8_t locty) "setting locality to %d"
-tpm_emulator_handle_request(void) "processing TPM command"
-tpm_emulator_probe_caps(uint64_t caps) "capabilities: 0x%"PRIx64
-tpm_emulator_set_buffer_size(uint32_t buffersize, uint32_t minsize, uint32_t maxsize) "buffer size: %u, min: %u, max: %u"
-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_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"
-tpm_emulator_handle_device_opts_startup_error(void) "Startup error"
-tpm_emulator_get_state_blob(uint8_t type, uint32_t size, uint32_t flags) "got state blob type %d, %u bytes, flags 0x%08x"
-tpm_emulator_set_state_blob(uint8_t type, uint32_t size, uint32_t flags) "set state blob type %d, %u bytes, flags 0x%08x"
-tpm_emulator_set_state_blobs(void) "setting state blobs"
-tpm_emulator_set_state_blobs_error(const char *msg) "error while setting state blobs: %s"
-tpm_emulator_set_state_blobs_done(void) "Done setting state blobs"
-tpm_emulator_pre_save(void) ""
-tpm_emulator_inst_init(void) ""
-
# tpm_tis.c
tpm_tis_raise_irq(uint32_t irqmask) "Raising IRQ for flag 0x%08x"
tpm_tis_new_active_locality(uint8_t locty) "Active locality is now %d"
@@ -56,7 +24,7 @@ tpm_tis_pre_save(uint8_t locty, uint32_t rw_offset) "locty: %d, rw_offset = %u"
# tpm_ppi.c
tpm_ppi_memset(uint8_t *ptr, size_t size) "memset: %p %zu"
-# hw/tpm/tpm_spapr.c
+# tpm_spapr.c
tpm_spapr_show_buffer(const char *direction, size_t len, const char *buf) "direction: %s len: %zu\n%s"
tpm_spapr_do_crq(uint8_t raw1, uint8_t raw2) "1st 2 bytes in CRQ: 0x%02x 0x%02x"
tpm_spapr_do_crq_crq_result(void) "SPAPR_VTPM_INIT_CRQ_RESULT"