aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char
diff options
context:
space:
mode:
authorJarkko Sakkinen <jarkko.sakkinen@linux.intel.com>2015-09-28 17:32:19 -0400
committerPeter Huewe <peterhuewe@gmx.de>2015-10-18 19:01:14 -0400
commit399235dc6e95400a1322a9999e92073bc572f0c8 (patch)
treeda5b36115c8e3a7681e649d7ec4791dc6ce503a0 /drivers/char
parent149789ce9d472e6b4fd99336e779ab843754a96c (diff)
tpm, tpm_tis: fix tpm_tis ACPI detection issue with TPM 2.0
Both for FIFO and CRB interface TCG has decided to use the same HID MSFT0101. They can be differentiated by looking at the start method from TPM2 ACPI table. This patches makes necessary fixes to tpm_tis and tpm_crb modules in order to correctly detect, which module should be used. For MSFT0101 we must use struct acpi_driver because struct pnp_driver has a 7 character limitation. It turned out that the root cause in b371616b8 was not correct for https://bugzilla.kernel.org/show_bug.cgi?id=98181. v2: * One fixup was missing from v1: is_tpm2_fifo -> is_fifo v3: * Use pnp_driver for existing HIDs and acpi_driver only for MSFT0101 in order ensure backwards compatibility. v4: * Check for FIFO before doing *anything* in crb_acpi_add(). * There was return immediately after acpi_bus_unregister_driver() in cleanup_tis(). This caused pnp_unregister_driver() not to be called. Cc: stable@kernel.org Reported-by: Michael Saunders <mick.saunders@gmail.com> Reported-by: Michael Marley <michael@michaelmarley.com> Reported-by: Jethro Beekman <kernel@jbeekman.nl> Reported-by: Matthew Garrett <mjg59@srcf.ucam.org> Signed-off-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com> Tested-by: Michael Marley <michael@michaelmarley.com> Tested-by: Mimi Zohar <zohar@linux.vnet.ibm.com> (on TPM 1.2) Reviewed-by: Peter Huewe <peterhuewe@gmx.de> Signed-off-by: Peter Huewe <peterhuewe@gmx.de>
Diffstat (limited to 'drivers/char')
-rw-r--r--drivers/char/tpm/tpm.h7
-rw-r--r--drivers/char/tpm/tpm_crb.c32
-rw-r--r--drivers/char/tpm/tpm_tis.c192
3 files changed, 181 insertions, 50 deletions
diff --git a/drivers/char/tpm/tpm.h b/drivers/char/tpm/tpm.h
index f8319a0860fd..39be5acc9c48 100644
--- a/drivers/char/tpm/tpm.h
+++ b/drivers/char/tpm/tpm.h
@@ -115,6 +115,13 @@ enum tpm2_startup_types {
115 TPM2_SU_STATE = 0x0001, 115 TPM2_SU_STATE = 0x0001,
116}; 116};
117 117
118enum tpm2_start_method {
119 TPM2_START_ACPI = 2,
120 TPM2_START_FIFO = 6,
121 TPM2_START_CRB = 7,
122 TPM2_START_CRB_WITH_ACPI = 8,
123};
124
118struct tpm_chip; 125struct tpm_chip;
119 126
120struct tpm_vendor_specific { 127struct tpm_vendor_specific {
diff --git a/drivers/char/tpm/tpm_crb.c b/drivers/char/tpm/tpm_crb.c
index 83068fa66e10..4bb9727c1047 100644
--- a/drivers/char/tpm/tpm_crb.c
+++ b/drivers/char/tpm/tpm_crb.c
@@ -34,12 +34,6 @@ enum crb_defaults {
34 CRB_ACPI_START_INDEX = 1, 34 CRB_ACPI_START_INDEX = 1,
35}; 35};
36 36
37enum crb_start_method {
38 CRB_SM_ACPI_START = 2,
39 CRB_SM_CRB = 7,
40 CRB_SM_CRB_WITH_ACPI_START = 8,
41};
42
43struct acpi_tpm2 { 37struct acpi_tpm2 {
44 struct acpi_table_header hdr; 38 struct acpi_table_header hdr;
45 u16 platform_class; 39 u16 platform_class;
@@ -221,12 +215,6 @@ static int crb_acpi_add(struct acpi_device *device)
221 u64 pa; 215 u64 pa;
222 int rc; 216 int rc;
223 217
224 chip = tpmm_chip_alloc(dev, &tpm_crb);
225 if (IS_ERR(chip))
226 return PTR_ERR(chip);
227
228 chip->flags = TPM_CHIP_FLAG_TPM2;
229
230 status = acpi_get_table(ACPI_SIG_TPM2, 1, 218 status = acpi_get_table(ACPI_SIG_TPM2, 1,
231 (struct acpi_table_header **) &buf); 219 (struct acpi_table_header **) &buf);
232 if (ACPI_FAILURE(status)) { 220 if (ACPI_FAILURE(status)) {
@@ -234,13 +222,15 @@ static int crb_acpi_add(struct acpi_device *device)
234 return -ENODEV; 222 return -ENODEV;
235 } 223 }
236 224
237 /* At least some versions of AMI BIOS have a bug that TPM2 table has 225 /* Should the FIFO driver handle this? */
238 * zero address for the control area and therefore we must fail. 226 if (buf->start_method == TPM2_START_FIFO)
239 */ 227 return -ENODEV;
240 if (!buf->control_area_pa) { 228
241 dev_err(dev, "TPM2 ACPI table has a zero address for the control area\n"); 229 chip = tpmm_chip_alloc(dev, &tpm_crb);
242 return -EINVAL; 230 if (IS_ERR(chip))
243 } 231 return PTR_ERR(chip);
232
233 chip->flags = TPM_CHIP_FLAG_TPM2;
244 234
245 if (buf->hdr.length < sizeof(struct acpi_tpm2)) { 235 if (buf->hdr.length < sizeof(struct acpi_tpm2)) {
246 dev_err(dev, "TPM2 ACPI table has wrong size"); 236 dev_err(dev, "TPM2 ACPI table has wrong size");
@@ -260,11 +250,11 @@ static int crb_acpi_add(struct acpi_device *device)
260 * report only ACPI start but in practice seems to require both 250 * report only ACPI start but in practice seems to require both
261 * ACPI start and CRB start. 251 * ACPI start and CRB start.
262 */ 252 */
263 if (sm == CRB_SM_CRB || sm == CRB_SM_CRB_WITH_ACPI_START || 253 if (sm == TPM2_START_CRB || sm == TPM2_START_FIFO ||
264 !strcmp(acpi_device_hid(device), "MSFT0101")) 254 !strcmp(acpi_device_hid(device), "MSFT0101"))
265 priv->flags |= CRB_FL_CRB_START; 255 priv->flags |= CRB_FL_CRB_START;
266 256
267 if (sm == CRB_SM_ACPI_START || sm == CRB_SM_CRB_WITH_ACPI_START) 257 if (sm == TPM2_START_ACPI || sm == TPM2_START_CRB_WITH_ACPI)
268 priv->flags |= CRB_FL_ACPI_START; 258 priv->flags |= CRB_FL_ACPI_START;
269 259
270 priv->cca = (struct crb_control_area __iomem *) 260 priv->cca = (struct crb_control_area __iomem *)
diff --git a/drivers/char/tpm/tpm_tis.c b/drivers/char/tpm/tpm_tis.c
index f2dffa770b8e..696ef1d56b4f 100644
--- a/drivers/char/tpm/tpm_tis.c
+++ b/drivers/char/tpm/tpm_tis.c
@@ -1,6 +1,6 @@
1/* 1/*
2 * Copyright (C) 2005, 2006 IBM Corporation 2 * Copyright (C) 2005, 2006 IBM Corporation
3 * Copyright (C) 2014 Intel Corporation 3 * Copyright (C) 2014, 2015 Intel Corporation
4 * 4 *
5 * Authors: 5 * Authors:
6 * Leendert van Doorn <leendert@watson.ibm.com> 6 * Leendert van Doorn <leendert@watson.ibm.com>
@@ -28,6 +28,7 @@
28#include <linux/wait.h> 28#include <linux/wait.h>
29#include <linux/acpi.h> 29#include <linux/acpi.h>
30#include <linux/freezer.h> 30#include <linux/freezer.h>
31#include <acpi/actbl2.h>
31#include "tpm.h" 32#include "tpm.h"
32 33
33enum tis_access { 34enum tis_access {
@@ -65,6 +66,17 @@ enum tis_defaults {
65 TIS_LONG_TIMEOUT = 2000, /* 2 sec */ 66 TIS_LONG_TIMEOUT = 2000, /* 2 sec */
66}; 67};
67 68
69struct tpm_info {
70 unsigned long start;
71 unsigned long len;
72 unsigned int irq;
73};
74
75static struct tpm_info tis_default_info = {
76 .start = TIS_MEM_BASE,
77 .len = TIS_MEM_LEN,
78 .irq = 0,
79};
68 80
69/* Some timeout values are needed before it is known whether the chip is 81/* Some timeout values are needed before it is known whether the chip is
70 * TPM 1.0 or TPM 2.0. 82 * TPM 1.0 or TPM 2.0.
@@ -91,26 +103,54 @@ struct priv_data {
91}; 103};
92 104
93#if defined(CONFIG_PNP) && defined(CONFIG_ACPI) 105#if defined(CONFIG_PNP) && defined(CONFIG_ACPI)
94static int is_itpm(struct pnp_dev *dev) 106static int has_hid(struct acpi_device *dev, const char *hid)
95{ 107{
96 struct acpi_device *acpi = pnp_acpi_device(dev);
97 struct acpi_hardware_id *id; 108 struct acpi_hardware_id *id;
98 109
99 if (!acpi) 110 list_for_each_entry(id, &dev->pnp.ids, list)
100 return 0; 111 if (!strcmp(hid, id->id))
101
102 list_for_each_entry(id, &acpi->pnp.ids, list) {
103 if (!strcmp("INTC0102", id->id))
104 return 1; 112 return 1;
105 }
106 113
107 return 0; 114 return 0;
108} 115}
116
117static inline int is_itpm(struct acpi_device *dev)
118{
119 return has_hid(dev, "INTC0102");
120}
121
122static inline int is_fifo(struct acpi_device *dev)
123{
124 struct acpi_table_tpm2 *tbl;
125 acpi_status st;
126
127 /* TPM 1.2 FIFO */
128 if (!has_hid(dev, "MSFT0101"))
129 return 1;
130
131 st = acpi_get_table(ACPI_SIG_TPM2, 1,
132 (struct acpi_table_header **) &tbl);
133 if (ACPI_FAILURE(st)) {
134 dev_err(&dev->dev, "failed to get TPM2 ACPI table\n");
135 return 0;
136 }
137
138 if (le32_to_cpu(tbl->start_method) != TPM2_START_FIFO)
139 return 0;
140
141 /* TPM 2.0 FIFO */
142 return 1;
143}
109#else 144#else
110static inline int is_itpm(struct pnp_dev *dev) 145static inline int is_itpm(struct acpi_device *dev)
111{ 146{
112 return 0; 147 return 0;
113} 148}
149
150static inline int is_fifo(struct acpi_device *dev)
151{
152 return 1;
153}
114#endif 154#endif
115 155
116/* Before we attempt to access the TPM we must see that the valid bit is set. 156/* Before we attempt to access the TPM we must see that the valid bit is set.
@@ -600,9 +640,8 @@ static void tpm_tis_remove(struct tpm_chip *chip)
600 release_locality(chip, chip->vendor.locality, 1); 640 release_locality(chip, chip->vendor.locality, 1);
601} 641}
602 642
603static int tpm_tis_init(struct device *dev, acpi_handle acpi_dev_handle, 643static int tpm_tis_init(struct device *dev, struct tpm_info *tpm_info,
604 resource_size_t start, resource_size_t len, 644 acpi_handle acpi_dev_handle)
605 unsigned int irq)
606{ 645{
607 u32 vendor, intfcaps, intmask; 646 u32 vendor, intfcaps, intmask;
608 int rc, i, irq_s, irq_e, probe; 647 int rc, i, irq_s, irq_e, probe;
@@ -622,7 +661,7 @@ static int tpm_tis_init(struct device *dev, acpi_handle acpi_dev_handle,
622 chip->acpi_dev_handle = acpi_dev_handle; 661 chip->acpi_dev_handle = acpi_dev_handle;
623#endif 662#endif
624 663
625 chip->vendor.iobase = devm_ioremap(dev, start, len); 664 chip->vendor.iobase = devm_ioremap(dev, tpm_info->start, tpm_info->len);
626 if (!chip->vendor.iobase) 665 if (!chip->vendor.iobase)
627 return -EIO; 666 return -EIO;
628 667
@@ -707,7 +746,7 @@ static int tpm_tis_init(struct device *dev, acpi_handle acpi_dev_handle,
707 chip->vendor.iobase + 746 chip->vendor.iobase +
708 TPM_INT_ENABLE(chip->vendor.locality)); 747 TPM_INT_ENABLE(chip->vendor.locality));
709 if (interrupts) 748 if (interrupts)
710 chip->vendor.irq = irq; 749 chip->vendor.irq = tpm_info->irq;
711 if (interrupts && !chip->vendor.irq) { 750 if (interrupts && !chip->vendor.irq) {
712 irq_s = 751 irq_s =
713 ioread8(chip->vendor.iobase + 752 ioread8(chip->vendor.iobase +
@@ -890,27 +929,27 @@ static SIMPLE_DEV_PM_OPS(tpm_tis_pm, tpm_pm_suspend, tpm_tis_resume);
890static int tpm_tis_pnp_init(struct pnp_dev *pnp_dev, 929static int tpm_tis_pnp_init(struct pnp_dev *pnp_dev,
891 const struct pnp_device_id *pnp_id) 930 const struct pnp_device_id *pnp_id)
892{ 931{
893 resource_size_t start, len; 932 struct tpm_info tpm_info = tis_default_info;
894 unsigned int irq = 0;
895 acpi_handle acpi_dev_handle = NULL; 933 acpi_handle acpi_dev_handle = NULL;
896 934
897 start = pnp_mem_start(pnp_dev, 0); 935 tpm_info.start = pnp_mem_start(pnp_dev, 0);
898 len = pnp_mem_len(pnp_dev, 0); 936 tpm_info.len = pnp_mem_len(pnp_dev, 0);
899 937
900 if (pnp_irq_valid(pnp_dev, 0)) 938 if (pnp_irq_valid(pnp_dev, 0))
901 irq = pnp_irq(pnp_dev, 0); 939 tpm_info.irq = pnp_irq(pnp_dev, 0);
902 else 940 else
903 interrupts = false; 941 interrupts = false;
904 942
905 if (is_itpm(pnp_dev))
906 itpm = true;
907
908#ifdef CONFIG_ACPI 943#ifdef CONFIG_ACPI
909 if (pnp_acpi_device(pnp_dev)) 944 if (pnp_acpi_device(pnp_dev)) {
945 if (is_itpm(pnp_acpi_device(pnp_dev)))
946 itpm = true;
947
910 acpi_dev_handle = pnp_acpi_device(pnp_dev)->handle; 948 acpi_dev_handle = pnp_acpi_device(pnp_dev)->handle;
949 }
911#endif 950#endif
912 951
913 return tpm_tis_init(&pnp_dev->dev, acpi_dev_handle, start, len, irq); 952 return tpm_tis_init(&pnp_dev->dev, &tpm_info, acpi_dev_handle);
914} 953}
915 954
916static struct pnp_device_id tpm_pnp_tbl[] = { 955static struct pnp_device_id tpm_pnp_tbl[] = {
@@ -930,6 +969,7 @@ MODULE_DEVICE_TABLE(pnp, tpm_pnp_tbl);
930static void tpm_tis_pnp_remove(struct pnp_dev *dev) 969static void tpm_tis_pnp_remove(struct pnp_dev *dev)
931{ 970{
932 struct tpm_chip *chip = pnp_get_drvdata(dev); 971 struct tpm_chip *chip = pnp_get_drvdata(dev);
972
933 tpm_chip_unregister(chip); 973 tpm_chip_unregister(chip);
934 tpm_tis_remove(chip); 974 tpm_tis_remove(chip);
935} 975}
@@ -950,6 +990,79 @@ module_param_string(hid, tpm_pnp_tbl[TIS_HID_USR_IDX].id,
950MODULE_PARM_DESC(hid, "Set additional specific HID for this driver to probe"); 990MODULE_PARM_DESC(hid, "Set additional specific HID for this driver to probe");
951#endif 991#endif
952 992
993#ifdef CONFIG_ACPI
994static int tpm_check_resource(struct acpi_resource *ares, void *data)
995{
996 struct tpm_info *tpm_info = (struct tpm_info *) data;
997 struct resource res;
998
999 if (acpi_dev_resource_interrupt(ares, 0, &res)) {
1000 tpm_info->irq = res.start;
1001 } else if (acpi_dev_resource_memory(ares, &res)) {
1002 tpm_info->start = res.start;
1003 tpm_info->len = resource_size(&res);
1004 }
1005
1006 return 1;
1007}
1008
1009static int tpm_tis_acpi_init(struct acpi_device *acpi_dev)
1010{
1011 struct list_head resources;
1012 struct tpm_info tpm_info = tis_default_info;
1013 int ret;
1014
1015 if (!is_fifo(acpi_dev))
1016 return -ENODEV;
1017
1018 INIT_LIST_HEAD(&resources);
1019 ret = acpi_dev_get_resources(acpi_dev, &resources, tpm_check_resource,
1020 &tpm_info);
1021 if (ret < 0)
1022 return ret;
1023
1024 acpi_dev_free_resource_list(&resources);
1025
1026 if (!tpm_info.irq)
1027 interrupts = false;
1028
1029 if (is_itpm(acpi_dev))
1030 itpm = true;
1031
1032 return tpm_tis_init(&acpi_dev->dev, &tpm_info, acpi_dev->handle);
1033}
1034
1035static int tpm_tis_acpi_remove(struct acpi_device *dev)
1036{
1037 struct tpm_chip *chip = dev_get_drvdata(&dev->dev);
1038
1039 tpm_chip_unregister(chip);
1040 tpm_tis_remove(chip);
1041
1042 return 0;
1043}
1044
1045static struct acpi_device_id tpm_acpi_tbl[] = {
1046 {"MSFT0101", 0}, /* TPM 2.0 */
1047 /* Add new here */
1048 {"", 0}, /* User Specified */
1049 {"", 0} /* Terminator */
1050};
1051MODULE_DEVICE_TABLE(acpi, tpm_acpi_tbl);
1052
1053static struct acpi_driver tis_acpi_driver = {
1054 .name = "tpm_tis",
1055 .ids = tpm_acpi_tbl,
1056 .ops = {
1057 .add = tpm_tis_acpi_init,
1058 .remove = tpm_tis_acpi_remove,
1059 },
1060 .drv = {
1061 .pm = &tpm_tis_pm,
1062 },
1063};
1064#endif
1065
953static struct platform_driver tis_drv = { 1066static struct platform_driver tis_drv = {
954 .driver = { 1067 .driver = {
955 .name = "tpm_tis", 1068 .name = "tpm_tis",
@@ -966,9 +1079,25 @@ static int __init init_tis(void)
966{ 1079{
967 int rc; 1080 int rc;
968#ifdef CONFIG_PNP 1081#ifdef CONFIG_PNP
969 if (!force) 1082 if (!force) {
970 return pnp_register_driver(&tis_pnp_driver); 1083 rc = pnp_register_driver(&tis_pnp_driver);
1084 if (rc)
1085 return rc;
1086 }
1087#endif
1088#ifdef CONFIG_ACPI
1089 if (!force) {
1090 rc = acpi_bus_register_driver(&tis_acpi_driver);
1091 if (rc) {
1092#ifdef CONFIG_PNP
1093 pnp_unregister_driver(&tis_pnp_driver);
971#endif 1094#endif
1095 return rc;
1096 }
1097 }
1098#endif
1099 if (!force)
1100 return 0;
972 1101
973 rc = platform_driver_register(&tis_drv); 1102 rc = platform_driver_register(&tis_drv);
974 if (rc < 0) 1103 if (rc < 0)
@@ -978,7 +1107,7 @@ static int __init init_tis(void)
978 rc = PTR_ERR(pdev); 1107 rc = PTR_ERR(pdev);
979 goto err_dev; 1108 goto err_dev;
980 } 1109 }
981 rc = tpm_tis_init(&pdev->dev, NULL, TIS_MEM_BASE, TIS_MEM_LEN, 0); 1110 rc = tpm_tis_init(&pdev->dev, &tis_default_info, NULL);
982 if (rc) 1111 if (rc)
983 goto err_init; 1112 goto err_init;
984 return 0; 1113 return 0;
@@ -992,9 +1121,14 @@ err_dev:
992static void __exit cleanup_tis(void) 1121static void __exit cleanup_tis(void)
993{ 1122{
994 struct tpm_chip *chip; 1123 struct tpm_chip *chip;
995#ifdef CONFIG_PNP 1124#if defined(CONFIG_PNP) || defined(CONFIG_ACPI)
996 if (!force) { 1125 if (!force) {
1126#ifdef CONFIG_ACPI
1127 acpi_bus_unregister_driver(&tis_acpi_driver);
1128#endif
1129#ifdef CONFIG_PNP
997 pnp_unregister_driver(&tis_pnp_driver); 1130 pnp_unregister_driver(&tis_pnp_driver);
1131#endif
998 return; 1132 return;
999 } 1133 }
1000#endif 1134#endif