[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
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- Re: [Qemu-devel] [PATCH 1/3] Extend TPM TIS interface to version 2.0,
Michael S. Tsirkin <=