aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char/tpm/tpm.c
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/tpm.c
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/tpm.c')
-rw-r--r--drivers/char/tpm/tpm.c48
1 files changed, 31 insertions, 17 deletions
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.