aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-10-03 00:38:48 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2012-10-03 00:38:48 -0400
commit88265322c14cce39f7afbc416726ef4fac413298 (patch)
treee4956f905ef617971f87788d8f8a09dbb66b70a3 /drivers/char
parent65b99c74fdd325d1ffa2e5663295888704712604 (diff)
parentbf5308344527d015ac9a6d2bda4ad4d40fd7d943 (diff)
Merge branch 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/jmorris/linux-security
Pull security subsystem updates from James Morris: "Highlights: - Integrity: add local fs integrity verification to detect offline attacks - Integrity: add digital signature verification - Simple stacking of Yama with other LSMs (per LSS discussions) - IBM vTPM support on ppc64 - Add new driver for Infineon I2C TIS TPM - Smack: add rule revocation for subject labels" Fixed conflicts with the user namespace support in kernel/auditsc.c and security/integrity/ima/ima_policy.c. * 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/jmorris/linux-security: (39 commits) Documentation: Update git repository URL for Smack userland tools ima: change flags container data type Smack: setprocattr memory leak fix Smack: implement revoking all rules for a subject label Smack: remove task_wait() hook. ima: audit log hashes ima: generic IMA action flag handling ima: rename ima_must_appraise_or_measure audit: export audit_log_task_info tpm: fix tpm_acpi sparse warning on different address spaces samples/seccomp: fix 31 bit build on s390 ima: digital signature verification support ima: add support for different security.ima data types ima: add ima_inode_setxattr/removexattr function and calls ima: add inode_post_setattr call ima: replace iint spinblock with rwlock/read_lock ima: allocating iint improvements ima: add appraise action keywords and default rules ima: integrity appraisal extension vfs: move ima_file_free before releasing the file ...
Diffstat (limited to 'drivers/char')
-rw-r--r--drivers/char/hw_random/Kconfig13
-rw-r--r--drivers/char/hw_random/Makefile1
-rw-r--r--drivers/char/hw_random/tpm-rng.c50
-rw-r--r--drivers/char/tpm/Kconfig19
-rw-r--r--drivers/char/tpm/Makefile8
-rw-r--r--drivers/char/tpm/tpm.c74
-rw-r--r--drivers/char/tpm/tpm.h35
-rw-r--r--drivers/char/tpm/tpm_acpi.c109
-rw-r--r--drivers/char/tpm/tpm_eventlog.c (renamed from drivers/char/tpm/tpm_bios.c)147
-rw-r--r--drivers/char/tpm/tpm_eventlog.h86
-rw-r--r--drivers/char/tpm/tpm_i2c_infineon.c695
-rw-r--r--drivers/char/tpm/tpm_ibmvtpm.c749
-rw-r--r--drivers/char/tpm/tpm_ibmvtpm.h77
-rw-r--r--drivers/char/tpm/tpm_of.c73
-rw-r--r--drivers/char/tpm/tpm_ppi.c461
-rw-r--r--drivers/char/tpm/tpm_tis.c3
16 files changed, 2440 insertions, 160 deletions
diff --git a/drivers/char/hw_random/Kconfig b/drivers/char/hw_random/Kconfig
index 7c0d391996b5..fbd9b2b850ef 100644
--- a/drivers/char/hw_random/Kconfig
+++ b/drivers/char/hw_random/Kconfig
@@ -289,3 +289,16 @@ config HW_RANDOM_EXYNOS
289 module will be called exynos-rng. 289 module will be called exynos-rng.
290 290
291 If unsure, say Y. 291 If unsure, say Y.
292
293config HW_RANDOM_TPM
294 tristate "TPM HW Random Number Generator support"
295 depends on HW_RANDOM && TCG_TPM
296 default HW_RANDOM
297 ---help---
298 This driver provides kernel-side support for the Random Number
299 Generator in the Trusted Platform Module
300
301 To compile this driver as a module, choose M here: the
302 module will be called tpm-rng.
303
304 If unsure, say Y.
diff --git a/drivers/char/hw_random/Makefile b/drivers/char/hw_random/Makefile
index 39a757ca15b6..1fd7eec9fbf6 100644
--- a/drivers/char/hw_random/Makefile
+++ b/drivers/char/hw_random/Makefile
@@ -25,3 +25,4 @@ obj-$(CONFIG_HW_RANDOM_PICOXCELL) += picoxcell-rng.o
25obj-$(CONFIG_HW_RANDOM_PPC4XX) += ppc4xx-rng.o 25obj-$(CONFIG_HW_RANDOM_PPC4XX) += ppc4xx-rng.o
26obj-$(CONFIG_HW_RANDOM_PSERIES) += pseries-rng.o 26obj-$(CONFIG_HW_RANDOM_PSERIES) += pseries-rng.o
27obj-$(CONFIG_HW_RANDOM_EXYNOS) += exynos-rng.o 27obj-$(CONFIG_HW_RANDOM_EXYNOS) += exynos-rng.o
28obj-$(CONFIG_HW_RANDOM_TPM) += tpm-rng.o
diff --git a/drivers/char/hw_random/tpm-rng.c b/drivers/char/hw_random/tpm-rng.c
new file mode 100644
index 000000000000..d6d448266f07
--- /dev/null
+++ b/drivers/char/hw_random/tpm-rng.c
@@ -0,0 +1,50 @@
1/*
2 * Copyright (C) 2012 Kent Yoder IBM Corporation
3 *
4 * HWRNG interfaces to pull RNG data from a TPM
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 */
19
20#include <linux/module.h>
21#include <linux/hw_random.h>
22#include <linux/tpm.h>
23
24#define MODULE_NAME "tpm-rng"
25
26static int tpm_rng_read(struct hwrng *rng, void *data, size_t max, bool wait)
27{
28 return tpm_get_random(TPM_ANY_NUM, data, max);
29}
30
31static struct hwrng tpm_rng = {
32 .name = MODULE_NAME,
33 .read = tpm_rng_read,
34};
35
36static int __init rng_init(void)
37{
38 return hwrng_register(&tpm_rng);
39}
40module_init(rng_init);
41
42static void __exit rng_exit(void)
43{
44 hwrng_unregister(&tpm_rng);
45}
46module_exit(rng_exit);
47
48MODULE_LICENSE("GPL v2");
49MODULE_AUTHOR("Kent Yoder <key@linux.vnet.ibm.com>");
50MODULE_DESCRIPTION("RNG driver for TPM devices");
diff --git a/drivers/char/tpm/Kconfig b/drivers/char/tpm/Kconfig
index a048199ce866..915875e431d2 100644
--- a/drivers/char/tpm/Kconfig
+++ b/drivers/char/tpm/Kconfig
@@ -33,6 +33,17 @@ config TCG_TIS
33 from within Linux. To compile this driver as a module, choose 33 from within Linux. To compile this driver as a module, choose
34 M here; the module will be called tpm_tis. 34 M here; the module will be called tpm_tis.
35 35
36config TCG_TIS_I2C_INFINEON
37 tristate "TPM Interface Specification 1.2 Interface (I2C - Infineon)"
38 depends on I2C
39 ---help---
40 If you have a TPM security chip that is compliant with the
41 TCG TIS 1.2 TPM specification and Infineon's I2C Protocol Stack
42 Specification 0.20 say Yes and it will be accessible from within
43 Linux.
44 To compile this driver as a module, choose M here; the module
45 will be called tpm_tis_i2c_infineon.
46
36config TCG_NSC 47config TCG_NSC
37 tristate "National Semiconductor TPM Interface" 48 tristate "National Semiconductor TPM Interface"
38 depends on X86 49 depends on X86
@@ -62,4 +73,12 @@ config TCG_INFINEON
62 Further information on this driver and the supported hardware 73 Further information on this driver and the supported hardware
63 can be found at http://www.trust.rub.de/projects/linux-device-driver-infineon-tpm/ 74 can be found at http://www.trust.rub.de/projects/linux-device-driver-infineon-tpm/
64 75
76config TCG_IBMVTPM
77 tristate "IBM VTPM Interface"
78 depends on PPC64
79 ---help---
80 If you have IBM virtual TPM (VTPM) support say Yes and it
81 will be accessible from within Linux. To compile this driver
82 as a module, choose M here; the module will be called tpm_ibmvtpm.
83
65endif # TCG_TPM 84endif # TCG_TPM
diff --git a/drivers/char/tpm/Makefile b/drivers/char/tpm/Makefile
index ea3a1e02a824..5b3fc8bc6c13 100644
--- a/drivers/char/tpm/Makefile
+++ b/drivers/char/tpm/Makefile
@@ -4,8 +4,16 @@
4obj-$(CONFIG_TCG_TPM) += tpm.o 4obj-$(CONFIG_TCG_TPM) += tpm.o
5ifdef CONFIG_ACPI 5ifdef CONFIG_ACPI
6 obj-$(CONFIG_TCG_TPM) += tpm_bios.o 6 obj-$(CONFIG_TCG_TPM) += tpm_bios.o
7 tpm_bios-objs += tpm_eventlog.o tpm_acpi.o tpm_ppi.o
8else
9ifdef CONFIG_TCG_IBMVTPM
10 obj-$(CONFIG_TCG_TPM) += tpm_bios.o
11 tpm_bios-objs += tpm_eventlog.o tpm_of.o
12endif
7endif 13endif
8obj-$(CONFIG_TCG_TIS) += tpm_tis.o 14obj-$(CONFIG_TCG_TIS) += tpm_tis.o
15obj-$(CONFIG_TCG_TIS_I2C_INFINEON) += tpm_i2c_infineon.o
9obj-$(CONFIG_TCG_NSC) += tpm_nsc.o 16obj-$(CONFIG_TCG_NSC) += tpm_nsc.o
10obj-$(CONFIG_TCG_ATMEL) += tpm_atmel.o 17obj-$(CONFIG_TCG_ATMEL) += tpm_atmel.o
11obj-$(CONFIG_TCG_INFINEON) += tpm_infineon.o 18obj-$(CONFIG_TCG_INFINEON) += tpm_infineon.o
19obj-$(CONFIG_TCG_IBMVTPM) += tpm_ibmvtpm.o
diff --git a/drivers/char/tpm/tpm.c b/drivers/char/tpm/tpm.c
index 3af9f4d1a23f..f26afdb1a702 100644
--- a/drivers/char/tpm/tpm.c
+++ b/drivers/char/tpm/tpm.c
@@ -30,12 +30,7 @@
30#include <linux/freezer.h> 30#include <linux/freezer.h>
31 31
32#include "tpm.h" 32#include "tpm.h"
33 33#include "tpm_eventlog.h"
34enum tpm_const {
35 TPM_MINOR = 224, /* officially assigned */
36 TPM_BUFSIZE = 4096,
37 TPM_NUM_DEVICES = 256,
38};
39 34
40enum tpm_duration { 35enum tpm_duration {
41 TPM_SHORT = 0, 36 TPM_SHORT = 0,
@@ -482,6 +477,7 @@ static ssize_t transmit_cmd(struct tpm_chip *chip, struct tpm_cmd_t *cmd,
482#define TPM_INTERNAL_RESULT_SIZE 200 477#define TPM_INTERNAL_RESULT_SIZE 200
483#define TPM_TAG_RQU_COMMAND cpu_to_be16(193) 478#define TPM_TAG_RQU_COMMAND cpu_to_be16(193)
484#define TPM_ORD_GET_CAP cpu_to_be32(101) 479#define TPM_ORD_GET_CAP cpu_to_be32(101)
480#define TPM_ORD_GET_RANDOM cpu_to_be32(70)
485 481
486static const struct tpm_input_header tpm_getcap_header = { 482static const struct tpm_input_header tpm_getcap_header = {
487 .tag = TPM_TAG_RQU_COMMAND, 483 .tag = TPM_TAG_RQU_COMMAND,
@@ -919,7 +915,7 @@ EXPORT_SYMBOL_GPL(tpm_show_pcrs);
919 915
920#define READ_PUBEK_RESULT_SIZE 314 916#define READ_PUBEK_RESULT_SIZE 314
921#define TPM_ORD_READPUBEK cpu_to_be32(124) 917#define TPM_ORD_READPUBEK cpu_to_be32(124)
922struct tpm_input_header tpm_readpubek_header = { 918static struct tpm_input_header tpm_readpubek_header = {
923 .tag = TPM_TAG_RQU_COMMAND, 919 .tag = TPM_TAG_RQU_COMMAND,
924 .length = cpu_to_be32(30), 920 .length = cpu_to_be32(30),
925 .ordinal = TPM_ORD_READPUBEK 921 .ordinal = TPM_ORD_READPUBEK
@@ -1175,7 +1171,7 @@ int tpm_release(struct inode *inode, struct file *file)
1175 flush_work(&chip->work); 1171 flush_work(&chip->work);
1176 file->private_data = NULL; 1172 file->private_data = NULL;
1177 atomic_set(&chip->data_pending, 0); 1173 atomic_set(&chip->data_pending, 0);
1178 kfree(chip->data_buffer); 1174 kzfree(chip->data_buffer);
1179 clear_bit(0, &chip->is_open); 1175 clear_bit(0, &chip->is_open);
1180 put_device(chip->dev); 1176 put_device(chip->dev);
1181 return 0; 1177 return 0;
@@ -1227,7 +1223,6 @@ ssize_t tpm_read(struct file *file, char __user *buf,
1227 del_singleshot_timer_sync(&chip->user_read_timer); 1223 del_singleshot_timer_sync(&chip->user_read_timer);
1228 flush_work(&chip->work); 1224 flush_work(&chip->work);
1229 ret_size = atomic_read(&chip->data_pending); 1225 ret_size = atomic_read(&chip->data_pending);
1230 atomic_set(&chip->data_pending, 0);
1231 if (ret_size > 0) { /* relay data */ 1226 if (ret_size > 0) { /* relay data */
1232 ssize_t orig_ret_size = ret_size; 1227 ssize_t orig_ret_size = ret_size;
1233 if (size < ret_size) 1228 if (size < ret_size)
@@ -1242,6 +1237,8 @@ ssize_t tpm_read(struct file *file, char __user *buf,
1242 mutex_unlock(&chip->buffer_mutex); 1237 mutex_unlock(&chip->buffer_mutex);
1243 } 1238 }
1244 1239
1240 atomic_set(&chip->data_pending, 0);
1241
1245 return ret_size; 1242 return ret_size;
1246} 1243}
1247EXPORT_SYMBOL_GPL(tpm_read); 1244EXPORT_SYMBOL_GPL(tpm_read);
@@ -1326,6 +1323,58 @@ int tpm_pm_resume(struct device *dev)
1326} 1323}
1327EXPORT_SYMBOL_GPL(tpm_pm_resume); 1324EXPORT_SYMBOL_GPL(tpm_pm_resume);
1328 1325
1326#define TPM_GETRANDOM_RESULT_SIZE 18
1327static struct tpm_input_header tpm_getrandom_header = {
1328 .tag = TPM_TAG_RQU_COMMAND,
1329 .length = cpu_to_be32(14),
1330 .ordinal = TPM_ORD_GET_RANDOM
1331};
1332
1333/**
1334 * tpm_get_random() - Get random bytes from the tpm's RNG
1335 * @chip_num: A specific chip number for the request or TPM_ANY_NUM
1336 * @out: destination buffer for the random bytes
1337 * @max: the max number of bytes to write to @out
1338 *
1339 * Returns < 0 on error and the number of bytes read on success
1340 */
1341int tpm_get_random(u32 chip_num, u8 *out, size_t max)
1342{
1343 struct tpm_chip *chip;
1344 struct tpm_cmd_t tpm_cmd;
1345 u32 recd, num_bytes = min_t(u32, max, TPM_MAX_RNG_DATA);
1346 int err, total = 0, retries = 5;
1347 u8 *dest = out;
1348
1349 chip = tpm_chip_find_get(chip_num);
1350 if (chip == NULL)
1351 return -ENODEV;
1352
1353 if (!out || !num_bytes || max > TPM_MAX_RNG_DATA)
1354 return -EINVAL;
1355
1356 do {
1357 tpm_cmd.header.in = tpm_getrandom_header;
1358 tpm_cmd.params.getrandom_in.num_bytes = cpu_to_be32(num_bytes);
1359
1360 err = transmit_cmd(chip, &tpm_cmd,
1361 TPM_GETRANDOM_RESULT_SIZE + num_bytes,
1362 "attempting get random");
1363 if (err)
1364 break;
1365
1366 recd = be32_to_cpu(tpm_cmd.params.getrandom_out.rng_data_len);
1367 memcpy(dest, tpm_cmd.params.getrandom_out.rng_data, recd);
1368
1369 dest += recd;
1370 total += recd;
1371 num_bytes -= recd;
1372 } while (retries-- && total < max);
1373
1374 return total ? total : -EIO;
1375}
1376EXPORT_SYMBOL_GPL(tpm_get_random);
1377
1329/* In case vendor provided release function, call it too.*/ 1378/* In case vendor provided release function, call it too.*/
1330 1379
1331void tpm_dev_vendor_release(struct tpm_chip *chip) 1380void tpm_dev_vendor_release(struct tpm_chip *chip)
@@ -1346,7 +1395,7 @@ EXPORT_SYMBOL_GPL(tpm_dev_vendor_release);
1346 * Once all references to platform device are down to 0, 1395 * Once all references to platform device are down to 0,
1347 * release all allocated structures. 1396 * release all allocated structures.
1348 */ 1397 */
1349void tpm_dev_release(struct device *dev) 1398static void tpm_dev_release(struct device *dev)
1350{ 1399{
1351 struct tpm_chip *chip = dev_get_drvdata(dev); 1400 struct tpm_chip *chip = dev_get_drvdata(dev);
1352 1401
@@ -1427,6 +1476,11 @@ struct tpm_chip *tpm_register_hardware(struct device *dev,
1427 goto put_device; 1476 goto put_device;
1428 } 1477 }
1429 1478
1479 if (sys_add_ppi(&dev->kobj)) {
1480 misc_deregister(&chip->vendor.miscdev);
1481 goto put_device;
1482 }
1483
1430 chip->bios_dir = tpm_bios_log_setup(devname); 1484 chip->bios_dir = tpm_bios_log_setup(devname);
1431 1485
1432 /* Make chip available */ 1486 /* Make chip available */
diff --git a/drivers/char/tpm/tpm.h b/drivers/char/tpm/tpm.h
index 917f727e6740..02c266aa2bf7 100644
--- a/drivers/char/tpm/tpm.h
+++ b/drivers/char/tpm/tpm.h
@@ -28,6 +28,12 @@
28#include <linux/io.h> 28#include <linux/io.h>
29#include <linux/tpm.h> 29#include <linux/tpm.h>
30 30
31enum tpm_const {
32 TPM_MINOR = 224, /* officially assigned */
33 TPM_BUFSIZE = 4096,
34 TPM_NUM_DEVICES = 256,
35};
36
31enum tpm_timeout { 37enum tpm_timeout {
32 TPM_TIMEOUT = 5, /* msecs */ 38 TPM_TIMEOUT = 5, /* msecs */
33}; 39};
@@ -94,6 +100,7 @@ struct tpm_vendor_specific {
94 bool timeout_adjusted; 100 bool timeout_adjusted;
95 unsigned long duration[3]; /* jiffies */ 101 unsigned long duration[3]; /* jiffies */
96 bool duration_adjusted; 102 bool duration_adjusted;
103 void *data;
97 104
98 wait_queue_head_t read_queue; 105 wait_queue_head_t read_queue;
99 wait_queue_head_t int_queue; 106 wait_queue_head_t int_queue;
@@ -269,6 +276,21 @@ struct tpm_pcrextend_in {
269 u8 hash[TPM_DIGEST_SIZE]; 276 u8 hash[TPM_DIGEST_SIZE];
270}__attribute__((packed)); 277}__attribute__((packed));
271 278
279/* 128 bytes is an arbitrary cap. This could be as large as TPM_BUFSIZE - 18
280 * bytes, but 128 is still a relatively large number of random bytes and
281 * anything much bigger causes users of struct tpm_cmd_t to start getting
282 * compiler warnings about stack frame size. */
283#define TPM_MAX_RNG_DATA 128
284
285struct tpm_getrandom_out {
286 __be32 rng_data_len;
287 u8 rng_data[TPM_MAX_RNG_DATA];
288}__attribute__((packed));
289
290struct tpm_getrandom_in {
291 __be32 num_bytes;
292}__attribute__((packed));
293
272typedef union { 294typedef union {
273 struct tpm_getcap_params_out getcap_out; 295 struct tpm_getcap_params_out getcap_out;
274 struct tpm_readpubek_params_out readpubek_out; 296 struct tpm_readpubek_params_out readpubek_out;
@@ -277,6 +299,8 @@ typedef union {
277 struct tpm_pcrread_in pcrread_in; 299 struct tpm_pcrread_in pcrread_in;
278 struct tpm_pcrread_out pcrread_out; 300 struct tpm_pcrread_out pcrread_out;
279 struct tpm_pcrextend_in pcrextend_in; 301 struct tpm_pcrextend_in pcrextend_in;
302 struct tpm_getrandom_in getrandom_in;
303 struct tpm_getrandom_out getrandom_out;
280} tpm_cmd_params; 304} tpm_cmd_params;
281 305
282struct tpm_cmd_t { 306struct tpm_cmd_t {
@@ -303,15 +327,12 @@ extern int tpm_pm_suspend(struct device *);
303extern int tpm_pm_resume(struct device *); 327extern int tpm_pm_resume(struct device *);
304extern int wait_for_tpm_stat(struct tpm_chip *, u8, unsigned long, 328extern int wait_for_tpm_stat(struct tpm_chip *, u8, unsigned long,
305 wait_queue_head_t *); 329 wait_queue_head_t *);
330
306#ifdef CONFIG_ACPI 331#ifdef CONFIG_ACPI
307extern struct dentry ** tpm_bios_log_setup(char *); 332extern ssize_t sys_add_ppi(struct kobject *parent);
308extern void tpm_bios_log_teardown(struct dentry **);
309#else 333#else
310static inline struct dentry ** tpm_bios_log_setup(char *name) 334static inline ssize_t sys_add_ppi(struct kobject *parent)
311{
312 return NULL;
313}
314static inline void tpm_bios_log_teardown(struct dentry **dir)
315{ 335{
336 return 0;
316} 337}
317#endif 338#endif
diff --git a/drivers/char/tpm/tpm_acpi.c b/drivers/char/tpm/tpm_acpi.c
new file mode 100644
index 000000000000..56051d0c97a2
--- /dev/null
+++ b/drivers/char/tpm/tpm_acpi.c
@@ -0,0 +1,109 @@
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 *
10 * Maintained by: <tpmdd-devel@lists.sourceforge.net>
11 *
12 * Access to the eventlog extended by the TCG BIOS of PC platform
13 *
14 * This program is free software; you can redistribute it and/or
15 * modify it under the terms of the GNU General Public License
16 * as published by the Free Software Foundation; either version
17 * 2 of the License, or (at your option) any later version.
18 *
19 */
20
21#include <linux/seq_file.h>
22#include <linux/fs.h>
23#include <linux/security.h>
24#include <linux/module.h>
25#include <linux/slab.h>
26#include <acpi/acpi.h>
27
28#include "tpm.h"
29#include "tpm_eventlog.h"
30
31struct acpi_tcpa {
32 struct acpi_table_header hdr;
33 u16 platform_class;
34 union {
35 struct client_hdr {
36 u32 log_max_len __attribute__ ((packed));
37 u64 log_start_addr __attribute__ ((packed));
38 } client;
39 struct server_hdr {
40 u16 reserved;
41 u64 log_max_len __attribute__ ((packed));
42 u64 log_start_addr __attribute__ ((packed));
43 } server;
44 };
45};
46
47/* read binary bios log */
48int read_log(struct tpm_bios_log *log)
49{
50 struct acpi_tcpa *buff;
51 acpi_status status;
52 void __iomem *virt;
53 u64 len, start;
54
55 if (log->bios_event_log != NULL) {
56 printk(KERN_ERR
57 "%s: ERROR - Eventlog already initialized\n",
58 __func__);
59 return -EFAULT;
60 }
61
62 /* Find TCPA entry in RSDT (ACPI_LOGICAL_ADDRESSING) */
63 status = acpi_get_table(ACPI_SIG_TCPA, 1,
64 (struct acpi_table_header **)&buff);
65
66 if (ACPI_FAILURE(status)) {
67 printk(KERN_ERR "%s: ERROR - Could not get TCPA table\n",
68 __func__);
69 return -EIO;
70 }
71
72 switch(buff->platform_class) {
73 case BIOS_SERVER:
74 len = buff->server.log_max_len;
75 start = buff->server.log_start_addr;
76 break;
77 case BIOS_CLIENT:
78 default:
79 len = buff->client.log_max_len;
80 start = buff->client.log_start_addr;
81 break;
82 }
83 if (!len) {
84 printk(KERN_ERR "%s: ERROR - TCPA log area empty\n", __func__);
85 return -EIO;
86 }
87
88 /* malloc EventLog space */
89 log->bios_event_log = kmalloc(len, GFP_KERNEL);
90 if (!log->bios_event_log) {
91 printk("%s: ERROR - Not enough Memory for BIOS measurements\n",
92 __func__);
93 return -ENOMEM;
94 }
95
96 log->bios_event_log_end = log->bios_event_log + len;
97
98 virt = acpi_os_map_memory(start, len);
99 if (!virt) {
100 kfree(log->bios_event_log);
101 printk("%s: ERROR - Unable to map memory\n", __func__);
102 return -EIO;
103 }
104
105 memcpy_fromio(log->bios_event_log, virt, len);
106
107 acpi_os_unmap_memory(virt, len);
108 return 0;
109}
diff --git a/drivers/char/tpm/tpm_bios.c b/drivers/char/tpm/tpm_eventlog.c
index 0636520fa9bf..84ddc557b8f8 100644
--- a/drivers/char/tpm/tpm_bios.c
+++ b/drivers/char/tpm/tpm_eventlog.c
@@ -1,7 +1,8 @@
1/* 1/*
2 * Copyright (C) 2005 IBM Corporation 2 * Copyright (C) 2005, 2012 IBM Corporation
3 * 3 *
4 * Authors: 4 * Authors:
5 * Kent Yoder <key@linux.vnet.ibm.com>
5 * Seiji Munetoh <munetoh@jp.ibm.com> 6 * Seiji Munetoh <munetoh@jp.ibm.com>
6 * Stefan Berger <stefanb@us.ibm.com> 7 * Stefan Berger <stefanb@us.ibm.com>
7 * Reiner Sailer <sailer@watson.ibm.com> 8 * Reiner Sailer <sailer@watson.ibm.com>
@@ -9,7 +10,7 @@
9 * 10 *
10 * Maintained by: <tpmdd-devel@lists.sourceforge.net> 11 * Maintained by: <tpmdd-devel@lists.sourceforge.net>
11 * 12 *
12 * Access to the eventlog extended by the TCG BIOS of PC platform 13 * Access to the eventlog created by a system's firmware / BIOS
13 * 14 *
14 * This program is free software; you can redistribute it and/or 15 * This program is free software; you can redistribute it and/or
15 * modify it under the terms of the GNU General Public License 16 * modify it under the terms of the GNU General Public License
@@ -23,67 +24,10 @@
23#include <linux/security.h> 24#include <linux/security.h>
24#include <linux/module.h> 25#include <linux/module.h>
25#include <linux/slab.h> 26#include <linux/slab.h>
26#include <acpi/acpi.h>
27#include "tpm.h"
28
29#define TCG_EVENT_NAME_LEN_MAX 255
30#define MAX_TEXT_EVENT 1000 /* Max event string length */
31#define ACPI_TCPA_SIG "TCPA" /* 0x41504354 /'TCPA' */
32
33enum bios_platform_class {
34 BIOS_CLIENT = 0x00,
35 BIOS_SERVER = 0x01,
36};
37
38struct tpm_bios_log {
39 void *bios_event_log;
40 void *bios_event_log_end;
41};
42
43struct acpi_tcpa {
44 struct acpi_table_header hdr;
45 u16 platform_class;
46 union {
47 struct client_hdr {
48 u32 log_max_len __attribute__ ((packed));
49 u64 log_start_addr __attribute__ ((packed));
50 } client;
51 struct server_hdr {
52 u16 reserved;
53 u64 log_max_len __attribute__ ((packed));
54 u64 log_start_addr __attribute__ ((packed));
55 } server;
56 };
57};
58 27
59struct tcpa_event { 28#include "tpm.h"
60 u32 pcr_index; 29#include "tpm_eventlog.h"
61 u32 event_type;
62 u8 pcr_value[20]; /* SHA1 */
63 u32 event_size;
64 u8 event_data[0];
65};
66 30
67enum tcpa_event_types {
68 PREBOOT = 0,
69 POST_CODE,
70 UNUSED,
71 NO_ACTION,
72 SEPARATOR,
73 ACTION,
74 EVENT_TAG,
75 SCRTM_CONTENTS,
76 SCRTM_VERSION,
77 CPU_MICROCODE,
78 PLATFORM_CONFIG_FLAGS,
79 TABLE_OF_DEVICES,
80 COMPACT_HASH,
81 IPL,
82 IPL_PARTITION_DATA,
83 NONHOST_CODE,
84 NONHOST_CONFIG,
85 NONHOST_INFO,
86};
87 31
88static const char* tcpa_event_type_strings[] = { 32static const char* tcpa_event_type_strings[] = {
89 "PREBOOT", 33 "PREBOOT",
@@ -106,28 +50,6 @@ static const char* tcpa_event_type_strings[] = {
106 "Non-Host Info" 50 "Non-Host Info"
107}; 51};
108 52
109struct tcpa_pc_event {
110 u32 event_id;
111 u32 event_size;
112 u8 event_data[0];
113};
114
115enum tcpa_pc_event_ids {
116 SMBIOS = 1,
117 BIS_CERT,
118 POST_BIOS_ROM,
119 ESCD,
120 CMOS,
121 NVRAM,
122 OPTION_ROM_EXEC,
123 OPTION_ROM_CONFIG,
124 OPTION_ROM_MICROCODE = 10,
125 S_CRTM_VERSION,
126 S_CRTM_CONTENTS,
127 POST_CONTENTS,
128 HOST_TABLE_OF_DEVICES,
129};
130
131static const char* tcpa_pc_event_id_strings[] = { 53static const char* tcpa_pc_event_id_strings[] = {
132 "", 54 "",
133 "SMBIOS", 55 "SMBIOS",
@@ -358,65 +280,6 @@ static const struct seq_operations tpm_binary_b_measurments_seqops = {
358 .show = tpm_binary_bios_measurements_show, 280 .show = tpm_binary_bios_measurements_show,
359}; 281};
360 282
361/* read binary bios log */
362static int read_log(struct tpm_bios_log *log)
363{
364 struct acpi_tcpa *buff;
365 acpi_status status;
366 struct acpi_table_header *virt;
367 u64 len, start;
368
369 if (log->bios_event_log != NULL) {
370 printk(KERN_ERR
371 "%s: ERROR - Eventlog already initialized\n",
372 __func__);
373 return -EFAULT;
374 }
375
376 /* Find TCPA entry in RSDT (ACPI_LOGICAL_ADDRESSING) */
377 status = acpi_get_table(ACPI_SIG_TCPA, 1,
378 (struct acpi_table_header **)&buff);
379
380 if (ACPI_FAILURE(status)) {
381 printk(KERN_ERR "%s: ERROR - Could not get TCPA table\n",
382 __func__);
383 return -EIO;
384 }
385
386 switch(buff->platform_class) {
387 case BIOS_SERVER:
388 len = buff->server.log_max_len;
389 start = buff->server.log_start_addr;
390 break;
391 case BIOS_CLIENT:
392 default:
393 len = buff->client.log_max_len;
394 start = buff->client.log_start_addr;
395 break;
396 }
397 if (!len) {
398 printk(KERN_ERR "%s: ERROR - TCPA log area empty\n", __func__);
399 return -EIO;
400 }
401
402 /* malloc EventLog space */
403 log->bios_event_log = kmalloc(len, GFP_KERNEL);
404 if (!log->bios_event_log) {
405 printk("%s: ERROR - Not enough Memory for BIOS measurements\n",
406 __func__);
407 return -ENOMEM;
408 }
409
410 log->bios_event_log_end = log->bios_event_log + len;
411
412 virt = acpi_os_map_memory(start, len);
413
414 memcpy(log->bios_event_log, virt, len);
415
416 acpi_os_unmap_memory(virt, len);
417 return 0;
418}
419
420static int tpm_ascii_bios_measurements_open(struct inode *inode, 283static int tpm_ascii_bios_measurements_open(struct inode *inode,
421 struct file *file) 284 struct file *file)
422{ 285{
diff --git a/drivers/char/tpm/tpm_eventlog.h b/drivers/char/tpm/tpm_eventlog.h
new file mode 100644
index 000000000000..e7da086d6928
--- /dev/null
+++ b/drivers/char/tpm/tpm_eventlog.h
@@ -0,0 +1,86 @@
1
2#ifndef __TPM_EVENTLOG_H__
3#define __TPM_EVENTLOG_H__
4
5#define TCG_EVENT_NAME_LEN_MAX 255
6#define MAX_TEXT_EVENT 1000 /* Max event string length */
7#define ACPI_TCPA_SIG "TCPA" /* 0x41504354 /'TCPA' */
8
9enum bios_platform_class {
10 BIOS_CLIENT = 0x00,
11 BIOS_SERVER = 0x01,
12};
13
14struct tpm_bios_log {
15 void *bios_event_log;
16 void *bios_event_log_end;
17};
18
19struct tcpa_event {
20 u32 pcr_index;
21 u32 event_type;
22 u8 pcr_value[20]; /* SHA1 */
23 u32 event_size;
24 u8 event_data[0];
25};
26
27enum tcpa_event_types {
28 PREBOOT = 0,
29 POST_CODE,
30 UNUSED,
31 NO_ACTION,
32 SEPARATOR,
33 ACTION,
34 EVENT_TAG,
35 SCRTM_CONTENTS,
36 SCRTM_VERSION,
37 CPU_MICROCODE,
38 PLATFORM_CONFIG_FLAGS,
39 TABLE_OF_DEVICES,
40 COMPACT_HASH,
41 IPL,
42 IPL_PARTITION_DATA,
43 NONHOST_CODE,
44 NONHOST_CONFIG,
45 NONHOST_INFO,
46};
47
48struct tcpa_pc_event {
49 u32 event_id;
50 u32 event_size;
51 u8 event_data[0];
52};
53
54enum tcpa_pc_event_ids {
55 SMBIOS = 1,
56 BIS_CERT,
57 POST_BIOS_ROM,
58 ESCD,
59 CMOS,
60 NVRAM,
61 OPTION_ROM_EXEC,
62 OPTION_ROM_CONFIG,
63 OPTION_ROM_MICROCODE = 10,
64 S_CRTM_VERSION,
65 S_CRTM_CONTENTS,
66 POST_CONTENTS,
67 HOST_TABLE_OF_DEVICES,
68};
69
70int read_log(struct tpm_bios_log *log);
71
72#if defined(CONFIG_TCG_IBMVTPM) || defined(CONFIG_TCG_IBMVTPM_MODULE) || \
73 defined(CONFIG_ACPI)
74extern struct dentry **tpm_bios_log_setup(char *);
75extern void tpm_bios_log_teardown(struct dentry **);
76#else
77static inline struct dentry **tpm_bios_log_setup(char *name)
78{
79 return NULL;
80}
81static inline void tpm_bios_log_teardown(struct dentry **dir)
82{
83}
84#endif
85
86#endif
diff --git a/drivers/char/tpm/tpm_i2c_infineon.c b/drivers/char/tpm/tpm_i2c_infineon.c
new file mode 100644
index 000000000000..5a831aec9d4b
--- /dev/null
+++ b/drivers/char/tpm/tpm_i2c_infineon.c
@@ -0,0 +1,695 @@
1/*
2 * Copyright (C) 2012 Infineon Technologies
3 *
4 * Authors:
5 * Peter Huewe <peter.huewe@infineon.com>
6 *
7 * Device driver for TCG/TCPA TPM (trusted platform module).
8 * Specifications at www.trustedcomputinggroup.org
9 *
10 * This device driver implements the TPM interface as defined in
11 * the TCG TPM Interface Spec version 1.2, revision 1.0 and the
12 * Infineon I2C Protocol Stack Specification v0.20.
13 *
14 * It is based on the original tpm_tis device driver from Leendert van
15 * Dorn and Kyleen Hall.
16 *
17 * This program is free software; you can redistribute it and/or
18 * modify it under the terms of the GNU General Public License as
19 * published by the Free Software Foundation, version 2 of the
20 * License.
21 *
22 *
23 */
24#include <linux/init.h>
25#include <linux/i2c.h>
26#include <linux/module.h>
27#include <linux/moduleparam.h>
28#include <linux/wait.h>
29#include "tpm.h"
30
31/* max. buffer size supported by our TPM */
32#define TPM_BUFSIZE 1260
33
34/* max. number of iterations after I2C NAK */
35#define MAX_COUNT 3
36
37#define SLEEP_DURATION_LOW 55
38#define SLEEP_DURATION_HI 65
39
40/* max. number of iterations after I2C NAK for 'long' commands
41 * we need this especially for sending TPM_READY, since the cleanup after the
42 * transtion to the ready state may take some time, but it is unpredictable
43 * how long it will take.
44 */
45#define MAX_COUNT_LONG 50
46
47#define SLEEP_DURATION_LONG_LOW 200
48#define SLEEP_DURATION_LONG_HI 220
49
50/* After sending TPM_READY to 'reset' the TPM we have to sleep even longer */
51#define SLEEP_DURATION_RESET_LOW 2400
52#define SLEEP_DURATION_RESET_HI 2600
53
54/* we want to use usleep_range instead of msleep for the 5ms TPM_TIMEOUT */
55#define TPM_TIMEOUT_US_LOW (TPM_TIMEOUT * 1000)
56#define TPM_TIMEOUT_US_HI (TPM_TIMEOUT_US_LOW + 2000)
57
58/* expected value for DIDVID register */
59#define TPM_TIS_I2C_DID_VID 0x000b15d1L
60
61/* Structure to store I2C TPM specific stuff */
62struct tpm_inf_dev {
63 struct i2c_client *client;
64 u8 buf[TPM_BUFSIZE + sizeof(u8)]; /* max. buffer size + addr */
65 struct tpm_chip *chip;
66};
67
68static struct tpm_inf_dev tpm_dev;
69static struct i2c_driver tpm_tis_i2c_driver;
70
71/*
72 * iic_tpm_read() - read from TPM register
73 * @addr: register address to read from
74 * @buffer: provided by caller
75 * @len: number of bytes to read
76 *
77 * Read len bytes from TPM register and put them into
78 * buffer (little-endian format, i.e. first byte is put into buffer[0]).
79 *
80 * NOTE: TPM is big-endian for multi-byte values. Multi-byte
81 * values have to be swapped.
82 *
83 * NOTE: We can't unfortunately use the combined read/write functions
84 * provided by the i2c core as the TPM currently does not support the
85 * repeated start condition and due to it's special requirements.
86 * The i2c_smbus* functions do not work for this chip.
87 *
88 * Return -EIO on error, 0 on success.
89 */
90static int iic_tpm_read(u8 addr, u8 *buffer, size_t len)
91{
92
93 struct i2c_msg msg1 = { tpm_dev.client->addr, 0, 1, &addr };
94 struct i2c_msg msg2 = { tpm_dev.client->addr, I2C_M_RD, len, buffer };
95
96 int rc;
97 int count;
98
99 /* Lock the adapter for the duration of the whole sequence. */
100 if (!tpm_dev.client->adapter->algo->master_xfer)
101 return -EOPNOTSUPP;
102 i2c_lock_adapter(tpm_dev.client->adapter);
103
104 for (count = 0; count < MAX_COUNT; count++) {
105 rc = __i2c_transfer(tpm_dev.client->adapter, &msg1, 1);
106 if (rc > 0)
107 break; /* break here to skip sleep */
108
109 usleep_range(SLEEP_DURATION_LOW, SLEEP_DURATION_HI);
110 }
111
112 if (rc <= 0)
113 goto out;
114
115 /* After the TPM has successfully received the register address it needs
116 * some time, thus we're sleeping here again, before retrieving the data
117 */
118 for (count = 0; count < MAX_COUNT; count++) {
119 usleep_range(SLEEP_DURATION_LOW, SLEEP_DURATION_HI);
120 rc = __i2c_transfer(tpm_dev.client->adapter, &msg2, 1);
121 if (rc > 0)
122 break;
123
124 }
125
126out:
127 i2c_unlock_adapter(tpm_dev.client->adapter);
128 if (rc <= 0)
129 return -EIO;
130
131 return 0;
132}
133
134static int iic_tpm_write_generic(u8 addr, u8 *buffer, size_t len,
135 unsigned int sleep_low,
136 unsigned int sleep_hi, u8 max_count)
137{
138 int rc = -EIO;
139 int count;
140
141 struct i2c_msg msg1 = { tpm_dev.client->addr, 0, len + 1, tpm_dev.buf };
142
143 if (len > TPM_BUFSIZE)
144 return -EINVAL;
145
146 if (!tpm_dev.client->adapter->algo->master_xfer)
147 return -EOPNOTSUPP;
148 i2c_lock_adapter(tpm_dev.client->adapter);
149
150 /* prepend the 'register address' to the buffer */
151 tpm_dev.buf[0] = addr;
152 memcpy(&(tpm_dev.buf[1]), buffer, len);
153
154 /*
155 * NOTE: We have to use these special mechanisms here and unfortunately
156 * cannot rely on the standard behavior of i2c_transfer.
157 */
158 for (count = 0; count < max_count; count++) {
159 rc = __i2c_transfer(tpm_dev.client->adapter, &msg1, 1);
160 if (rc > 0)
161 break;
162
163 usleep_range(sleep_low, sleep_hi);
164 }
165
166 i2c_unlock_adapter(tpm_dev.client->adapter);
167 if (rc <= 0)
168 return -EIO;
169
170 return 0;
171}
172
173/*
174 * iic_tpm_write() - write to TPM register
175 * @addr: register address to write to
176 * @buffer: containing data to be written
177 * @len: number of bytes to write
178 *
179 * Write len bytes from provided buffer to TPM register (little
180 * endian format, i.e. buffer[0] is written as first byte).
181 *
182 * NOTE: TPM is big-endian for multi-byte values. Multi-byte
183 * values have to be swapped.
184 *
185 * NOTE: use this function instead of the iic_tpm_write_generic function.
186 *
187 * Return -EIO on error, 0 on success
188 */
189static int iic_tpm_write(u8 addr, u8 *buffer, size_t len)
190{
191 return iic_tpm_write_generic(addr, buffer, len, SLEEP_DURATION_LOW,
192 SLEEP_DURATION_HI, MAX_COUNT);
193}
194
195/*
196 * This function is needed especially for the cleanup situation after
197 * sending TPM_READY
198 * */
199static int iic_tpm_write_long(u8 addr, u8 *buffer, size_t len)
200{
201 return iic_tpm_write_generic(addr, buffer, len, SLEEP_DURATION_LONG_LOW,
202 SLEEP_DURATION_LONG_HI, MAX_COUNT_LONG);
203}
204
205enum tis_access {
206 TPM_ACCESS_VALID = 0x80,
207 TPM_ACCESS_ACTIVE_LOCALITY = 0x20,
208 TPM_ACCESS_REQUEST_PENDING = 0x04,
209 TPM_ACCESS_REQUEST_USE = 0x02,
210};
211
212enum tis_status {
213 TPM_STS_VALID = 0x80,
214 TPM_STS_COMMAND_READY = 0x40,
215 TPM_STS_GO = 0x20,
216 TPM_STS_DATA_AVAIL = 0x10,
217 TPM_STS_DATA_EXPECT = 0x08,
218};
219
220enum tis_defaults {
221 TIS_SHORT_TIMEOUT = 750, /* ms */
222 TIS_LONG_TIMEOUT = 2000, /* 2 sec */
223};
224
225#define TPM_ACCESS(l) (0x0000 | ((l) << 4))
226#define TPM_STS(l) (0x0001 | ((l) << 4))
227#define TPM_DATA_FIFO(l) (0x0005 | ((l) << 4))
228#define TPM_DID_VID(l) (0x0006 | ((l) << 4))
229
230static int check_locality(struct tpm_chip *chip, int loc)
231{
232 u8 buf;
233 int rc;
234
235 rc = iic_tpm_read(TPM_ACCESS(loc), &buf, 1);
236 if (rc < 0)
237 return rc;
238
239 if ((buf & (TPM_ACCESS_ACTIVE_LOCALITY | TPM_ACCESS_VALID)) ==
240 (TPM_ACCESS_ACTIVE_LOCALITY | TPM_ACCESS_VALID)) {
241 chip->vendor.locality = loc;
242 return loc;
243 }
244
245 return -EIO;
246}
247
248/* implementation similar to tpm_tis */
249static void release_locality(struct tpm_chip *chip, int loc, int force)
250{
251 u8 buf;
252 if (iic_tpm_read(TPM_ACCESS(loc), &buf, 1) < 0)
253 return;
254
255 if (force || (buf & (TPM_ACCESS_REQUEST_PENDING | TPM_ACCESS_VALID)) ==
256 (TPM_ACCESS_REQUEST_PENDING | TPM_ACCESS_VALID)) {
257 buf = TPM_ACCESS_ACTIVE_LOCALITY;
258 iic_tpm_write(TPM_ACCESS(loc), &buf, 1);
259 }
260}
261
262static int request_locality(struct tpm_chip *chip, int loc)
263{
264 unsigned long stop;
265 u8 buf = TPM_ACCESS_REQUEST_USE;
266
267 if (check_locality(chip, loc) >= 0)
268 return loc;
269
270 iic_tpm_write(TPM_ACCESS(loc), &buf, 1);
271
272 /* wait for burstcount */
273 stop = jiffies + chip->vendor.timeout_a;
274 do {
275 if (check_locality(chip, loc) >= 0)
276 return loc;
277 usleep_range(TPM_TIMEOUT_US_LOW, TPM_TIMEOUT_US_HI);
278 } while (time_before(jiffies, stop));
279
280 return -ETIME;
281}
282
283static u8 tpm_tis_i2c_status(struct tpm_chip *chip)
284{
285 /* NOTE: since I2C read may fail, return 0 in this case --> time-out */
286 u8 buf;
287 if (iic_tpm_read(TPM_STS(chip->vendor.locality), &buf, 1) < 0)
288 return 0;
289 else
290 return buf;
291}
292
293static void tpm_tis_i2c_ready(struct tpm_chip *chip)
294{
295 /* this causes the current command to be aborted */
296 u8 buf = TPM_STS_COMMAND_READY;
297 iic_tpm_write_long(TPM_STS(chip->vendor.locality), &buf, 1);
298}
299
300static ssize_t get_burstcount(struct tpm_chip *chip)
301{
302 unsigned long stop;
303 ssize_t burstcnt;
304 u8 buf[3];
305
306 /* wait for burstcount */
307 /* which timeout value, spec has 2 answers (c & d) */
308 stop = jiffies + chip->vendor.timeout_d;
309 do {
310 /* Note: STS is little endian */
311 if (iic_tpm_read(TPM_STS(chip->vendor.locality)+1, buf, 3) < 0)
312 burstcnt = 0;
313 else
314 burstcnt = (buf[2] << 16) + (buf[1] << 8) + buf[0];
315
316 if (burstcnt)
317 return burstcnt;
318
319 usleep_range(TPM_TIMEOUT_US_LOW, TPM_TIMEOUT_US_HI);
320 } while (time_before(jiffies, stop));
321 return -EBUSY;
322}
323
324static int wait_for_stat(struct tpm_chip *chip, u8 mask, unsigned long timeout,
325 int *status)
326{
327 unsigned long stop;
328
329 /* check current status */
330 *status = tpm_tis_i2c_status(chip);
331 if ((*status & mask) == mask)
332 return 0;
333
334 stop = jiffies + timeout;
335 do {
336 /* since we just checked the status, give the TPM some time */
337 usleep_range(TPM_TIMEOUT_US_LOW, TPM_TIMEOUT_US_HI);
338 *status = tpm_tis_i2c_status(chip);
339 if ((*status & mask) == mask)
340 return 0;
341
342 } while (time_before(jiffies, stop));
343
344 return -ETIME;
345}
346
347static int recv_data(struct tpm_chip *chip, u8 *buf, size_t count)
348{
349 size_t size = 0;
350 ssize_t burstcnt;
351 u8 retries = 0;
352 int rc;
353
354 while (size < count) {
355 burstcnt = get_burstcount(chip);
356
357 /* burstcnt < 0 = TPM is busy */
358 if (burstcnt < 0)
359 return burstcnt;
360
361 /* limit received data to max. left */
362 if (burstcnt > (count - size))
363 burstcnt = count - size;
364
365 rc = iic_tpm_read(TPM_DATA_FIFO(chip->vendor.locality),
366 &(buf[size]), burstcnt);
367 if (rc == 0)
368 size += burstcnt;
369 else if (rc < 0)
370 retries++;
371
372 /* avoid endless loop in case of broken HW */
373 if (retries > MAX_COUNT_LONG)
374 return -EIO;
375
376 }
377 return size;
378}
379
380static int tpm_tis_i2c_recv(struct tpm_chip *chip, u8 *buf, size_t count)
381{
382 int size = 0;
383 int expected, status;
384
385 if (count < TPM_HEADER_SIZE) {
386 size = -EIO;
387 goto out;
388 }
389
390 /* read first 10 bytes, including tag, paramsize, and result */
391 size = recv_data(chip, buf, TPM_HEADER_SIZE);
392 if (size < TPM_HEADER_SIZE) {
393 dev_err(chip->dev, "Unable to read header\n");
394 goto out;
395 }
396
397 expected = be32_to_cpu(*(__be32 *)(buf + 2));
398 if ((size_t) expected > count) {
399 size = -EIO;
400 goto out;
401 }
402
403 size += recv_data(chip, &buf[TPM_HEADER_SIZE],
404 expected - TPM_HEADER_SIZE);
405 if (size < expected) {
406 dev_err(chip->dev, "Unable to read remainder of result\n");
407 size = -ETIME;
408 goto out;
409 }
410
411 wait_for_stat(chip, TPM_STS_VALID, chip->vendor.timeout_c, &status);
412 if (status & TPM_STS_DATA_AVAIL) { /* retry? */
413 dev_err(chip->dev, "Error left over data\n");
414 size = -EIO;
415 goto out;
416 }
417
418out:
419 tpm_tis_i2c_ready(chip);
420 /* The TPM needs some time to clean up here,
421 * so we sleep rather than keeping the bus busy
422 */
423 usleep_range(SLEEP_DURATION_RESET_LOW, SLEEP_DURATION_RESET_HI);
424 release_locality(chip, chip->vendor.locality, 0);
425 return size;
426}
427
428static int tpm_tis_i2c_send(struct tpm_chip *chip, u8 *buf, size_t len)
429{
430 int rc, status;
431 ssize_t burstcnt;
432 size_t count = 0;
433 u8 retries = 0;
434 u8 sts = TPM_STS_GO;
435
436 if (len > TPM_BUFSIZE)
437 return -E2BIG; /* command is too long for our tpm, sorry */
438
439 if (request_locality(chip, 0) < 0)
440 return -EBUSY;
441
442 status = tpm_tis_i2c_status(chip);
443 if ((status & TPM_STS_COMMAND_READY) == 0) {
444 tpm_tis_i2c_ready(chip);
445 if (wait_for_stat
446 (chip, TPM_STS_COMMAND_READY,
447 chip->vendor.timeout_b, &status) < 0) {
448 rc = -ETIME;
449 goto out_err;
450 }
451 }
452
453 while (count < len - 1) {
454 burstcnt = get_burstcount(chip);
455
456 /* burstcnt < 0 = TPM is busy */
457 if (burstcnt < 0)
458 return burstcnt;
459
460 if (burstcnt > (len - 1 - count))
461 burstcnt = len - 1 - count;
462
463 rc = iic_tpm_write(TPM_DATA_FIFO(chip->vendor.locality),
464 &(buf[count]), burstcnt);
465 if (rc == 0)
466 count += burstcnt;
467 else if (rc < 0)
468 retries++;
469
470 /* avoid endless loop in case of broken HW */
471 if (retries > MAX_COUNT_LONG) {
472 rc = -EIO;
473 goto out_err;
474 }
475
476 wait_for_stat(chip, TPM_STS_VALID,
477 chip->vendor.timeout_c, &status);
478
479 if ((status & TPM_STS_DATA_EXPECT) == 0) {
480 rc = -EIO;
481 goto out_err;
482 }
483
484 }
485
486 /* write last byte */
487 iic_tpm_write(TPM_DATA_FIFO(chip->vendor.locality), &(buf[count]), 1);
488 wait_for_stat(chip, TPM_STS_VALID, chip->vendor.timeout_c, &status);
489 if ((status & TPM_STS_DATA_EXPECT) != 0) {
490 rc = -EIO;
491 goto out_err;
492 }
493
494 /* go and do it */
495 iic_tpm_write(TPM_STS(chip->vendor.locality), &sts, 1);
496
497 return len;
498out_err:
499 tpm_tis_i2c_ready(chip);
500 /* The TPM needs some time to clean up here,
501 * so we sleep rather than keeping the bus busy
502 */
503 usleep_range(SLEEP_DURATION_RESET_LOW, SLEEP_DURATION_RESET_HI);
504 release_locality(chip, chip->vendor.locality, 0);
505 return rc;
506}
507
508static const struct file_operations tis_ops = {
509 .owner = THIS_MODULE,
510 .llseek = no_llseek,
511 .open = tpm_open,
512 .read = tpm_read,
513 .write = tpm_write,
514 .release = tpm_release,
515};
516
517static DEVICE_ATTR(pubek, S_IRUGO, tpm_show_pubek, NULL);
518static DEVICE_ATTR(pcrs, S_IRUGO, tpm_show_pcrs, NULL);
519static DEVICE_ATTR(enabled, S_IRUGO, tpm_show_enabled, NULL);
520static DEVICE_ATTR(active, S_IRUGO, tpm_show_active, NULL);
521static DEVICE_ATTR(owned, S_IRUGO, tpm_show_owned, NULL);
522static DEVICE_ATTR(temp_deactivated, S_IRUGO, tpm_show_temp_deactivated, NULL);
523static DEVICE_ATTR(caps, S_IRUGO, tpm_show_caps_1_2, NULL);
524static DEVICE_ATTR(cancel, S_IWUSR | S_IWGRP, NULL, tpm_store_cancel);
525static DEVICE_ATTR(durations, S_IRUGO, tpm_show_durations, NULL);
526static DEVICE_ATTR(timeouts, S_IRUGO, tpm_show_timeouts, NULL);
527
528static struct attribute *tis_attrs[] = {
529 &dev_attr_pubek.attr,
530 &dev_attr_pcrs.attr,
531 &dev_attr_enabled.attr,
532 &dev_attr_active.attr,
533 &dev_attr_owned.attr,
534 &dev_attr_temp_deactivated.attr,
535 &dev_attr_caps.attr,
536 &dev_attr_cancel.attr,
537 &dev_attr_durations.attr,
538 &dev_attr_timeouts.attr,
539 NULL,
540};
541
542static struct attribute_group tis_attr_grp = {
543 .attrs = tis_attrs
544};
545
546static struct tpm_vendor_specific tpm_tis_i2c = {
547 .status = tpm_tis_i2c_status,
548 .recv = tpm_tis_i2c_recv,
549 .send = tpm_tis_i2c_send,
550 .cancel = tpm_tis_i2c_ready,
551 .req_complete_mask = TPM_STS_DATA_AVAIL | TPM_STS_VALID,
552 .req_complete_val = TPM_STS_DATA_AVAIL | TPM_STS_VALID,
553 .req_canceled = TPM_STS_COMMAND_READY,
554 .attr_group = &tis_attr_grp,
555 .miscdev.fops = &tis_ops,
556};
557
558static int __devinit tpm_tis_i2c_init(struct device *dev)
559{
560 u32 vendor;
561 int rc = 0;
562 struct tpm_chip *chip;
563
564 chip = tpm_register_hardware(dev, &tpm_tis_i2c);
565 if (!chip) {
566 rc = -ENODEV;
567 goto out_err;
568 }
569
570 /* Disable interrupts */
571 chip->vendor.irq = 0;
572
573 /* Default timeouts */
574 chip->vendor.timeout_a = msecs_to_jiffies(TIS_SHORT_TIMEOUT);
575 chip->vendor.timeout_b = msecs_to_jiffies(TIS_LONG_TIMEOUT);
576 chip->vendor.timeout_c = msecs_to_jiffies(TIS_SHORT_TIMEOUT);
577 chip->vendor.timeout_d = msecs_to_jiffies(TIS_SHORT_TIMEOUT);
578
579 if (request_locality(chip, 0) != 0) {
580 rc = -ENODEV;
581 goto out_vendor;
582 }
583
584 /* read four bytes from DID_VID register */
585 if (iic_tpm_read(TPM_DID_VID(0), (u8 *)&vendor, 4) < 0) {
586 rc = -EIO;
587 goto out_release;
588 }
589
590 /* create DID_VID register value, after swapping to little-endian */
591 vendor = be32_to_cpu((__be32) vendor);
592
593 if (vendor != TPM_TIS_I2C_DID_VID) {
594 rc = -ENODEV;
595 goto out_release;
596 }
597
598 dev_info(dev, "1.2 TPM (device-id 0x%X)\n", vendor >> 16);
599
600 INIT_LIST_HEAD(&chip->vendor.list);
601 tpm_dev.chip = chip;
602
603 tpm_get_timeouts(chip);
604 tpm_do_selftest(chip);
605
606 return 0;
607
608out_release:
609 release_locality(chip, chip->vendor.locality, 1);
610
611out_vendor:
612 /* close file handles */
613 tpm_dev_vendor_release(chip);
614
615 /* remove hardware */
616 tpm_remove_hardware(chip->dev);
617
618 /* reset these pointers, otherwise we oops */
619 chip->dev->release = NULL;
620 chip->release = NULL;
621 tpm_dev.client = NULL;
622 dev_set_drvdata(chip->dev, chip);
623out_err:
624 return rc;
625}
626
627static const struct i2c_device_id tpm_tis_i2c_table[] = {
628 {"tpm_i2c_infineon", 0},
629 {},
630};
631
632MODULE_DEVICE_TABLE(i2c, tpm_tis_i2c_table);
633static SIMPLE_DEV_PM_OPS(tpm_tis_i2c_ops, tpm_pm_suspend, tpm_pm_resume);
634
635static int __devinit tpm_tis_i2c_probe(struct i2c_client *client,
636 const struct i2c_device_id *id)
637{
638 int rc;
639 if (tpm_dev.client != NULL)
640 return -EBUSY; /* We only support one client */
641
642 if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
643 dev_err(&client->dev,
644 "no algorithms associated to the i2c bus\n");
645 return -ENODEV;
646 }
647
648 client->driver = &tpm_tis_i2c_driver;
649 tpm_dev.client = client;
650 rc = tpm_tis_i2c_init(&client->dev);
651 if (rc != 0) {
652 client->driver = NULL;
653 tpm_dev.client = NULL;
654 rc = -ENODEV;
655 }
656 return rc;
657}
658
659static int __devexit tpm_tis_i2c_remove(struct i2c_client *client)
660{
661 struct tpm_chip *chip = tpm_dev.chip;
662 release_locality(chip, chip->vendor.locality, 1);
663
664 /* close file handles */
665 tpm_dev_vendor_release(chip);
666
667 /* remove hardware */
668 tpm_remove_hardware(chip->dev);
669
670 /* reset these pointers, otherwise we oops */
671 chip->dev->release = NULL;
672 chip->release = NULL;
673 tpm_dev.client = NULL;
674 dev_set_drvdata(chip->dev, chip);
675
676 return 0;
677}
678
679static struct i2c_driver tpm_tis_i2c_driver = {
680
681 .id_table = tpm_tis_i2c_table,
682 .probe = tpm_tis_i2c_probe,
683 .remove = tpm_tis_i2c_remove,
684 .driver = {
685 .name = "tpm_i2c_infineon",
686 .owner = THIS_MODULE,
687 .pm = &tpm_tis_i2c_ops,
688 },
689};
690
691module_i2c_driver(tpm_tis_i2c_driver);
692MODULE_AUTHOR("Peter Huewe <peter.huewe@infineon.com>");
693MODULE_DESCRIPTION("TPM TIS I2C Infineon Driver");
694MODULE_VERSION("2.1.5");
695MODULE_LICENSE("GPL");
diff --git a/drivers/char/tpm/tpm_ibmvtpm.c b/drivers/char/tpm/tpm_ibmvtpm.c
new file mode 100644
index 000000000000..efc4ab36a9d6
--- /dev/null
+++ b/drivers/char/tpm/tpm_ibmvtpm.c
@@ -0,0 +1,749 @@
1/*
2 * Copyright (C) 2012 IBM Corporation
3 *
4 * Author: Ashley Lai <adlai@us.ibm.com>
5 *
6 * Maintained by: <tpmdd-devel@lists.sourceforge.net>
7 *
8 * Device driver for TCG/TCPA TPM (trusted platform module).
9 * Specifications at www.trustedcomputinggroup.org
10 *
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License as
13 * published by the Free Software Foundation, version 2 of the
14 * License.
15 *
16 */
17
18#include <linux/dma-mapping.h>
19#include <linux/dmapool.h>
20#include <linux/slab.h>
21#include <asm/vio.h>
22#include <asm/irq.h>
23#include <linux/types.h>
24#include <linux/list.h>
25#include <linux/spinlock.h>
26#include <linux/interrupt.h>
27#include <linux/wait.h>
28#include <asm/prom.h>
29
30#include "tpm.h"
31#include "tpm_ibmvtpm.h"
32
33static const char tpm_ibmvtpm_driver_name[] = "tpm_ibmvtpm";
34
35static struct vio_device_id tpm_ibmvtpm_device_table[] __devinitdata = {
36 { "IBM,vtpm", "IBM,vtpm"},
37 { "", "" }
38};
39MODULE_DEVICE_TABLE(vio, tpm_ibmvtpm_device_table);
40
41DECLARE_WAIT_QUEUE_HEAD(wq);
42
43/**
44 * ibmvtpm_send_crq - Send a CRQ request
45 * @vdev: vio device struct
46 * @w1: first word
47 * @w2: second word
48 *
49 * Return value:
50 * 0 -Sucess
51 * Non-zero - Failure
52 */
53static int ibmvtpm_send_crq(struct vio_dev *vdev, u64 w1, u64 w2)
54{
55 return plpar_hcall_norets(H_SEND_CRQ, vdev->unit_address, w1, w2);
56}
57
58/**
59 * ibmvtpm_get_data - Retrieve ibm vtpm data
60 * @dev: device struct
61 *
62 * Return value:
63 * vtpm device struct
64 */
65static struct ibmvtpm_dev *ibmvtpm_get_data(const struct device *dev)
66{
67 struct tpm_chip *chip = dev_get_drvdata(dev);
68 if (chip)
69 return (struct ibmvtpm_dev *)chip->vendor.data;
70 return NULL;
71}
72
73/**
74 * tpm_ibmvtpm_recv - Receive data after send
75 * @chip: tpm chip struct
76 * @buf: buffer to read
77 * count: size of buffer
78 *
79 * Return value:
80 * Number of bytes read
81 */
82static int tpm_ibmvtpm_recv(struct tpm_chip *chip, u8 *buf, size_t count)
83{
84 struct ibmvtpm_dev *ibmvtpm;
85 u16 len;
86
87 ibmvtpm = (struct ibmvtpm_dev *)chip->vendor.data;
88
89 if (!ibmvtpm->rtce_buf) {
90 dev_err(ibmvtpm->dev, "ibmvtpm device is not ready\n");
91 return 0;
92 }
93
94 wait_event_interruptible(wq, ibmvtpm->crq_res.len != 0);
95
96 if (count < ibmvtpm->crq_res.len) {
97 dev_err(ibmvtpm->dev,
98 "Invalid size in recv: count=%ld, crq_size=%d\n",
99 count, ibmvtpm->crq_res.len);
100 return -EIO;
101 }
102
103 spin_lock(&ibmvtpm->rtce_lock);
104 memcpy((void *)buf, (void *)ibmvtpm->rtce_buf, ibmvtpm->crq_res.len);
105 memset(ibmvtpm->rtce_buf, 0, ibmvtpm->crq_res.len);
106 ibmvtpm->crq_res.valid = 0;
107 ibmvtpm->crq_res.msg = 0;
108 len = ibmvtpm->crq_res.len;
109 ibmvtpm->crq_res.len = 0;
110 spin_unlock(&ibmvtpm->rtce_lock);
111 return len;
112}
113
114/**
115 * tpm_ibmvtpm_send - Send tpm request
116 * @chip: tpm chip struct
117 * @buf: buffer contains data to send
118 * count: size of buffer
119 *
120 * Return value:
121 * Number of bytes sent
122 */
123static int tpm_ibmvtpm_send(struct tpm_chip *chip, u8 *buf, size_t count)
124{
125 struct ibmvtpm_dev *ibmvtpm;
126 struct ibmvtpm_crq crq;
127 u64 *word = (u64 *) &crq;
128 int rc;
129
130 ibmvtpm = (struct ibmvtpm_dev *)chip->vendor.data;
131
132 if (!ibmvtpm->rtce_buf) {
133 dev_err(ibmvtpm->dev, "ibmvtpm device is not ready\n");
134 return 0;
135 }
136
137 if (count > ibmvtpm->rtce_size) {
138 dev_err(ibmvtpm->dev,
139 "Invalid size in send: count=%ld, rtce_size=%d\n",
140 count, ibmvtpm->rtce_size);
141 return -EIO;
142 }
143
144 spin_lock(&ibmvtpm->rtce_lock);
145 memcpy((void *)ibmvtpm->rtce_buf, (void *)buf, count);
146 crq.valid = (u8)IBMVTPM_VALID_CMD;
147 crq.msg = (u8)VTPM_TPM_COMMAND;
148 crq.len = (u16)count;
149 crq.data = ibmvtpm->rtce_dma_handle;
150
151 rc = ibmvtpm_send_crq(ibmvtpm->vdev, word[0], word[1]);
152 if (rc != H_SUCCESS) {
153 dev_err(ibmvtpm->dev, "tpm_ibmvtpm_send failed rc=%d\n", rc);
154 rc = 0;
155 } else
156 rc = count;
157
158 spin_unlock(&ibmvtpm->rtce_lock);
159 return rc;
160}
161
162static void tpm_ibmvtpm_cancel(struct tpm_chip *chip)
163{
164 return;
165}
166
167static u8 tpm_ibmvtpm_status(struct tpm_chip *chip)
168{
169 return 0;
170}
171
172/**
173 * ibmvtpm_crq_get_rtce_size - Send a CRQ request to get rtce size
174 * @ibmvtpm: vtpm device struct
175 *
176 * Return value:
177 * 0 - Success
178 * Non-zero - Failure
179 */
180static int ibmvtpm_crq_get_rtce_size(struct ibmvtpm_dev *ibmvtpm)
181{
182 struct ibmvtpm_crq crq;
183 u64 *buf = (u64 *) &crq;
184 int rc;
185
186 crq.valid = (u8)IBMVTPM_VALID_CMD;
187 crq.msg = (u8)VTPM_GET_RTCE_BUFFER_SIZE;
188
189 rc = ibmvtpm_send_crq(ibmvtpm->vdev, buf[0], buf[1]);
190 if (rc != H_SUCCESS)
191 dev_err(ibmvtpm->dev,
192 "ibmvtpm_crq_get_rtce_size failed rc=%d\n", rc);
193
194 return rc;
195}
196
197/**
198 * ibmvtpm_crq_get_version - Send a CRQ request to get vtpm version
199 * - Note that this is vtpm version and not tpm version
200 * @ibmvtpm: vtpm device struct
201 *
202 * Return value:
203 * 0 - Success
204 * Non-zero - Failure
205 */
206static int ibmvtpm_crq_get_version(struct ibmvtpm_dev *ibmvtpm)
207{
208 struct ibmvtpm_crq crq;
209 u64 *buf = (u64 *) &crq;
210 int rc;
211
212 crq.valid = (u8)IBMVTPM_VALID_CMD;
213 crq.msg = (u8)VTPM_GET_VERSION;
214
215 rc = ibmvtpm_send_crq(ibmvtpm->vdev, buf[0], buf[1]);
216 if (rc != H_SUCCESS)
217 dev_err(ibmvtpm->dev,
218 "ibmvtpm_crq_get_version failed rc=%d\n", rc);
219
220 return rc;
221}
222
223/**
224 * ibmvtpm_crq_send_init_complete - Send a CRQ initialize complete message
225 * @ibmvtpm: vtpm device struct
226 *
227 * Return value:
228 * 0 - Success
229 * Non-zero - Failure
230 */
231static int ibmvtpm_crq_send_init_complete(struct ibmvtpm_dev *ibmvtpm)
232{
233 int rc;
234
235 rc = ibmvtpm_send_crq(ibmvtpm->vdev, INIT_CRQ_COMP_CMD, 0);
236 if (rc != H_SUCCESS)
237 dev_err(ibmvtpm->dev,
238 "ibmvtpm_crq_send_init_complete failed rc=%d\n", rc);
239
240 return rc;
241}
242
243/**
244 * ibmvtpm_crq_send_init - Send a CRQ initialize message
245 * @ibmvtpm: vtpm device struct
246 *
247 * Return value:
248 * 0 - Success
249 * Non-zero - Failure
250 */
251static int ibmvtpm_crq_send_init(struct ibmvtpm_dev *ibmvtpm)
252{
253 int rc;
254
255 rc = ibmvtpm_send_crq(ibmvtpm->vdev, INIT_CRQ_CMD, 0);
256 if (rc != H_SUCCESS)
257 dev_err(ibmvtpm->dev,
258 "ibmvtpm_crq_send_init failed rc=%d\n", rc);
259
260 return rc;
261}
262
263/**
264 * tpm_ibmvtpm_remove - ibm vtpm remove entry point
265 * @vdev: vio device struct
266 *
267 * Return value:
268 * 0
269 */
270static int __devexit tpm_ibmvtpm_remove(struct vio_dev *vdev)
271{
272 struct ibmvtpm_dev *ibmvtpm = ibmvtpm_get_data(&vdev->dev);
273 int rc = 0;
274
275 free_irq(vdev->irq, ibmvtpm);
276 tasklet_kill(&ibmvtpm->tasklet);
277
278 do {
279 if (rc)
280 msleep(100);
281 rc = plpar_hcall_norets(H_FREE_CRQ, vdev->unit_address);
282 } while (rc == H_BUSY || H_IS_LONG_BUSY(rc));
283
284 dma_unmap_single(ibmvtpm->dev, ibmvtpm->crq_dma_handle,
285 CRQ_RES_BUF_SIZE, DMA_BIDIRECTIONAL);
286 free_page((unsigned long)ibmvtpm->crq_queue.crq_addr);
287
288 if (ibmvtpm->rtce_buf) {
289 dma_unmap_single(ibmvtpm->dev, ibmvtpm->rtce_dma_handle,
290 ibmvtpm->rtce_size, DMA_BIDIRECTIONAL);
291 kfree(ibmvtpm->rtce_buf);
292 }
293
294 tpm_remove_hardware(ibmvtpm->dev);
295
296 kfree(ibmvtpm);
297
298 return 0;
299}
300
301/**
302 * tpm_ibmvtpm_get_desired_dma - Get DMA size needed by this driver
303 * @vdev: vio device struct
304 *
305 * Return value:
306 * Number of bytes the driver needs to DMA map
307 */
308static unsigned long tpm_ibmvtpm_get_desired_dma(struct vio_dev *vdev)
309{
310 struct ibmvtpm_dev *ibmvtpm = ibmvtpm_get_data(&vdev->dev);
311 return CRQ_RES_BUF_SIZE + ibmvtpm->rtce_size;
312}
313
314/**
315 * tpm_ibmvtpm_suspend - Suspend
316 * @dev: device struct
317 *
318 * Return value:
319 * 0
320 */
321static int tpm_ibmvtpm_suspend(struct device *dev)
322{
323 struct ibmvtpm_dev *ibmvtpm = ibmvtpm_get_data(dev);
324 struct ibmvtpm_crq crq;
325 u64 *buf = (u64 *) &crq;
326 int rc = 0;
327
328 crq.valid = (u8)IBMVTPM_VALID_CMD;
329 crq.msg = (u8)VTPM_PREPARE_TO_SUSPEND;
330
331 rc = ibmvtpm_send_crq(ibmvtpm->vdev, buf[0], buf[1]);
332 if (rc != H_SUCCESS)
333 dev_err(ibmvtpm->dev,
334 "tpm_ibmvtpm_suspend failed rc=%d\n", rc);
335
336 return rc;
337}
338
339/**
340 * ibmvtpm_reset_crq - Reset CRQ
341 * @ibmvtpm: ibm vtpm struct
342 *
343 * Return value:
344 * 0 - Success
345 * Non-zero - Failure
346 */
347static int ibmvtpm_reset_crq(struct ibmvtpm_dev *ibmvtpm)
348{
349 int rc = 0;
350
351 do {
352 if (rc)
353 msleep(100);
354 rc = plpar_hcall_norets(H_FREE_CRQ,
355 ibmvtpm->vdev->unit_address);
356 } while (rc == H_BUSY || H_IS_LONG_BUSY(rc));
357
358 memset(ibmvtpm->crq_queue.crq_addr, 0, CRQ_RES_BUF_SIZE);
359 ibmvtpm->crq_queue.index = 0;
360
361 return plpar_hcall_norets(H_REG_CRQ, ibmvtpm->vdev->unit_address,
362 ibmvtpm->crq_dma_handle, CRQ_RES_BUF_SIZE);
363}
364
365/**
366 * tpm_ibmvtpm_resume - Resume from suspend
367 * @dev: device struct
368 *
369 * Return value:
370 * 0
371 */
372static int tpm_ibmvtpm_resume(struct device *dev)
373{
374 struct ibmvtpm_dev *ibmvtpm = ibmvtpm_get_data(dev);
375 unsigned long flags;
376 int rc = 0;
377
378 do {
379 if (rc)
380 msleep(100);
381 rc = plpar_hcall_norets(H_ENABLE_CRQ,
382 ibmvtpm->vdev->unit_address);
383 } while (rc == H_IN_PROGRESS || rc == H_BUSY || H_IS_LONG_BUSY(rc));
384
385 if (rc) {
386 dev_err(dev, "Error enabling ibmvtpm rc=%d\n", rc);
387 return rc;
388 }
389
390 spin_lock_irqsave(&ibmvtpm->lock, flags);
391 vio_disable_interrupts(ibmvtpm->vdev);
392 tasklet_schedule(&ibmvtpm->tasklet);
393 spin_unlock_irqrestore(&ibmvtpm->lock, flags);
394
395 rc = ibmvtpm_crq_send_init(ibmvtpm);
396 if (rc)
397 dev_err(dev, "Error send_init rc=%d\n", rc);
398
399 return rc;
400}
401
402static const struct file_operations ibmvtpm_ops = {
403 .owner = THIS_MODULE,
404 .llseek = no_llseek,
405 .open = tpm_open,
406 .read = tpm_read,
407 .write = tpm_write,
408 .release = tpm_release,
409};
410
411static DEVICE_ATTR(pubek, S_IRUGO, tpm_show_pubek, NULL);
412static DEVICE_ATTR(pcrs, S_IRUGO, tpm_show_pcrs, NULL);
413static DEVICE_ATTR(enabled, S_IRUGO, tpm_show_enabled, NULL);
414static DEVICE_ATTR(active, S_IRUGO, tpm_show_active, NULL);
415static DEVICE_ATTR(owned, S_IRUGO, tpm_show_owned, NULL);
416static DEVICE_ATTR(temp_deactivated, S_IRUGO, tpm_show_temp_deactivated,
417 NULL);
418static DEVICE_ATTR(caps, S_IRUGO, tpm_show_caps_1_2, NULL);
419static DEVICE_ATTR(cancel, S_IWUSR | S_IWGRP, NULL, tpm_store_cancel);
420static DEVICE_ATTR(durations, S_IRUGO, tpm_show_durations, NULL);
421static DEVICE_ATTR(timeouts, S_IRUGO, tpm_show_timeouts, NULL);
422
423static struct attribute *ibmvtpm_attrs[] = {
424 &dev_attr_pubek.attr,
425 &dev_attr_pcrs.attr,
426 &dev_attr_enabled.attr,
427 &dev_attr_active.attr,
428 &dev_attr_owned.attr,
429 &dev_attr_temp_deactivated.attr,
430 &dev_attr_caps.attr,
431 &dev_attr_cancel.attr,
432 &dev_attr_durations.attr,
433 &dev_attr_timeouts.attr, NULL,
434};
435
436static struct attribute_group ibmvtpm_attr_grp = { .attrs = ibmvtpm_attrs };
437
438static const struct tpm_vendor_specific tpm_ibmvtpm = {
439 .recv = tpm_ibmvtpm_recv,
440 .send = tpm_ibmvtpm_send,
441 .cancel = tpm_ibmvtpm_cancel,
442 .status = tpm_ibmvtpm_status,
443 .req_complete_mask = 0,
444 .req_complete_val = 0,
445 .req_canceled = 0,
446 .attr_group = &ibmvtpm_attr_grp,
447 .miscdev = { .fops = &ibmvtpm_ops, },
448};
449
450static const struct dev_pm_ops tpm_ibmvtpm_pm_ops = {
451 .suspend = tpm_ibmvtpm_suspend,
452 .resume = tpm_ibmvtpm_resume,
453};
454
455/**
456 * ibmvtpm_crq_get_next - Get next responded crq
457 * @ibmvtpm vtpm device struct
458 *
459 * Return value:
460 * vtpm crq pointer
461 */
462static struct ibmvtpm_crq *ibmvtpm_crq_get_next(struct ibmvtpm_dev *ibmvtpm)
463{
464 struct ibmvtpm_crq_queue *crq_q = &ibmvtpm->crq_queue;
465 struct ibmvtpm_crq *crq = &crq_q->crq_addr[crq_q->index];
466
467 if (crq->valid & VTPM_MSG_RES) {
468 if (++crq_q->index == crq_q->num_entry)
469 crq_q->index = 0;
470 rmb();
471 } else
472 crq = NULL;
473 return crq;
474}
475
476/**
477 * ibmvtpm_crq_process - Process responded crq
478 * @crq crq to be processed
479 * @ibmvtpm vtpm device struct
480 *
481 * Return value:
482 * Nothing
483 */
484static void ibmvtpm_crq_process(struct ibmvtpm_crq *crq,
485 struct ibmvtpm_dev *ibmvtpm)
486{
487 int rc = 0;
488
489 switch (crq->valid) {
490 case VALID_INIT_CRQ:
491 switch (crq->msg) {
492 case INIT_CRQ_RES:
493 dev_info(ibmvtpm->dev, "CRQ initialized\n");
494 rc = ibmvtpm_crq_send_init_complete(ibmvtpm);
495 if (rc)
496 dev_err(ibmvtpm->dev, "Unable to send CRQ init complete rc=%d\n", rc);
497 return;
498 case INIT_CRQ_COMP_RES:
499 dev_info(ibmvtpm->dev,
500 "CRQ initialization completed\n");
501 return;
502 default:
503 dev_err(ibmvtpm->dev, "Unknown crq message type: %d\n", crq->msg);
504 return;
505 }
506 return;
507 case IBMVTPM_VALID_CMD:
508 switch (crq->msg) {
509 case VTPM_GET_RTCE_BUFFER_SIZE_RES:
510 if (crq->len <= 0) {
511 dev_err(ibmvtpm->dev, "Invalid rtce size\n");
512 return;
513 }
514 ibmvtpm->rtce_size = crq->len;
515 ibmvtpm->rtce_buf = kmalloc(ibmvtpm->rtce_size,
516 GFP_KERNEL);
517 if (!ibmvtpm->rtce_buf) {
518 dev_err(ibmvtpm->dev, "Failed to allocate memory for rtce buffer\n");
519 return;
520 }
521
522 ibmvtpm->rtce_dma_handle = dma_map_single(ibmvtpm->dev,
523 ibmvtpm->rtce_buf, ibmvtpm->rtce_size,
524 DMA_BIDIRECTIONAL);
525
526 if (dma_mapping_error(ibmvtpm->dev,
527 ibmvtpm->rtce_dma_handle)) {
528 kfree(ibmvtpm->rtce_buf);
529 ibmvtpm->rtce_buf = NULL;
530 dev_err(ibmvtpm->dev, "Failed to dma map rtce buffer\n");
531 }
532
533 return;
534 case VTPM_GET_VERSION_RES:
535 ibmvtpm->vtpm_version = crq->data;
536 return;
537 case VTPM_TPM_COMMAND_RES:
538 ibmvtpm->crq_res.valid = crq->valid;
539 ibmvtpm->crq_res.msg = crq->msg;
540 ibmvtpm->crq_res.len = crq->len;
541 ibmvtpm->crq_res.data = crq->data;
542 wake_up_interruptible(&wq);
543 return;
544 default:
545 return;
546 }
547 }
548 return;
549}
550
551/**
552 * ibmvtpm_interrupt - Interrupt handler
553 * @irq: irq number to handle
554 * @vtpm_instance: vtpm that received interrupt
555 *
556 * Returns:
557 * IRQ_HANDLED
558 **/
559static irqreturn_t ibmvtpm_interrupt(int irq, void *vtpm_instance)
560{
561 struct ibmvtpm_dev *ibmvtpm = (struct ibmvtpm_dev *) vtpm_instance;
562 unsigned long flags;
563
564 spin_lock_irqsave(&ibmvtpm->lock, flags);
565 vio_disable_interrupts(ibmvtpm->vdev);
566 tasklet_schedule(&ibmvtpm->tasklet);
567 spin_unlock_irqrestore(&ibmvtpm->lock, flags);
568
569 return IRQ_HANDLED;
570}
571
572/**
573 * ibmvtpm_tasklet - Interrupt handler tasklet
574 * @data: ibm vtpm device struct
575 *
576 * Returns:
577 * Nothing
578 **/
579static void ibmvtpm_tasklet(void *data)
580{
581 struct ibmvtpm_dev *ibmvtpm = data;
582 struct ibmvtpm_crq *crq;
583 unsigned long flags;
584
585 spin_lock_irqsave(&ibmvtpm->lock, flags);
586 while ((crq = ibmvtpm_crq_get_next(ibmvtpm)) != NULL) {
587 ibmvtpm_crq_process(crq, ibmvtpm);
588 crq->valid = 0;
589 wmb();
590 }
591
592 vio_enable_interrupts(ibmvtpm->vdev);
593 spin_unlock_irqrestore(&ibmvtpm->lock, flags);
594}
595
596/**
597 * tpm_ibmvtpm_probe - ibm vtpm initialize entry point
598 * @vio_dev: vio device struct
599 * @id: vio device id struct
600 *
601 * Return value:
602 * 0 - Success
603 * Non-zero - Failure
604 */
605static int __devinit tpm_ibmvtpm_probe(struct vio_dev *vio_dev,
606 const struct vio_device_id *id)
607{
608 struct ibmvtpm_dev *ibmvtpm;
609 struct device *dev = &vio_dev->dev;
610 struct ibmvtpm_crq_queue *crq_q;
611 struct tpm_chip *chip;
612 int rc = -ENOMEM, rc1;
613
614 chip = tpm_register_hardware(dev, &tpm_ibmvtpm);
615 if (!chip) {
616 dev_err(dev, "tpm_register_hardware failed\n");
617 return -ENODEV;
618 }
619
620 ibmvtpm = kzalloc(sizeof(struct ibmvtpm_dev), GFP_KERNEL);
621 if (!ibmvtpm) {
622 dev_err(dev, "kzalloc for ibmvtpm failed\n");
623 goto cleanup;
624 }
625
626 crq_q = &ibmvtpm->crq_queue;
627 crq_q->crq_addr = (struct ibmvtpm_crq *)get_zeroed_page(GFP_KERNEL);
628 if (!crq_q->crq_addr) {
629 dev_err(dev, "Unable to allocate memory for crq_addr\n");
630 goto cleanup;
631 }
632
633 crq_q->num_entry = CRQ_RES_BUF_SIZE / sizeof(*crq_q->crq_addr);
634 ibmvtpm->crq_dma_handle = dma_map_single(dev, crq_q->crq_addr,
635 CRQ_RES_BUF_SIZE,
636 DMA_BIDIRECTIONAL);
637
638 if (dma_mapping_error(dev, ibmvtpm->crq_dma_handle)) {
639 dev_err(dev, "dma mapping failed\n");
640 goto cleanup;
641 }
642
643 rc = plpar_hcall_norets(H_REG_CRQ, vio_dev->unit_address,
644 ibmvtpm->crq_dma_handle, CRQ_RES_BUF_SIZE);
645 if (rc == H_RESOURCE)
646 rc = ibmvtpm_reset_crq(ibmvtpm);
647
648 if (rc) {
649 dev_err(dev, "Unable to register CRQ rc=%d\n", rc);
650 goto reg_crq_cleanup;
651 }
652
653 tasklet_init(&ibmvtpm->tasklet, (void *)ibmvtpm_tasklet,
654 (unsigned long)ibmvtpm);
655
656 rc = request_irq(vio_dev->irq, ibmvtpm_interrupt, 0,
657 tpm_ibmvtpm_driver_name, ibmvtpm);
658 if (rc) {
659 dev_err(dev, "Error %d register irq 0x%x\n", rc, vio_dev->irq);
660 goto init_irq_cleanup;
661 }
662
663 rc = vio_enable_interrupts(vio_dev);
664 if (rc) {
665 dev_err(dev, "Error %d enabling interrupts\n", rc);
666 goto init_irq_cleanup;
667 }
668
669 crq_q->index = 0;
670
671 ibmvtpm->dev = dev;
672 ibmvtpm->vdev = vio_dev;
673 chip->vendor.data = (void *)ibmvtpm;
674
675 spin_lock_init(&ibmvtpm->lock);
676 spin_lock_init(&ibmvtpm->rtce_lock);
677
678 rc = ibmvtpm_crq_send_init(ibmvtpm);
679 if (rc)
680 goto init_irq_cleanup;
681
682 rc = ibmvtpm_crq_get_version(ibmvtpm);
683 if (rc)
684 goto init_irq_cleanup;
685
686 rc = ibmvtpm_crq_get_rtce_size(ibmvtpm);
687 if (rc)
688 goto init_irq_cleanup;
689
690 return rc;
691init_irq_cleanup:
692 tasklet_kill(&ibmvtpm->tasklet);
693 do {
694 rc1 = plpar_hcall_norets(H_FREE_CRQ, vio_dev->unit_address);
695 } while (rc1 == H_BUSY || H_IS_LONG_BUSY(rc1));
696reg_crq_cleanup:
697 dma_unmap_single(dev, ibmvtpm->crq_dma_handle, CRQ_RES_BUF_SIZE,
698 DMA_BIDIRECTIONAL);
699cleanup:
700 if (ibmvtpm) {
701 if (crq_q->crq_addr)
702 free_page((unsigned long)crq_q->crq_addr);
703 kfree(ibmvtpm);
704 }
705
706 tpm_remove_hardware(dev);
707
708 return rc;
709}
710
711static struct vio_driver ibmvtpm_driver = {
712 .id_table = tpm_ibmvtpm_device_table,
713 .probe = tpm_ibmvtpm_probe,
714 .remove = tpm_ibmvtpm_remove,
715 .get_desired_dma = tpm_ibmvtpm_get_desired_dma,
716 .name = tpm_ibmvtpm_driver_name,
717 .pm = &tpm_ibmvtpm_pm_ops,
718};
719
720/**
721 * ibmvtpm_module_init - Initialize ibm vtpm module
722 *
723 * Return value:
724 * 0 -Success
725 * Non-zero - Failure
726 */
727static int __init ibmvtpm_module_init(void)
728{
729 return vio_register_driver(&ibmvtpm_driver);
730}
731
732/**
733 * ibmvtpm_module_exit - Teardown ibm vtpm module
734 *
735 * Return value:
736 * Nothing
737 */
738static void __exit ibmvtpm_module_exit(void)
739{
740 vio_unregister_driver(&ibmvtpm_driver);
741}
742
743module_init(ibmvtpm_module_init);
744module_exit(ibmvtpm_module_exit);
745
746MODULE_AUTHOR("adlai@us.ibm.com");
747MODULE_DESCRIPTION("IBM vTPM Driver");
748MODULE_VERSION("1.0");
749MODULE_LICENSE("GPL");
diff --git a/drivers/char/tpm/tpm_ibmvtpm.h b/drivers/char/tpm/tpm_ibmvtpm.h
new file mode 100644
index 000000000000..4296eb4b4d82
--- /dev/null
+++ b/drivers/char/tpm/tpm_ibmvtpm.h
@@ -0,0 +1,77 @@
1/*
2 * Copyright (C) 2012 IBM Corporation
3 *
4 * Author: Ashley Lai <adlai@us.ibm.com>
5 *
6 * Maintained by: <tpmdd-devel@lists.sourceforge.net>
7 *
8 * Device driver for TCG/TCPA TPM (trusted platform module).
9 * Specifications at www.trustedcomputinggroup.org
10 *
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License as
13 * published by the Free Software Foundation, version 2 of the
14 * License.
15 *
16 */
17
18#ifndef __TPM_IBMVTPM_H__
19#define __TPM_IBMVTPM_H__
20
21/* vTPM Message Format 1 */
22struct ibmvtpm_crq {
23 u8 valid;
24 u8 msg;
25 u16 len;
26 u32 data;
27 u64 reserved;
28} __attribute__((packed, aligned(8)));
29
30struct ibmvtpm_crq_queue {
31 struct ibmvtpm_crq *crq_addr;
32 u32 index;
33 u32 num_entry;
34};
35
36struct ibmvtpm_dev {
37 struct device *dev;
38 struct vio_dev *vdev;
39 struct ibmvtpm_crq_queue crq_queue;
40 dma_addr_t crq_dma_handle;
41 spinlock_t lock;
42 struct tasklet_struct tasklet;
43 u32 rtce_size;
44 void __iomem *rtce_buf;
45 dma_addr_t rtce_dma_handle;
46 spinlock_t rtce_lock;
47 struct ibmvtpm_crq crq_res;
48 u32 vtpm_version;
49};
50
51#define CRQ_RES_BUF_SIZE PAGE_SIZE
52
53/* Initialize CRQ */
54#define INIT_CRQ_CMD 0xC001000000000000LL /* Init cmd */
55#define INIT_CRQ_COMP_CMD 0xC002000000000000LL /* Init complete cmd */
56#define INIT_CRQ_RES 0x01 /* Init respond */
57#define INIT_CRQ_COMP_RES 0x02 /* Init complete respond */
58#define VALID_INIT_CRQ 0xC0 /* Valid command for init crq */
59
60/* vTPM CRQ response is the message type | 0x80 */
61#define VTPM_MSG_RES 0x80
62#define IBMVTPM_VALID_CMD 0x80
63
64/* vTPM CRQ message types */
65#define VTPM_GET_VERSION 0x01
66#define VTPM_GET_VERSION_RES (0x01 | VTPM_MSG_RES)
67
68#define VTPM_TPM_COMMAND 0x02
69#define VTPM_TPM_COMMAND_RES (0x02 | VTPM_MSG_RES)
70
71#define VTPM_GET_RTCE_BUFFER_SIZE 0x03
72#define VTPM_GET_RTCE_BUFFER_SIZE_RES (0x03 | VTPM_MSG_RES)
73
74#define VTPM_PREPARE_TO_SUSPEND 0x04
75#define VTPM_PREPARE_TO_SUSPEND_RES (0x04 | VTPM_MSG_RES)
76
77#endif
diff --git a/drivers/char/tpm/tpm_of.c b/drivers/char/tpm/tpm_of.c
new file mode 100644
index 000000000000..98ba2bd1a355
--- /dev/null
+++ b/drivers/char/tpm/tpm_of.c
@@ -0,0 +1,73 @@
1/*
2 * Copyright 2012 IBM Corporation
3 *
4 * Author: Ashley Lai <adlai@us.ibm.com>
5 *
6 * Maintained by: <tpmdd-devel@lists.sourceforge.net>
7 *
8 * Read the event log created by the firmware on PPC64
9 *
10 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License
12 * as published by the Free Software Foundation; either version
13 * 2 of the License, or (at your option) any later version.
14 *
15 */
16
17#include <linux/slab.h>
18#include <linux/of.h>
19
20#include "tpm.h"
21#include "tpm_eventlog.h"
22
23int read_log(struct tpm_bios_log *log)
24{
25 struct device_node *np;
26 const u32 *sizep;
27 const __be64 *basep;
28
29 if (log->bios_event_log != NULL) {
30 pr_err("%s: ERROR - Eventlog already initialized\n", __func__);
31 return -EFAULT;
32 }
33
34 np = of_find_node_by_name(NULL, "ibm,vtpm");
35 if (!np) {
36 pr_err("%s: ERROR - IBMVTPM not supported\n", __func__);
37 return -ENODEV;
38 }
39
40 sizep = of_get_property(np, "linux,sml-size", NULL);
41 if (sizep == NULL) {
42 pr_err("%s: ERROR - SML size not found\n", __func__);
43 goto cleanup_eio;
44 }
45 if (*sizep == 0) {
46 pr_err("%s: ERROR - event log area empty\n", __func__);
47 goto cleanup_eio;
48 }
49
50 basep = of_get_property(np, "linux,sml-base", NULL);
51 if (basep == NULL) {
52 pr_err(KERN_ERR "%s: ERROR - SML not found\n", __func__);
53 goto cleanup_eio;
54 }
55
56 of_node_put(np);
57 log->bios_event_log = kmalloc(*sizep, GFP_KERNEL);
58 if (!log->bios_event_log) {
59 pr_err("%s: ERROR - Not enough memory for BIOS measurements\n",
60 __func__);
61 return -ENOMEM;
62 }
63
64 log->bios_event_log_end = log->bios_event_log + *sizep;
65
66 memcpy(log->bios_event_log, __va(be64_to_cpup(basep)), *sizep);
67
68 return 0;
69
70cleanup_eio:
71 of_node_put(np);
72 return -EIO;
73}
diff --git a/drivers/char/tpm/tpm_ppi.c b/drivers/char/tpm/tpm_ppi.c
new file mode 100644
index 000000000000..f27b58cfae98
--- /dev/null
+++ b/drivers/char/tpm/tpm_ppi.c
@@ -0,0 +1,461 @@
1#include <linux/acpi.h>
2#include <acpi/acpi_drivers.h>
3#include "tpm.h"
4
5static const u8 tpm_ppi_uuid[] = {
6 0xA6, 0xFA, 0xDD, 0x3D,
7 0x1B, 0x36,
8 0xB4, 0x4E,
9 0xA4, 0x24,
10 0x8D, 0x10, 0x08, 0x9D, 0x16, 0x53
11};
12static char *tpm_device_name = "TPM";
13
14#define TPM_PPI_REVISION_ID 1
15#define TPM_PPI_FN_VERSION 1
16#define TPM_PPI_FN_SUBREQ 2
17#define TPM_PPI_FN_GETREQ 3
18#define TPM_PPI_FN_GETACT 4
19#define TPM_PPI_FN_GETRSP 5
20#define TPM_PPI_FN_SUBREQ2 7
21#define TPM_PPI_FN_GETOPR 8
22#define PPI_TPM_REQ_MAX 22
23#define PPI_VS_REQ_START 128
24#define PPI_VS_REQ_END 255
25#define PPI_VERSION_LEN 3
26
27static acpi_status ppi_callback(acpi_handle handle, u32 level, void *context,
28 void **return_value)
29{
30 acpi_status status;
31 struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
32 status = acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer);
33 if (strstr(buffer.pointer, context) != NULL) {
34 *return_value = handle;
35 kfree(buffer.pointer);
36 return AE_CTRL_TERMINATE;
37 }
38 return AE_OK;
39}
40
41static inline void ppi_assign_params(union acpi_object params[4],
42 u64 function_num)
43{
44 params[0].type = ACPI_TYPE_BUFFER;
45 params[0].buffer.length = sizeof(tpm_ppi_uuid);
46 params[0].buffer.pointer = (char *)tpm_ppi_uuid;
47 params[1].type = ACPI_TYPE_INTEGER;
48 params[1].integer.value = TPM_PPI_REVISION_ID;
49 params[2].type = ACPI_TYPE_INTEGER;
50 params[2].integer.value = function_num;
51 params[3].type = ACPI_TYPE_PACKAGE;
52 params[3].package.count = 0;
53 params[3].package.elements = NULL;
54}
55
56static ssize_t tpm_show_ppi_version(struct device *dev,
57 struct device_attribute *attr, char *buf)
58{
59 acpi_handle handle;
60 acpi_status status;
61 struct acpi_object_list input;
62 struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL };
63 union acpi_object params[4];
64 union acpi_object *obj;
65
66 input.count = 4;
67 ppi_assign_params(params, TPM_PPI_FN_VERSION);
68 input.pointer = params;
69 status = acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
70 ACPI_UINT32_MAX, ppi_callback, NULL,
71 tpm_device_name, &handle);
72 if (ACPI_FAILURE(status))
73 return -ENXIO;
74
75 status = acpi_evaluate_object_typed(handle, "_DSM", &input, &output,
76 ACPI_TYPE_STRING);
77 if (ACPI_FAILURE(status))
78 return -ENOMEM;
79 obj = (union acpi_object *)output.pointer;
80 status = scnprintf(buf, PAGE_SIZE, "%s\n", obj->string.pointer);
81 kfree(output.pointer);
82 return status;
83}
84
85static ssize_t tpm_show_ppi_request(struct device *dev,
86 struct device_attribute *attr, char *buf)
87{
88 acpi_handle handle;
89 acpi_status status;
90 struct acpi_object_list input;
91 struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL };
92 union acpi_object params[4];
93 union acpi_object *ret_obj;
94
95 input.count = 4;
96 ppi_assign_params(params, TPM_PPI_FN_GETREQ);
97 input.pointer = params;
98 status = acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
99 ACPI_UINT32_MAX, ppi_callback, NULL,
100 tpm_device_name, &handle);
101 if (ACPI_FAILURE(status))
102 return -ENXIO;
103
104 status = acpi_evaluate_object_typed(handle, "_DSM", &input, &output,
105 ACPI_TYPE_PACKAGE);
106 if (ACPI_FAILURE(status))
107 return -ENOMEM;
108 /*
109 * output.pointer should be of package type, including two integers.
110 * The first is function return code, 0 means success and 1 means
111 * error. The second is pending TPM operation requested by the OS, 0
112 * means none and >0 means operation value.
113 */
114 ret_obj = ((union acpi_object *)output.pointer)->package.elements;
115 if (ret_obj->type == ACPI_TYPE_INTEGER) {
116 if (ret_obj->integer.value) {
117 status = -EFAULT;
118 goto cleanup;
119 }
120 ret_obj++;
121 if (ret_obj->type == ACPI_TYPE_INTEGER)
122 status = scnprintf(buf, PAGE_SIZE, "%llu\n",
123 ret_obj->integer.value);
124 else
125 status = -EINVAL;
126 } else {
127 status = -EINVAL;
128 }
129cleanup:
130 kfree(output.pointer);
131 return status;
132}
133
134static ssize_t tpm_store_ppi_request(struct device *dev,
135 struct device_attribute *attr,
136 const char *buf, size_t count)
137{
138 char version[PPI_VERSION_LEN + 1];
139 acpi_handle handle;
140 acpi_status status;
141 struct acpi_object_list input;
142 struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL };
143 union acpi_object params[4];
144 union acpi_object obj;
145 u32 req;
146 u64 ret;
147
148 input.count = 4;
149 ppi_assign_params(params, TPM_PPI_FN_VERSION);
150 input.pointer = params;
151 status = acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
152 ACPI_UINT32_MAX, ppi_callback, NULL,
153 tpm_device_name, &handle);
154 if (ACPI_FAILURE(status))
155 return -ENXIO;
156
157 status = acpi_evaluate_object_typed(handle, "_DSM", &input, &output,
158 ACPI_TYPE_STRING);
159 if (ACPI_FAILURE(status))
160 return -ENOMEM;
161 strncpy(version,
162 ((union acpi_object *)output.pointer)->string.pointer,
163 PPI_VERSION_LEN);
164 kfree(output.pointer);
165 output.length = ACPI_ALLOCATE_BUFFER;
166 output.pointer = NULL;
167 /*
168 * the function to submit TPM operation request to pre-os environment
169 * is updated with function index from SUBREQ to SUBREQ2 since PPI
170 * version 1.1
171 */
172 if (strcmp(version, "1.1") == -1)
173 params[2].integer.value = TPM_PPI_FN_SUBREQ;
174 else
175 params[2].integer.value = TPM_PPI_FN_SUBREQ2;
176 /*
177 * PPI spec defines params[3].type as ACPI_TYPE_PACKAGE. Some BIOS
178 * accept buffer/string/integer type, but some BIOS accept buffer/
179 * string/package type. For PPI version 1.0 and 1.1, use buffer type
180 * for compatibility, and use package type since 1.2 according to spec.
181 */
182 if (strcmp(version, "1.2") == -1) {
183 params[3].type = ACPI_TYPE_BUFFER;
184 params[3].buffer.length = sizeof(req);
185 sscanf(buf, "%d", &req);
186 params[3].buffer.pointer = (char *)&req;
187 } else {
188 params[3].package.count = 1;
189 obj.type = ACPI_TYPE_INTEGER;
190 sscanf(buf, "%llu", &obj.integer.value);
191 params[3].package.elements = &obj;
192 }
193
194 status = acpi_evaluate_object_typed(handle, "_DSM", &input, &output,
195 ACPI_TYPE_INTEGER);
196 if (ACPI_FAILURE(status))
197 return -ENOMEM;
198 ret = ((union acpi_object *)output.pointer)->integer.value;
199 if (ret == 0)
200 status = (acpi_status)count;
201 else if (ret == 1)
202 status = -EPERM;
203 else
204 status = -EFAULT;
205 kfree(output.pointer);
206 return status;
207}
208
209static ssize_t tpm_show_ppi_transition_action(struct device *dev,
210 struct device_attribute *attr,
211 char *buf)
212{
213 char version[PPI_VERSION_LEN + 1];
214 acpi_handle handle;
215 acpi_status status;
216 struct acpi_object_list input;
217 struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL };
218 union acpi_object params[4];
219 u32 ret;
220 char *info[] = {
221 "None",
222 "Shutdown",
223 "Reboot",
224 "OS Vendor-specific",
225 "Error",
226 };
227 input.count = 4;
228 ppi_assign_params(params, TPM_PPI_FN_VERSION);
229 input.pointer = params;
230 status = acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
231 ACPI_UINT32_MAX, ppi_callback, NULL,
232 tpm_device_name, &handle);
233 if (ACPI_FAILURE(status))
234 return -ENXIO;
235
236 status = acpi_evaluate_object_typed(handle, "_DSM", &input, &output,
237 ACPI_TYPE_STRING);
238 if (ACPI_FAILURE(status))
239 return -ENOMEM;
240 strncpy(version,
241 ((union acpi_object *)output.pointer)->string.pointer,
242 PPI_VERSION_LEN);
243 /*
244 * PPI spec defines params[3].type as empty package, but some platforms
245 * (e.g. Capella with PPI 1.0) need integer/string/buffer type, so for
246 * compatibility, define params[3].type as buffer, if PPI version < 1.2
247 */
248 if (strcmp(version, "1.2") == -1) {
249 params[3].type = ACPI_TYPE_BUFFER;
250 params[3].buffer.length = 0;
251 params[3].buffer.pointer = NULL;
252 }
253 params[2].integer.value = TPM_PPI_FN_GETACT;
254 kfree(output.pointer);
255 output.length = ACPI_ALLOCATE_BUFFER;
256 output.pointer = NULL;
257 status = acpi_evaluate_object_typed(handle, "_DSM", &input, &output,
258 ACPI_TYPE_INTEGER);
259 if (ACPI_FAILURE(status))
260 return -ENOMEM;
261 ret = ((union acpi_object *)output.pointer)->integer.value;
262 if (ret < ARRAY_SIZE(info) - 1)
263 status = scnprintf(buf, PAGE_SIZE, "%d: %s\n", ret, info[ret]);
264 else
265 status = scnprintf(buf, PAGE_SIZE, "%d: %s\n", ret,
266 info[ARRAY_SIZE(info)-1]);
267 kfree(output.pointer);
268 return status;
269}
270
271static ssize_t tpm_show_ppi_response(struct device *dev,
272 struct device_attribute *attr,
273 char *buf)
274{
275 acpi_handle handle;
276 acpi_status status;
277 struct acpi_object_list input;
278 struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL };
279 union acpi_object params[4];
280 union acpi_object *ret_obj;
281 u64 req;
282
283 input.count = 4;
284 ppi_assign_params(params, TPM_PPI_FN_GETRSP);
285 input.pointer = params;
286 status = acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
287 ACPI_UINT32_MAX, ppi_callback, NULL,
288 tpm_device_name, &handle);
289 if (ACPI_FAILURE(status))
290 return -ENXIO;
291
292 status = acpi_evaluate_object_typed(handle, "_DSM", &input, &output,
293 ACPI_TYPE_PACKAGE);
294 if (ACPI_FAILURE(status))
295 return -ENOMEM;
296 /*
297 * parameter output.pointer should be of package type, including
298 * 3 integers. The first means function return code, the second means
299 * most recent TPM operation request, and the last means response to
300 * the most recent TPM operation request. Only if the first is 0, and
301 * the second integer is not 0, the response makes sense.
302 */
303 ret_obj = ((union acpi_object *)output.pointer)->package.elements;
304 if (ret_obj->type != ACPI_TYPE_INTEGER) {
305 status = -EINVAL;
306 goto cleanup;
307 }
308 if (ret_obj->integer.value) {
309 status = -EFAULT;
310 goto cleanup;
311 }
312 ret_obj++;
313 if (ret_obj->type != ACPI_TYPE_INTEGER) {
314 status = -EINVAL;
315 goto cleanup;
316 }
317 if (ret_obj->integer.value) {
318 req = ret_obj->integer.value;
319 ret_obj++;
320 if (ret_obj->type != ACPI_TYPE_INTEGER) {
321 status = -EINVAL;
322 goto cleanup;
323 }
324 if (ret_obj->integer.value == 0)
325 status = scnprintf(buf, PAGE_SIZE, "%llu %s\n", req,
326 "0: Success");
327 else if (ret_obj->integer.value == 0xFFFFFFF0)
328 status = scnprintf(buf, PAGE_SIZE, "%llu %s\n", req,
329 "0xFFFFFFF0: User Abort");
330 else if (ret_obj->integer.value == 0xFFFFFFF1)
331 status = scnprintf(buf, PAGE_SIZE, "%llu %s\n", req,
332 "0xFFFFFFF1: BIOS Failure");
333 else if (ret_obj->integer.value >= 1 &&
334 ret_obj->integer.value <= 0x00000FFF)
335 status = scnprintf(buf, PAGE_SIZE, "%llu %llu: %s\n",
336 req, ret_obj->integer.value,
337 "Corresponding TPM error");
338 else
339 status = scnprintf(buf, PAGE_SIZE, "%llu %llu: %s\n",
340 req, ret_obj->integer.value,
341 "Error");
342 } else {
343 status = scnprintf(buf, PAGE_SIZE, "%llu: %s\n",
344 ret_obj->integer.value, "No Recent Request");
345 }
346cleanup:
347 kfree(output.pointer);
348 return status;
349}
350
351static ssize_t show_ppi_operations(char *buf, u32 start, u32 end)
352{
353 char *str = buf;
354 char version[PPI_VERSION_LEN];
355 acpi_handle handle;
356 acpi_status status;
357 struct acpi_object_list input;
358 struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL };
359 union acpi_object params[4];
360 union acpi_object obj;
361 int i;
362 u32 ret;
363 char *info[] = {
364 "Not implemented",
365 "BIOS only",
366 "Blocked for OS by BIOS",
367 "User required",
368 "User not required",
369 };
370 input.count = 4;
371 ppi_assign_params(params, TPM_PPI_FN_VERSION);
372 input.pointer = params;
373 status = acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
374 ACPI_UINT32_MAX, ppi_callback, NULL,
375 tpm_device_name, &handle);
376 if (ACPI_FAILURE(status))
377 return -ENXIO;
378
379 status = acpi_evaluate_object_typed(handle, "_DSM", &input, &output,
380 ACPI_TYPE_STRING);
381 if (ACPI_FAILURE(status))
382 return -ENOMEM;
383
384 strncpy(version,
385 ((union acpi_object *)output.pointer)->string.pointer,
386 PPI_VERSION_LEN);
387 kfree(output.pointer);
388 output.length = ACPI_ALLOCATE_BUFFER;
389 output.pointer = NULL;
390 if (strcmp(version, "1.2") == -1)
391 return -EPERM;
392
393 params[2].integer.value = TPM_PPI_FN_GETOPR;
394 params[3].package.count = 1;
395 obj.type = ACPI_TYPE_INTEGER;
396 params[3].package.elements = &obj;
397 for (i = start; i <= end; i++) {
398 obj.integer.value = i;
399 status = acpi_evaluate_object_typed(handle, "_DSM",
400 &input, &output, ACPI_TYPE_INTEGER);
401 if (ACPI_FAILURE(status))
402 return -ENOMEM;
403
404 ret = ((union acpi_object *)output.pointer)->integer.value;
405 if (ret > 0 && ret < ARRAY_SIZE(info))
406 str += scnprintf(str, PAGE_SIZE, "%d %d: %s\n",
407 i, ret, info[ret]);
408 kfree(output.pointer);
409 output.length = ACPI_ALLOCATE_BUFFER;
410 output.pointer = NULL;
411 }
412 return str - buf;
413}
414
415static ssize_t tpm_show_ppi_tcg_operations(struct device *dev,
416 struct device_attribute *attr,
417 char *buf)
418{
419 return show_ppi_operations(buf, 0, PPI_TPM_REQ_MAX);
420}
421
422static ssize_t tpm_show_ppi_vs_operations(struct device *dev,
423 struct device_attribute *attr,
424 char *buf)
425{
426 return show_ppi_operations(buf, PPI_VS_REQ_START, PPI_VS_REQ_END);
427}
428
429static DEVICE_ATTR(version, S_IRUGO, tpm_show_ppi_version, NULL);
430static DEVICE_ATTR(request, S_IRUGO | S_IWUSR | S_IWGRP,
431 tpm_show_ppi_request, tpm_store_ppi_request);
432static DEVICE_ATTR(transition_action, S_IRUGO,
433 tpm_show_ppi_transition_action, NULL);
434static DEVICE_ATTR(response, S_IRUGO, tpm_show_ppi_response, NULL);
435static DEVICE_ATTR(tcg_operations, S_IRUGO, tpm_show_ppi_tcg_operations, NULL);
436static DEVICE_ATTR(vs_operations, S_IRUGO, tpm_show_ppi_vs_operations, NULL);
437
438static struct attribute *ppi_attrs[] = {
439 &dev_attr_version.attr,
440 &dev_attr_request.attr,
441 &dev_attr_transition_action.attr,
442 &dev_attr_response.attr,
443 &dev_attr_tcg_operations.attr,
444 &dev_attr_vs_operations.attr, NULL,
445};
446static struct attribute_group ppi_attr_grp = {
447 .attrs = ppi_attrs
448};
449
450ssize_t sys_add_ppi(struct kobject *parent)
451{
452 struct kobject *ppi;
453 ppi = kobject_create_and_add("ppi", parent);
454 if (sysfs_create_group(ppi, &ppi_attr_grp))
455 return -EFAULT;
456 else
457 return 0;
458}
459EXPORT_SYMBOL_GPL(sys_add_ppi);
460
461MODULE_LICENSE("GPL");
diff --git a/drivers/char/tpm/tpm_tis.c b/drivers/char/tpm/tpm_tis.c
index c4be3519a587..6bdf2671254f 100644
--- a/drivers/char/tpm/tpm_tis.c
+++ b/drivers/char/tpm/tpm_tis.c
@@ -705,6 +705,7 @@ out_err:
705 return rc; 705 return rc;
706} 706}
707 707
708#if defined(CONFIG_PNP) || defined(CONFIG_PM_SLEEP)
708static void tpm_tis_reenable_interrupts(struct tpm_chip *chip) 709static void tpm_tis_reenable_interrupts(struct tpm_chip *chip)
709{ 710{
710 u32 intmask; 711 u32 intmask;
@@ -725,7 +726,7 @@ static void tpm_tis_reenable_interrupts(struct tpm_chip *chip)
725 iowrite32(intmask, 726 iowrite32(intmask,
726 chip->vendor.iobase + TPM_INT_ENABLE(chip->vendor.locality)); 727 chip->vendor.iobase + TPM_INT_ENABLE(chip->vendor.locality));
727} 728}
728 729#endif
729 730
730#ifdef CONFIG_PNP 731#ifdef CONFIG_PNP
731static int __devinit tpm_tis_pnp_init(struct pnp_dev *pnp_dev, 732static int __devinit tpm_tis_pnp_init(struct pnp_dev *pnp_dev,