Message ID | 20170329074326.jxeoxtn4tbjjwcl2@petr-dev3.eng.vmware.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
On Wed, Mar 29, 2017 at 12:43:26AM -0700, Petr Vandrovec wrote: > From: Petr Vandrovec <petr@vmware.com> > > Latest draft of TPM 2 ACPI specification added TCG log start/length > to the TPM2 ACPI table. So Linux kernel can now read it without > having to get involved with boot loader, same way TPM1/TCPA tables > work. > > Signed-off-by: Petr Vandrovec <petr@vmware.com> > --- > drivers/char/tpm/tpm_acpi.c | 70 ++++++++++++++++++++++++++++----------------- > 1 file changed, 43 insertions(+), 27 deletions(-) > > diff --git a/drivers/char/tpm/tpm_acpi.c b/drivers/char/tpm/tpm_acpi.c > index 169edf3ce86d..e48b1503220c 100644 > --- a/drivers/char/tpm/tpm_acpi.c > +++ b/drivers/char/tpm/tpm_acpi.c > @@ -48,46 +48,62 @@ struct acpi_tcpa { > /* read binary bios log */ > int tpm_read_log_acpi(struct tpm_chip *chip) > { > - struct acpi_tcpa *buff; > acpi_status status; > void __iomem *virt; > u64 len, start; > struct tpm_bios_log *log; > > - if (chip->flags & TPM_CHIP_FLAG_TPM2) > - return -ENODEV; > - > - log = &chip->log; > - > /* Unfortuntely ACPI does not associate the event log with a specific > * TPM, like PPI. Thus all ACPI TPMs will read the same log. > */ > if (!chip->acpi_dev_handle) > return -ENODEV; > > - /* Find TCPA entry in RSDT (ACPI_LOGICAL_ADDRESSING) */ > - status = acpi_get_table(ACPI_SIG_TCPA, 1, > - (struct acpi_table_header **)&buff); > - > - if (ACPI_FAILURE(status)) > - return -ENODEV; > - > - switch(buff->platform_class) { > - case BIOS_SERVER: > - len = buff->server.log_max_len; > - start = buff->server.log_start_addr; > - break; > - case BIOS_CLIENT: > - default: > - len = buff->client.log_max_len; > - start = buff->client.log_start_addr; > - break; > - } > - if (!len) { > - dev_warn(&chip->dev, "%s: TCPA log area empty\n", __func__); > - return -EIO; > + if (chip->flags & TPM_CHIP_FLAG_TPM2) { > + struct acpi_table_tpm2 *buff; > + > + /* Find TPM2 entry in RSDT (ACPI_LOGICAL_ADDRESSING) */ > + status = acpi_get_table(ACPI_SIG_TPM2, 1, > + (struct acpi_table_header **)&buff); > + > + if (ACPI_FAILURE(status) || buff->header.length < ACPI_TPM2_SIZE_WITH_LOG) > + return -ENODEV; > + > + len = buff->minimum_log_length; > + start = buff->log_address; > + if (!len) { > + dev_warn(&chip->dev, "%s: TPM2 log area empty\n", __func__); > + return -EIO; > + } > + } else { > + struct acpi_tcpa *buff; > + > + /* Find TCPA entry in RSDT (ACPI_LOGICAL_ADDRESSING) */ > + status = acpi_get_table(ACPI_SIG_TCPA, 1, > + (struct acpi_table_header **)&buff); > + > + if (ACPI_FAILURE(status)) > + return -ENODEV; > + > + switch(buff->platform_class) { > + case BIOS_SERVER: > + len = buff->server.log_max_len; > + start = buff->server.log_start_addr; > + break; > + case BIOS_CLIENT: > + default: > + len = buff->client.log_max_len; > + start = buff->client.log_start_addr; > + break; > + } > + if (!len) { > + dev_warn(&chip->dev, "%s: TCPA log area empty\n", __func__); > + return -EIO; > + } > } > > + log = &chip->log; > + > /* malloc EventLog space */ > log->bios_event_log = kmalloc(len, GFP_KERNEL); > if (!log->bios_event_log) > -- > 2.11.0 > It would be a better idea to rename the existing function as tpm1_read_log_acpi() and add a new function called tpm2_read_log_acpi(). /Jarkko ------------------------------------------------------------------------------ Check out the vibrant tech community on one of the world's most engaging tech sites, Slashdot.org! http://sdm.link/slashdot
diff --git a/drivers/char/tpm/tpm_acpi.c b/drivers/char/tpm/tpm_acpi.c index 169edf3ce86d..e48b1503220c 100644 --- a/drivers/char/tpm/tpm_acpi.c +++ b/drivers/char/tpm/tpm_acpi.c @@ -48,46 +48,62 @@ struct acpi_tcpa { /* read binary bios log */ int tpm_read_log_acpi(struct tpm_chip *chip) { - struct acpi_tcpa *buff; acpi_status status; void __iomem *virt; u64 len, start; struct tpm_bios_log *log; - if (chip->flags & TPM_CHIP_FLAG_TPM2) - return -ENODEV; - - log = &chip->log; - /* Unfortuntely ACPI does not associate the event log with a specific * TPM, like PPI. Thus all ACPI TPMs will read the same log. */ if (!chip->acpi_dev_handle) return -ENODEV; - /* Find TCPA entry in RSDT (ACPI_LOGICAL_ADDRESSING) */ - status = acpi_get_table(ACPI_SIG_TCPA, 1, - (struct acpi_table_header **)&buff); - - if (ACPI_FAILURE(status)) - return -ENODEV; - - switch(buff->platform_class) { - case BIOS_SERVER: - len = buff->server.log_max_len; - start = buff->server.log_start_addr; - break; - case BIOS_CLIENT: - default: - len = buff->client.log_max_len; - start = buff->client.log_start_addr; - break; - } - if (!len) { - dev_warn(&chip->dev, "%s: TCPA log area empty\n", __func__); - return -EIO; + if (chip->flags & TPM_CHIP_FLAG_TPM2) { + struct acpi_table_tpm2 *buff; + + /* Find TPM2 entry in RSDT (ACPI_LOGICAL_ADDRESSING) */ + status = acpi_get_table(ACPI_SIG_TPM2, 1, + (struct acpi_table_header **)&buff); + + if (ACPI_FAILURE(status) || buff->header.length < ACPI_TPM2_SIZE_WITH_LOG) + return -ENODEV; + + len = buff->minimum_log_length; + start = buff->log_address; + if (!len) { + dev_warn(&chip->dev, "%s: TPM2 log area empty\n", __func__); + return -EIO; + } + } else { + struct acpi_tcpa *buff; + + /* Find TCPA entry in RSDT (ACPI_LOGICAL_ADDRESSING) */ + status = acpi_get_table(ACPI_SIG_TCPA, 1, + (struct acpi_table_header **)&buff); + + if (ACPI_FAILURE(status)) + return -ENODEV; + + switch(buff->platform_class) { + case BIOS_SERVER: + len = buff->server.log_max_len; + start = buff->server.log_start_addr; + break; + case BIOS_CLIENT: + default: + len = buff->client.log_max_len; + start = buff->client.log_start_addr; + break; + } + if (!len) { + dev_warn(&chip->dev, "%s: TCPA log area empty\n", __func__); + return -EIO; + } } + log = &chip->log; + /* malloc EventLog space */ log->bios_event_log = kmalloc(len, GFP_KERNEL); if (!log->bios_event_log)