From 9f41d3037e37d91d5aaf14208ba43ba76a76031f Mon Sep 17 00:00:00 2001 From: Mario Limonciello Date: Mon, 31 Jul 2023 21:30:13 -0500 Subject: [PATCH] tpm: Disable RNG for fTPMs on SOCs that support RDRAND/RDSEED The TPM RNG functionality is not necessary for entropy when the CPU already supports dedicated instructions for RNG. Furthermore it continues to show problems on some systems causing stutter. Cc: stable@vger.kernel.org # 6.1.y+ Fixes: b006c439d58d ("hwrng: core - start hwrng kthread also for untrusted sources") Reported-by: daniil.stas@posteo.net Closes: https://bugzilla.kernel.org/show_bug.cgi?id=217719 Signed-off-by: Mario Limonciello --- drivers/char/tpm/tpm-chip.c | 53 ++++++++----------------------------- 1 file changed, 11 insertions(+), 42 deletions(-) diff --git a/drivers/char/tpm/tpm-chip.c b/drivers/char/tpm/tpm-chip.c index cf5499e51999b..ac39ed8c9704a 100644 --- a/drivers/char/tpm/tpm-chip.c +++ b/drivers/char/tpm/tpm-chip.c @@ -510,19 +510,10 @@ static int tpm_add_legacy_sysfs(struct tpm_chip *chip) return 0; } -/* - * Some AMD fTPM versions may cause stutter - * https://www.amd.com/en/support/kb/faq/pa-410 - * - * Fixes are available in two series of fTPM firmware: - * 6.x.y.z series: 6.0.18.6 + - * 3.x.y.z series: 3.57.y.5 + - */ #ifdef CONFIG_X86 -static bool tpm_amd_is_rng_defective(struct tpm_chip *chip) +static bool tpm_skip_rng(struct tpm_chip *chip) { - u32 val1, val2; - u64 version; + u32 val1; int ret; if (!(chip->flags & TPM_CHIP_FLAG_TPM2)) @@ -531,44 +522,22 @@ static bool tpm_amd_is_rng_defective(struct tpm_chip *chip) ret = tpm_request_locality(chip); if (ret) return false; - ret = tpm2_get_tpm_pt(chip, TPM2_PT_MANUFACTURER, &val1, NULL); - if (ret) - goto release; - if (val1 != 0x414D4400U /* AMD */) { - ret = -ENODEV; - goto release; - } - ret = tpm2_get_tpm_pt(chip, TPM2_PT_FIRMWARE_VERSION_1, &val1, NULL); - if (ret) - goto release; - ret = tpm2_get_tpm_pt(chip, TPM2_PT_FIRMWARE_VERSION_2, &val2, NULL); - -release: tpm_relinquish_locality(chip); - if (ret) return false; - version = ((u64)val1 << 32) | val2; - if ((version >> 48) == 6) { - if (version >= 0x0006000000180006ULL) - return false; - } else if ((version >> 48) == 3) { - if (version >= 0x0003005700000005ULL) - return false; - } else { + /* if CPU supports RDRAND/RDSEED ignore fTPM for RNG */ + switch (val1) { + case 0x414D4400U: /* AMD */ + case 0x494E5443U: /* INTC */ + return boot_cpu_has(X86_FEATURE_RDRAND) || boot_cpu_has(X86_FEATURE_RDSEED); + default: return false; } - - dev_warn(&chip->dev, - "AMD fTPM version 0x%llx causes system stutter; hwrng disabled\n", - version); - - return true; } #else -static inline bool tpm_amd_is_rng_defective(struct tpm_chip *chip) +static inline bool tpm_skip_rng(struct tpm_chip *chip) { return false; } @@ -588,7 +557,7 @@ static int tpm_hwrng_read(struct hwrng *rng, void *data, size_t max, bool wait) static int tpm_add_hwrng(struct tpm_chip *chip) { if (!IS_ENABLED(CONFIG_HW_RANDOM_TPM) || tpm_is_firmware_upgrade(chip) || - tpm_amd_is_rng_defective(chip)) + tpm_skip_rng(chip)) return 0; snprintf(chip->hwrng_name, sizeof(chip->hwrng_name), @@ -719,7 +688,7 @@ void tpm_chip_unregister(struct tpm_chip *chip) { tpm_del_legacy_sysfs(chip); if (IS_ENABLED(CONFIG_HW_RANDOM_TPM) && !tpm_is_firmware_upgrade(chip) && - !tpm_amd_is_rng_defective(chip)) + !tpm_skip_rng(chip)) hwrng_unregister(&chip->hwrng); tpm_bios_log_teardown(chip); if (chip->flags & TPM_CHIP_FLAG_TPM2 && !tpm_is_firmware_upgrade(chip)) -- 2.34.1