1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23#include <linux/poll.h>
24#include <linux/slab.h>
25#include <linux/mutex.h>
26#include <linux/spinlock.h>
27#include <linux/freezer.h>
28#include <linux/major.h>
29#include "tpm.h"
30#include "tpm_eventlog.h"
31
32DEFINE_IDR(dev_nums_idr);
33static DEFINE_MUTEX(idr_lock);
34
35struct class *tpm_class;
36struct class *tpmrm_class;
37dev_t tpm_devt;
38
39
40
41
42
43
44
45
46
47
48
49
50int tpm_try_get_ops(struct tpm_chip *chip)
51{
52 int rc = -EIO;
53
54 get_device(&chip->dev);
55
56 down_read(&chip->ops_sem);
57 if (!chip->ops)
58 goto out_lock;
59
60 return 0;
61out_lock:
62 up_read(&chip->ops_sem);
63 put_device(&chip->dev);
64 return rc;
65}
66EXPORT_SYMBOL_GPL(tpm_try_get_ops);
67
68
69
70
71
72
73
74
75void tpm_put_ops(struct tpm_chip *chip)
76{
77 up_read(&chip->ops_sem);
78 put_device(&chip->dev);
79}
80EXPORT_SYMBOL_GPL(tpm_put_ops);
81
82
83
84
85
86
87
88
89struct tpm_chip *tpm_chip_find_get(int chip_num)
90{
91 struct tpm_chip *chip, *res = NULL;
92 int chip_prev;
93
94 mutex_lock(&idr_lock);
95
96 if (chip_num == TPM_ANY_NUM) {
97 chip_num = 0;
98 do {
99 chip_prev = chip_num;
100 chip = idr_get_next(&dev_nums_idr, &chip_num);
101 if (chip && !tpm_try_get_ops(chip)) {
102 res = chip;
103 break;
104 }
105 } while (chip_prev != chip_num);
106 } else {
107 chip = idr_find(&dev_nums_idr, chip_num);
108 if (chip && !tpm_try_get_ops(chip))
109 res = chip;
110 }
111
112 mutex_unlock(&idr_lock);
113
114 return res;
115}
116
117
118
119
120
121
122
123static void tpm_dev_release(struct device *dev)
124{
125 struct tpm_chip *chip = container_of(dev, struct tpm_chip, dev);
126
127 mutex_lock(&idr_lock);
128 idr_remove(&dev_nums_idr, chip->dev_num);
129 mutex_unlock(&idr_lock);
130
131 kfree(chip->log.bios_event_log);
132 kfree(chip->work_space.context_buf);
133 kfree(chip->work_space.session_buf);
134 kfree(chip);
135}
136
137static void tpm_devs_release(struct device *dev)
138{
139 struct tpm_chip *chip = container_of(dev, struct tpm_chip, devs);
140
141
142 put_device(&chip->dev);
143}
144
145
146
147
148
149
150
151
152
153
154
155
156
157static int tpm_class_shutdown(struct device *dev)
158{
159 struct tpm_chip *chip = container_of(dev, struct tpm_chip, dev);
160
161 if (chip->flags & TPM_CHIP_FLAG_TPM2) {
162 down_write(&chip->ops_sem);
163 tpm2_shutdown(chip, TPM2_SU_CLEAR);
164 chip->ops = NULL;
165 up_write(&chip->ops_sem);
166 }
167
168 return 0;
169}
170
171
172
173
174
175
176
177
178
179
180
181struct tpm_chip *tpm_chip_alloc(struct device *pdev,
182 const struct tpm_class_ops *ops)
183{
184 struct tpm_chip *chip;
185 int rc;
186
187 chip = kzalloc(sizeof(*chip), GFP_KERNEL);
188 if (chip == NULL)
189 return ERR_PTR(-ENOMEM);
190
191 mutex_init(&chip->tpm_mutex);
192 init_rwsem(&chip->ops_sem);
193
194 chip->ops = ops;
195
196 mutex_lock(&idr_lock);
197 rc = idr_alloc(&dev_nums_idr, NULL, 0, TPM_NUM_DEVICES, GFP_KERNEL);
198 mutex_unlock(&idr_lock);
199 if (rc < 0) {
200 dev_err(pdev, "No available tpm device numbers\n");
201 kfree(chip);
202 return ERR_PTR(rc);
203 }
204 chip->dev_num = rc;
205
206 device_initialize(&chip->dev);
207 device_initialize(&chip->devs);
208
209 chip->dev.class = tpm_class;
210 chip->dev.class->shutdown_pre = tpm_class_shutdown;
211 chip->dev.release = tpm_dev_release;
212 chip->dev.parent = pdev;
213 chip->dev.groups = chip->groups;
214
215 chip->devs.parent = pdev;
216 chip->devs.class = tpmrm_class;
217 chip->devs.release = tpm_devs_release;
218
219
220
221
222
223 if (chip->flags & TPM_CHIP_FLAG_TPM2)
224 get_device(&chip->dev);
225
226 if (chip->dev_num == 0)
227 chip->dev.devt = MKDEV(MISC_MAJOR, TPM_MINOR);
228 else
229 chip->dev.devt = MKDEV(MAJOR(tpm_devt), chip->dev_num);
230
231 chip->devs.devt =
232 MKDEV(MAJOR(tpm_devt), chip->dev_num + TPM_NUM_DEVICES);
233
234 rc = dev_set_name(&chip->dev, "tpm%d", chip->dev_num);
235 if (rc)
236 goto out;
237 rc = dev_set_name(&chip->devs, "tpmrm%d", chip->dev_num);
238 if (rc)
239 goto out;
240
241 if (!pdev)
242 chip->flags |= TPM_CHIP_FLAG_VIRTUAL;
243
244 cdev_init(&chip->cdev, &tpm_fops);
245 cdev_init(&chip->cdevs, &tpmrm_fops);
246 chip->cdev.owner = THIS_MODULE;
247 chip->cdevs.owner = THIS_MODULE;
248
249 chip->work_space.context_buf = kzalloc(PAGE_SIZE, GFP_KERNEL);
250 if (!chip->work_space.context_buf) {
251 rc = -ENOMEM;
252 goto out;
253 }
254 chip->work_space.session_buf = kzalloc(PAGE_SIZE, GFP_KERNEL);
255 if (!chip->work_space.session_buf) {
256 rc = -ENOMEM;
257 goto out;
258 }
259
260 chip->locality = -1;
261 return chip;
262
263out:
264 put_device(&chip->devs);
265 put_device(&chip->dev);
266 return ERR_PTR(rc);
267}
268EXPORT_SYMBOL_GPL(tpm_chip_alloc);
269
270
271
272
273
274
275
276
277struct tpm_chip *tpmm_chip_alloc(struct device *pdev,
278 const struct tpm_class_ops *ops)
279{
280 struct tpm_chip *chip;
281 int rc;
282
283 chip = tpm_chip_alloc(pdev, ops);
284 if (IS_ERR(chip))
285 return chip;
286
287 rc = devm_add_action_or_reset(pdev,
288 (void (*)(void *)) put_device,
289 &chip->dev);
290 if (rc)
291 return ERR_PTR(rc);
292
293 dev_set_drvdata(pdev, chip);
294
295 return chip;
296}
297EXPORT_SYMBOL_GPL(tpmm_chip_alloc);
298
299static int tpm_add_char_device(struct tpm_chip *chip)
300{
301 int rc;
302
303 rc = cdev_device_add(&chip->cdev, &chip->dev);
304 if (rc) {
305 dev_err(&chip->dev,
306 "unable to cdev_device_add() %s, major %d, minor %d, err=%d\n",
307 dev_name(&chip->dev), MAJOR(chip->dev.devt),
308 MINOR(chip->dev.devt), rc);
309 return rc;
310 }
311
312 if (chip->flags & TPM_CHIP_FLAG_TPM2) {
313 rc = cdev_device_add(&chip->cdevs, &chip->devs);
314 if (rc) {
315 dev_err(&chip->devs,
316 "unable to cdev_device_add() %s, major %d, minor %d, err=%d\n",
317 dev_name(&chip->devs), MAJOR(chip->devs.devt),
318 MINOR(chip->devs.devt), rc);
319 return rc;
320 }
321 }
322
323
324 mutex_lock(&idr_lock);
325 idr_replace(&dev_nums_idr, chip, chip->dev_num);
326 mutex_unlock(&idr_lock);
327
328 return rc;
329}
330
331static void tpm_del_char_device(struct tpm_chip *chip)
332{
333 cdev_device_del(&chip->cdev, &chip->dev);
334
335
336 mutex_lock(&idr_lock);
337 idr_replace(&dev_nums_idr, NULL, chip->dev_num);
338 mutex_unlock(&idr_lock);
339
340
341 down_write(&chip->ops_sem);
342 if (chip->flags & TPM_CHIP_FLAG_TPM2)
343 tpm2_shutdown(chip, TPM2_SU_CLEAR);
344 chip->ops = NULL;
345 up_write(&chip->ops_sem);
346}
347
348static void tpm_del_legacy_sysfs(struct tpm_chip *chip)
349{
350 struct attribute **i;
351
352 if (chip->flags & (TPM_CHIP_FLAG_TPM2 | TPM_CHIP_FLAG_VIRTUAL))
353 return;
354
355 sysfs_remove_link(&chip->dev.parent->kobj, "ppi");
356
357 for (i = chip->groups[0]->attrs; *i != NULL; ++i)
358 sysfs_remove_link(&chip->dev.parent->kobj, (*i)->name);
359}
360
361
362
363
364
365static int tpm_add_legacy_sysfs(struct tpm_chip *chip)
366{
367 struct attribute **i;
368 int rc;
369
370 if (chip->flags & (TPM_CHIP_FLAG_TPM2 | TPM_CHIP_FLAG_VIRTUAL))
371 return 0;
372
373 rc = __compat_only_sysfs_link_entry_to_kobj(
374 &chip->dev.parent->kobj, &chip->dev.kobj, "ppi");
375 if (rc && rc != -ENOENT)
376 return rc;
377
378
379 for (i = chip->groups[0]->attrs; *i != NULL; ++i) {
380 rc = __compat_only_sysfs_link_entry_to_kobj(
381 &chip->dev.parent->kobj, &chip->dev.kobj, (*i)->name);
382 if (rc) {
383 tpm_del_legacy_sysfs(chip);
384 return rc;
385 }
386 }
387
388 return 0;
389}
390
391
392
393
394
395
396
397
398
399
400
401int tpm_chip_register(struct tpm_chip *chip)
402{
403 int rc;
404
405 if (chip->ops->flags & TPM_OPS_AUTO_STARTUP) {
406 if (chip->flags & TPM_CHIP_FLAG_TPM2)
407 rc = tpm2_auto_startup(chip);
408 else
409 rc = tpm1_auto_startup(chip);
410 if (rc)
411 return rc;
412 }
413
414 tpm_sysfs_add_device(chip);
415
416 rc = tpm_bios_log_setup(chip);
417 if (rc != 0 && rc != -ENODEV)
418 return rc;
419
420 tpm_add_ppi(chip);
421
422 rc = tpm_add_char_device(chip);
423 if (rc) {
424 tpm_bios_log_teardown(chip);
425 return rc;
426 }
427
428 rc = tpm_add_legacy_sysfs(chip);
429 if (rc) {
430 tpm_chip_unregister(chip);
431 return rc;
432 }
433
434 return 0;
435}
436EXPORT_SYMBOL_GPL(tpm_chip_register);
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451void tpm_chip_unregister(struct tpm_chip *chip)
452{
453 tpm_del_legacy_sysfs(chip);
454 tpm_bios_log_teardown(chip);
455 if (chip->flags & TPM_CHIP_FLAG_TPM2)
456 cdev_device_del(&chip->cdevs, &chip->devs);
457 tpm_del_char_device(chip);
458}
459EXPORT_SYMBOL_GPL(tpm_chip_unregister);
460