Skip to content

Commit 554b841

Browse files
superm1jarkkojs
authored andcommitted
tpm: Disable RNG for all AMD fTPMs
The TPM RNG functionality is not necessary for entropy when the CPU already supports the RDRAND instruction. The TPM RNG functionality was previously disabled on a subset of AMD fTPM series, but reports continue to show problems on some systems causing stutter root caused to TPM RNG functionality. Expand disabling TPM RNG use for all AMD fTPMs whether they have versions that claim to have fixed or not. To accomplish this, move the detection into part of the TPM CRB registration and add a flag indicating that the TPM should opt-out of registration to hwrng. Cc: [email protected] # 6.1.y+ Fixes: b006c43 ("hwrng: core - start hwrng kthread also for untrusted sources") Fixes: f1324bb ("tpm: disable hwrng for fTPM on some AMD designs") Reported-by: [email protected] Closes: https://bugzilla.kernel.org/show_bug.cgi?id=217719 Reported-by: [email protected] Closes: https://bugzilla.kernel.org/show_bug.cgi?id=217212 Signed-off-by: Mario Limonciello <[email protected]> Reviewed-by: Jarkko Sakkinen <[email protected]> Signed-off-by: Jarkko Sakkinen <[email protected]>
1 parent 0de030b commit 554b841

File tree

3 files changed

+33
-66
lines changed

3 files changed

+33
-66
lines changed

drivers/char/tpm/tpm-chip.c

Lines changed: 2 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -510,70 +510,6 @@ static int tpm_add_legacy_sysfs(struct tpm_chip *chip)
510510
return 0;
511511
}
512512

513-
/*
514-
* Some AMD fTPM versions may cause stutter
515-
* https://www.amd.com/en/support/kb/faq/pa-410
516-
*
517-
* Fixes are available in two series of fTPM firmware:
518-
* 6.x.y.z series: 6.0.18.6 +
519-
* 3.x.y.z series: 3.57.y.5 +
520-
*/
521-
#ifdef CONFIG_X86
522-
static bool tpm_amd_is_rng_defective(struct tpm_chip *chip)
523-
{
524-
u32 val1, val2;
525-
u64 version;
526-
int ret;
527-
528-
if (!(chip->flags & TPM_CHIP_FLAG_TPM2))
529-
return false;
530-
531-
ret = tpm_request_locality(chip);
532-
if (ret)
533-
return false;
534-
535-
ret = tpm2_get_tpm_pt(chip, TPM2_PT_MANUFACTURER, &val1, NULL);
536-
if (ret)
537-
goto release;
538-
if (val1 != 0x414D4400U /* AMD */) {
539-
ret = -ENODEV;
540-
goto release;
541-
}
542-
ret = tpm2_get_tpm_pt(chip, TPM2_PT_FIRMWARE_VERSION_1, &val1, NULL);
543-
if (ret)
544-
goto release;
545-
ret = tpm2_get_tpm_pt(chip, TPM2_PT_FIRMWARE_VERSION_2, &val2, NULL);
546-
547-
release:
548-
tpm_relinquish_locality(chip);
549-
550-
if (ret)
551-
return false;
552-
553-
version = ((u64)val1 << 32) | val2;
554-
if ((version >> 48) == 6) {
555-
if (version >= 0x0006000000180006ULL)
556-
return false;
557-
} else if ((version >> 48) == 3) {
558-
if (version >= 0x0003005700000005ULL)
559-
return false;
560-
} else {
561-
return false;
562-
}
563-
564-
dev_warn(&chip->dev,
565-
"AMD fTPM version 0x%llx causes system stutter; hwrng disabled\n",
566-
version);
567-
568-
return true;
569-
}
570-
#else
571-
static inline bool tpm_amd_is_rng_defective(struct tpm_chip *chip)
572-
{
573-
return false;
574-
}
575-
#endif /* CONFIG_X86 */
576-
577513
static int tpm_hwrng_read(struct hwrng *rng, void *data, size_t max, bool wait)
578514
{
579515
struct tpm_chip *chip = container_of(rng, struct tpm_chip, hwrng);
@@ -588,7 +524,7 @@ static int tpm_hwrng_read(struct hwrng *rng, void *data, size_t max, bool wait)
588524
static int tpm_add_hwrng(struct tpm_chip *chip)
589525
{
590526
if (!IS_ENABLED(CONFIG_HW_RANDOM_TPM) || tpm_is_firmware_upgrade(chip) ||
591-
tpm_amd_is_rng_defective(chip))
527+
chip->flags & TPM_CHIP_FLAG_HWRNG_DISABLED)
592528
return 0;
593529

594530
snprintf(chip->hwrng_name, sizeof(chip->hwrng_name),
@@ -719,7 +655,7 @@ void tpm_chip_unregister(struct tpm_chip *chip)
719655
{
720656
tpm_del_legacy_sysfs(chip);
721657
if (IS_ENABLED(CONFIG_HW_RANDOM_TPM) && !tpm_is_firmware_upgrade(chip) &&
722-
!tpm_amd_is_rng_defective(chip))
658+
!(chip->flags & TPM_CHIP_FLAG_HWRNG_DISABLED))
723659
hwrng_unregister(&chip->hwrng);
724660
tpm_bios_log_teardown(chip);
725661
if (chip->flags & TPM_CHIP_FLAG_TPM2 && !tpm_is_firmware_upgrade(chip))

drivers/char/tpm/tpm_crb.c

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -463,6 +463,28 @@ static bool crb_req_canceled(struct tpm_chip *chip, u8 status)
463463
return (cancel & CRB_CANCEL_INVOKE) == CRB_CANCEL_INVOKE;
464464
}
465465

466+
static int crb_check_flags(struct tpm_chip *chip)
467+
{
468+
u32 val;
469+
int ret;
470+
471+
ret = crb_request_locality(chip, 0);
472+
if (ret)
473+
return ret;
474+
475+
ret = tpm2_get_tpm_pt(chip, TPM2_PT_MANUFACTURER, &val, NULL);
476+
if (ret)
477+
goto release;
478+
479+
if (val == 0x414D4400U /* AMD */)
480+
chip->flags |= TPM_CHIP_FLAG_HWRNG_DISABLED;
481+
482+
release:
483+
crb_relinquish_locality(chip, 0);
484+
485+
return ret;
486+
}
487+
466488
static const struct tpm_class_ops tpm_crb = {
467489
.flags = TPM_OPS_AUTO_STARTUP,
468490
.status = crb_status,
@@ -800,6 +822,14 @@ static int crb_acpi_add(struct acpi_device *device)
800822
chip->acpi_dev_handle = device->handle;
801823
chip->flags = TPM_CHIP_FLAG_TPM2;
802824

825+
rc = tpm_chip_bootstrap(chip);
826+
if (rc)
827+
goto out;
828+
829+
rc = crb_check_flags(chip);
830+
if (rc)
831+
goto out;
832+
803833
rc = tpm_chip_register(chip);
804834

805835
out:

include/linux/tpm.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -283,6 +283,7 @@ enum tpm_chip_flags {
283283
TPM_CHIP_FLAG_FIRMWARE_POWER_MANAGED = BIT(6),
284284
TPM_CHIP_FLAG_FIRMWARE_UPGRADE = BIT(7),
285285
TPM_CHIP_FLAG_SUSPENDED = BIT(8),
286+
TPM_CHIP_FLAG_HWRNG_DISABLED = BIT(9),
286287
};
287288

288289
#define to_tpm_chip(d) container_of(d, struct tpm_chip, dev)

0 commit comments

Comments
 (0)