.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
---|
1 | 2 | /* |
---|
2 | 3 | * Copyright (C) 2005, 2006 IBM Corporation |
---|
3 | 4 | * Copyright (C) 2014, 2015 Intel Corporation |
---|
.. | .. |
---|
13 | 14 | * |
---|
14 | 15 | * This device driver implements the TPM interface as defined in |
---|
15 | 16 | * the TCG TPM Interface Spec version 1.2, revision 1.0. |
---|
16 | | - * |
---|
17 | | - * This program is free software; you can redistribute it and/or |
---|
18 | | - * modify it under the terms of the GNU General Public License as |
---|
19 | | - * published by the Free Software Foundation, version 2 of the |
---|
20 | | - * License. |
---|
21 | 17 | */ |
---|
22 | 18 | #include <linux/init.h> |
---|
23 | 19 | #include <linux/module.h> |
---|
.. | .. |
---|
52 | 48 | unsigned long timeout, wait_queue_head_t *queue, |
---|
53 | 49 | bool check_cancel) |
---|
54 | 50 | { |
---|
| 51 | + struct tpm_tis_data *priv = dev_get_drvdata(&chip->dev); |
---|
55 | 52 | unsigned long stop; |
---|
56 | 53 | long rc; |
---|
57 | 54 | u8 status; |
---|
.. | .. |
---|
84 | 81 | } |
---|
85 | 82 | } else { |
---|
86 | 83 | do { |
---|
87 | | - usleep_range(TPM_TIMEOUT_USECS_MIN, |
---|
88 | | - TPM_TIMEOUT_USECS_MAX); |
---|
| 84 | + usleep_range(priv->timeout_min, |
---|
| 85 | + priv->timeout_max); |
---|
89 | 86 | status = chip->ops->status(chip); |
---|
90 | 87 | if ((status & mask) == mask) |
---|
91 | 88 | return 0; |
---|
.. | .. |
---|
198 | 195 | rc = tpm_tis_read8(priv, TPM_STS(priv->locality), &status); |
---|
199 | 196 | if (rc < 0) |
---|
200 | 197 | return 0; |
---|
| 198 | + |
---|
| 199 | + if (unlikely((status & TPM_STS_READ_ZERO) != 0)) { |
---|
| 200 | + if (!test_and_set_bit(TPM_TIS_INVALID_STATUS, &priv->flags)) { |
---|
| 201 | + /* |
---|
| 202 | + * If this trips, the chances are the read is |
---|
| 203 | + * returning 0xff because the locality hasn't been |
---|
| 204 | + * acquired. Usually because tpm_try_get_ops() hasn't |
---|
| 205 | + * been called before doing a TPM operation. |
---|
| 206 | + */ |
---|
| 207 | + dev_err(&chip->dev, "invalid TPM_STS.x 0x%02x, dumping stack for forensics\n", |
---|
| 208 | + status); |
---|
| 209 | + |
---|
| 210 | + /* |
---|
| 211 | + * Dump stack for forensics, as invalid TPM_STS.x could be |
---|
| 212 | + * potentially triggered by impaired tpm_try_get_ops() or |
---|
| 213 | + * tpm_find_get_ops(). |
---|
| 214 | + */ |
---|
| 215 | + dump_stack(); |
---|
| 216 | + } |
---|
| 217 | + |
---|
| 218 | + return 0; |
---|
| 219 | + } |
---|
201 | 220 | |
---|
202 | 221 | return status; |
---|
203 | 222 | } |
---|
.. | .. |
---|
432 | 451 | if (chip->flags & TPM_CHIP_FLAG_IRQ) { |
---|
433 | 452 | ordinal = be32_to_cpu(*((__be32 *) (buf + 6))); |
---|
434 | 453 | |
---|
435 | | - if (chip->flags & TPM_CHIP_FLAG_TPM2) |
---|
436 | | - dur = tpm2_calc_ordinal_duration(chip, ordinal); |
---|
437 | | - else |
---|
438 | | - dur = tpm_calc_ordinal_duration(chip, ordinal); |
---|
439 | | - |
---|
| 454 | + dur = tpm_calc_ordinal_duration(chip, ordinal); |
---|
440 | 455 | if (wait_for_tpm_stat |
---|
441 | 456 | (chip, TPM_STS_DATA_AVAIL | TPM_STS_VALID, dur, |
---|
442 | 457 | &priv->read_queue, false) < 0) { |
---|
.. | .. |
---|
473 | 488 | return rc; |
---|
474 | 489 | } |
---|
475 | 490 | |
---|
| 491 | +struct tis_vendor_durations_override { |
---|
| 492 | + u32 did_vid; |
---|
| 493 | + struct tpm1_version version; |
---|
| 494 | + unsigned long durations[3]; |
---|
| 495 | +}; |
---|
| 496 | + |
---|
| 497 | +static const struct tis_vendor_durations_override vendor_dur_overrides[] = { |
---|
| 498 | + /* STMicroelectronics 0x104a */ |
---|
| 499 | + { 0x0000104a, |
---|
| 500 | + { 1, 2, 8, 28 }, |
---|
| 501 | + { (2 * 60 * HZ), (2 * 60 * HZ), (2 * 60 * HZ) } }, |
---|
| 502 | +}; |
---|
| 503 | + |
---|
| 504 | +static void tpm_tis_update_durations(struct tpm_chip *chip, |
---|
| 505 | + unsigned long *duration_cap) |
---|
| 506 | +{ |
---|
| 507 | + struct tpm_tis_data *priv = dev_get_drvdata(&chip->dev); |
---|
| 508 | + struct tpm1_version *version; |
---|
| 509 | + u32 did_vid; |
---|
| 510 | + int i, rc; |
---|
| 511 | + cap_t cap; |
---|
| 512 | + |
---|
| 513 | + chip->duration_adjusted = false; |
---|
| 514 | + |
---|
| 515 | + if (chip->ops->clk_enable != NULL) |
---|
| 516 | + chip->ops->clk_enable(chip, true); |
---|
| 517 | + |
---|
| 518 | + rc = tpm_tis_read32(priv, TPM_DID_VID(0), &did_vid); |
---|
| 519 | + if (rc < 0) { |
---|
| 520 | + dev_warn(&chip->dev, "%s: failed to read did_vid. %d\n", |
---|
| 521 | + __func__, rc); |
---|
| 522 | + goto out; |
---|
| 523 | + } |
---|
| 524 | + |
---|
| 525 | + /* Try to get a TPM version 1.2 or 1.1 TPM_CAP_VERSION_INFO */ |
---|
| 526 | + rc = tpm1_getcap(chip, TPM_CAP_VERSION_1_2, &cap, |
---|
| 527 | + "attempting to determine the 1.2 version", |
---|
| 528 | + sizeof(cap.version2)); |
---|
| 529 | + if (!rc) { |
---|
| 530 | + version = &cap.version2.version; |
---|
| 531 | + } else { |
---|
| 532 | + rc = tpm1_getcap(chip, TPM_CAP_VERSION_1_1, &cap, |
---|
| 533 | + "attempting to determine the 1.1 version", |
---|
| 534 | + sizeof(cap.version1)); |
---|
| 535 | + |
---|
| 536 | + if (rc) |
---|
| 537 | + goto out; |
---|
| 538 | + |
---|
| 539 | + version = &cap.version1; |
---|
| 540 | + } |
---|
| 541 | + |
---|
| 542 | + for (i = 0; i != ARRAY_SIZE(vendor_dur_overrides); i++) { |
---|
| 543 | + if (vendor_dur_overrides[i].did_vid != did_vid) |
---|
| 544 | + continue; |
---|
| 545 | + |
---|
| 546 | + if ((version->major == |
---|
| 547 | + vendor_dur_overrides[i].version.major) && |
---|
| 548 | + (version->minor == |
---|
| 549 | + vendor_dur_overrides[i].version.minor) && |
---|
| 550 | + (version->rev_major == |
---|
| 551 | + vendor_dur_overrides[i].version.rev_major) && |
---|
| 552 | + (version->rev_minor == |
---|
| 553 | + vendor_dur_overrides[i].version.rev_minor)) { |
---|
| 554 | + |
---|
| 555 | + memcpy(duration_cap, |
---|
| 556 | + vendor_dur_overrides[i].durations, |
---|
| 557 | + sizeof(vendor_dur_overrides[i].durations)); |
---|
| 558 | + |
---|
| 559 | + chip->duration_adjusted = true; |
---|
| 560 | + goto out; |
---|
| 561 | + } |
---|
| 562 | + } |
---|
| 563 | + |
---|
| 564 | +out: |
---|
| 565 | + if (chip->ops->clk_enable != NULL) |
---|
| 566 | + chip->ops->clk_enable(chip, false); |
---|
| 567 | +} |
---|
| 568 | + |
---|
476 | 569 | struct tis_vendor_timeout_override { |
---|
477 | 570 | u32 did_vid; |
---|
478 | 571 | unsigned long timeout_us[4]; |
---|
.. | .. |
---|
484 | 577 | (TIS_SHORT_TIMEOUT*1000), (TIS_SHORT_TIMEOUT*1000) } }, |
---|
485 | 578 | }; |
---|
486 | 579 | |
---|
487 | | -static bool tpm_tis_update_timeouts(struct tpm_chip *chip, |
---|
| 580 | +static void tpm_tis_update_timeouts(struct tpm_chip *chip, |
---|
488 | 581 | unsigned long *timeout_cap) |
---|
489 | 582 | { |
---|
490 | 583 | struct tpm_tis_data *priv = dev_get_drvdata(&chip->dev); |
---|
491 | 584 | int i, rc; |
---|
492 | 585 | u32 did_vid; |
---|
493 | 586 | |
---|
| 587 | + chip->timeout_adjusted = false; |
---|
| 588 | + |
---|
494 | 589 | if (chip->ops->clk_enable != NULL) |
---|
495 | 590 | chip->ops->clk_enable(chip, true); |
---|
496 | 591 | |
---|
497 | 592 | rc = tpm_tis_read32(priv, TPM_DID_VID(0), &did_vid); |
---|
498 | | - if (rc < 0) |
---|
| 593 | + if (rc < 0) { |
---|
| 594 | + dev_warn(&chip->dev, "%s: failed to read did_vid: %d\n", |
---|
| 595 | + __func__, rc); |
---|
499 | 596 | goto out; |
---|
| 597 | + } |
---|
500 | 598 | |
---|
501 | 599 | for (i = 0; i != ARRAY_SIZE(vendor_timeout_overrides); i++) { |
---|
502 | 600 | if (vendor_timeout_overrides[i].did_vid != did_vid) |
---|
503 | 601 | continue; |
---|
504 | 602 | memcpy(timeout_cap, vendor_timeout_overrides[i].timeout_us, |
---|
505 | 603 | sizeof(vendor_timeout_overrides[i].timeout_us)); |
---|
506 | | - rc = true; |
---|
| 604 | + chip->timeout_adjusted = true; |
---|
507 | 605 | } |
---|
508 | | - |
---|
509 | | - rc = false; |
---|
510 | 606 | |
---|
511 | 607 | out: |
---|
512 | 608 | if (chip->ops->clk_enable != NULL) |
---|
513 | 609 | chip->ops->clk_enable(chip, false); |
---|
514 | 610 | |
---|
515 | | - return rc; |
---|
| 611 | + return; |
---|
516 | 612 | } |
---|
517 | 613 | |
---|
518 | 614 | /* |
---|
.. | .. |
---|
623 | 719 | const char *desc = "attempting to generate an interrupt"; |
---|
624 | 720 | u32 cap2; |
---|
625 | 721 | cap_t cap; |
---|
| 722 | + int ret; |
---|
| 723 | + |
---|
| 724 | + ret = request_locality(chip, 0); |
---|
| 725 | + if (ret < 0) |
---|
| 726 | + return ret; |
---|
626 | 727 | |
---|
627 | 728 | if (chip->flags & TPM_CHIP_FLAG_TPM2) |
---|
628 | | - return tpm2_get_tpm_pt(chip, 0x100, &cap2, desc); |
---|
| 729 | + ret = tpm2_get_tpm_pt(chip, 0x100, &cap2, desc); |
---|
629 | 730 | else |
---|
630 | | - return tpm_getcap(chip, TPM_CAP_PROP_TIS_TIMEOUT, &cap, desc, |
---|
631 | | - 0); |
---|
| 731 | + ret = tpm1_getcap(chip, TPM_CAP_PROP_TIS_TIMEOUT, &cap, desc, 0); |
---|
| 732 | + |
---|
| 733 | + release_locality(chip, 0); |
---|
| 734 | + |
---|
| 735 | + return ret; |
---|
632 | 736 | } |
---|
633 | 737 | |
---|
634 | 738 | /* Register the IRQ and issue a command that will cause an interrupt. If an |
---|
.. | .. |
---|
806 | 910 | .send = tpm_tis_send, |
---|
807 | 911 | .cancel = tpm_tis_ready, |
---|
808 | 912 | .update_timeouts = tpm_tis_update_timeouts, |
---|
| 913 | + .update_durations = tpm_tis_update_durations, |
---|
809 | 914 | .req_complete_mask = TPM_STS_DATA_AVAIL | TPM_STS_VALID, |
---|
810 | 915 | .req_complete_val = TPM_STS_DATA_AVAIL | TPM_STS_VALID, |
---|
811 | 916 | .req_canceled = tpm_tis_req_canceled, |
---|
.. | .. |
---|
841 | 946 | chip->timeout_b = msecs_to_jiffies(TIS_TIMEOUT_B_MAX); |
---|
842 | 947 | chip->timeout_c = msecs_to_jiffies(TIS_TIMEOUT_C_MAX); |
---|
843 | 948 | chip->timeout_d = msecs_to_jiffies(TIS_TIMEOUT_D_MAX); |
---|
| 949 | + priv->timeout_min = TPM_TIMEOUT_USECS_MIN; |
---|
| 950 | + priv->timeout_max = TPM_TIMEOUT_USECS_MAX; |
---|
844 | 951 | priv->phy_ops = phy_ops; |
---|
| 952 | + |
---|
845 | 953 | dev_set_drvdata(&chip->dev, priv); |
---|
| 954 | + |
---|
| 955 | + rc = tpm_tis_read32(priv, TPM_DID_VID(0), &vendor); |
---|
| 956 | + if (rc < 0) |
---|
| 957 | + return rc; |
---|
| 958 | + |
---|
| 959 | + priv->manufacturer_id = vendor; |
---|
| 960 | + |
---|
| 961 | + if (priv->manufacturer_id == TPM_VID_ATML && |
---|
| 962 | + !(chip->flags & TPM_CHIP_FLAG_TPM2)) { |
---|
| 963 | + priv->timeout_min = TIS_TIMEOUT_MIN_ATML; |
---|
| 964 | + priv->timeout_max = TIS_TIMEOUT_MAX_ATML; |
---|
| 965 | + } |
---|
846 | 966 | |
---|
847 | 967 | if (is_bsw()) { |
---|
848 | 968 | priv->ilb_base_addr = ioremap(INTEL_LEGACY_BLK_BASE_ADDR, |
---|
.. | .. |
---|
884 | 1004 | tpm_tis_write32(priv, TPM_INT_ENABLE(priv->locality), intmask); |
---|
885 | 1005 | release_locality(chip, 0); |
---|
886 | 1006 | |
---|
887 | | - rc = tpm2_probe(chip); |
---|
| 1007 | + rc = tpm_chip_start(chip); |
---|
888 | 1008 | if (rc) |
---|
889 | 1009 | goto out_err; |
---|
890 | | - |
---|
891 | | - rc = tpm_tis_read32(priv, TPM_DID_VID(0), &vendor); |
---|
892 | | - if (rc < 0) |
---|
| 1010 | + rc = tpm2_probe(chip); |
---|
| 1011 | + tpm_chip_stop(chip); |
---|
| 1012 | + if (rc) |
---|
893 | 1013 | goto out_err; |
---|
894 | | - |
---|
895 | | - priv->manufacturer_id = vendor; |
---|
896 | 1014 | |
---|
897 | 1015 | rc = tpm_tis_read8(priv, TPM_RID(0), &rid); |
---|
898 | 1016 | if (rc < 0) |
---|
.. | .. |
---|
938 | 1056 | init_waitqueue_head(&priv->read_queue); |
---|
939 | 1057 | init_waitqueue_head(&priv->int_queue); |
---|
940 | 1058 | if (irq != -1) { |
---|
941 | | - /* Before doing irq testing issue a command to the TPM in polling mode |
---|
| 1059 | + /* |
---|
| 1060 | + * Before doing irq testing issue a command to the TPM in polling mode |
---|
942 | 1061 | * to make sure it works. May as well use that command to set the |
---|
943 | 1062 | * proper timeouts for the driver. |
---|
944 | 1063 | */ |
---|
945 | | - if (tpm_get_timeouts(chip)) { |
---|
| 1064 | + |
---|
| 1065 | + rc = request_locality(chip, 0); |
---|
| 1066 | + if (rc < 0) |
---|
| 1067 | + goto out_err; |
---|
| 1068 | + |
---|
| 1069 | + rc = tpm_get_timeouts(chip); |
---|
| 1070 | + |
---|
| 1071 | + release_locality(chip, 0); |
---|
| 1072 | + |
---|
| 1073 | + if (rc) { |
---|
946 | 1074 | dev_err(dev, "Could not get TPM timeouts and durations\n"); |
---|
947 | 1075 | rc = -ENODEV; |
---|
948 | 1076 | goto out_err; |
---|
.. | .. |
---|
1026 | 1154 | if (ret) |
---|
1027 | 1155 | return ret; |
---|
1028 | 1156 | |
---|
1029 | | - /* TPM 1.2 requires self-test on resume. This function actually returns |
---|
| 1157 | + /* |
---|
| 1158 | + * TPM 1.2 requires self-test on resume. This function actually returns |
---|
1030 | 1159 | * an error code but for unknown reason it isn't handled. |
---|
1031 | 1160 | */ |
---|
1032 | | - if (!(chip->flags & TPM_CHIP_FLAG_TPM2)) |
---|
1033 | | - tpm_do_selftest(chip); |
---|
| 1161 | + if (!(chip->flags & TPM_CHIP_FLAG_TPM2)) { |
---|
| 1162 | + ret = request_locality(chip, 0); |
---|
| 1163 | + if (ret < 0) |
---|
| 1164 | + return ret; |
---|
| 1165 | + |
---|
| 1166 | + tpm1_do_selftest(chip); |
---|
| 1167 | + |
---|
| 1168 | + release_locality(chip, 0); |
---|
| 1169 | + } |
---|
1034 | 1170 | |
---|
1035 | 1171 | return 0; |
---|
1036 | 1172 | } |
---|