All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Michael S. Tsirkin" <mst@redhat.com>
To: Stefan Berger <stefanb@linux.vnet.ibm.com>
Cc: qemu-devel@nongnu.org, quan.xu@intel.com
Subject: Re: [Qemu-devel] [PATCH 1/3] Extend TPM TIS interface to version 2.0
Date: Tue, 14 Apr 2015 07:50:11 +0200	[thread overview]
Message-ID: <20150414074841-mutt-send-email-mst@redhat.com> (raw)
In-Reply-To: <1427830813-639306-2-git-send-email-stefanb@linux.vnet.ibm.com>

On Tue, Mar 31, 2015 at 03:40:11PM -0400, Stefan Berger wrote:
> Following the recent upgrade to version 1.3, extend the TPM TIS
> interface with capabilities introduced for support of a TPM 2.
> 
> TPM TIS for TPM 2 introduced the following extensions beyond the
> TPM TIS 1.3 (used for TPM 1.2):
> 
> - A new 32bit interface Id register was introduced.
> - New flags for the status (STS) register were defined.
> - New flags for the capability flags were defined.
> 
> Support the above if a TPM TIS 1.3 for TPM 2 is used with a TPM 2
> on the backend side. Support the old TPM TIS 1.3 configuration if a
> TPM 1.2 is being used. A subsequent patch will then determine which
> TPM version is being used in the backend.
> 
> Signed-off-by: Stefan Berger <stefanb@linux.vnet.ibm.com>
> ---
>  backends/tpm.c               |  14 ++++++
>  hw/tpm/tpm_int.h             |   1 +
>  hw/tpm/tpm_passthrough.c     |  14 ++++++
>  hw/tpm/tpm_tis.c             | 109 +++++++++++++++++++++++++++++++++++++++----
>  hw/tpm/tpm_tis.h             |   1 +
>  include/sysemu/tpm.h         |   7 +++
>  include/sysemu/tpm_backend.h |  23 +++++++++
>  7 files changed, 160 insertions(+), 9 deletions(-)
> 
> diff --git a/backends/tpm.c b/backends/tpm.c
> index 4efe367..3ebb603 100644
> --- a/backends/tpm.c
> +++ b/backends/tpm.c
> @@ -96,6 +96,20 @@ bool tpm_backend_get_tpm_established_flag(TPMBackend *s)
>      return k->ops->get_tpm_established_flag(s);
>  }
>  
> +int tpm_backend_reset_tpm_established_flag(TPMBackend *s, uint8_t locty)
> +{
> +    TPMBackendClass *k = TPM_BACKEND_GET_CLASS(s);
> +
> +    return k->ops->reset_tpm_established_flag(s, locty);
> +}
> +
> +enum TPMVersion tpm_backend_get_tpm_version(TPMBackend *s)


use typedef without enum pls

> +{
> +    TPMBackendClass *k = TPM_BACKEND_GET_CLASS(s);
> +
> +    return k->ops->get_tpm_version(s);
> +}
> +
>  static bool tpm_backend_prop_get_opened(Object *obj, Error **errp)
>  {
>      TPMBackend *s = TPM_BACKEND(obj);
> diff --git a/hw/tpm/tpm_int.h b/hw/tpm/tpm_int.h
> index 2b35fe2..24e12ce 100644
> --- a/hw/tpm/tpm_int.h
> +++ b/hw/tpm/tpm_int.h
> @@ -29,6 +29,7 @@ struct TPMState {
>  
>      char *backend;
>      TPMBackend *be_driver;
> +    enum TPMVersion be_tpm_version;

same

>  };
>  
>  #define TPM(obj) OBJECT_CHECK(TPMState, (obj), TYPE_TPM_TIS)
> diff --git a/hw/tpm/tpm_passthrough.c b/hw/tpm/tpm_passthrough.c
> index 73ca906..dd769a7 100644
> --- a/hw/tpm/tpm_passthrough.c
> +++ b/hw/tpm/tpm_passthrough.c
> @@ -267,6 +267,13 @@ 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 bool tpm_passthrough_get_startup_error(TPMBackend *tb)
>  {
>      TPMPassthruState *tpm_pt = TPM_PASSTHROUGH(tb);
> @@ -324,6 +331,11 @@ static const char *tpm_passthrough_create_desc(void)
>      return "Passthrough TPM backend driver";
>  }
>  
> +static enum TPMVersion tpm_passthrough_get_tpm_version(TPMBackend *tb)
> +{
> +    return TPMVersion1_2;
> +}
> +
>  /*
>   * A basic test of a TPM device. We expect a well formatted response header
>   * (error response is fine) within one second.
> @@ -540,6 +552,8 @@ static const TPMDriverOps tpm_passthrough_driver = {
>      .deliver_request          = tpm_passthrough_deliver_request,
>      .cancel_cmd               = tpm_passthrough_cancel_cmd,
>      .get_tpm_established_flag = tpm_passthrough_get_tpm_established_flag,
> +    .reset_tpm_established_flag = tpm_passthrough_reset_tpm_established_flag,
> +    .get_tpm_version          = tpm_passthrough_get_tpm_version,
>  };
>  
>  static void tpm_passthrough_inst_init(Object *obj)
> diff --git a/hw/tpm/tpm_tis.c b/hw/tpm/tpm_tis.c
> index 4b6d601..89e401d 100644
> --- a/hw/tpm/tpm_tis.c
> +++ b/hw/tpm/tpm_tis.c
> @@ -17,6 +17,9 @@
>   * supports version 1.3, 21 March 2013
>   * In the developers menu choose the PC Client section then find the TIS
>   * specification.
> + *
> + * TPM TIS for TPM 2 implementation following TCG PC Client Platform
> + * TPM Profile (PTP) Specification, Familiy 2.0, Revision 00.43
>   */
>  
>  #include "sysemu/tpm_backend.h"
> @@ -49,6 +52,7 @@
>  #define TPM_TIS_REG_INTF_CAPABILITY       0x14
>  #define TPM_TIS_REG_STS                   0x18
>  #define TPM_TIS_REG_DATA_FIFO             0x24
> +#define TPM_TIS_REG_INTERFACE_ID          0x30
>  #define TPM_TIS_REG_DATA_XFIFO            0x80
>  #define TPM_TIS_REG_DATA_XFIFO_END        0xbc
>  #define TPM_TIS_REG_DID_VID               0xf00
> @@ -57,6 +61,12 @@
>  /* vendor-specific registers */
>  #define TPM_TIS_REG_DEBUG                 0xf90
>  
> +#define TPM_TIS_STS_TPM_FAMILY_MASK         (0x3 << 26)/* TPM 2.0 */
> +#define TPM_TIS_STS_TPM_FAMILY1_2           (0 << 26)  /* TPM 2.0 */
> +#define TPM_TIS_STS_TPM_FAMILY2_0           (1 << 26)  /* TPM 2.0 */
> +#define TPM_TIS_STS_RESET_ESTABLISHMENT_BIT (1 << 25)  /* TPM 2.0 */
> +#define TPM_TIS_STS_COMMAND_CANCEL          (1 << 24)  /* TPM 2.0 */
> +
>  #define TPM_TIS_STS_VALID                 (1 << 7)
>  #define TPM_TIS_STS_COMMAND_READY         (1 << 6)
>  #define TPM_TIS_STS_TPM_GO                (1 << 5)
> @@ -102,15 +112,42 @@
>  #endif
>  
>  #define TPM_TIS_CAP_INTERFACE_VERSION1_3 (2 << 28)
> +#define TPM_TIS_CAP_INTERFACE_VERSION1_3_FOR_TPM2_0 (3 << 28)
>  #define TPM_TIS_CAP_DATA_TRANSFER_64B    (3 << 9)
>  #define TPM_TIS_CAP_DATA_TRANSFER_LEGACY (0 << 9)
>  #define TPM_TIS_CAP_BURST_COUNT_DYNAMIC  (0 << 8)
>  #define TPM_TIS_CAP_INTERRUPT_LOW_LEVEL  (1 << 4) /* support is mandatory */
> -#define TPM_TIS_CAPABILITIES_SUPPORTED   (TPM_TIS_CAP_INTERRUPT_LOW_LEVEL | \
> -                                          TPM_TIS_CAP_BURST_COUNT_DYNAMIC | \
> -                                          TPM_TIS_CAP_DATA_TRANSFER_64B | \
> -                                          TPM_TIS_CAP_INTERFACE_VERSION1_3 | \
> -                                          TPM_TIS_INTERRUPTS_SUPPORTED)
> +#define TPM_TIS_CAPABILITIES_SUPPORTED1_3 \
> +    (TPM_TIS_CAP_INTERRUPT_LOW_LEVEL | \
> +     TPM_TIS_CAP_BURST_COUNT_DYNAMIC | \
> +     TPM_TIS_CAP_DATA_TRANSFER_64B | \
> +     TPM_TIS_CAP_INTERFACE_VERSION1_3 | \
> +     TPM_TIS_INTERRUPTS_SUPPORTED)
> +
> +#define TPM_TIS_CAPABILITIES_SUPPORTED2_0 \
> +    (TPM_TIS_CAP_INTERRUPT_LOW_LEVEL | \
> +     TPM_TIS_CAP_BURST_COUNT_DYNAMIC | \
> +     TPM_TIS_CAP_DATA_TRANSFER_64B | \
> +     TPM_TIS_CAP_INTERFACE_VERSION1_3_FOR_TPM2_0 | \
> +     TPM_TIS_INTERRUPTS_SUPPORTED)
> +
> +#define TPM_TIS_IFACE_ID_INTERFACE_TIS1_3   (0xf)     /* TPM 2.0 */
> +#define TPM_TIS_IFACE_ID_INTERFACE_FIFO     (0x0)     /* TPM 2.0 */
> +#define TPM_TIS_IFACE_ID_INTERFACE_VER_FIFO (0 << 4)  /* TPM 2.0 */
> +#define TPM_TIS_IFACE_ID_CAP_5_LOCALITIES   (1 << 8)  /* TPM 2.0 */
> +#define TPM_TIS_IFACE_ID_CAP_TIS_SUPPORTED  (1 << 13) /* TPM 2.0 */
> +#define TPM_TIS_IFACE_ID_INT_SEL_LOCK       (1 << 19) /* TPM 2.0 */
> +
> +#define TPM_TIS_IFACE_ID_SUPPORTED_FLAGS1_3 \
> +    (TPM_TIS_IFACE_ID_INTERFACE_TIS1_3 | \
> +     (~0 << 4)/* all of it is don't care */)
> +
> +/* if backend was a TPM 2.0: */
> +#define TPM_TIS_IFACE_ID_SUPPORTED_FLAGS2_0 \
> +    (TPM_TIS_IFACE_ID_INTERFACE_FIFO | \
> +     TPM_TIS_IFACE_ID_INTERFACE_VER_FIFO | \
> +     TPM_TIS_IFACE_ID_CAP_5_LOCALITIES | \
> +     TPM_TIS_IFACE_ID_CAP_TIS_SUPPORTED)
>  
>  #define TPM_TIS_TPM_DID       0x0001
>  #define TPM_TIS_TPM_VID       PCI_VENDOR_ID_IBM
> @@ -154,7 +191,8 @@ static void tpm_tis_show_buffer(const TPMSizedBuffer *sb, const char *string)
>  
>  /*
>   * Set the given flags in the STS register by clearing the register but
> - * preserving the SELFTEST_DONE flag and then setting the new flags.
> + * preserving the SELFTEST_DONE and TPMFAMILY_MASK flags and then setting
> + * the new flags.
>   *
>   * The SELFTEST_DONE flag is acquired from the backend that determines it by
>   * peeking into TPM commands.
> @@ -166,7 +204,7 @@ static void tpm_tis_show_buffer(const TPMSizedBuffer *sb, const char *string)
>   */
>  static void tpm_tis_sts_set(TPMLocality *l, uint32_t flags)
>  {
> -    l->sts &= TPM_TIS_STS_SELFTEST_DONE;
> +    l->sts &= (TPM_TIS_STS_SELFTEST_DONE | TPM_TIS_STS_TPM_FAMILY_MASK);

no () to right of = please.

>      l->sts |= flags;
>  }
>  
> @@ -489,7 +527,17 @@ static uint64_t tpm_tis_mmio_read(void *opaque, hwaddr addr,
>          val = tis->loc[locty].ints;
>          break;
>      case TPM_TIS_REG_INTF_CAPABILITY:
> -        val = TPM_TIS_CAPABILITIES_SUPPORTED;
> +        switch (s->be_tpm_version) {
> +        case TPMVersion_Unspec:
> +            val = 0;
> +            break;
> +        case TPMVersion1_2:
> +            val = TPM_TIS_CAPABILITIES_SUPPORTED1_3;
> +            break;
> +        case TPMVersion2_0:
> +            val = TPM_TIS_CAPABILITIES_SUPPORTED2_0;
> +            break;
> +        }
>          break;
>      case TPM_TIS_REG_STS:
>          if (tis->active_locty == locty) {
> @@ -536,6 +584,9 @@ static uint64_t tpm_tis_mmio_read(void *opaque, hwaddr addr,
>              shift = 0; /* no more adjustments */
>          }
>          break;
> +    case TPM_TIS_REG_INTERFACE_ID:
> +        val = tis->loc[locty].iface_id;
> +        break;
>      case TPM_TIS_REG_DID_VID:
>          val = (TPM_TIS_TPM_DID << 16) | TPM_TIS_TPM_VID;
>          break;
> @@ -736,6 +787,25 @@ static void tpm_tis_mmio_write_intern(void *opaque, hwaddr addr,
>              break;
>          }
>  
> +        if (s->be_tpm_version == TPMVersion2_0) {
> +            /* some flags that are only supported for TPM 2 */
> +            if (val & TPM_TIS_STS_COMMAND_CANCEL) {
> +                if (tis->loc[locty].state == TPM_TIS_STATE_EXECUTION) {
> +                    /*
> +                     * request the backend to cancel. Some backends may not
> +                     * support it
> +                     */
> +                    tpm_backend_cancel_cmd(s->be_driver);
> +                }
> +            }
> +
> +            if (val & TPM_TIS_STS_RESET_ESTABLISHMENT_BIT) {
> +                if (locty == 3 || locty == 4) {
> +                    tpm_backend_reset_tpm_established_flag(s->be_driver, locty);
> +                }
> +            }
> +        }
> +
>          val &= (TPM_TIS_STS_COMMAND_READY | TPM_TIS_STS_TPM_GO |
>                  TPM_TIS_STS_RESPONSE_RETRY);
>  
> @@ -860,6 +930,14 @@ static void tpm_tis_mmio_write_intern(void *opaque, hwaddr addr,
>              }
>          }
>          break;
> +        case TPM_TIS_REG_INTERFACE_ID:
> +            if (val & TPM_TIS_IFACE_ID_INT_SEL_LOCK) {
> +                for (l = 0; l < TPM_TIS_NUM_LOCALITIES; l++) {
> +                    tis->loc[l].iface_id |= TPM_TIS_IFACE_ID_INT_SEL_LOCK;
> +                }
> +            }
> +
> +        break;
>      }
>  }
>  
> @@ -894,6 +972,8 @@ static void tpm_tis_reset(DeviceState *dev)
>      TPMTISEmuState *tis = &s->s.tis;
>      int c;
>  
> +    s->be_tpm_version = tpm_backend_get_tpm_version(s->be_driver);
> +
>      tpm_backend_reset(s->be_driver);
>  
>      tis->active_locty = TPM_TIS_NO_LOCALITY;
> @@ -902,7 +982,18 @@ static void tpm_tis_reset(DeviceState *dev)
>  
>      for (c = 0; c < TPM_TIS_NUM_LOCALITIES; c++) {
>          tis->loc[c].access = TPM_TIS_ACCESS_TPM_REG_VALID_STS;
> -        tis->loc[c].sts = 0;
> +        switch (s->be_tpm_version) {
> +        case TPMVersion_Unspec:
> +            break;
> +        case TPMVersion1_2:
> +            tis->loc[c].sts = TPM_TIS_STS_TPM_FAMILY1_2;
> +            tis->loc[c].iface_id = TPM_TIS_IFACE_ID_SUPPORTED_FLAGS1_3;
> +            break;
> +        case TPMVersion2_0:
> +            tis->loc[c].sts = TPM_TIS_STS_TPM_FAMILY2_0;
> +            tis->loc[c].iface_id = TPM_TIS_IFACE_ID_SUPPORTED_FLAGS2_0;
> +            break;
> +        }
>          tis->loc[c].inte = TPM_TIS_INT_POLARITY_LOW_LEVEL;
>          tis->loc[c].ints = 0;
>          tis->loc[c].state = TPM_TIS_STATE_IDLE;
> diff --git a/hw/tpm/tpm_tis.h b/hw/tpm/tpm_tis.h
> index db78d51..a1df41f 100644
> --- a/hw/tpm/tpm_tis.h
> +++ b/hw/tpm/tpm_tis.h
> @@ -42,6 +42,7 @@ typedef struct TPMLocality {
>      TPMTISState state;
>      uint8_t access;
>      uint32_t sts;
> +    uint32_t iface_id;
>      uint32_t inte;
>      uint32_t ints;
>  
> diff --git a/include/sysemu/tpm.h b/include/sysemu/tpm.h
> index 9b81ce9..9a77889 100644
> --- a/include/sysemu/tpm.h
> +++ b/include/sysemu/tpm.h
> @@ -20,6 +20,13 @@ int tpm_config_parse(QemuOptsList *opts_list, const char *optarg);
>  int tpm_init(void);
>  void tpm_cleanup(void);
>  
> +enum TPMVersion {
> +    TPMVersion_Unspec = 0,
> +    TPMVersion1_2 = 1,
> +    TPMVersion2_0 = 2,
> +};


needs a typedef

> +
> +

don't add two empty lines pls

>  #define TYPE_TPM_TIS                "tpm-tis"
>  
>  static inline bool tpm_find(void)
> diff --git a/include/sysemu/tpm_backend.h b/include/sysemu/tpm_backend.h
> index 540ee25..cbe064f 100644
> --- a/include/sysemu/tpm_backend.h
> +++ b/include/sysemu/tpm_backend.h
> @@ -88,6 +88,10 @@ struct TPMDriverOps {
>      void (*cancel_cmd)(TPMBackend *t);
>  
>      bool (*get_tpm_established_flag)(TPMBackend *t);
> +
> +    int (*reset_tpm_established_flag)(TPMBackend *t, uint8_t locty);
> +
> +    enum TPMVersion (*get_tpm_version)(TPMBackend *t);


drop enum

>  };
>  
>  
> @@ -192,6 +196,15 @@ void tpm_backend_cancel_cmd(TPMBackend *s);
>  bool tpm_backend_get_tpm_established_flag(TPMBackend *s);
>  
>  /**
> + * tpm_backend_reset_tpm_established_flag:
> + * @s: the backend
> + * @locty: the locality number
> + *
> + * Reset the TPM establishment flag.
> + */
> +int tpm_backend_reset_tpm_established_flag(TPMBackend *s, uint8_t locty);
> +
> +/**
>   * tpm_backend_open:
>   * @s: the backend to open
>   * @errp: a pointer to return the #Error object if an error occurs.
> @@ -201,6 +214,16 @@ bool tpm_backend_get_tpm_established_flag(TPMBackend *s);
>   */
>  void tpm_backend_open(TPMBackend *s, Error **errp);
>  
> +/**
> + * tpm_backend_get_tpm_version:
> + * @s: the backend to call into
> + *
> + * Get the TPM Version that is emulated at the backend.
> + *
> + * Returns an enum TPMVersion.
> + */
> +enum TPMVersion tpm_backend_get_tpm_version(TPMBackend *s);
> +

same

>  TPMBackend *qemu_find_tpm(const char *id);
>  
>  const TPMDriverOps *tpm_get_backend_driver(const char *type);
> -- 
> 1.9.3

  reply	other threads:[~2015-04-14  5:50 UTC|newest]

Thread overview: 14+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-03-31 19:40 [Qemu-devel] [PATCH 0/3] tpm: Upgrade TPM TIS for support of a TPM 2 Stefan Berger
2015-03-31 19:40 ` [Qemu-devel] [PATCH 1/3] Extend TPM TIS interface to version 2.0 Stefan Berger
2015-04-14  5:50   ` Michael S. Tsirkin [this message]
2015-03-31 19:40 ` [Qemu-devel] [PATCH 2/3] tpm: Probe for connected TPM 1.2 or TPM 2 Stefan Berger
2015-04-07  8:54   ` Xu, Quan
2015-04-12 20:59     ` Stefan Berger
2015-04-13 14:43       ` Eric Blake
2015-04-13 14:58         ` Stefan Berger
2015-04-14  5:48   ` Michael S. Tsirkin
2015-03-31 19:40 ` [Qemu-devel] [PATCH 3/3] TPM2 ACPI table support Stefan Berger
2015-04-07  8:58   ` Xu, Quan
2015-04-13  6:27   ` Michael S. Tsirkin
2015-04-14  2:29     ` Stefan Berger
2015-04-14  5:51       ` Michael S. Tsirkin

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20150414074841-mutt-send-email-mst@redhat.com \
    --to=mst@redhat.com \
    --cc=qemu-devel@nongnu.org \
    --cc=quan.xu@intel.com \
    --cc=stefanb@linux.vnet.ibm.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.