diff mbox

[3/3] TPM2 ACPI table support

Message ID 1427830813-639306-4-git-send-email-stefanb@linux.vnet.ibm.com
State New
Headers show

Commit Message

Stefan Berger March 31, 2015, 7:40 p.m. UTC
Add a TPM2 ACPI table if a TPM2 is used in the backend.

Rename tpm_find() to tpm_get_version() and have this function
return the version of the TPM found, TPMVersion_Unspec if
no TPM is found. Use the version number to build version
specific ACPI tables.

Signed-off-by: Stefan Berger <stefanb@linux.vnet.ibm.com>
---
 hw/i386/acpi-build.c  | 34 ++++++++++++++++++++++++++++++----
 hw/i386/acpi-defs.h   | 18 ++++++++++++++++++
 hw/tpm/tpm_tis.c      | 11 +++++++++++
 include/hw/acpi/tpm.h |  5 +++++
 include/sysemu/tpm.h  | 10 ++++++++--
 5 files changed, 72 insertions(+), 6 deletions(-)

Comments

Xu, Quan April 7, 2015, 8:58 a.m. UTC | #1
> -----Original Message-----
> From: Stefan Berger [mailto:stefanb@linux.vnet.ibm.com]
> Sent: Wednesday, April 01, 2015 3:40 AM
> To: qemu-devel@nongnu.org; mst@redhat.com
> Cc: Xu, Quan; Stefan Berger
> Subject: [PATCH 3/3] TPM2 ACPI table support
> 
> Add a TPM2 ACPI table if a TPM2 is used in the backend.
> 
> Rename tpm_find() to tpm_get_version() and have this function return the
> version of the TPM found, TPMVersion_Unspec if no TPM is found. Use the
> version number to build version specific ACPI tables.
> 
> Signed-off-by: Stefan Berger <stefanb@linux.vnet.ibm.com>
> ---
>  hw/i386/acpi-build.c  | 34 ++++++++++++++++++++++++++++++----
>  hw/i386/acpi-defs.h   | 18 ++++++++++++++++++
>  hw/tpm/tpm_tis.c      | 11 +++++++++++
>  include/hw/acpi/tpm.h |  5 +++++
>  include/sysemu/tpm.h  | 10 ++++++++--
>  5 files changed, 72 insertions(+), 6 deletions(-)
> 
> diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c index d0a5c85..8e01e1b
> 100644
> --- a/hw/i386/acpi-build.c
> +++ b/hw/i386/acpi-build.c
> @@ -42,6 +42,7 @@
>  #include "hw/acpi/memory_hotplug.h"
>  #include "sysemu/tpm.h"
>  #include "hw/acpi/tpm.h"
> +#include "sysemu/tpm_backend.h"
> 
>  /* Supported chipsets: */
>  #include "hw/acpi/piix4.h"
> @@ -111,7 +112,7 @@ typedef struct AcpiPmInfo {
> 
>  typedef struct AcpiMiscInfo {
>      bool has_hpet;
> -    bool has_tpm;
> +    enum TPMVersion tpm_version;
>      const unsigned char *dsdt_code;
>      unsigned dsdt_size;
>      uint16_t pvpanic_port;
> @@ -239,7 +240,7 @@ static void acpi_get_pm_info(AcpiPmInfo *pm)  static
> void acpi_get_misc_info(AcpiMiscInfo *info)  {
>      info->has_hpet = hpet_find();
> -    info->has_tpm = tpm_find();
> +    info->tpm_version = tpm_get_version();
>      info->pvpanic_port = pvpanic_port();
>      info->applesmc_io_base = applesmc_port();  } @@ -1065,6 +1066,21 @@
> build_tpm_ssdt(GArray *table_data, GArray *linker)
>      memcpy(tpm_ptr, ssdt_tpm_aml, sizeof(ssdt_tpm_aml));  }
> 
> +static void
> +build_tpm2(GArray *table_data, GArray *linker) {
> +    Acpi20TPM2 *tpm2_ptr;
> +
> +    tpm2_ptr = acpi_data_push(table_data, sizeof *tpm2_ptr);
> +
> +    tpm2_ptr->platform_class = cpu_to_le16(TPM2_ACPI_CLASS_CLIENT);
> +    tpm2_ptr->control_area_address = cpu_to_le64(0);
> +    tpm2_ptr->start_method = cpu_to_le32(TPM2_START_METHOD_MMIO);
> +
> +    build_header(linker, table_data,
> +                 (void *)tpm2_ptr, "TPM2", sizeof(*tpm2_ptr), 4); }
> +
>  typedef enum {
>      MEM_AFFINITY_NOFLAGS      = 0,
>      MEM_AFFINITY_ENABLED      = (1 << 0),
> @@ -1428,12 +1444,22 @@ void acpi_build(PcGuestInfo *guest_info,
> AcpiBuildTables *tables)
>          acpi_add_table(table_offsets, tables_blob);
>          build_hpet(tables_blob, tables->linker);
>      }
> -    if (misc.has_tpm) {
> +    if (misc.tpm_version != TPMVersion_Unspec) {
>          acpi_add_table(table_offsets, tables_blob);
>          build_tpm_tcpa(tables_blob, tables->linker, tables->tcpalog);
> 
>          acpi_add_table(table_offsets, tables_blob);
> -        build_tpm_ssdt(tables_blob, tables->linker);
> +        switch (misc.tpm_version) {
> +        case TPMVersion1_2:
> +            build_tpm_ssdt(tables_blob, tables->linker);
> +            break;
> +        case TPMVersion2_0:
> +            build_tpm2(tables_blob, tables->linker);
> +            break;
> +        case TPMVersion_Unspec:
> +            /* not possible */
> +            break;
> +        }
>      }
>      if (guest_info->numa_nodes) {
>          acpi_add_table(table_offsets, tables_blob); diff --git
> a/hw/i386/acpi-defs.h b/hw/i386/acpi-defs.h index c4468f8..79ee9b1 100644
> --- a/hw/i386/acpi-defs.h
> +++ b/hw/i386/acpi-defs.h
> @@ -316,6 +316,9 @@ typedef struct AcpiTableMcfg AcpiTableMcfg;
> 
>  /*
>   * TCPA Description Table
> + *
> + * Following Level 00, Rev 00.37 of specs:
> + *
> + http://www.trustedcomputinggroup.org/resources/tcg_acpi_specification
>   */
>  struct Acpi20Tcpa {
>      ACPI_TABLE_HEADER_DEF                    /* ACPI common table
> header */
> @@ -325,6 +328,21 @@ struct Acpi20Tcpa {  } QEMU_PACKED;  typedef struct
> Acpi20Tcpa Acpi20Tcpa;
> 
> +/*
> + * TPM2
> + *
> + * Following Level 00, Rev 00.37 of specs:
> + *
> +http://www.trustedcomputinggroup.org/resources/tcg_acpi_specification
> + */
> +struct Acpi20TPM2 {
> +    ACPI_TABLE_HEADER_DEF
> +    uint16_t platform_class;
> +    uint16_t reserved;
> +    uint64_t control_area_address;
> +    uint32_t start_method;
> +} QEMU_PACKED;
> +typedef struct Acpi20TPM2 Acpi20TPM2;
> +
>  /* DMAR - DMA Remapping table r2.2 */
>  struct AcpiTableDmar {
>      ACPI_TABLE_HEADER_DEF
> diff --git a/hw/tpm/tpm_tis.c b/hw/tpm/tpm_tis.c index 89e401d..56ce1d2
> 100644
> --- a/hw/tpm/tpm_tis.c
> +++ b/hw/tpm/tpm_tis.c
> @@ -32,6 +32,7 @@
>  #include "tpm_tis.h"
>  #include "qemu-common.h"
>  #include "qemu/main-loop.h"
> +#include "sysemu/tpm_backend.h"
> 
>  #define DEBUG_TIS 0
> 
> @@ -963,6 +964,16 @@ static int tpm_tis_do_startup_tpm(TPMState *s)  }
> 
>  /*
> + * Get the TPMVersion of the backend device being used  */ enum
> +TPMVersion tpm_tis_get_tpm_version(Object *obj) {
> +    TPMState *s = TPM(obj);
> +
> +    return tpm_backend_get_tpm_version(s->be_driver);
> +}
> +
> +/*
>   * This function is called when the machine starts, resets or due to
>   * S3 resume.
>   */
> diff --git a/include/hw/acpi/tpm.h b/include/hw/acpi/tpm.h index
> 792fcbf..6d516c6 100644
> --- a/include/hw/acpi/tpm.h
> +++ b/include/hw/acpi/tpm.h
> @@ -26,4 +26,9 @@
>  #define TPM_TCPA_ACPI_CLASS_CLIENT  0
>  #define TPM_TCPA_ACPI_CLASS_SERVER  1
> 
> +#define TPM2_ACPI_CLASS_CLIENT      0
> +#define TPM2_ACPI_CLASS_SERVER      1
> +
> +#define TPM2_START_METHOD_MMIO      6
> +
>  #endif /* HW_ACPI_TPM_H */
> diff --git a/include/sysemu/tpm.h b/include/sysemu/tpm.h index
> 9a77889..b11d1c8 100644
> --- a/include/sysemu/tpm.h
> +++ b/include/sysemu/tpm.h
> @@ -26,12 +26,18 @@ enum TPMVersion {
>      TPMVersion2_0 = 2,
>  };
> 
> +enum TPMVersion tpm_tis_get_tpm_version(Object *obj);
> 
>  #define TYPE_TPM_TIS                "tpm-tis"
> 
> -static inline bool tpm_find(void)
> +static inline enum TPMVersion tpm_get_version(void)
>  {
> -    return object_resolve_path_type("", TYPE_TPM_TIS, NULL);
> +    Object *obj = object_resolve_path_type("", TYPE_TPM_TIS, NULL);
> +
> +    if (obj) {
> +        return tpm_tis_get_tpm_version(obj);
> +    }
> +    return TPMVersion_Unspec;
>  }
> 
>  #endif /* QEMU_TPM_H */
> --
> 1.9.3


Looks good.

Intel
Quan Xu
Michael S. Tsirkin April 13, 2015, 6:27 a.m. UTC | #2
> @@ -1428,12 +1444,22 @@ void acpi_build(PcGuestInfo *guest_info, AcpiBuildTables *tables)
>          acpi_add_table(table_offsets, tables_blob);
>          build_hpet(tables_blob, tables->linker);
>      }
> -    if (misc.has_tpm) {
> +    if (misc.tpm_version != TPMVersion_Unspec) {
>          acpi_add_table(table_offsets, tables_blob);
>          build_tpm_tcpa(tables_blob, tables->linker, tables->tcpalog);
>  
>          acpi_add_table(table_offsets, tables_blob);
> -        build_tpm_ssdt(tables_blob, tables->linker);
> +        switch (misc.tpm_version) {
> +        case TPMVersion1_2:
> +            build_tpm_ssdt(tables_blob, tables->linker);
> +            break;
> +        case TPMVersion2_0:
> +            build_tpm2(tables_blob, tables->linker);
> +            break;
> +        case TPMVersion_Unspec:
> +            /* not possible */
> +            break;
> +        }
>      }
>      if (guest_info->numa_nodes) {
>          acpi_add_table(table_offsets, tables_blob);

I think we should fix QEMU coding style violations in TPM code.
In particular, mixing of _ and camel case, enum and define values
not all upper case, local variables not all lower case.
This was less of an issue when the violations were contained
within hw/tpm/, but it's more of an issue now that this affects
other code.
Stefan Berger April 14, 2015, 2:29 a.m. UTC | #3
On 04/13/2015 02:27 AM, Michael S. Tsirkin wrote:
>> @@ -1428,12 +1444,22 @@ void acpi_build(PcGuestInfo *guest_info, AcpiBuildTables *tables)
>>           acpi_add_table(table_offsets, tables_blob);
>>           build_hpet(tables_blob, tables->linker);
>>       }
>> -    if (misc.has_tpm) {
>> +    if (misc.tpm_version != TPMVersion_Unspec) {
>>           acpi_add_table(table_offsets, tables_blob);
>>           build_tpm_tcpa(tables_blob, tables->linker, tables->tcpalog);
>>   
>>           acpi_add_table(table_offsets, tables_blob);
>> -        build_tpm_ssdt(tables_blob, tables->linker);
>> +        switch (misc.tpm_version) {
>> +        case TPMVersion1_2:
>> +            build_tpm_ssdt(tables_blob, tables->linker);
>> +            break;
>> +        case TPMVersion2_0:
>> +            build_tpm2(tables_blob, tables->linker);
>> +            break;
>> +        case TPMVersion_Unspec:
>> +            /* not possible */
>> +            break;
>> +        }
>>       }
>>       if (guest_info->numa_nodes) {
>>           acpi_add_table(table_offsets, tables_blob);
> I think we should fix QEMU coding style violations in TPM code.
> In particular, mixing of _ and camel case, enum and define values
> not all upper case, local variables not all lower case.
> This was less of an issue when the violations were contained
> within hw/tpm/, but it's more of an issue now that this affects
> other code.
>

The above enums look like the only violation to me. Fixed.

     Stefan
Michael S. Tsirkin April 14, 2015, 5:51 a.m. UTC | #4
On Mon, Apr 13, 2015 at 10:29:32PM -0400, Stefan Berger wrote:
> On 04/13/2015 02:27 AM, Michael S. Tsirkin wrote:
> >>@@ -1428,12 +1444,22 @@ void acpi_build(PcGuestInfo *guest_info, AcpiBuildTables *tables)
> >>          acpi_add_table(table_offsets, tables_blob);
> >>          build_hpet(tables_blob, tables->linker);
> >>      }
> >>-    if (misc.has_tpm) {
> >>+    if (misc.tpm_version != TPMVersion_Unspec) {
> >>          acpi_add_table(table_offsets, tables_blob);
> >>          build_tpm_tcpa(tables_blob, tables->linker, tables->tcpalog);
> >>          acpi_add_table(table_offsets, tables_blob);
> >>-        build_tpm_ssdt(tables_blob, tables->linker);
> >>+        switch (misc.tpm_version) {
> >>+        case TPMVersion1_2:
> >>+            build_tpm_ssdt(tables_blob, tables->linker);
> >>+            break;
> >>+        case TPMVersion2_0:
> >>+            build_tpm2(tables_blob, tables->linker);
> >>+            break;
> >>+        case TPMVersion_Unspec:
> >>+            /* not possible */
> >>+            break;
> >>+        }
> >>      }
> >>      if (guest_info->numa_nodes) {
> >>          acpi_add_table(table_offsets, tables_blob);
> >I think we should fix QEMU coding style violations in TPM code.
> >In particular, mixing of _ and camel case, enum and define values
> >not all upper case, local variables not all lower case.
> >This was less of an issue when the violations were contained
> >within hw/tpm/, but it's more of an issue now that this affects
> >other code.
> >
> 
> The above enums look like the only violation to me. Fixed.
> 
>     Stefan


there's also needIrq in existing code, let's fix that.
diff mbox

Patch

diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
index d0a5c85..8e01e1b 100644
--- a/hw/i386/acpi-build.c
+++ b/hw/i386/acpi-build.c
@@ -42,6 +42,7 @@ 
 #include "hw/acpi/memory_hotplug.h"
 #include "sysemu/tpm.h"
 #include "hw/acpi/tpm.h"
+#include "sysemu/tpm_backend.h"
 
 /* Supported chipsets: */
 #include "hw/acpi/piix4.h"
@@ -111,7 +112,7 @@  typedef struct AcpiPmInfo {
 
 typedef struct AcpiMiscInfo {
     bool has_hpet;
-    bool has_tpm;
+    enum TPMVersion tpm_version;
     const unsigned char *dsdt_code;
     unsigned dsdt_size;
     uint16_t pvpanic_port;
@@ -239,7 +240,7 @@  static void acpi_get_pm_info(AcpiPmInfo *pm)
 static void acpi_get_misc_info(AcpiMiscInfo *info)
 {
     info->has_hpet = hpet_find();
-    info->has_tpm = tpm_find();
+    info->tpm_version = tpm_get_version();
     info->pvpanic_port = pvpanic_port();
     info->applesmc_io_base = applesmc_port();
 }
@@ -1065,6 +1066,21 @@  build_tpm_ssdt(GArray *table_data, GArray *linker)
     memcpy(tpm_ptr, ssdt_tpm_aml, sizeof(ssdt_tpm_aml));
 }
 
+static void
+build_tpm2(GArray *table_data, GArray *linker)
+{
+    Acpi20TPM2 *tpm2_ptr;
+
+    tpm2_ptr = acpi_data_push(table_data, sizeof *tpm2_ptr);
+
+    tpm2_ptr->platform_class = cpu_to_le16(TPM2_ACPI_CLASS_CLIENT);
+    tpm2_ptr->control_area_address = cpu_to_le64(0);
+    tpm2_ptr->start_method = cpu_to_le32(TPM2_START_METHOD_MMIO);
+
+    build_header(linker, table_data,
+                 (void *)tpm2_ptr, "TPM2", sizeof(*tpm2_ptr), 4);
+}
+
 typedef enum {
     MEM_AFFINITY_NOFLAGS      = 0,
     MEM_AFFINITY_ENABLED      = (1 << 0),
@@ -1428,12 +1444,22 @@  void acpi_build(PcGuestInfo *guest_info, AcpiBuildTables *tables)
         acpi_add_table(table_offsets, tables_blob);
         build_hpet(tables_blob, tables->linker);
     }
-    if (misc.has_tpm) {
+    if (misc.tpm_version != TPMVersion_Unspec) {
         acpi_add_table(table_offsets, tables_blob);
         build_tpm_tcpa(tables_blob, tables->linker, tables->tcpalog);
 
         acpi_add_table(table_offsets, tables_blob);
-        build_tpm_ssdt(tables_blob, tables->linker);
+        switch (misc.tpm_version) {
+        case TPMVersion1_2:
+            build_tpm_ssdt(tables_blob, tables->linker);
+            break;
+        case TPMVersion2_0:
+            build_tpm2(tables_blob, tables->linker);
+            break;
+        case TPMVersion_Unspec:
+            /* not possible */
+            break;
+        }
     }
     if (guest_info->numa_nodes) {
         acpi_add_table(table_offsets, tables_blob);
diff --git a/hw/i386/acpi-defs.h b/hw/i386/acpi-defs.h
index c4468f8..79ee9b1 100644
--- a/hw/i386/acpi-defs.h
+++ b/hw/i386/acpi-defs.h
@@ -316,6 +316,9 @@  typedef struct AcpiTableMcfg AcpiTableMcfg;
 
 /*
  * TCPA Description Table
+ *
+ * Following Level 00, Rev 00.37 of specs:
+ * http://www.trustedcomputinggroup.org/resources/tcg_acpi_specification
  */
 struct Acpi20Tcpa {
     ACPI_TABLE_HEADER_DEF                    /* ACPI common table header */
@@ -325,6 +328,21 @@  struct Acpi20Tcpa {
 } QEMU_PACKED;
 typedef struct Acpi20Tcpa Acpi20Tcpa;
 
+/*
+ * TPM2
+ *
+ * Following Level 00, Rev 00.37 of specs:
+ * http://www.trustedcomputinggroup.org/resources/tcg_acpi_specification
+ */
+struct Acpi20TPM2 {
+    ACPI_TABLE_HEADER_DEF
+    uint16_t platform_class;
+    uint16_t reserved;
+    uint64_t control_area_address;
+    uint32_t start_method;
+} QEMU_PACKED;
+typedef struct Acpi20TPM2 Acpi20TPM2;
+
 /* DMAR - DMA Remapping table r2.2 */
 struct AcpiTableDmar {
     ACPI_TABLE_HEADER_DEF
diff --git a/hw/tpm/tpm_tis.c b/hw/tpm/tpm_tis.c
index 89e401d..56ce1d2 100644
--- a/hw/tpm/tpm_tis.c
+++ b/hw/tpm/tpm_tis.c
@@ -32,6 +32,7 @@ 
 #include "tpm_tis.h"
 #include "qemu-common.h"
 #include "qemu/main-loop.h"
+#include "sysemu/tpm_backend.h"
 
 #define DEBUG_TIS 0
 
@@ -963,6 +964,16 @@  static int tpm_tis_do_startup_tpm(TPMState *s)
 }
 
 /*
+ * Get the TPMVersion of the backend device being used
+ */
+enum TPMVersion tpm_tis_get_tpm_version(Object *obj)
+{
+    TPMState *s = TPM(obj);
+
+    return tpm_backend_get_tpm_version(s->be_driver);
+}
+
+/*
  * This function is called when the machine starts, resets or due to
  * S3 resume.
  */
diff --git a/include/hw/acpi/tpm.h b/include/hw/acpi/tpm.h
index 792fcbf..6d516c6 100644
--- a/include/hw/acpi/tpm.h
+++ b/include/hw/acpi/tpm.h
@@ -26,4 +26,9 @@ 
 #define TPM_TCPA_ACPI_CLASS_CLIENT  0
 #define TPM_TCPA_ACPI_CLASS_SERVER  1
 
+#define TPM2_ACPI_CLASS_CLIENT      0
+#define TPM2_ACPI_CLASS_SERVER      1
+
+#define TPM2_START_METHOD_MMIO      6
+
 #endif /* HW_ACPI_TPM_H */
diff --git a/include/sysemu/tpm.h b/include/sysemu/tpm.h
index 9a77889..b11d1c8 100644
--- a/include/sysemu/tpm.h
+++ b/include/sysemu/tpm.h
@@ -26,12 +26,18 @@  enum TPMVersion {
     TPMVersion2_0 = 2,
 };
 
+enum TPMVersion tpm_tis_get_tpm_version(Object *obj);
 
 #define TYPE_TPM_TIS                "tpm-tis"
 
-static inline bool tpm_find(void)
+static inline enum TPMVersion tpm_get_version(void)
 {
-    return object_resolve_path_type("", TYPE_TPM_TIS, NULL);
+    Object *obj = object_resolve_path_type("", TYPE_TPM_TIS, NULL);
+
+    if (obj) {
+        return tpm_tis_get_tpm_version(obj);
+    }
+    return TPMVersion_Unspec;
 }
 
 #endif /* QEMU_TPM_H */