[prev in list] [next in list] [prev in thread] [next in thread] 

List:       qemu-devel
Subject:    Re: [PATCH v10 2/2] tpm: add backend for mssim
From:       Stefan Berger <stefanb () linux ! ibm ! com>
Date:       2024-04-30 21:12:46
Message-ID: 2825c9bb-a4d5-4196-b025-5f46571b3953 () linux ! ibm ! com
[Download RAW message or body]



On 4/30/24 15:08, James Bottomley wrote:
> The Microsoft Simulator (mssim) is the reference emulation platform
> for the TCG TPM 2.0 specification.
> 
> https://github.com/Microsoft/ms-tpm-20-ref.git
> 
> It exports a fairly simple network socket based protocol on two
> sockets, one for command (default 2321) and one for control (default
> 2322).  This patch adds a simple backend that can speak the mssim
> protocol over the network.  It also allows the two sockets to be
> specified on the command line.  The benefits are twofold: firstly it
> gives us a backend that actually speaks a standard TPM emulation
> protocol instead of the linux specific TPM driver format of the
> current emulated TPM backend and secondly, using the microsoft
> protocol, the end point of the emulator can be anywhere on the
> network, facilitating the cloud use case where a central TPM service
> can be used over a control network.
> 
> The implementation does basic control commands like power off/on, but
> doesn't implement cancellation or startup.  The former because
> cancellation is pretty much useless on a fast operating TPM emulator
> and the latter because this emulator is designed to be used with OVMF
> which itself does TPM startup and I wanted to validate that.
> 
> To run this, simply download an emulator based on the MS specification
> (package ibmswtpm2 on openSUSE) and run it, then add these two lines
> to the qemu command and it will use the emulator.
> 
> -tpmdev mssim,id=tpm0 \
> -device tpm-crb,tpmdev=tpm0 \
> 
> to use a remote emulator replace the first line with
> 
> -tpmdev "{'type':'mssim','id':'tpm0','command':{'type':inet,'host':'remote','port':'2321'}}"
>  
> tpm-tis also works as the backend.
> 
> Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
> Acked-by: Markus Armbruster <armbru@redhat.com>
> 
> ---
> 
> v2: convert to SocketAddr json and use qio_channel_socket_connect_sync()
> v3: gate control power off by migration state keep control socket disconnected
> to test outside influence and add docs.
> v7: TPMmssim -> TPMMssim; doc and json fixes
> Make command socket open each time (makes OS debugging easier)
> ---
> MAINTAINERS              |   6 +
> backends/tpm/Kconfig     |   5 +
> backends/tpm/meson.build |   1 +
> backends/tpm/tpm_mssim.c | 319 +++++++++++++++++++++++++++++++++++++++
> backends/tpm/tpm_mssim.h |  44 ++++++
> docs/specs/tpm.rst       |  39 +++++
> qapi/tpm.json            |  31 +++-
> system/tpm-hmp-cmds.c    |   9 ++
> 8 files changed, 450 insertions(+), 4 deletions(-)
> create mode 100644 backends/tpm/tpm_mssim.c
> create mode 100644 backends/tpm/tpm_mssim.h
> 
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 302b6fd00c..6bd7e82d1b 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -3386,10 +3386,16 @@ F: include/hw/acpi/tpm.h
> F: include/sysemu/tpm*
> F: qapi/tpm.json
> F: backends/tpm/
> +X: backends/tpm/tpm_mssim.*
> F: tests/qtest/*tpm*
> F: docs/specs/tpm.rst
> T: git https://github.com/stefanberger/qemu-tpm.git tpm-next
> 
> +MSSIM TPM Backend
> +M: James Bottomley <jejb@linux.ibm.com>
> +S: Maintained
> +F: backends/tpm/tpm_mssim.*
> +
> Checkpatch
> S: Odd Fixes
> F: scripts/checkpatch.pl
> diff --git a/backends/tpm/Kconfig b/backends/tpm/Kconfig
> index 5d91eb89c2..d6d6fa53e9 100644
> --- a/backends/tpm/Kconfig
> +++ b/backends/tpm/Kconfig
> @@ -12,3 +12,8 @@ config TPM_EMULATOR
> bool
> default y
> depends on TPM_BACKEND
> +
> +config TPM_MSSIM
> +    bool
> +    default y
> +    depends on TPM_BACKEND
> diff --git a/backends/tpm/meson.build b/backends/tpm/meson.build
> index 0bfa6c422b..c6f7c24cb1 100644
> --- a/backends/tpm/meson.build
> +++ b/backends/tpm/meson.build
> @@ -3,4 +3,5 @@ if have_tpm
> system_ss.add(files('tpm_util.c'))
> system_ss.add(when: 'CONFIG_TPM_PASSTHROUGH', if_true: files('tpm_passthrough.c'))
> system_ss.add(when: 'CONFIG_TPM_EMULATOR', if_true: files('tpm_emulator.c'))
> +  system_ss.add(when: 'CONFIG_TPM_MSSIM', if_true: files('tpm_mssim.c'))
> endif
> diff --git a/backends/tpm/tpm_mssim.c b/backends/tpm/tpm_mssim.c
> new file mode 100644
> index 0000000000..962ad340c3
> --- /dev/null
> +++ b/backends/tpm/tpm_mssim.c
> @@ -0,0 +1,319 @@
> +/*
> + * Emulator TPM driver which connects over the mssim protocol
> + * SPDX-License-Identifier: GPL-2.0-or-later
> + *
> + * Copyright (c) 2022
> + * Author: James Bottomley <jejb@linux.ibm.com>
> + */
> +
> +#include "qemu/osdep.h"
> +#include "qemu/error-report.h"
> +#include "qemu/sockets.h"
> +
> +#include "qapi/clone-visitor.h"
> +#include "qapi/qapi-visit-tpm.h"
> +
> +#include "io/channel-socket.h"
> +
> +#include "sysemu/runstate.h"
> +#include "sysemu/tpm_backend.h"
> +#include "sysemu/tpm_util.h"
> +
> +#include "qom/object.h"
> +
> +#include "tpm_int.h"
> +#include "tpm_mssim.h"
> +
> +#define ERROR_PREFIX "TPM mssim Emulator: "
> +
> +#define TYPE_TPM_MSSIM "tpm-mssim"
> +OBJECT_DECLARE_SIMPLE_TYPE(TPMMssim, TPM_MSSIM)
> +
> +struct TPMMssim {
> +    TPMBackend parent;
> +
> +    TPMMssimOptions opts;
> +
> +    QIOChannelSocket *cmd_qc, *ctrl_qc;
> +};
> +
> +static int tpm_send_ctrl(TPMMssim *t, uint32_t cmd, Error **errp)
> +{
> +    int ret, retc;
> +    Error *local_err = NULL;
> +
> +    ret = qio_channel_socket_connect_sync(t->ctrl_qc, t->opts.control, errp);
> +    if (ret != 0) {
> +        return ret;
> +    }
> +    cmd = htonl(cmd);
> +    ret = qio_channel_write_all(QIO_CHANNEL(t->ctrl_qc),
> +                                (char *)&cmd, sizeof(cmd), errp);
> +    if (ret != 0) {
> +        goto out;
> +    }
> +
> +    ret = qio_channel_read_all(QIO_CHANNEL(t->ctrl_qc),
> +                               (char *)&cmd, sizeof(cmd), errp);
> +    if (ret != 0) {
> +        goto out;
> +    }
> +    if (cmd != 0) {
> +        error_setg(errp, ERROR_PREFIX
> +                   "Incorrect ACK recieved on control channel 0x%x", cmd);
> +        ret = -1;
> +    }
> + out:
> +    /*
> +     * need to close the channel here, but if that fails report it
> +     * while not letting a prior failure get overwritten
> +     */
> +    retc = qio_channel_close(QIO_CHANNEL(t->ctrl_qc), &local_err);
> +    error_propagate(errp, local_err);
> +    return retc ? retc : ret;
> +}
> +
> +static void tpm_mssim_instance_init(Object *obj)
> +{
> +}
> +
> +static void tpm_mssim_instance_finalize(Object *obj)
> +{
> +    TPMMssim *t = TPM_MSSIM(obj);
> +
> +    if (t->cmd_qc && !runstate_check(RUN_STATE_POSTMIGRATE)) {
> +        Error *errp = NULL;
> +        int ret;
> +
> +        ret = tpm_send_ctrl(t, TPM_SIGNAL_POWER_OFF, &errp);
> +        if (ret != 0) {
> +            error_report_err(errp);
> +        }
> +    }
> +
> +    object_unref(OBJECT(t->ctrl_qc));
> +    object_unref(OBJECT(t->cmd_qc));
> +}
> +
> +static void tpm_mssim_cancel_cmd(TPMBackend *tb)
> +{
> +        return;
> +}
> +
> +static TPMVersion tpm_mssim_get_version(TPMBackend *tb)
> +{
> +    return TPM_VERSION_2_0;
> +}
> +
> +static size_t tpm_mssim_get_buffer_size(TPMBackend *tb)
> +{
> +    /* TCG standard profile max buffer size */
> +    return 4096;
> +}
> +
> +static TpmTypeOptions *tpm_mssim_get_opts(TPMBackend *tb)
> +{
> +    TPMMssim *t = TPM_MSSIM(tb);
> +    TpmTypeOptions *opts = g_new0(TpmTypeOptions, 1);
> +
> +    opts->type = TPM_TYPE_MSSIM;
> +    QAPI_CLONE_MEMBERS(TPMMssimOptions, &opts->u.mssim, &t->opts);
> +
> +    return opts;
> +}
> +
> +static void tpm_mssim_handle_request(TPMBackend *tb, TPMBackendCmd *cmd,
> +                                     Error **errp)
> +{
> +    TPMMssim *t = TPM_MSSIM(tb);
> +    uint32_t header, len;
> +    uint8_t locality = cmd->locty;
> +    struct iovec iov[4];
> +    int ret;
> +
> +    ret = qio_channel_socket_connect_sync(t->cmd_qc, t->opts.command, errp);
> +    if (ret != 0) {
> +        goto fail_msg;
> +    }
> +
> +    header = htonl(TPM_SEND_COMMAND);
> +    len = htonl(cmd->in_len);
> +
> +    iov[0].iov_base = &header;
> +    iov[0].iov_len = sizeof(header);
> +    iov[1].iov_base = &locality;
> +    iov[1].iov_len = sizeof(locality);
> +    iov[2].iov_base = &len;
> +    iov[2].iov_len = sizeof(len);
> +    iov[3].iov_base = (void *)cmd->in;
> +    iov[3].iov_len = cmd->in_len;
> +
> +    ret = qio_channel_writev_all(QIO_CHANNEL(t->cmd_qc), iov, 4, errp);
> +    if (ret != 0) {
> +        goto fail;
> +    }
> +
> +    ret = qio_channel_read_all(QIO_CHANNEL(t->cmd_qc),
> +                               (char *)&len, sizeof(len), errp);
> +    if (ret != 0) {
> +        goto fail;
> +    }
> +
> +    len = ntohl(len);
> +    if (len > cmd->out_len) {
> +        error_setg(errp, "receive size is too large");
> +        goto fail;
> +    }
> +    ret = qio_channel_read_all(QIO_CHANNEL(t->cmd_qc),
> +                               (char *)cmd->out, len, errp);
> +    if (ret != 0) {
> +        goto fail;
> +    }
> +
> +    /* ACK packet */
> +    ret = qio_channel_read_all(QIO_CHANNEL(t->cmd_qc),
> +                               (char *)&header, sizeof(header), errp);
> +    if (ret != 0) {
> +        goto fail;
> +    }
> +    if (header != 0) {
> +        error_setg(errp, "incorrect ACK received on command channel 0x%x", len);
> +        goto fail;
> +    }
> +
> +    ret = qio_channel_close(QIO_CHANNEL(t->cmd_qc), errp);
> +    if (ret != 0) {
> +        goto fail_msg;
> +    }
> +
> +    return;
> +
> + fail:
> +    /* we're already failing, so don't worry if this fails too */
> +    qio_channel_close(QIO_CHANNEL(t->cmd_qc), NULL);
> + fail_msg:
> +    error_prepend(errp, ERROR_PREFIX);
> +    tpm_util_write_fatal_error_response(cmd->out, cmd->out_len);
> +}
> +
> +static TPMBackend *tpm_mssim_create(TpmCreateOptions *opts)
> +{
> +    TPMBackend *be = TPM_BACKEND(object_new(TYPE_TPM_MSSIM));
> +    TPMMssim *t = TPM_MSSIM(be);
> +    int ret;
> +    Error *errp = NULL;
> +    TPMMssimOptions *mo = &opts->u.mssim;
> +
> +    if (!mo->command) {
> +            mo->command = g_new0(SocketAddress, 1);
> +            mo->command->type = SOCKET_ADDRESS_TYPE_INET;
> +            mo->command->u.inet.host = g_strdup("localhost");
> +            mo->command->u.inet.port = g_strdup("2321");
> +    }
> +    if (!mo->control) {
> +            int port;
> +
> +            mo->control = g_new0(SocketAddress, 1);
> +            mo->control->type = SOCKET_ADDRESS_TYPE_INET;
> +            mo->control->u.inet.host = g_strdup(mo->command->u.inet.host);
> +            /*
> +             * in the reference implementation, the control port is
> +             * always one above the command port
> +             */
> +            port = atoi(mo->command->u.inet.port) + 1;
> +            mo->control->u.inet.port = g_strdup_printf("%d", port);
> +    }
> +
> +    QAPI_CLONE_MEMBERS(TPMMssimOptions, &t->opts, &opts->u.mssim);
> +    t->cmd_qc = qio_channel_socket_new();
> +    t->ctrl_qc = qio_channel_socket_new();
> +
> +    if (qio_channel_socket_connect_sync(t->cmd_qc, mo->command, &errp) < 0) {
> +        goto fail;
> +    }
> +
> +    if (qio_channel_socket_connect_sync(t->ctrl_qc, mo->control, &errp) < 0) {
> +        goto fail;
> +    }
> +    qio_channel_close(QIO_CHANNEL(t->ctrl_qc), NULL);
> +    qio_channel_close(QIO_CHANNEL(t->cmd_qc), NULL);
> +
> +    if (!runstate_check(RUN_STATE_INMIGRATE)) {
> +        /*
> +         * reset the TPM using a power cycle sequence, in case someone
> +         * has previously powered it up
> +         */
> +        ret = tpm_send_ctrl(t, TPM_SIGNAL_POWER_OFF, &errp);
> +        if (ret != 0) {
> +            goto fail;
> +        }
> +
> +        ret = tpm_send_ctrl(t, TPM_SIGNAL_POWER_ON, &errp);
> +        if (ret != 0) {
> +            goto fail;
> +        }
> +
> +        ret = tpm_send_ctrl(t, TPM_SIGNAL_NV_ON, &errp);
> +        if (ret != 0) {
> +            goto fail;
> +        }
> +    }
> +
> +    return be;
> +
> + fail:
> +    object_unref(OBJECT(t->ctrl_qc));
> +    object_unref(OBJECT(t->cmd_qc));
> +    t->ctrl_qc = NULL;
> +    t->cmd_qc = NULL;
> +    error_prepend(&errp, ERROR_PREFIX);
> +    error_report_err(errp);
> +    object_unref(OBJECT(be));
> +
> +    return NULL;
> +}
> +
> +static const QemuOptDesc tpm_mssim_cmdline_opts[] = {
> +    TPM_STANDARD_CMDLINE_OPTS,
> +    {
> +        .name = "command",
> +        .type = QEMU_OPT_STRING,
> +        .help = "Command socket (default localhost:2321)",
> +    },
> +    {
> +        .name = "control",
> +        .type = QEMU_OPT_STRING,
> +        .help = "control socket (default localhost:2322)",
> +    },
> +};
> +
> +static void tpm_mssim_class_init(ObjectClass *klass, void *data)
> +{
> +    TPMBackendClass *cl = TPM_BACKEND_CLASS(klass);
> +
> +    cl->type = TPM_TYPE_MSSIM;
> +    cl->opts = tpm_mssim_cmdline_opts;
> +    cl->desc = "TPM mssim emulator backend driver";
> +    cl->create = tpm_mssim_create;
> +    cl->cancel_cmd = tpm_mssim_cancel_cmd;
> +    cl->get_tpm_version = tpm_mssim_get_version;
> +    cl->get_buffer_size = tpm_mssim_get_buffer_size;
> +    cl->get_tpm_options = tpm_mssim_get_opts;
> +    cl->handle_request = tpm_mssim_handle_request;
> +}
> +
> +static const TypeInfo tpm_mssim_info = {
> +    .name = TYPE_TPM_MSSIM,
> +    .parent = TYPE_TPM_BACKEND,
> +    .instance_size = sizeof(TPMMssim),
> +    .class_init = tpm_mssim_class_init,
> +    .instance_init = tpm_mssim_instance_init,
> +    .instance_finalize = tpm_mssim_instance_finalize,
> +};
> +
> +static void tpm_mssim_register(void)
> +{
> +    type_register_static(&tpm_mssim_info);
> +}
> +
> +type_init(tpm_mssim_register)
> diff --git a/backends/tpm/tpm_mssim.h b/backends/tpm/tpm_mssim.h
> new file mode 100644
> index 0000000000..397474e4f6
> --- /dev/null
> +++ b/backends/tpm/tpm_mssim.h
> @@ -0,0 +1,44 @@
> +/*
> + * SPDX-License-Identifier: BSD-2-Clause
> + *
> + * The code below is copied from the Microsoft/TCG Reference implementation
> + *
> + *  https://github.com/Microsoft/ms-tpm-20-ref.git
> + *
> + * In file TPMCmd/Simulator/include/TpmTcpProtocol.h
> + */
> +
> +#define TPM_SIGNAL_POWER_ON         1
> +#define TPM_SIGNAL_POWER_OFF        2
> +#define TPM_SIGNAL_PHYS_PRES_ON     3
> +#define TPM_SIGNAL_PHYS_PRES_OFF    4
> +#define TPM_SIGNAL_HASH_START       5
> +#define TPM_SIGNAL_HASH_DATA        6
> +/* {uint32_t BufferSize, uint8_t[BufferSize] Buffer} */
> +#define TPM_SIGNAL_HASH_END         7
> +#define TPM_SEND_COMMAND            8
> +/*
> + * {uint8_t Locality, uint32_t InBufferSize, uint8_t[InBufferSize] InBuffer} ->
> + *   {uint32_t OutBufferSize, uint8_t[OutBufferSize] OutBuffer}
> + */
> +#define TPM_SIGNAL_CANCEL_ON        9
> +#define TPM_SIGNAL_CANCEL_OFF       10
> +#define TPM_SIGNAL_NV_ON            11
> +#define TPM_SIGNAL_NV_OFF           12
> +#define TPM_SIGNAL_KEY_CACHE_ON     13
> +#define TPM_SIGNAL_KEY_CACHE_OFF    14
> +
> +#define TPM_REMOTE_HANDSHAKE        15
> +#define TPM_SET_ALTERNATIVE_RESULT  16
> +
> +#define TPM_SIGNAL_RESET            17
> +#define TPM_SIGNAL_RESTART          18
> +
> +#define TPM_SESSION_END             20
> +#define TPM_STOP                    21
> +
> +#define TPM_GET_COMMAND_RESPONSE_SIZES  25
> +
> +#define TPM_ACT_GET_SIGNALED        26
> +
> +#define TPM_TEST_FAILURE_MODE       30
> diff --git a/docs/specs/tpm.rst b/docs/specs/tpm.rst
> index 68cb8cf7e6..051a5c041a 100644
> --- a/docs/specs/tpm.rst
> +++ b/docs/specs/tpm.rst
> @@ -276,6 +276,42 @@ available as a module (assuming a TPM 2 is passed through):
> /sys/devices/LNXSYSTEM:00/LNXSYBUS:00/MSFT0101:00/tpm/tpm0/pcr-sha256/9
> ...
> 
> +The QEMU TPM Microsoft Simulator Device
> +---------------------------------------
> +
> +The Microsoft Simulator (mssim) is the reference emulation platform
> +for the TCG TPM 2.0 specification.  It provides a reference
> +implementation for the TPM 2.0 written by Microsoft (See
> +`ms-tpm-20-ref`_ on github).  The reference implementation starts a
> +network server and listens for TPM commands on port 2321 and TPM
> +Platform control commands on port 2322, although these can be altered.
> +The QEMU mssim TPM backend talks to this implementation.  By default
> +it connects to the default ports on localhost:
> +
> +.. code-block:: console
> +
> +  qemu-system-x86_64 <qemu-options> \
> +    -tpmdev mssim,id=tpm0 \
> +    -device tpm-crb,tpmdev=tpm0
> +
> +
> +Although it can also communicate with a remote host, which must be
> +specified as a SocketAddress via json or dotted keys on the command
> +line for each of the command and control ports:
> +
> +.. code-block:: console
> +
> +  qemu-system-x86_64 <qemu-options> \
> +    -tpmdev "{'type':'mssim','id':'tpm0','command':{'type':'inet','host':'remote','port':'2321'},'control':{'type':'inet','host':'remote','port':'2322'}}" \
> \ +    -device tpm-crb,tpmdev=tpm0
> +
> +
> +The mssim backend supports snapshotting and migration by not resetting

I don't thing snapshotting is supported because snapshooting would 
require you to be able to set the state of the vTPM from the snapshot 
you started. I would remove the claim.


Rest LGTM.

> +the TPM on start up and not powering it down on halt if the VM is in
> +migration, but the state of the Microsoft Simulator server must be
> +preserved (or the server kept running) outside of QEMU for restore to
> +be successful.
> +
> The QEMU TPM emulator device
> ----------------------------
> 
> @@ -549,3 +585,6 @@ the following:
> 
> .. _SWTPM protocol:
> https://github.com/stefanberger/swtpm/blob/master/man/man3/swtpm_ioctls.pod
> +
> +.. _ms-tpm-20-ref:
> +   https://github.com/microsoft/ms-tpm-20-ref
> diff --git a/qapi/tpm.json b/qapi/tpm.json
> index 5604553b7d..0532d3ba3d 100644
> --- a/qapi/tpm.json
> +++ b/qapi/tpm.json
> @@ -6,6 +6,8 @@
> # = TPM (trusted platform module) devices
> ##
> 
> +{ 'include': 'sockets.json' }
> +
> ##
> # @TpmModel:
> #
> @@ -48,9 +50,11 @@
> #
> # @emulator: Software Emulator TPM type (since 2.11)
> #
> +# @mssim: Microsoft TPM Emulator (since 9.0)
> +#
> # Since: 1.5
> ##
> -{ 'enum': 'TpmType', 'data': [ 'passthrough', 'emulator' ],
> +{ 'enum': 'TpmType', 'data': [ 'passthrough', 'emulator', 'mssim' ],
> 'if': 'CONFIG_TPM' }
> 
> ##
> @@ -65,7 +69,7 @@
> # Example:
> #
> #     -> { "execute": "query-tpm-types" }
> -#     <- { "return": [ "passthrough", "emulator" ] }
> +#     <- { "return": [ "passthrough", "emulator", "mssim" ] }
> ##
> { 'command': 'query-tpm-types', 'returns': ['TpmType'],
> 'if': 'CONFIG_TPM' }
> @@ -121,6 +125,22 @@
> 'data': { 'data': 'TPMEmulatorOptions' },
> 'if': 'CONFIG_TPM' }
> 
> +##
> +# @TPMMssimOptions:
> +#
> +# Information for the mssim emulator connection
> +#
> +# @command: command socket for the TPM emulator
> +#
> +# @control: control socket for the TPM emulator
> +#
> +# Since: 9.0
> +##
> +{ 'struct': 'TPMMssimOptions',
> +  'data': { '*command': 'SocketAddress',
> +            '*control': 'SocketAddress' },
> +  'if': 'CONFIG_TPM' }
> +
> ##
> # @TpmTypeOptions:
> #
> @@ -132,6 +152,7 @@
> #       passthrough type
> #     - 'emulator' The configuration options for TPM emulator backend
> #       type
> +#     - 'mssim' The configuration options for TPM emulator mssim type
> #
> # Since: 1.5
> ##
> @@ -139,7 +160,8 @@
> 'base': { 'type': 'TpmType' },
> 'discriminator': 'type',
> 'data': { 'passthrough' : 'TPMPassthroughOptionsWrapper',
> -            'emulator': 'TPMEmulatorOptionsWrapper' },
> +            'emulator': 'TPMEmulatorOptionsWrapper',
> +            'mssim' : 'TPMMssimOptions' },
> 'if': 'CONFIG_TPM' }
> 
> ##
> @@ -160,7 +182,8 @@
> 'id' : 'str' },
> 'discriminator': 'type',
> 'data': { 'passthrough' : 'TPMPassthroughOptions',
> -            'emulator': 'TPMEmulatorOptions' },
> +            'emulator': 'TPMEmulatorOptions',
> +            'mssim': 'TPMMssimOptions' },
> 'if': 'CONFIG_TPM' }
> 
> ##
> diff --git a/system/tpm-hmp-cmds.c b/system/tpm-hmp-cmds.c
> index 9ed6ad6c4d..12293f86c1 100644
> --- a/system/tpm-hmp-cmds.c
> +++ b/system/tpm-hmp-cmds.c
> @@ -19,6 +19,7 @@ void hmp_info_tpm(Monitor *mon, const QDict *qdict)
> unsigned int c = 0;
> TPMPassthroughOptions *tpo;
> TPMEmulatorOptions *teo;
> +    TPMMssimOptions *tmo;
> 
> info_list = qmp_query_tpm(&err);
> if (err) {
> @@ -52,6 +53,14 @@ void hmp_info_tpm(Monitor *mon, const QDict *qdict)
> teo = ti->options->u.emulator.data;
> monitor_printf(mon, ",chardev=%s", teo->chardev);
> break;
> +        case TPM_TYPE_MSSIM:
> +            tmo = &ti->options->u.mssim;
> +            monitor_printf(mon, ",command=%s:%s,control=%s:%s",
> +                           tmo->command->u.inet.host,
> +                           tmo->command->u.inet.port,
> +                           tmo->control->u.inet.host,
> +                           tmo->control->u.inet.port);
> +            break;
> case TPM_TYPE__MAX:
> break;
> }


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic