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 #include "common.h" 32 33 struct acpi_tcpa { 34 struct acpi_table_header hdr; 35 u16 platform_class; 36 union { 37 struct client_hdr { 38 u32 log_max_len __packed; 39 u64 log_start_addr __packed; 40 } client; 41 struct server_hdr { 42 u16 reserved; 43 u64 log_max_len __packed; 44 u64 log_start_addr __packed; 45 } server; 46 }; 47 }; 48 49 /* read binary bios log */ 50 int tpm_read_log_acpi(struct tpm_chip *chip) 51 { 52 struct acpi_tcpa *buff; 53 acpi_status status; 54 void __iomem *virt; 55 u64 len, start; 56 struct tpm_bios_log *log; 57 58 if (chip->flags & TPM_CHIP_FLAG_TPM2) 59 return -ENODEV; 60 61 log = &chip->log; 62 63 /* Unfortuntely ACPI does not associate the event log with a specific 64 * TPM, like PPI. Thus all ACPI TPMs will read the same log. 65 */ 66 if (!chip->acpi_dev_handle) 67 return -ENODEV; 68 69 /* Find TCPA entry in RSDT (ACPI_LOGICAL_ADDRESSING) */ 70 status = acpi_get_table(ACPI_SIG_TCPA, 1, 71 (struct acpi_table_header **)&buff); 72 73 if (ACPI_FAILURE(status)) 74 return -ENODEV; 75 76 switch(buff->platform_class) { 77 case BIOS_SERVER: 78 len = buff->server.log_max_len; 79 start = buff->server.log_start_addr; 80 break; 81 case BIOS_CLIENT: 82 default: 83 len = buff->client.log_max_len; 84 start = buff->client.log_start_addr; 85 break; 86 } 87 if (!len) { 88 dev_warn(&chip->dev, "%s: TCPA log area empty\n", __func__); 89 return -EIO; 90 } 91 92 /* malloc EventLog space */ 93 log->bios_event_log = kmalloc(len, GFP_KERNEL); 94 if (!log->bios_event_log) 95 return -ENOMEM; 96 97 log->bios_event_log_end = log->bios_event_log + len; 98 99 virt = acpi_os_map_iomem(start, len); 100 if (!virt) 101 goto err; 102 103 memcpy_fromio(log->bios_event_log, virt, len); 104 105 acpi_os_unmap_iomem(virt, len); 106 return EFI_TCG2_EVENT_LOG_FORMAT_TCG_1_2; 107 108 err: 109 kfree(log->bios_event_log); 110 log->bios_event_log = NULL; 111 return -EIO; 112 113 } 114