From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:45614) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1XCRsk-0002Pj-3B for qemu-devel@nongnu.org; Wed, 30 Jul 2014 07:17:22 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1XCRsf-0002oN-Jb for qemu-devel@nongnu.org; Wed, 30 Jul 2014 07:17:18 -0400 Received: from mx1.redhat.com ([209.132.183.28]:33187) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1XCRsf-0002oF-BN for qemu-devel@nongnu.org; Wed, 30 Jul 2014 07:17:13 -0400 Date: Wed, 30 Jul 2014 13:17:27 +0200 From: "Michael S. Tsirkin" Message-ID: <20140730111727.GB15928@redhat.com> References: <1406631139-6754-1-git-send-email-stefanb@us.ibm.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <1406631139-6754-1-git-send-email-stefanb@us.ibm.com> Subject: Re: [Qemu-devel] [PATCH v2] Add ACPI tables for TPM List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: Stefan Berger Cc: qemu-devel@nongnu.org, Stefan Berger On Tue, Jul 29, 2014 at 06:52:19AM -0400, Stefan Berger wrote: > From: Stefan Berger > > Add an SSDT ACPI table for the TPM device. > Add a TCPA table for BIOS logging area when a TPM is being used. > > The latter follows this spec here: > > http://www.trustedcomputinggroup.org/files/static_page_files/DCD4188E-1A4B-B294-D050A155FB6F7385/TCG_ACPIGeneralSpecification_PublicReview.pdf > > Signed-off-by: Stefan Berger OK just to confirm, so far we only support passthrough tpm, this means we don't need to worry about generating compatible ACPI for old machine types, since passthrough disables migration. Correct? > --- > hw/i386/Makefile.objs | 3 ++- > hw/i386/acpi-build.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++ > hw/i386/acpi-defs.h | 11 +++++++++++ > hw/i386/ssdt-tpm.dsl | 43 +++++++++++++++++++++++++++++++++++++++++++ > hw/tpm/tpm_tis.h | 5 +---- > include/hw/acpi/tpm.h | 29 +++++++++++++++++++++++++++++ > include/sysemu/tpm.h | 5 +++++ > 7 files changed, 137 insertions(+), 5 deletions(-) > create mode 100644 hw/i386/ssdt-tpm.dsl > create mode 100644 include/hw/acpi/tpm.h > > diff --git a/hw/i386/Makefile.objs b/hw/i386/Makefile.objs > index 48014ab..3688cf8 100644 > --- a/hw/i386/Makefile.objs > +++ b/hw/i386/Makefile.objs > @@ -10,7 +10,8 @@ obj-y += bios-linker-loader.o > hw/i386/acpi-build.o: hw/i386/acpi-build.c hw/i386/acpi-dsdt.hex \ > hw/i386/ssdt-proc.hex hw/i386/ssdt-pcihp.hex hw/i386/ssdt-misc.hex \ > hw/i386/acpi-dsdt.hex hw/i386/q35-acpi-dsdt.hex \ > - hw/i386/q35-acpi-dsdt.hex hw/i386/ssdt-mem.hex > + hw/i386/q35-acpi-dsdt.hex hw/i386/ssdt-mem.hex \ > + hw/i386/ssdt-tpm.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/acpi-build.c b/hw/i386/acpi-build.c > index ebc5f03..d767e37 100644 > --- a/hw/i386/acpi-build.c > +++ b/hw/i386/acpi-build.c > @@ -38,6 +38,8 @@ > #include "hw/loader.h" > #include "hw/isa/isa.h" > #include "hw/acpi/memory_hotplug.h" > +#include "sysemu/tpm.h" > +#include "hw/acpi/tpm.h" > > /* Supported chipsets: */ > #include "hw/acpi/piix4.h" > @@ -75,6 +77,7 @@ typedef struct AcpiPmInfo { > > typedef struct AcpiMiscInfo { > bool has_hpet; > + bool has_tpm; > DECLARE_BITMAP(slot_hotplug_enable, PCI_SLOT_MAX); > const unsigned char *dsdt_code; > unsigned dsdt_size; > @@ -193,6 +196,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->pvpanic_port = pvpanic_port(); > } > > @@ -681,6 +685,7 @@ static inline char acpi_get_hex(uint32_t val) > > #include "hw/i386/ssdt-misc.hex" > #include "hw/i386/ssdt-pcihp.hex" > +#include "hw/i386/ssdt-tpm.hex" > > static void > build_append_notify_method(GArray *device, const char *name, > @@ -1167,6 +1172,40 @@ build_hpet(GArray *table_data, GArray *linker) > (void *)hpet, "HPET", sizeof(*hpet), 1); > } > > +static void > +build_tpm_tcpa(GArray *table_data, GArray *linker) > +{ > + Acpi20Tcpa *tcpa; > + uint32_t log_area_minimum_length = TPM_LOG_AREA_MINIMUM_SIZE; > + uint64_t log_area_start_address; > + size_t len = log_area_minimum_length + sizeof(*tcpa); > + > + log_area_start_address = table_data->len + sizeof(*tcpa); > + > + tcpa = acpi_data_push(table_data, len); > + > + tcpa->platform_class = cpu_to_le16(TPM_TCPA_ACPI_CLASS_CLIENT); > + tcpa->log_area_minimum_length = cpu_to_le32(log_area_minimum_length); > + tcpa->log_area_start_address = cpu_to_le64(log_area_start_address); > + > + /* LASA address to be filled by Guest linker */ > + bios_linker_loader_add_pointer(linker, ACPI_BUILD_TABLE_FILE, > + ACPI_BUILD_TABLE_FILE, > + table_data, &tcpa->log_area_start_address, > + sizeof(tcpa->log_area_start_address)); > + build_header(linker, table_data, > + (void *)tcpa, "TCPA", sizeof(*tcpa), 2); > +} > + > +static void > +build_tpm_ssdt(GArray *table_data, GArray *linker) > +{ > + void *tpm_ptr; > + > + tpm_ptr = acpi_data_push(table_data, sizeof(ssdt_tpm_aml)); > + memcpy(tpm_ptr, ssdt_tpm_aml, sizeof(ssdt_tpm_aml)); > +} > + > typedef enum { > MEM_AFFINITY_NOFLAGS = 0, > MEM_AFFINITY_ENABLED = (1 << 0), > @@ -1489,6 +1528,13 @@ void acpi_build(PcGuestInfo *guest_info, AcpiBuildTables *tables) > acpi_add_table(table_offsets, tables->table_data); > build_hpet(tables->table_data, tables->linker); > } > + if (misc.has_tpm) { > + acpi_add_table(table_offsets, tables->table_data); > + build_tpm_ssdt(tables->table_data, tables->linker); > + > + acpi_add_table(table_offsets, tables->table_data); > + build_tpm_tcpa(tables->table_data, tables->linker); > + } > if (guest_info->numa_nodes) { > acpi_add_table(table_offsets, tables->table_data); > build_srat(tables->table_data, tables->linker, &cpu, guest_info); > diff --git a/hw/i386/acpi-defs.h b/hw/i386/acpi-defs.h > index e93babb..1bc974a 100644 > --- a/hw/i386/acpi-defs.h > +++ b/hw/i386/acpi-defs.h > @@ -314,4 +314,15 @@ struct AcpiTableMcfg { > } QEMU_PACKED; > typedef struct AcpiTableMcfg AcpiTableMcfg; > > +/* > + * TCPA Description Table > + */ > +struct Acpi20Tcpa { > + ACPI_TABLE_HEADER_DEF /* ACPI common table header */ > + uint16_t platform_class; > + uint32_t log_area_minimum_length; > + uint64_t log_area_start_address; > +} QEMU_PACKED; > +typedef struct Acpi20Tcpa Acpi20Tcpa; > + > #endif > diff --git a/hw/i386/ssdt-tpm.dsl b/hw/i386/ssdt-tpm.dsl > new file mode 100644 > index 0000000..75d9691 > --- /dev/null > +++ b/hw/i386/ssdt-tpm.dsl > @@ -0,0 +1,43 @@ > +/* > + * 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_tpm_aml > + > +DefinitionBlock ( > + "ssdt-tpm.aml", // Output Filename > + "SSDT", // Signature > + 0x01, // SSDT Compliance Revision > + "BXPC", // OEMID > + "BXSSDT", // TABLE ID > + 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) > + } > + } > + } > +} > diff --git a/hw/tpm/tpm_tis.h b/hw/tpm/tpm_tis.h > index 916152a..6cdac24 100644 > --- a/hw/tpm/tpm_tis.h > +++ b/hw/tpm/tpm_tis.h > @@ -18,18 +18,15 @@ > #define TPM_TPM_TIS_H > > #include "hw/isa/isa.h" > +#include "hw/acpi/tpm.h" > #include "qemu-common.h" > > -#define TPM_TIS_ADDR_BASE 0xFED40000 > - > #define TPM_TIS_NUM_LOCALITIES 5 /* per spec */ > #define TPM_TIS_LOCALITY_SHIFT 12 > #define TPM_TIS_NO_LOCALITY 0xff > > #define TPM_TIS_IS_VALID_LOCTY(x) ((x) < TPM_TIS_NUM_LOCALITIES) > > -#define TPM_TIS_IRQ 5 > - > #define TPM_TIS_BUFFER_MAX 4096 > > #define TYPE_TPM_TIS "tpm-tis" > diff --git a/include/hw/acpi/tpm.h b/include/hw/acpi/tpm.h > new file mode 100644 > index 0000000..792fcbf > --- /dev/null > +++ b/include/hw/acpi/tpm.h > @@ -0,0 +1,29 @@ > +/* > + * tpm.h - TPM ACPI definitions > + * > + * Copyright (C) 2014 IBM Corporation > + * > + * Authors: > + * Stefan Berger > + * > + * This work is licensed under the terms of the GNU GPL, version 2 or later. > + * See the COPYING file in the top-level directory. > + * > + * Implementation of the TIS interface according to specs found at > + * http://www.trustedcomputinggroup.org > + * > + */ > +#ifndef HW_ACPI_TPM_H > +#define HW_ACPI_TPM_H > + > +#define TPM_TIS_ADDR_BASE 0xFED40000 > +#define TPM_TIS_ADDR_SIZE 0x5000 > + > +#define TPM_TIS_IRQ 5 > + > +#define TPM_LOG_AREA_MINIMUM_SIZE (64 * 1024) > + > +#define TPM_TCPA_ACPI_CLASS_CLIENT 0 > +#define TPM_TCPA_ACPI_CLASS_SERVER 1 > + > +#endif /* HW_ACPI_TPM_H */ > diff --git a/include/sysemu/tpm.h b/include/sysemu/tpm.h > index 13febdd..7030109 100644 > --- a/include/sysemu/tpm.h > +++ b/include/sysemu/tpm.h > @@ -20,4 +20,9 @@ int tpm_config_parse(QemuOptsList *opts_list, const char *optarg); > int tpm_init(void); > void tpm_cleanup(void); > > +static inline bool tpm_find(void) > +{ > + return object_resolve_path_type("", "tpm-tis", NULL) != NULL; > +} > + > #endif /* QEMU_TPM_H */ > -- > 1.9.3