aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJason Gunthorpe <jgunthorpe@obsidianresearch.com>2016-04-18 13:26:13 -0400
committerJarkko Sakkinen <jarkko.sakkinen@linux.intel.com>2016-06-25 10:26:35 -0400
commit062807f20e3f363dc5db0c7927bb6223dd1f46a2 (patch)
tree8905ff192e21247ef36cf7e9fc0f62fda6503d12
parent9e0d39d8a6a0a8805d05fba22e3fbe80b5c8c4cb (diff)
tpm: Remove all uses of drvdata from the TPM Core
The final thing preventing this was the way the sysfs files were attached to the pdev. Follow the approach developed for ppi and move the sysfs files to the chip->dev with symlinks from the pdev for compatibility. Everything in the core now sanely uses container_of to get the chip. Signed-off-by: Jason Gunthorpe <jgunthorpe@obsidianresearch.com> Signed-off-by: Stefan Berger <stefanb@linux.vnet.ibm.com> Tested-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com> Tested-by: Stefan Berger <stefanb@linux.vnet.ibm.com> Signed-off-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
-rw-r--r--drivers/char/tpm/tpm-chip.c73
-rw-r--r--drivers/char/tpm/tpm-interface.c7
-rw-r--r--drivers/char/tpm/tpm-sysfs.c61
-rw-r--r--drivers/char/tpm/tpm.h10
4 files changed, 84 insertions, 67 deletions
diff --git a/drivers/char/tpm/tpm-chip.c b/drivers/char/tpm/tpm-chip.c
index 2ea2f1561e59..57d9794dac94 100644
--- a/drivers/char/tpm/tpm-chip.c
+++ b/drivers/char/tpm/tpm-chip.c
@@ -170,9 +170,7 @@ struct tpm_chip *tpm_chip_alloc(struct device *dev,
170 chip->dev.class = tpm_class; 170 chip->dev.class = tpm_class;
171 chip->dev.release = tpm_dev_release; 171 chip->dev.release = tpm_dev_release;
172 chip->dev.parent = dev; 172 chip->dev.parent = dev;
173#ifdef CONFIG_ACPI
174 chip->dev.groups = chip->groups; 173 chip->dev.groups = chip->groups;
175#endif
176 174
177 if (chip->dev_num == 0) 175 if (chip->dev_num == 0)
178 chip->dev.devt = MKDEV(MISC_MAJOR, TPM_MINOR); 176 chip->dev.devt = MKDEV(MISC_MAJOR, TPM_MINOR);
@@ -277,14 +275,10 @@ static void tpm_del_char_device(struct tpm_chip *chip)
277 275
278static int tpm1_chip_register(struct tpm_chip *chip) 276static int tpm1_chip_register(struct tpm_chip *chip)
279{ 277{
280 int rc;
281
282 if (chip->flags & TPM_CHIP_FLAG_TPM2) 278 if (chip->flags & TPM_CHIP_FLAG_TPM2)
283 return 0; 279 return 0;
284 280
285 rc = tpm_sysfs_add_device(chip); 281 tpm_sysfs_add_device(chip);
286 if (rc)
287 return rc;
288 282
289 chip->bios_dir = tpm_bios_log_setup(dev_name(&chip->dev)); 283 chip->bios_dir = tpm_bios_log_setup(dev_name(&chip->dev));
290 284
@@ -298,10 +292,50 @@ static void tpm1_chip_unregister(struct tpm_chip *chip)
298 292
299 if (chip->bios_dir) 293 if (chip->bios_dir)
300 tpm_bios_log_teardown(chip->bios_dir); 294 tpm_bios_log_teardown(chip->bios_dir);
295}
296
297static void tpm_del_legacy_sysfs(struct tpm_chip *chip)
298{
299 struct attribute **i;
300
301 if (chip->flags & TPM_CHIP_FLAG_TPM2)
302 return;
301 303
302 tpm_sysfs_del_device(chip); 304 sysfs_remove_link(&chip->dev.parent->kobj, "ppi");
305
306 for (i = chip->groups[0]->attrs; *i != NULL; ++i)
307 sysfs_remove_link(&chip->dev.parent->kobj, (*i)->name);
303} 308}
304 309
310/* For compatibility with legacy sysfs paths we provide symlinks from the
311 * parent dev directory to selected names within the tpm chip directory. Old
312 * kernel versions created these files directly under the parent.
313 */
314static int tpm_add_legacy_sysfs(struct tpm_chip *chip)
315{
316 struct attribute **i;
317 int rc;
318
319 if (chip->flags & TPM_CHIP_FLAG_TPM2)
320 return 0;
321
322 rc = __compat_only_sysfs_link_entry_to_kobj(
323 &chip->dev.parent->kobj, &chip->dev.kobj, "ppi");
324 if (rc && rc != -ENOENT)
325 return rc;
326
327 /* All the names from tpm-sysfs */
328 for (i = chip->groups[0]->attrs; *i != NULL; ++i) {
329 rc = __compat_only_sysfs_link_entry_to_kobj(
330 &chip->dev.parent->kobj, &chip->dev.kobj, (*i)->name);
331 if (rc) {
332 tpm_del_legacy_sysfs(chip);
333 return rc;
334 }
335 }
336
337 return 0;
338}
305/* 339/*
306 * tpm_chip_register() - create a character device for the TPM chip 340 * tpm_chip_register() - create a character device for the TPM chip
307 * @chip: TPM chip to use. 341 * @chip: TPM chip to use.
@@ -324,24 +358,20 @@ int tpm_chip_register(struct tpm_chip *chip)
324 tpm_add_ppi(chip); 358 tpm_add_ppi(chip);
325 359
326 rc = tpm_add_char_device(chip); 360 rc = tpm_add_char_device(chip);
327 if (rc) 361 if (rc) {
328 goto out_err; 362 tpm1_chip_unregister(chip);
363 return rc;
364 }
329 365
330 chip->flags |= TPM_CHIP_FLAG_REGISTERED; 366 chip->flags |= TPM_CHIP_FLAG_REGISTERED;
331 367
332 if (!(chip->flags & TPM_CHIP_FLAG_TPM2)) { 368 rc = tpm_add_legacy_sysfs(chip);
333 rc = __compat_only_sysfs_link_entry_to_kobj( 369 if (rc) {
334 &chip->dev.parent->kobj, &chip->dev.kobj, "ppi"); 370 tpm_chip_unregister(chip);
335 if (rc && rc != -ENOENT) { 371 return rc;
336 tpm_chip_unregister(chip);
337 return rc;
338 }
339 } 372 }
340 373
341 return 0; 374 return 0;
342out_err:
343 tpm1_chip_unregister(chip);
344 return rc;
345} 375}
346EXPORT_SYMBOL_GPL(tpm_chip_register); 376EXPORT_SYMBOL_GPL(tpm_chip_register);
347 377
@@ -363,8 +393,7 @@ void tpm_chip_unregister(struct tpm_chip *chip)
363 if (!(chip->flags & TPM_CHIP_FLAG_REGISTERED)) 393 if (!(chip->flags & TPM_CHIP_FLAG_REGISTERED))
364 return; 394 return;
365 395
366 if (!(chip->flags & TPM_CHIP_FLAG_TPM2)) 396 tpm_del_legacy_sysfs(chip);
367 sysfs_remove_link(&chip->dev.parent->kobj, "ppi");
368 397
369 tpm1_chip_unregister(chip); 398 tpm1_chip_unregister(chip);
370 tpm_del_char_device(chip); 399 tpm_del_char_device(chip);
diff --git a/drivers/char/tpm/tpm-interface.c b/drivers/char/tpm/tpm-interface.c
index 7cba092e3069..080dade5e80f 100644
--- a/drivers/char/tpm/tpm-interface.c
+++ b/drivers/char/tpm/tpm-interface.c
@@ -432,12 +432,11 @@ static const struct tpm_input_header tpm_getcap_header = {
432 .ordinal = TPM_ORD_GET_CAP 432 .ordinal = TPM_ORD_GET_CAP
433}; 433};
434 434
435ssize_t tpm_getcap(struct device *dev, __be32 subcap_id, cap_t *cap, 435ssize_t tpm_getcap(struct tpm_chip *chip, __be32 subcap_id, cap_t *cap,
436 const char *desc) 436 const char *desc)
437{ 437{
438 struct tpm_cmd_t tpm_cmd; 438 struct tpm_cmd_t tpm_cmd;
439 int rc; 439 int rc;
440 struct tpm_chip *chip = dev_get_drvdata(dev);
441 440
442 tpm_cmd.header.in = tpm_getcap_header; 441 tpm_cmd.header.in = tpm_getcap_header;
443 if (subcap_id == CAP_VERSION_1_1 || subcap_id == CAP_VERSION_1_2) { 442 if (subcap_id == CAP_VERSION_1_1 || subcap_id == CAP_VERSION_1_2) {
@@ -935,7 +934,7 @@ static struct tpm_input_header savestate_header = {
935 */ 934 */
936int tpm_pm_suspend(struct device *dev) 935int tpm_pm_suspend(struct device *dev)
937{ 936{
938 struct tpm_chip *chip = dev_get_drvdata(dev); 937 struct tpm_chip *chip = to_tpm_chip(dev);
939 struct tpm_cmd_t cmd; 938 struct tpm_cmd_t cmd;
940 int rc, try; 939 int rc, try;
941 940
@@ -996,7 +995,7 @@ EXPORT_SYMBOL_GPL(tpm_pm_suspend);
996 */ 995 */
997int tpm_pm_resume(struct device *dev) 996int tpm_pm_resume(struct device *dev)
998{ 997{
999 struct tpm_chip *chip = dev_get_drvdata(dev); 998 struct tpm_chip *chip = to_tpm_chip(dev);
1000 999
1001 if (chip == NULL) 1000 if (chip == NULL)
1002 return -ENODEV; 1001 return -ENODEV;
diff --git a/drivers/char/tpm/tpm-sysfs.c b/drivers/char/tpm/tpm-sysfs.c
index a7c3473c3421..b46cf70c8b16 100644
--- a/drivers/char/tpm/tpm-sysfs.c
+++ b/drivers/char/tpm/tpm-sysfs.c
@@ -36,7 +36,7 @@ static ssize_t pubek_show(struct device *dev, struct device_attribute *attr,
36 int i, rc; 36 int i, rc;
37 char *str = buf; 37 char *str = buf;
38 38
39 struct tpm_chip *chip = dev_get_drvdata(dev); 39 struct tpm_chip *chip = to_tpm_chip(dev);
40 40
41 tpm_cmd.header.in = tpm_readpubek_header; 41 tpm_cmd.header.in = tpm_readpubek_header;
42 err = tpm_transmit_cmd(chip, &tpm_cmd, READ_PUBEK_RESULT_SIZE, 42 err = tpm_transmit_cmd(chip, &tpm_cmd, READ_PUBEK_RESULT_SIZE,
@@ -92,9 +92,9 @@ static ssize_t pcrs_show(struct device *dev, struct device_attribute *attr,
92 ssize_t rc; 92 ssize_t rc;
93 int i, j, num_pcrs; 93 int i, j, num_pcrs;
94 char *str = buf; 94 char *str = buf;
95 struct tpm_chip *chip = dev_get_drvdata(dev); 95 struct tpm_chip *chip = to_tpm_chip(dev);
96 96
97 rc = tpm_getcap(dev, TPM_CAP_PROP_PCR, &cap, 97 rc = tpm_getcap(chip, TPM_CAP_PROP_PCR, &cap,
98 "attempting to determine the number of PCRS"); 98 "attempting to determine the number of PCRS");
99 if (rc) 99 if (rc)
100 return 0; 100 return 0;
@@ -119,8 +119,8 @@ static ssize_t enabled_show(struct device *dev, struct device_attribute *attr,
119 cap_t cap; 119 cap_t cap;
120 ssize_t rc; 120 ssize_t rc;
121 121
122 rc = tpm_getcap(dev, TPM_CAP_FLAG_PERM, &cap, 122 rc = tpm_getcap(to_tpm_chip(dev), TPM_CAP_FLAG_PERM, &cap,
123 "attempting to determine the permanent enabled state"); 123 "attempting to determine the permanent enabled state");
124 if (rc) 124 if (rc)
125 return 0; 125 return 0;
126 126
@@ -135,8 +135,8 @@ static ssize_t active_show(struct device *dev, struct device_attribute *attr,
135 cap_t cap; 135 cap_t cap;
136 ssize_t rc; 136 ssize_t rc;
137 137
138 rc = tpm_getcap(dev, TPM_CAP_FLAG_PERM, &cap, 138 rc = tpm_getcap(to_tpm_chip(dev), TPM_CAP_FLAG_PERM, &cap,
139 "attempting to determine the permanent active state"); 139 "attempting to determine the permanent active state");
140 if (rc) 140 if (rc)
141 return 0; 141 return 0;
142 142
@@ -151,8 +151,8 @@ static ssize_t owned_show(struct device *dev, struct device_attribute *attr,
151 cap_t cap; 151 cap_t cap;
152 ssize_t rc; 152 ssize_t rc;
153 153
154 rc = tpm_getcap(dev, TPM_CAP_PROP_OWNER, &cap, 154 rc = tpm_getcap(to_tpm_chip(dev), TPM_CAP_PROP_OWNER, &cap,
155 "attempting to determine the owner state"); 155 "attempting to determine the owner state");
156 if (rc) 156 if (rc)
157 return 0; 157 return 0;
158 158
@@ -167,8 +167,8 @@ static ssize_t temp_deactivated_show(struct device *dev,
167 cap_t cap; 167 cap_t cap;
168 ssize_t rc; 168 ssize_t rc;
169 169
170 rc = tpm_getcap(dev, TPM_CAP_FLAG_VOL, &cap, 170 rc = tpm_getcap(to_tpm_chip(dev), TPM_CAP_FLAG_VOL, &cap,
171 "attempting to determine the temporary state"); 171 "attempting to determine the temporary state");
172 if (rc) 172 if (rc)
173 return 0; 173 return 0;
174 174
@@ -180,11 +180,12 @@ static DEVICE_ATTR_RO(temp_deactivated);
180static ssize_t caps_show(struct device *dev, struct device_attribute *attr, 180static ssize_t caps_show(struct device *dev, struct device_attribute *attr,
181 char *buf) 181 char *buf)
182{ 182{
183 struct tpm_chip *chip = to_tpm_chip(dev);
183 cap_t cap; 184 cap_t cap;
184 ssize_t rc; 185 ssize_t rc;
185 char *str = buf; 186 char *str = buf;
186 187
187 rc = tpm_getcap(dev, TPM_CAP_PROP_MANUFACTURER, &cap, 188 rc = tpm_getcap(chip, TPM_CAP_PROP_MANUFACTURER, &cap,
188 "attempting to determine the manufacturer"); 189 "attempting to determine the manufacturer");
189 if (rc) 190 if (rc)
190 return 0; 191 return 0;
@@ -192,8 +193,8 @@ static ssize_t caps_show(struct device *dev, struct device_attribute *attr,
192 be32_to_cpu(cap.manufacturer_id)); 193 be32_to_cpu(cap.manufacturer_id));
193 194
194 /* Try to get a TPM version 1.2 TPM_CAP_VERSION_INFO */ 195 /* Try to get a TPM version 1.2 TPM_CAP_VERSION_INFO */
195 rc = tpm_getcap(dev, CAP_VERSION_1_2, &cap, 196 rc = tpm_getcap(chip, CAP_VERSION_1_2, &cap,
196 "attempting to determine the 1.2 version"); 197 "attempting to determine the 1.2 version");
197 if (!rc) { 198 if (!rc) {
198 str += sprintf(str, 199 str += sprintf(str,
199 "TCG version: %d.%d\nFirmware version: %d.%d\n", 200 "TCG version: %d.%d\nFirmware version: %d.%d\n",
@@ -203,7 +204,7 @@ static ssize_t caps_show(struct device *dev, struct device_attribute *attr,
203 cap.tpm_version_1_2.revMinor); 204 cap.tpm_version_1_2.revMinor);
204 } else { 205 } else {
205 /* Otherwise just use TPM_STRUCT_VER */ 206 /* Otherwise just use TPM_STRUCT_VER */
206 rc = tpm_getcap(dev, CAP_VERSION_1_1, &cap, 207 rc = tpm_getcap(chip, CAP_VERSION_1_1, &cap,
207 "attempting to determine the 1.1 version"); 208 "attempting to determine the 1.1 version");
208 if (rc) 209 if (rc)
209 return 0; 210 return 0;
@@ -222,7 +223,7 @@ static DEVICE_ATTR_RO(caps);
222static ssize_t cancel_store(struct device *dev, struct device_attribute *attr, 223static ssize_t cancel_store(struct device *dev, struct device_attribute *attr,
223 const char *buf, size_t count) 224 const char *buf, size_t count)
224{ 225{
225 struct tpm_chip *chip = dev_get_drvdata(dev); 226 struct tpm_chip *chip = to_tpm_chip(dev);
226 if (chip == NULL) 227 if (chip == NULL)
227 return 0; 228 return 0;
228 229
@@ -234,7 +235,7 @@ static DEVICE_ATTR_WO(cancel);
234static ssize_t durations_show(struct device *dev, struct device_attribute *attr, 235static ssize_t durations_show(struct device *dev, struct device_attribute *attr,
235 char *buf) 236 char *buf)
236{ 237{
237 struct tpm_chip *chip = dev_get_drvdata(dev); 238 struct tpm_chip *chip = to_tpm_chip(dev);
238 239
239 if (chip->duration[TPM_LONG] == 0) 240 if (chip->duration[TPM_LONG] == 0)
240 return 0; 241 return 0;
@@ -251,7 +252,7 @@ static DEVICE_ATTR_RO(durations);
251static ssize_t timeouts_show(struct device *dev, struct device_attribute *attr, 252static ssize_t timeouts_show(struct device *dev, struct device_attribute *attr,
252 char *buf) 253 char *buf)
253{ 254{
254 struct tpm_chip *chip = dev_get_drvdata(dev); 255 struct tpm_chip *chip = to_tpm_chip(dev);
255 256
256 return sprintf(buf, "%d %d %d %d [%s]\n", 257 return sprintf(buf, "%d %d %d %d [%s]\n",
257 jiffies_to_usecs(chip->timeout_a), 258 jiffies_to_usecs(chip->timeout_a),
@@ -281,24 +282,12 @@ static const struct attribute_group tpm_dev_group = {
281 .attrs = tpm_dev_attrs, 282 .attrs = tpm_dev_attrs,
282}; 283};
283 284
284int tpm_sysfs_add_device(struct tpm_chip *chip) 285void tpm_sysfs_add_device(struct tpm_chip *chip)
285{ 286{
286 int err; 287 /* The sysfs routines rely on an implicit tpm_try_get_ops, device_del
287 err = sysfs_create_group(&chip->dev.parent->kobj, 288 * is called before ops is null'd and the sysfs core synchronizes this
288 &tpm_dev_group); 289 * removal so that no callbacks are running or can run again
289
290 if (err)
291 dev_err(&chip->dev,
292 "failed to create sysfs attributes, %d\n", err);
293 return err;
294}
295
296void tpm_sysfs_del_device(struct tpm_chip *chip)
297{
298 /* The sysfs routines rely on an implicit tpm_try_get_ops, this
299 * function is called before ops is null'd and the sysfs core
300 * synchronizes this removal so that no callbacks are running or can
301 * run again
302 */ 290 */
303 sysfs_remove_group(&chip->dev.parent->kobj, &tpm_dev_group); 291 WARN_ON(chip->groups_cnt != 0);
292 chip->groups[chip->groups_cnt++] = &tpm_dev_group;
304} 293}
diff --git a/drivers/char/tpm/tpm.h b/drivers/char/tpm/tpm.h
index 8bc6fb85fb38..508e8e00c9c1 100644
--- a/drivers/char/tpm/tpm.h
+++ b/drivers/char/tpm/tpm.h
@@ -168,9 +168,9 @@ struct tpm_chip {
168 168
169 struct dentry **bios_dir; 169 struct dentry **bios_dir;
170 170
171#ifdef CONFIG_ACPI 171 const struct attribute_group *groups[3];
172 const struct attribute_group *groups[2];
173 unsigned int groups_cnt; 172 unsigned int groups_cnt;
173#ifdef CONFIG_ACPI
174 acpi_handle acpi_dev_handle; 174 acpi_handle acpi_dev_handle;
175 char ppi_version[TPM_PPI_VERSION_LEN + 1]; 175 char ppi_version[TPM_PPI_VERSION_LEN + 1];
176#endif /* CONFIG_ACPI */ 176#endif /* CONFIG_ACPI */
@@ -471,7 +471,8 @@ extern dev_t tpm_devt;
471extern const struct file_operations tpm_fops; 471extern const struct file_operations tpm_fops;
472extern struct idr dev_nums_idr; 472extern struct idr dev_nums_idr;
473 473
474ssize_t tpm_getcap(struct device *, __be32, cap_t *, const char *); 474ssize_t tpm_getcap(struct tpm_chip *chip, __be32 subcap_id, cap_t *cap,
475 const char *desc);
475ssize_t tpm_transmit(struct tpm_chip *chip, const char *buf, 476ssize_t tpm_transmit(struct tpm_chip *chip, const char *buf,
476 size_t bufsiz); 477 size_t bufsiz);
477ssize_t tpm_transmit_cmd(struct tpm_chip *chip, void *cmd, int len, 478ssize_t tpm_transmit_cmd(struct tpm_chip *chip, void *cmd, int len,
@@ -496,8 +497,7 @@ extern struct tpm_chip *tpmm_chip_alloc(struct device *pdev,
496extern int tpm_chip_register(struct tpm_chip *chip); 497extern int tpm_chip_register(struct tpm_chip *chip);
497extern void tpm_chip_unregister(struct tpm_chip *chip); 498extern void tpm_chip_unregister(struct tpm_chip *chip);
498 499
499int tpm_sysfs_add_device(struct tpm_chip *chip); 500void tpm_sysfs_add_device(struct tpm_chip *chip);
500void tpm_sysfs_del_device(struct tpm_chip *chip);
501 501
502int tpm_pcr_read_dev(struct tpm_chip *chip, int pcr_idx, u8 *res_buf); 502int tpm_pcr_read_dev(struct tpm_chip *chip, int pcr_idx, u8 *res_buf);
503 503