aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char/tpm
diff options
context:
space:
mode:
authorGlenn Elliott <gelliott@cs.unc.edu>2012-03-04 19:47:13 -0500
committerGlenn Elliott <gelliott@cs.unc.edu>2012-03-04 19:47:13 -0500
commitc71c03bda1e86c9d5198c5d83f712e695c4f2a1e (patch)
treeecb166cb3e2b7e2adb3b5e292245fefd23381ac8 /drivers/char/tpm
parentea53c912f8a86a8567697115b6a0d8152beee5c8 (diff)
parent6a00f206debf8a5c8899055726ad127dbeeed098 (diff)
Merge branch 'mpi-master' into wip-k-fmlpwip-k-fmlp
Conflicts: litmus/sched_cedf.c
Diffstat (limited to 'drivers/char/tpm')
-rw-r--r--drivers/char/tpm/Kconfig2
-rw-r--r--drivers/char/tpm/tpm.c48
-rw-r--r--drivers/char/tpm/tpm.h5
-rw-r--r--drivers/char/tpm/tpm_infineon.c2
-rw-r--r--drivers/char/tpm/tpm_tis.c24
5 files changed, 62 insertions, 19 deletions
diff --git a/drivers/char/tpm/Kconfig b/drivers/char/tpm/Kconfig
index 4dc338f3d1aa..f6595aba4f0f 100644
--- a/drivers/char/tpm/Kconfig
+++ b/drivers/char/tpm/Kconfig
@@ -58,6 +58,6 @@ config TCG_INFINEON
58 To compile this driver as a module, choose M here; the module 58 To compile this driver as a module, choose M here; the module
59 will be called tpm_infineon. 59 will be called tpm_infineon.
60 Further information on this driver and the supported hardware 60 Further information on this driver and the supported hardware
61 can be found at http://www.prosec.rub.de/tpm 61 can be found at http://www.trust.rub.de/projects/linux-device-driver-infineon-tpm/
62 62
63endif # TCG_TPM 63endif # TCG_TPM
diff --git a/drivers/char/tpm/tpm.c b/drivers/char/tpm/tpm.c
index 05ad4a17a28f..7beb0e25f1e1 100644
--- a/drivers/char/tpm/tpm.c
+++ b/drivers/char/tpm/tpm.c
@@ -47,6 +47,16 @@ enum tpm_duration {
47#define TPM_MAX_PROTECTED_ORDINAL 12 47#define TPM_MAX_PROTECTED_ORDINAL 12
48#define TPM_PROTECTED_ORDINAL_MASK 0xFF 48#define TPM_PROTECTED_ORDINAL_MASK 0xFF
49 49
50/*
51 * Bug workaround - some TPM's don't flush the most
52 * recently changed pcr on suspend, so force the flush
53 * with an extend to the selected _unused_ non-volatile pcr.
54 */
55static int tpm_suspend_pcr;
56module_param_named(suspend_pcr, tpm_suspend_pcr, uint, 0644);
57MODULE_PARM_DESC(suspend_pcr,
58 "PCR to use for dummy writes to faciltate flush on suspend.");
59
50static LIST_HEAD(tpm_chip_list); 60static LIST_HEAD(tpm_chip_list);
51static DEFINE_SPINLOCK(driver_lock); 61static DEFINE_SPINLOCK(driver_lock);
52static DECLARE_BITMAP(dev_mask, TPM_NUM_DEVICES); 62static DECLARE_BITMAP(dev_mask, TPM_NUM_DEVICES);
@@ -726,7 +736,7 @@ int tpm_pcr_read(u32 chip_num, int pcr_idx, u8 *res_buf)
726 if (chip == NULL) 736 if (chip == NULL)
727 return -ENODEV; 737 return -ENODEV;
728 rc = __tpm_pcr_read(chip, pcr_idx, res_buf); 738 rc = __tpm_pcr_read(chip, pcr_idx, res_buf);
729 module_put(chip->dev->driver->owner); 739 tpm_chip_put(chip);
730 return rc; 740 return rc;
731} 741}
732EXPORT_SYMBOL_GPL(tpm_pcr_read); 742EXPORT_SYMBOL_GPL(tpm_pcr_read);
@@ -765,11 +775,27 @@ int tpm_pcr_extend(u32 chip_num, int pcr_idx, const u8 *hash)
765 rc = transmit_cmd(chip, &cmd, EXTEND_PCR_RESULT_SIZE, 775 rc = transmit_cmd(chip, &cmd, EXTEND_PCR_RESULT_SIZE,
766 "attempting extend a PCR value"); 776 "attempting extend a PCR value");
767 777
768 module_put(chip->dev->driver->owner); 778 tpm_chip_put(chip);
769 return rc; 779 return rc;
770} 780}
771EXPORT_SYMBOL_GPL(tpm_pcr_extend); 781EXPORT_SYMBOL_GPL(tpm_pcr_extend);
772 782
783int tpm_send(u32 chip_num, void *cmd, size_t buflen)
784{
785 struct tpm_chip *chip;
786 int rc;
787
788 chip = tpm_chip_find_get(chip_num);
789 if (chip == NULL)
790 return -ENODEV;
791
792 rc = transmit_cmd(chip, cmd, buflen, "attempting tpm_cmd");
793
794 tpm_chip_put(chip);
795 return rc;
796}
797EXPORT_SYMBOL_GPL(tpm_send);
798
773ssize_t tpm_show_pcrs(struct device *dev, struct device_attribute *attr, 799ssize_t tpm_show_pcrs(struct device *dev, struct device_attribute *attr,
774 char *buf) 800 char *buf)
775{ 801{
@@ -954,7 +980,7 @@ int tpm_open(struct inode *inode, struct file *file)
954 return -EBUSY; 980 return -EBUSY;
955 } 981 }
956 982
957 chip->data_buffer = kmalloc(TPM_BUFSIZE * sizeof(u8), GFP_KERNEL); 983 chip->data_buffer = kzalloc(TPM_BUFSIZE, GFP_KERNEL);
958 if (chip->data_buffer == NULL) { 984 if (chip->data_buffer == NULL) {
959 clear_bit(0, &chip->is_open); 985 clear_bit(0, &chip->is_open);
960 put_device(chip->dev); 986 put_device(chip->dev);
@@ -976,7 +1002,7 @@ int tpm_release(struct inode *inode, struct file *file)
976 struct tpm_chip *chip = file->private_data; 1002 struct tpm_chip *chip = file->private_data;
977 1003
978 del_singleshot_timer_sync(&chip->user_read_timer); 1004 del_singleshot_timer_sync(&chip->user_read_timer);
979 flush_scheduled_work(); 1005 flush_work_sync(&chip->work);
980 file->private_data = NULL; 1006 file->private_data = NULL;
981 atomic_set(&chip->data_pending, 0); 1007 atomic_set(&chip->data_pending, 0);
982 kfree(chip->data_buffer); 1008 kfree(chip->data_buffer);
@@ -1028,7 +1054,7 @@ ssize_t tpm_read(struct file *file, char __user *buf,
1028 ssize_t ret_size; 1054 ssize_t ret_size;
1029 1055
1030 del_singleshot_timer_sync(&chip->user_read_timer); 1056 del_singleshot_timer_sync(&chip->user_read_timer);
1031 flush_scheduled_work(); 1057 flush_work_sync(&chip->work);
1032 ret_size = atomic_read(&chip->data_pending); 1058 ret_size = atomic_read(&chip->data_pending);
1033 atomic_set(&chip->data_pending, 0); 1059 atomic_set(&chip->data_pending, 0);
1034 if (ret_size > 0) { /* relay data */ 1060 if (ret_size > 0) { /* relay data */
@@ -1077,18 +1103,6 @@ static struct tpm_input_header savestate_header = {
1077 .ordinal = TPM_ORD_SAVESTATE 1103 .ordinal = TPM_ORD_SAVESTATE
1078}; 1104};
1079 1105
1080/* Bug workaround - some TPM's don't flush the most
1081 * recently changed pcr on suspend, so force the flush
1082 * with an extend to the selected _unused_ non-volatile pcr.
1083 */
1084static int tpm_suspend_pcr;
1085static int __init tpm_suspend_setup(char *str)
1086{
1087 get_option(&str, &tpm_suspend_pcr);
1088 return 1;
1089}
1090__setup("tpm_suspend_pcr=", tpm_suspend_setup);
1091
1092/* 1106/*
1093 * We are about to suspend. Save the TPM state 1107 * We are about to suspend. Save the TPM state
1094 * so that it can be restored. 1108 * so that it can be restored.
diff --git a/drivers/char/tpm/tpm.h b/drivers/char/tpm/tpm.h
index 792868d24f2a..72ddb031b69a 100644
--- a/drivers/char/tpm/tpm.h
+++ b/drivers/char/tpm/tpm.h
@@ -113,6 +113,11 @@ struct tpm_chip {
113 113
114#define to_tpm_chip(n) container_of(n, struct tpm_chip, vendor) 114#define to_tpm_chip(n) container_of(n, struct tpm_chip, vendor)
115 115
116static inline void tpm_chip_put(struct tpm_chip *chip)
117{
118 module_put(chip->dev->driver->owner);
119}
120
116static inline int tpm_read_index(int base, int index) 121static inline int tpm_read_index(int base, int index)
117{ 122{
118 outb(index, base); 123 outb(index, base);
diff --git a/drivers/char/tpm/tpm_infineon.c b/drivers/char/tpm/tpm_infineon.c
index f58440791e65..76da32e11f18 100644
--- a/drivers/char/tpm/tpm_infineon.c
+++ b/drivers/char/tpm/tpm_infineon.c
@@ -7,7 +7,7 @@
7 * Copyright (C) 2005, Marcel Selhorst <m.selhorst@sirrix.com> 7 * Copyright (C) 2005, Marcel Selhorst <m.selhorst@sirrix.com>
8 * Sirrix AG - security technologies, http://www.sirrix.com and 8 * Sirrix AG - security technologies, http://www.sirrix.com and
9 * Applied Data Security Group, Ruhr-University Bochum, Germany 9 * Applied Data Security Group, Ruhr-University Bochum, Germany
10 * Project-Homepage: http://www.prosec.rub.de/tpm 10 * Project-Homepage: http://www.trust.rub.de/projects/linux-device-driver-infineon-tpm/
11 * 11 *
12 * This program is free software; you can redistribute it and/or 12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License as 13 * modify it under the terms of the GNU General Public License as
diff --git a/drivers/char/tpm/tpm_tis.c b/drivers/char/tpm/tpm_tis.c
index 1030f8420137..dd21df55689d 100644
--- a/drivers/char/tpm/tpm_tis.c
+++ b/drivers/char/tpm/tpm_tis.c
@@ -25,6 +25,7 @@
25#include <linux/slab.h> 25#include <linux/slab.h>
26#include <linux/interrupt.h> 26#include <linux/interrupt.h>
27#include <linux/wait.h> 27#include <linux/wait.h>
28#include <linux/acpi.h>
28#include "tpm.h" 29#include "tpm.h"
29 30
30#define TPM_HEADER_SIZE 10 31#define TPM_HEADER_SIZE 10
@@ -78,6 +79,26 @@ enum tis_defaults {
78static LIST_HEAD(tis_chips); 79static LIST_HEAD(tis_chips);
79static DEFINE_SPINLOCK(tis_lock); 80static DEFINE_SPINLOCK(tis_lock);
80 81
82#ifdef CONFIG_ACPI
83static int is_itpm(struct pnp_dev *dev)
84{
85 struct acpi_device *acpi = pnp_acpi_device(dev);
86 struct acpi_hardware_id *id;
87
88 list_for_each_entry(id, &acpi->pnp.ids, list) {
89 if (!strcmp("INTC0102", id->id))
90 return 1;
91 }
92
93 return 0;
94}
95#else
96static int is_itpm(struct pnp_dev *dev)
97{
98 return 0;
99}
100#endif
101
81static int check_locality(struct tpm_chip *chip, int l) 102static int check_locality(struct tpm_chip *chip, int l)
82{ 103{
83 if ((ioread8(chip->vendor.iobase + TPM_ACCESS(l)) & 104 if ((ioread8(chip->vendor.iobase + TPM_ACCESS(l)) &
@@ -613,6 +634,9 @@ static int __devinit tpm_tis_pnp_init(struct pnp_dev *pnp_dev,
613 else 634 else
614 interrupts = 0; 635 interrupts = 0;
615 636
637 if (is_itpm(pnp_dev))
638 itpm = 1;
639
616 return tpm_tis_init(&pnp_dev->dev, start, len, irq); 640 return tpm_tis_init(&pnp_dev->dev, start, len, irq);
617} 641}
618 642