diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2018-01-31 13:12:31 -0800 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2018-01-31 13:12:31 -0800 |
commit | ae0cb7be35fe6c7e8bcc816ec4185d0a37748cc1 (patch) | |
tree | 2453151c8d507502ce91c6827f3e8a35e1777996 /drivers/char/tpm/tpm_eventlog_acpi.c | |
parent | 2a7149031457c5dd05f670737a9dd5d32524f145 (diff) | |
parent | ebceb1c87c0c482d47cb92dc3cc51d28f7387716 (diff) |
Merge branch 'next-tpm' of git://git.kernel.org/pub/scm/linux/kernel/git/jmorris/linux-security
Pull tpm updates from James Morris:
- reduce polling delays in tpm_tis
- support retrieving TPM 2.0 Event Log through EFI before
ExitBootServices
- replace tpm-rng.c with a hwrng device managed by the driver for each
TPM device
- TPM resource manager synthesizes TPM_RC_COMMAND_CODE response instead
of returning -EINVAL for unknown TPM commands. This makes user space
more sound.
- CLKRUN fixes:
* Keep #CLKRUN disable through the entier TPM command/response flow
* Check whether #CLKRUN is enabled before disabling and enabling it
again because enabling it breaks PS/2 devices on a system where it
is disabled
* 'next-tpm' of git://git.kernel.org/pub/scm/linux/kernel/git/jmorris/linux-security:
tpm: remove unused variables
tpm: remove unused data fields from I2C and OF device ID tables
tpm: only attempt to disable the LPC CLKRUN if is already enabled
tpm: follow coding style for variable declaration in tpm_tis_core_init()
tpm: delete the TPM_TIS_CLK_ENABLE flag
tpm: Update MAINTAINERS for Jason Gunthorpe
tpm: Keep CLKRUN enabled throughout the duration of transmit_cmd()
tpm_tis: Move ilb_base_addr to tpm_tis_data
tpm2-cmd: allow more attempts for selftest execution
tpm: return a TPM_RC_COMMAND_CODE response if command is not implemented
tpm: Move Linux RNG connection to hwrng
tpm: use struct tpm_chip for tpm_chip_find_get()
tpm: parse TPM event logs based on EFI table
efi: call get_event_log before ExitBootServices
tpm: add event log format version
tpm: rename event log provider files
tpm: move tpm_eventlog.h outside of drivers folder
tpm: use tpm_msleep() value as max delay
tpm: reduce tpm polling delay in tpm_tis_core
tpm: move wait_for_tpm_stat() to respective driver files
Diffstat (limited to 'drivers/char/tpm/tpm_eventlog_acpi.c')
-rw-r--r-- | drivers/char/tpm/tpm_eventlog_acpi.c | 112 |
1 files changed, 112 insertions, 0 deletions
diff --git a/drivers/char/tpm/tpm_eventlog_acpi.c b/drivers/char/tpm/tpm_eventlog_acpi.c new file mode 100644 index 000000000000..66f19e93c216 --- /dev/null +++ b/drivers/char/tpm/tpm_eventlog_acpi.c @@ -0,0 +1,112 @@ +/* + * Copyright (C) 2005 IBM Corporation + * + * Authors: + * Seiji Munetoh <munetoh@jp.ibm.com> + * Stefan Berger <stefanb@us.ibm.com> + * Reiner Sailer <sailer@watson.ibm.com> + * Kylene Hall <kjhall@us.ibm.com> + * Nayna Jain <nayna@linux.vnet.ibm.com> + * + * Maintained by: <tpmdd-devel@lists.sourceforge.net> + * + * Access to the event log extended by the TCG BIOS of PC platform + * + * 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. + * + */ + +#include <linux/seq_file.h> +#include <linux/fs.h> +#include <linux/security.h> +#include <linux/module.h> +#include <linux/slab.h> +#include <linux/acpi.h> +#include <linux/tpm_eventlog.h> + +#include "tpm.h" + +struct acpi_tcpa { + struct acpi_table_header hdr; + u16 platform_class; + union { + struct client_hdr { + u32 log_max_len __packed; + u64 log_start_addr __packed; + } client; + struct server_hdr { + u16 reserved; + u64 log_max_len __packed; + u64 log_start_addr __packed; + } server; + }; +}; + +/* 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; + } + + /* malloc EventLog space */ + log->bios_event_log = kmalloc(len, GFP_KERNEL); + if (!log->bios_event_log) + return -ENOMEM; + + log->bios_event_log_end = log->bios_event_log + len; + + virt = acpi_os_map_iomem(start, len); + if (!virt) + goto err; + + memcpy_fromio(log->bios_event_log, virt, len); + + acpi_os_unmap_iomem(virt, len); + return EFI_TCG2_EVENT_LOG_FORMAT_TCG_1_2; + +err: + kfree(log->bios_event_log); + log->bios_event_log = NULL; + return -EIO; + +} |