diff options
author | Glenn Elliott <gelliott@cs.unc.edu> | 2012-03-04 19:47:13 -0500 |
---|---|---|
committer | Glenn Elliott <gelliott@cs.unc.edu> | 2012-03-04 19:47:13 -0500 |
commit | c71c03bda1e86c9d5198c5d83f712e695c4f2a1e (patch) | |
tree | ecb166cb3e2b7e2adb3b5e292245fefd23381ac8 /drivers/char/tpm | |
parent | ea53c912f8a86a8567697115b6a0d8152beee5c8 (diff) | |
parent | 6a00f206debf8a5c8899055726ad127dbeeed098 (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/Kconfig | 2 | ||||
-rw-r--r-- | drivers/char/tpm/tpm.c | 48 | ||||
-rw-r--r-- | drivers/char/tpm/tpm.h | 5 | ||||
-rw-r--r-- | drivers/char/tpm/tpm_infineon.c | 2 | ||||
-rw-r--r-- | drivers/char/tpm/tpm_tis.c | 24 |
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 | ||
63 | endif # TCG_TPM | 63 | endif # 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 | */ | ||
55 | static int tpm_suspend_pcr; | ||
56 | module_param_named(suspend_pcr, tpm_suspend_pcr, uint, 0644); | ||
57 | MODULE_PARM_DESC(suspend_pcr, | ||
58 | "PCR to use for dummy writes to faciltate flush on suspend."); | ||
59 | |||
50 | static LIST_HEAD(tpm_chip_list); | 60 | static LIST_HEAD(tpm_chip_list); |
51 | static DEFINE_SPINLOCK(driver_lock); | 61 | static DEFINE_SPINLOCK(driver_lock); |
52 | static DECLARE_BITMAP(dev_mask, TPM_NUM_DEVICES); | 62 | static 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 | } |
732 | EXPORT_SYMBOL_GPL(tpm_pcr_read); | 742 | EXPORT_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 | } |
771 | EXPORT_SYMBOL_GPL(tpm_pcr_extend); | 781 | EXPORT_SYMBOL_GPL(tpm_pcr_extend); |
772 | 782 | ||
783 | int 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 | } | ||
797 | EXPORT_SYMBOL_GPL(tpm_send); | ||
798 | |||
773 | ssize_t tpm_show_pcrs(struct device *dev, struct device_attribute *attr, | 799 | ssize_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 | */ | ||
1084 | static int tpm_suspend_pcr; | ||
1085 | static 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 | ||
116 | static inline void tpm_chip_put(struct tpm_chip *chip) | ||
117 | { | ||
118 | module_put(chip->dev->driver->owner); | ||
119 | } | ||
120 | |||
116 | static inline int tpm_read_index(int base, int index) | 121 | static 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 { | |||
78 | static LIST_HEAD(tis_chips); | 79 | static LIST_HEAD(tis_chips); |
79 | static DEFINE_SPINLOCK(tis_lock); | 80 | static DEFINE_SPINLOCK(tis_lock); |
80 | 81 | ||
82 | #ifdef CONFIG_ACPI | ||
83 | static 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 | ||
96 | static int is_itpm(struct pnp_dev *dev) | ||
97 | { | ||
98 | return 0; | ||
99 | } | ||
100 | #endif | ||
101 | |||
81 | static int check_locality(struct tpm_chip *chip, int l) | 102 | static 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 | ||