1 /* 2 * Copyright (C) 2005 IBM Corporation 3 * 4 * Authors: 5 * Seiji Munetoh <munetoh@jp.ibm.com> 6 * Stefan Berger <stefanb@us.ibm.com> 7 * Reiner Sailer <sailer@watson.ibm.com> 8 * Kylene Hall <kjhall@us.ibm.com> 9 * Nayna Jain <nayna@linux.vnet.ibm.com> 10 * 11 * Maintained by: <tpmdd-devel@lists.sourceforge.net> 12 * 13 * Access to the event log extended by the TCG BIOS of PC platform 14 * 15 * This program is free software; you can redistribute it and/or 16 * modify it under the terms of the GNU General Public License 17 * as published by the Free Software Foundation; either version 18 * 2 of the License, or (at your option) any later version. 19 * 20 */ 21 22 #include <linux/seq_file.h> 23 #include <linux/fs.h> 24 #include <linux/security.h> 25 #include <linux/module.h> 26 #include <linux/slab.h> 27 #include <linux/acpi.h> 28 #include <linux/tpm_eventlog.h> 29 30 #include "../tpm.h" 31 32 struct acpi_tcpa { 33 struct acpi_table_header hdr; 34 u16 platform_class; 35 union { 36 struct client_hdr { 37 u32 log_max_len __packed; 38 u64 log_start_addr __packed; 39 } client; 40 struct server_hdr { 41 u16 reserved; 42 u64 log_max_len __packed; 43 u64 log_start_addr __packed; 44 } server; 45 }; 46 }; 47 48 /* read binary bios log */ 49 int tpm_read_log_acpi(struct tpm_chip *chip) 50 { 51 struct acpi_tcpa *buff; 52 acpi_status status; 53 void __iomem *virt; 54 u64 len, start; 55 struct tpm_bios_log *log; 56 57 if (chip->flags & TPM_CHIP_FLAG_TPM2) 58 return -ENODEV; 59 60 log = &chip->log; 61 62 /* Unfortuntely ACPI does not associate the event log with a specific 63 * TPM, like PPI. Thus all ACPI TPMs will read the same log. 64 */ 65 if (!chip->acpi_dev_handle) 66 return -ENODEV; 67 68 /* Find TCPA entry in RSDT (ACPI_LOGICAL_ADDRESSING) */ 69 status = acpi_get_table(ACPI_SIG_TCPA, 1, 70 (struct acpi_table_header **)&buff); 71 72 if (ACPI_FAILURE(status)) 73 return -ENODEV; 74 75 switch(buff->platform_class) { 76 case BIOS_SERVER: 77 len = buff->server.log_max_len; 78 start = buff->server.log_start_addr; 79 break; 80 case BIOS_CLIENT: 81 default: 82 len = buff->client.log_max_len; 83 start = buff->client.log_start_addr; 84 break; 85 } 86 if (!len) { 87 dev_warn(&chip->dev, "%s: TCPA log area empty\n", __func__); 88 return -EIO; 89 } 90 91 /* malloc EventLog space */ 92 log->bios_event_log = kmalloc(len, GFP_KERNEL); 93 if (!log->bios_event_log) 94 return -ENOMEM; 95 96 log->bios_event_log_end = log->bios_event_log + len; 97 98 virt = acpi_os_map_iomem(start, len); 99 if (!virt) 100 goto err; 101 102 memcpy_fromio(log->bios_event_log, virt, len); 103 104 acpi_os_unmap_iomem(virt, len); 105 return EFI_TCG2_EVENT_LOG_FORMAT_TCG_1_2; 106 107 err: 108 kfree(log->bios_event_log); 109 log->bios_event_log = NULL; 110 return -EIO; 111 112 } 113