From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:34984) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1YzOmS-0001YK-Ba for qemu-devel@nongnu.org; Mon, 01 Jun 2015 08:25:26 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1YzOmQ-0008OA-77 for qemu-devel@nongnu.org; Mon, 01 Jun 2015 08:25:24 -0400 Received: from mx1.redhat.com ([209.132.183.28]:55951) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1YzOmP-0008NP-TY for qemu-devel@nongnu.org; Mon, 01 Jun 2015 08:25:22 -0400 Date: Mon, 1 Jun 2015 14:25:18 +0200 From: "Michael S. Tsirkin" Message-ID: <1433161230-29421-49-git-send-email-mst@redhat.com> References: <1433161230-29421-1-git-send-email-mst@redhat.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <1433161230-29421-1-git-send-email-mst@redhat.com> Subject: [Qemu-devel] [PULL v2 48/60] TPM2 ACPI table support List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Cc: Peter Maydell , Richard Henderson , Paolo Bonzini , Eduardo Habkost , Stefan Berger From: Stefan Berger Add a TPM2 ACPI table if a TPM 2 is used in the backend. Also add an SSDT for the TPM 2. 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 Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- include/hw/acpi/acpi-defs.h | 18 +++++++ include/hw/acpi/tpm.h | 5 ++ include/sysemu/tpm.h | 11 +++- hw/i386/acpi-build.c | 38 ++++++++++++-- hw/tpm/tpm_tis.c | 11 ++++ hw/i386/Makefile.objs | 2 +- hw/i386/ssdt-tpm.dsl | 16 +----- hw/i386/ssdt-tpm.hex.generated | 26 +++++++--- hw/i386/ssdt-tpm2.dsl | 29 +++++++++++ hw/i386/ssdt-tpm2.hex.generated | 109 ++++++++++++++++++++++++++++++++++++++++ 10 files changed, 237 insertions(+), 28 deletions(-) create mode 100644 hw/i386/ssdt-tpm2.dsl create mode 100644 hw/i386/ssdt-tpm2.hex.generated diff --git a/include/hw/acpi/acpi-defs.h b/include/hw/acpi/acpi-defs.h index f503ec4..59cf277 100644 --- a/include/hw/acpi/acpi-defs.h +++ b/include/hw/acpi/acpi-defs.h @@ -450,6 +450,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 */ @@ -459,6 +462,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/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 848df41..c143890 100644 --- a/include/sysemu/tpm.h +++ b/include/sysemu/tpm.h @@ -26,11 +26,18 @@ typedef enum TPMVersion { TPM_VERSION_2_0 = 2, } TPMVersion; +TPMVersion tpm_tis_get_tpm_version(Object *obj); + #define TYPE_TPM_TIS "tpm-tis" -static inline bool tpm_find(void) +static inline 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 TPM_VERSION_UNSPEC; } #endif /* QEMU_TPM_H */ diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c index 283d02e..2c7399b 100644 --- a/hw/i386/acpi-build.c +++ b/hw/i386/acpi-build.c @@ -41,6 +41,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" @@ -106,7 +107,7 @@ typedef struct AcpiPmInfo { typedef struct AcpiMiscInfo { bool has_hpet; - bool has_tpm; + TPMVersion tpm_version; const unsigned char *dsdt_code; unsigned dsdt_size; uint16_t pvpanic_port; @@ -234,7 +235,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(); } @@ -414,6 +415,7 @@ build_madt(GArray *table_data, GArray *linker, AcpiCpuInfo *cpu, } #include "hw/i386/ssdt-tpm.hex" +#include "hw/i386/ssdt-tpm2.hex" /* Assign BSEL property to all buses. In the future, this can be changed * to only assign to buses that support hotplug. @@ -1029,6 +1031,25 @@ 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; + void *tpm_ptr; + + tpm_ptr = acpi_data_push(table_data, sizeof(ssdt_tpm2_aml)); + memcpy(tpm_ptr, ssdt_tpm2_aml, sizeof(ssdt_tpm2_aml)); + + 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), @@ -1343,12 +1364,21 @@ 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 != TPM_VERSION_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 TPM_VERSION_1_2: + build_tpm_ssdt(tables_blob, tables->linker); + break; + case TPM_VERSION_2_0: + build_tpm2(tables_blob, tables->linker); + break; + default: + assert(false); + } } if (guest_info->numa_nodes) { acpi_add_table(table_offsets, tables_blob); diff --git a/hw/tpm/tpm_tis.c b/hw/tpm/tpm_tis.c index e804757..0806b5f 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 @@ -962,6 +963,16 @@ static int tpm_tis_do_startup_tpm(TPMState *s) } /* + * Get the TPMVersion of the backend device being used + */ +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/hw/i386/Makefile.objs b/hw/i386/Makefile.objs index e058a39..0be5d97 100644 --- a/hw/i386/Makefile.objs +++ b/hw/i386/Makefile.objs @@ -9,7 +9,7 @@ obj-y += kvmvapic.o obj-y += acpi-build.o hw/i386/acpi-build.o: hw/i386/acpi-build.c \ hw/i386/acpi-dsdt.hex hw/i386/q35-acpi-dsdt.hex \ - hw/i386/ssdt-tpm.hex + hw/i386/ssdt-tpm.hex hw/i386/ssdt-tpm2.hex iasl-option=$(shell if test -z "`$(1) $(2) 2>&1 > /dev/null`" \ ; then echo "$(2)"; else echo "$(3)"; fi ;) diff --git a/hw/i386/ssdt-tpm.dsl b/hw/i386/ssdt-tpm.dsl index 75d9691..d81478c 100644 --- a/hw/i386/ssdt-tpm.dsl +++ b/hw/i386/ssdt-tpm.dsl @@ -25,19 +25,5 @@ DefinitionBlock ( 0x1 // OEM Revision ) { - Scope(\_SB) { - /* TPM with emulated TPM TIS interface */ - Device (TPM) { - Name (_HID, EisaID ("PNP0C31")) - Name (_CRS, ResourceTemplate () - { - Memory32Fixed (ReadWrite, TPM_TIS_ADDR_BASE, TPM_TIS_ADDR_SIZE) - // older Linux tpm_tis drivers do not work with IRQ - //IRQNoFlags () {TPM_TIS_IRQ} - }) - Method (_STA, 0, NotSerialized) { - Return (0x0F) - } - } - } +#include "ssdt-tpm-common.dsl" } diff --git a/hw/i386/ssdt-tpm.hex.generated b/hw/i386/ssdt-tpm.hex.generated index e84dc6c..874418c 100644 --- a/hw/i386/ssdt-tpm.hex.generated +++ b/hw/i386/ssdt-tpm.hex.generated @@ -3,12 +3,12 @@ static unsigned char ssdt_tpm_aml[] = { 0x53, 0x44, 0x54, -0x5d, +0x6b, 0x0, 0x0, 0x0, 0x1, -0x1c, +0x37, 0x42, 0x58, 0x50, @@ -36,15 +36,26 @@ static unsigned char ssdt_tpm_aml[] = { 0x14, 0x20, 0x10, -0x38, +0x46, +0x4, 0x5c, +0x2f, +0x3, 0x5f, 0x53, 0x42, 0x5f, +0x50, +0x43, +0x49, +0x30, +0x49, +0x53, +0x41, +0x5f, 0x5b, 0x82, -0x30, +0x33, 0x54, 0x50, 0x4d, @@ -65,9 +76,9 @@ static unsigned char ssdt_tpm_aml[] = { 0x52, 0x53, 0x11, -0x11, +0x14, 0xa, -0xe, +0x11, 0x86, 0x9, 0x0, @@ -80,6 +91,9 @@ static unsigned char ssdt_tpm_aml[] = { 0x50, 0x0, 0x0, +0x22, +0x20, +0x0, 0x79, 0x0, 0x14, diff --git a/hw/i386/ssdt-tpm2.dsl b/hw/i386/ssdt-tpm2.dsl new file mode 100644 index 0000000..58bbbf8 --- /dev/null +++ b/hw/i386/ssdt-tpm2.dsl @@ -0,0 +1,29 @@ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License along + * with this program; if not, see . + */ +#include "hw/acpi/tpm.h" + +ACPI_EXTRACT_ALL_CODE ssdt_tpm2_aml + +DefinitionBlock ( + "ssdt-tpm2.aml", // Output Filename + "SSDT", // Signature + 0x01, // SSDT Compliance Revision + "BXPC", // OEMID + "BXSSDT", // TABLE ID + 0x1 // OEM Revision + ) +{ +#include "ssdt-tpm-common.dsl" +} diff --git a/hw/i386/ssdt-tpm2.hex.generated b/hw/i386/ssdt-tpm2.hex.generated new file mode 100644 index 0000000..9ea8271 --- /dev/null +++ b/hw/i386/ssdt-tpm2.hex.generated @@ -0,0 +1,109 @@ +static unsigned char ssdt_tpm2_aml[] = { +0x53, +0x53, +0x44, +0x54, +0x6b, +0x0, +0x0, +0x0, +0x1, +0x37, +0x42, +0x58, +0x50, +0x43, +0x0, +0x0, +0x42, +0x58, +0x53, +0x53, +0x44, +0x54, +0x0, +0x0, +0x1, +0x0, +0x0, +0x0, +0x49, +0x4e, +0x54, +0x4c, +0x7, +0x11, +0x14, +0x20, +0x10, +0x46, +0x4, +0x5c, +0x2f, +0x3, +0x5f, +0x53, +0x42, +0x5f, +0x50, +0x43, +0x49, +0x30, +0x49, +0x53, +0x41, +0x5f, +0x5b, +0x82, +0x33, +0x54, +0x50, +0x4d, +0x5f, +0x8, +0x5f, +0x48, +0x49, +0x44, +0xc, +0x41, +0xd0, +0xc, +0x31, +0x8, +0x5f, +0x43, +0x52, +0x53, +0x11, +0x14, +0xa, +0x11, +0x86, +0x9, +0x0, +0x1, +0x0, +0x0, +0xd4, +0xfe, +0x0, +0x50, +0x0, +0x0, +0x22, +0x20, +0x0, +0x79, +0x0, +0x14, +0x9, +0x5f, +0x53, +0x54, +0x41, +0x0, +0xa4, +0xa, +0xf +}; -- MST