The event log is an optional firmware feature, if the firmware
does not support it then the securityfs files should not be created
and no other notification given.
- Uniformly return -ENODEV from the tpm_bios_log_setup cone if
no event log is detected.
- Check in ACPI if this node was discovered via ACPI.
- Improve the check in OF to make sure there is a parent and to
fail detection if the two log properties are not declared
- Pass through all other error codes instead of filtering just some
Signed-off-by: Jason Gunthorpe <jgunthorpe@obsidianresearch.com>
Reviewed-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
Tested-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
Signed-off-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
tpm_sysfs_add_device(chip);
rc = tpm_bios_log_setup(chip);
tpm_sysfs_add_device(chip);
rc = tpm_bios_log_setup(chip);
+ if (rc != 0 && rc != -ENODEV)
return rc;
tpm_add_ppi(chip);
return rc;
tpm_add_ppi(chip);
+ /* 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))
/* 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))
switch(buff->platform_class) {
case BIOS_SERVER:
switch(buff->platform_class) {
case BIOS_SERVER:
}
rc = tpm_read_log_acpi(chip);
}
rc = tpm_read_log_acpi(chip);
- if ((rc == 0) || (rc == -ENOMEM))
- rc = tpm_read_log_of(chip);
-
- return rc;
+ return tpm_read_log_of(chip);
+/*
+ * tpm_bios_log_setup() - Read the event log from the firmware
+ * @chip: TPM chip to use.
+ *
+ * If an event log is found then the securityfs files are setup to
+ * export it to userspace, otherwise nothing is done.
+ *
+ * Returns -ENODEV if the firmware has no event log.
+ */
int tpm_bios_log_setup(struct tpm_chip *chip)
{
const char *name = dev_name(&chip->dev);
int tpm_bios_log_setup(struct tpm_chip *chip)
{
const char *name = dev_name(&chip->dev);
return 0;
rc = tpm_read_log(chip);
return 0;
rc = tpm_read_log(chip);
- /*
- * read_log failure means event log is not supported except for ENOMEM.
- */
- if (rc < 0) {
- if (rc == -ENOMEM)
- return -ENODEV;
- else
- return rc;
- }
cnt = 0;
chip->bios_dir[cnt] = securityfs_create_dir(name, NULL);
cnt = 0;
chip->bios_dir[cnt] = securityfs_create_dir(name, NULL);
struct tpm_bios_log *log;
log = &chip->log;
struct tpm_bios_log *log;
log = &chip->log;
- if (chip->dev.parent->of_node)
+ if (chip->dev.parent && chip->dev.parent->of_node)
np = chip->dev.parent->of_node;
else
return -ENODEV;
sizep = of_get_property(np, "linux,sml-size", NULL);
np = chip->dev.parent->of_node;
else
return -ENODEV;
sizep = of_get_property(np, "linux,sml-size", NULL);
+ basep = of_get_property(np, "linux,sml-base", NULL);
+ if (sizep == NULL && basep == NULL)
+ return -ENODEV;
+ if (sizep == NULL || basep == NULL)
return -EIO;
if (*sizep == 0) {
return -EIO;
if (*sizep == 0) {
- basep = of_get_property(np, "linux,sml-base", NULL);
- if (basep == NULL)
- return -EIO;
-
log->bios_event_log = kmalloc(*sizep, GFP_KERNEL);
if (!log->bios_event_log)
return -ENOMEM;
log->bios_event_log = kmalloc(*sizep, GFP_KERNEL);
if (!log->bios_event_log)
return -ENOMEM;