Skip to content

Commit e89f8b1

Browse files
jgunthorpeJarkko Sakkinen
authored andcommitted
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>
1 parent 2815716 commit e89f8b1

File tree

4 files changed

+84
-67
lines changed

4 files changed

+84
-67
lines changed

drivers/char/tpm/tpm-chip.c

Lines changed: 51 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -170,9 +170,7 @@ struct tpm_chip *tpm_chip_alloc(struct device *dev,
170170
chip->dev.class = tpm_class;
171171
chip->dev.release = tpm_dev_release;
172172
chip->dev.parent = dev;
173-
#ifdef CONFIG_ACPI
174173
chip->dev.groups = chip->groups;
175-
#endif
176174

177175
if (chip->dev_num == 0)
178176
chip->dev.devt = MKDEV(MISC_MAJOR, TPM_MINOR);
@@ -277,14 +275,10 @@ static void tpm_del_char_device(struct tpm_chip *chip)
277275

278276
static int tpm1_chip_register(struct tpm_chip *chip)
279277
{
280-
int rc;
281-
282278
if (chip->flags & TPM_CHIP_FLAG_TPM2)
283279
return 0;
284280

285-
rc = tpm_sysfs_add_device(chip);
286-
if (rc)
287-
return rc;
281+
tpm_sysfs_add_device(chip);
288282

289283
chip->bios_dir = tpm_bios_log_setup(dev_name(&chip->dev));
290284

@@ -298,10 +292,50 @@ static void tpm1_chip_unregister(struct tpm_chip *chip)
298292

299293
if (chip->bios_dir)
300294
tpm_bios_log_teardown(chip->bios_dir);
295+
}
296+
297+
static 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;
301303

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);
303308
}
304309

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+
*/
314+
static 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+
}
305339
/*
306340
* tpm_chip_register() - create a character device for the TPM chip
307341
* @chip: TPM chip to use.
@@ -324,24 +358,20 @@ int tpm_chip_register(struct tpm_chip *chip)
324358
tpm_add_ppi(chip);
325359

326360
rc = tpm_add_char_device(chip);
327-
if (rc)
328-
goto out_err;
361+
if (rc) {
362+
tpm1_chip_unregister(chip);
363+
return rc;
364+
}
329365

330366
chip->flags |= TPM_CHIP_FLAG_REGISTERED;
331367

332-
if (!(chip->flags & TPM_CHIP_FLAG_TPM2)) {
333-
rc = __compat_only_sysfs_link_entry_to_kobj(
334-
&chip->dev.parent->kobj, &chip->dev.kobj, "ppi");
335-
if (rc && rc != -ENOENT) {
336-
tpm_chip_unregister(chip);
337-
return rc;
338-
}
368+
rc = tpm_add_legacy_sysfs(chip);
369+
if (rc) {
370+
tpm_chip_unregister(chip);
371+
return rc;
339372
}
340373

341374
return 0;
342-
out_err:
343-
tpm1_chip_unregister(chip);
344-
return rc;
345375
}
346376
EXPORT_SYMBOL_GPL(tpm_chip_register);
347377

@@ -363,8 +393,7 @@ void tpm_chip_unregister(struct tpm_chip *chip)
363393
if (!(chip->flags & TPM_CHIP_FLAG_REGISTERED))
364394
return;
365395

366-
if (!(chip->flags & TPM_CHIP_FLAG_TPM2))
367-
sysfs_remove_link(&chip->dev.parent->kobj, "ppi");
396+
tpm_del_legacy_sysfs(chip);
368397

369398
tpm1_chip_unregister(chip);
370399
tpm_del_char_device(chip);

drivers/char/tpm/tpm-interface.c

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -432,12 +432,11 @@ static const struct tpm_input_header tpm_getcap_header = {
432432
.ordinal = TPM_ORD_GET_CAP
433433
};
434434

435-
ssize_t tpm_getcap(struct device *dev, __be32 subcap_id, cap_t *cap,
435+
ssize_t tpm_getcap(struct tpm_chip *chip, __be32 subcap_id, cap_t *cap,
436436
const char *desc)
437437
{
438438
struct tpm_cmd_t tpm_cmd;
439439
int rc;
440-
struct tpm_chip *chip = dev_get_drvdata(dev);
441440

442441
tpm_cmd.header.in = tpm_getcap_header;
443442
if (subcap_id == CAP_VERSION_1_1 || subcap_id == CAP_VERSION_1_2) {
@@ -935,7 +934,7 @@ static struct tpm_input_header savestate_header = {
935934
*/
936935
int tpm_pm_suspend(struct device *dev)
937936
{
938-
struct tpm_chip *chip = dev_get_drvdata(dev);
937+
struct tpm_chip *chip = to_tpm_chip(dev);
939938
struct tpm_cmd_t cmd;
940939
int rc, try;
941940

@@ -996,7 +995,7 @@ EXPORT_SYMBOL_GPL(tpm_pm_suspend);
996995
*/
997996
int tpm_pm_resume(struct device *dev)
998997
{
999-
struct tpm_chip *chip = dev_get_drvdata(dev);
998+
struct tpm_chip *chip = to_tpm_chip(dev);
1000999

10011000
if (chip == NULL)
10021001
return -ENODEV;

drivers/char/tpm/tpm-sysfs.c

Lines changed: 25 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ static ssize_t pubek_show(struct device *dev, struct device_attribute *attr,
3636
int i, rc;
3737
char *str = buf;
3838

39-
struct tpm_chip *chip = dev_get_drvdata(dev);
39+
struct tpm_chip *chip = to_tpm_chip(dev);
4040

4141
tpm_cmd.header.in = tpm_readpubek_header;
4242
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,
9292
ssize_t rc;
9393
int i, j, num_pcrs;
9494
char *str = buf;
95-
struct tpm_chip *chip = dev_get_drvdata(dev);
95+
struct tpm_chip *chip = to_tpm_chip(dev);
9696

97-
rc = tpm_getcap(dev, TPM_CAP_PROP_PCR, &cap,
97+
rc = tpm_getcap(chip, TPM_CAP_PROP_PCR, &cap,
9898
"attempting to determine the number of PCRS");
9999
if (rc)
100100
return 0;
@@ -119,8 +119,8 @@ static ssize_t enabled_show(struct device *dev, struct device_attribute *attr,
119119
cap_t cap;
120120
ssize_t rc;
121121

122-
rc = tpm_getcap(dev, TPM_CAP_FLAG_PERM, &cap,
123-
"attempting to determine the permanent enabled state");
122+
rc = tpm_getcap(to_tpm_chip(dev), TPM_CAP_FLAG_PERM, &cap,
123+
"attempting to determine the permanent enabled state");
124124
if (rc)
125125
return 0;
126126

@@ -135,8 +135,8 @@ static ssize_t active_show(struct device *dev, struct device_attribute *attr,
135135
cap_t cap;
136136
ssize_t rc;
137137

138-
rc = tpm_getcap(dev, TPM_CAP_FLAG_PERM, &cap,
139-
"attempting to determine the permanent active state");
138+
rc = tpm_getcap(to_tpm_chip(dev), TPM_CAP_FLAG_PERM, &cap,
139+
"attempting to determine the permanent active state");
140140
if (rc)
141141
return 0;
142142

@@ -151,8 +151,8 @@ static ssize_t owned_show(struct device *dev, struct device_attribute *attr,
151151
cap_t cap;
152152
ssize_t rc;
153153

154-
rc = tpm_getcap(dev, TPM_CAP_PROP_OWNER, &cap,
155-
"attempting to determine the owner state");
154+
rc = tpm_getcap(to_tpm_chip(dev), TPM_CAP_PROP_OWNER, &cap,
155+
"attempting to determine the owner state");
156156
if (rc)
157157
return 0;
158158

@@ -167,8 +167,8 @@ static ssize_t temp_deactivated_show(struct device *dev,
167167
cap_t cap;
168168
ssize_t rc;
169169

170-
rc = tpm_getcap(dev, TPM_CAP_FLAG_VOL, &cap,
171-
"attempting to determine the temporary state");
170+
rc = tpm_getcap(to_tpm_chip(dev), TPM_CAP_FLAG_VOL, &cap,
171+
"attempting to determine the temporary state");
172172
if (rc)
173173
return 0;
174174

@@ -180,20 +180,21 @@ static DEVICE_ATTR_RO(temp_deactivated);
180180
static ssize_t caps_show(struct device *dev, struct device_attribute *attr,
181181
char *buf)
182182
{
183+
struct tpm_chip *chip = to_tpm_chip(dev);
183184
cap_t cap;
184185
ssize_t rc;
185186
char *str = buf;
186187

187-
rc = tpm_getcap(dev, TPM_CAP_PROP_MANUFACTURER, &cap,
188+
rc = tpm_getcap(chip, TPM_CAP_PROP_MANUFACTURER, &cap,
188189
"attempting to determine the manufacturer");
189190
if (rc)
190191
return 0;
191192
str += sprintf(str, "Manufacturer: 0x%x\n",
192193
be32_to_cpu(cap.manufacturer_id));
193194

194195
/* Try to get a TPM version 1.2 TPM_CAP_VERSION_INFO */
195-
rc = tpm_getcap(dev, CAP_VERSION_1_2, &cap,
196-
"attempting to determine the 1.2 version");
196+
rc = tpm_getcap(chip, CAP_VERSION_1_2, &cap,
197+
"attempting to determine the 1.2 version");
197198
if (!rc) {
198199
str += sprintf(str,
199200
"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,
203204
cap.tpm_version_1_2.revMinor);
204205
} else {
205206
/* 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,
207208
"attempting to determine the 1.1 version");
208209
if (rc)
209210
return 0;
@@ -222,7 +223,7 @@ static DEVICE_ATTR_RO(caps);
222223
static ssize_t cancel_store(struct device *dev, struct device_attribute *attr,
223224
const char *buf, size_t count)
224225
{
225-
struct tpm_chip *chip = dev_get_drvdata(dev);
226+
struct tpm_chip *chip = to_tpm_chip(dev);
226227
if (chip == NULL)
227228
return 0;
228229

@@ -234,7 +235,7 @@ static DEVICE_ATTR_WO(cancel);
234235
static ssize_t durations_show(struct device *dev, struct device_attribute *attr,
235236
char *buf)
236237
{
237-
struct tpm_chip *chip = dev_get_drvdata(dev);
238+
struct tpm_chip *chip = to_tpm_chip(dev);
238239

239240
if (chip->duration[TPM_LONG] == 0)
240241
return 0;
@@ -251,7 +252,7 @@ static DEVICE_ATTR_RO(durations);
251252
static ssize_t timeouts_show(struct device *dev, struct device_attribute *attr,
252253
char *buf)
253254
{
254-
struct tpm_chip *chip = dev_get_drvdata(dev);
255+
struct tpm_chip *chip = to_tpm_chip(dev);
255256

256257
return sprintf(buf, "%d %d %d %d [%s]\n",
257258
jiffies_to_usecs(chip->timeout_a),
@@ -281,24 +282,12 @@ static const struct attribute_group tpm_dev_group = {
281282
.attrs = tpm_dev_attrs,
282283
};
283284

284-
int tpm_sysfs_add_device(struct tpm_chip *chip)
285+
void tpm_sysfs_add_device(struct tpm_chip *chip)
285286
{
286-
int err;
287-
err = sysfs_create_group(&chip->dev.parent->kobj,
288-
&tpm_dev_group);
289-
290-
if (err)
291-
dev_err(&chip->dev,
292-
"failed to create sysfs attributes, %d\n", err);
293-
return err;
294-
}
295-
296-
void 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
287+
/* The sysfs routines rely on an implicit tpm_try_get_ops, device_del
288+
* is called before ops is null'd and the sysfs core synchronizes this
289+
* removal so that no callbacks are running or can run again
302290
*/
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;
304293
}

drivers/char/tpm/tpm.h

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -168,9 +168,9 @@ struct tpm_chip {
168168

169169
struct dentry **bios_dir;
170170

171-
#ifdef CONFIG_ACPI
172-
const struct attribute_group *groups[2];
171+
const struct attribute_group *groups[3];
173172
unsigned int groups_cnt;
173+
#ifdef CONFIG_ACPI
174174
acpi_handle acpi_dev_handle;
175175
char ppi_version[TPM_PPI_VERSION_LEN + 1];
176176
#endif /* CONFIG_ACPI */
@@ -471,7 +471,8 @@ extern dev_t tpm_devt;
471471
extern const struct file_operations tpm_fops;
472472
extern struct idr dev_nums_idr;
473473

474-
ssize_t tpm_getcap(struct device *, __be32, cap_t *, const char *);
474+
ssize_t tpm_getcap(struct tpm_chip *chip, __be32 subcap_id, cap_t *cap,
475+
const char *desc);
475476
ssize_t tpm_transmit(struct tpm_chip *chip, const char *buf,
476477
size_t bufsiz);
477478
ssize_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,
496497
extern int tpm_chip_register(struct tpm_chip *chip);
497498
extern void tpm_chip_unregister(struct tpm_chip *chip);
498499

499-
int tpm_sysfs_add_device(struct tpm_chip *chip);
500-
void tpm_sysfs_del_device(struct tpm_chip *chip);
500+
void tpm_sysfs_add_device(struct tpm_chip *chip);
501501

502502
int tpm_pcr_read_dev(struct tpm_chip *chip, int pcr_idx, u8 *res_buf);
503503

0 commit comments

Comments
 (0)