xref: /linux/drivers/char/tpm/eventlog/acpi.c (revision 0bfb23746052168620c5b52f49d8a47c3bb022fa)
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