From: Stefan Berger <stefanb@linux.vnet.ibm.com>
To: Igor Mammedov <imammedo@redhat.com>
Cc: stefanb@us.ibm.com, mst@redhat.com, qemu-devel@nongnu.org,
George Wilson <gcwilson@us.ibm.com>,
Dimitrios Pendarakis <dimitris@us.ibm.com>,
quan.xu@intel.com
Subject: Re: [Qemu-devel] [PATCH v3 3/3] TPM2 ACPI table support
Date: Fri, 15 May 2015 11:31:30 -0400 [thread overview]
Message-ID: <55561152.7060800@linux.vnet.ibm.com> (raw)
In-Reply-To: <20150515164401.409f58dd@nial.brq.redhat.com>
On 05/15/2015 10:44 AM, Igor Mammedov wrote:
> On Fri, 8 May 2015 11:52:46 -0400
> Stefan Berger <stefanb@linux.vnet.ibm.com> wrote:
>
>> 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 <stefanb@linux.vnet.ibm.com>
>>
>> ---
>>
>> v2->v3:
>> - followed Igor's suggestion of a default case with an assert()
>> - added an SSDT for TPM2; it will be a bit different than TPM1.2's
>> SSDT once we add PPI to it
>> ---
>> hw/i386/Makefile.objs | 2 +-
>> hw/i386/acpi-build.c | 38 ++++++++++++++++++++++++++++++++++----
>> hw/i386/acpi-defs.h | 18 ++++++++++++++++++
>> hw/i386/ssdt-tpm2.dsl | 44 ++++++++++++++++++++++++++++++++++++++++++++
>> hw/tpm/tpm_tis.c | 11 +++++++++++
>> include/hw/acpi/tpm.h | 5 +++++
>> include/sysemu/tpm.h | 11 +++++++++--
>> 7 files changed, 122 insertions(+), 7 deletions(-)
>> create mode 100644 hw/i386/ssdt-tpm2.dsl
>>
>> 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/acpi-build.c b/hw/i386/acpi-build.c
>> index e761005..e648ab5 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;
>> + 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();
>> }
>> @@ -468,6 +469,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.
>> @@ -1065,6 +1067,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));
> ^^^ does almost the same as build_tpm_ssdt(), replacing
> AML template with dynamic AML generation would help to consolidate
> v1 and v2 versions of build_tpm_ssdt().
So the SSDT's for the TPM v1.2 and TPM 2 differ, but only slightly so.
What does building the AML template via Opcodes etc. help in this case?
Doesn't this
make the code more or less unreadable? I don't understand why we
shoudln't use
the AML compiler on it?
>
>> +
>> + 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 +1449,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/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/i386/ssdt-tpm2.dsl b/hw/i386/ssdt-tpm2.dsl
>> new file mode 100644
>> index 0000000..96936ed
>> --- /dev/null
>> +++ b/hw/i386/ssdt-tpm2.dsl
>> @@ -0,0 +1,44 @@
>> +/*
>> + * 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 <http://www.gnu.org/licenses/>.
>> + */
>> +#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
>> + )
>> +{
>> + 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)
>> +
>> + /* TPM 2 is recent enough to support interrupts */
>> + IRQNoFlags () {TPM_TIS_IRQ}
>> + })
>> + Method (_STA, 0, NotSerialized) {
>> + Return (0x0F)
>> + }
>> + }
>> + }
>> +}
> Pls, don't add another ASL template.
Pls tell me why it is better to compile by hand rather than use a higher
level language here?
Regards,
Stefan
> It would be better to rewrite above using AML API in C
> and while at it convert hw/i386/ssdt-tpm.dsl to AML API as well.
> hw/i386/ssdt-tpm.dsl is pretty much the same as ssdt-tpm2.aml
> except of IRQNoFlags() so they could share common code
> and for v2 you'll add extra IRQ resource.
>
> Also I'd suggest to put TPM device under \_SB.PCI0 scope
> so that its _CRS wouldn't conflict with PCI0._CRS but rather
> be a consumer of it.
>
>
>
>> diff --git a/hw/tpm/tpm_tis.c b/hw/tpm/tpm_tis.c
>> index 69fbfae..daf2ac9 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/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 */
next prev parent reply other threads:[~2015-05-15 15:31 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-05-08 15:52 [Qemu-devel] [PATCH v3 0/3] tpm: Upgrade TPM TIS for support of a TPM 2 Stefan Berger
2015-05-08 15:52 ` [Qemu-devel] [PATCH v3 1/3] Extend TPM TIS interface to support " Stefan Berger
2015-05-08 15:52 ` [Qemu-devel] [PATCH v3 2/3] tpm: Probe for connected TPM 1.2 or " Stefan Berger
2015-05-08 15:52 ` [Qemu-devel] [PATCH v3 3/3] TPM2 ACPI table support Stefan Berger
2015-05-15 14:44 ` Igor Mammedov
2015-05-15 15:31 ` Stefan Berger [this message]
2015-05-15 16:57 ` Igor Mammedov
2015-05-15 19:13 ` Stefan Berger
2015-05-19 13:16 ` Igor Mammedov
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=55561152.7060800@linux.vnet.ibm.com \
--to=stefanb@linux.vnet.ibm.com \
--cc=dimitris@us.ibm.com \
--cc=gcwilson@us.ibm.com \
--cc=imammedo@redhat.com \
--cc=mst@redhat.com \
--cc=qemu-devel@nongnu.org \
--cc=quan.xu@intel.com \
--cc=stefanb@us.ibm.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.