qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Qemu-devel] [PATCH 1/3] Extend TPM TIS interface to version 2.0


From: Michael S. Tsirkin
Subject: Re: [Qemu-devel] [PATCH 1/3] Extend TPM TIS interface to version 2.0
Date: Tue, 14 Apr 2015 07:50:11 +0200

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 <address@hidden>
> ---
>  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 via email to

[Prev in Thread] Current Thread [Next in Thread]