Message ID | 1427830813-639306-4-git-send-email-stefanb@linux.vnet.ibm.com |
---|---|
State | New |
Headers | show |
> -----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
> @@ -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.
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
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 --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 */
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(-)