Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

tpm: Enable hwrng only for Pluton on AMD CPUs

The vendor check introduced by commit 554b841d4703 ("tpm: Disable RNG for
all AMD fTPMs") doesn't work properly on a number of Intel fTPMs. On the
reported systems the TPM doesn't reply at bootup and returns back the
command code. This makes the TPM fail probe on Lenovo Legion Y540 laptop.

Since only Microsoft Pluton is the only known combination of AMD CPU and
fTPM from other vendor, disable hwrng otherwise. In order to make sysadmin
aware of this, print also info message to the klog.

Cc: stable@vger.kernel.org
Fixes: 554b841d4703 ("tpm: Disable RNG for all AMD fTPMs")
Reported-by: Todd Brandt <todd.e.brandt@intel.com>
Closes: https://bugzilla.kernel.org/show_bug.cgi?id=217804
Reported-by: Patrick Steinhardt <ps@pks.im>
Reported-by: Raymond Jay Golo <rjgolo@gmail.com>
Reported-by: Ronan Pigott <ronan@rjp.ie>
Reviewed-by: Jerry Snitselaar <jsnitsel@redhat.com>
Signed-off-by: Jarkko Sakkinen <jarkko@kernel.org>

+8 -25
+8 -25
drivers/char/tpm/tpm_crb.c
··· 463 463 return (cancel & CRB_CANCEL_INVOKE) == CRB_CANCEL_INVOKE; 464 464 } 465 465 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 - 488 466 static const struct tpm_class_ops tpm_crb = { 489 467 .flags = TPM_OPS_AUTO_STARTUP, 490 468 .status = crb_status, ··· 805 827 if (rc) 806 828 goto out; 807 829 808 - rc = crb_check_flags(chip); 809 - if (rc) 810 - goto out; 830 + #ifdef CONFIG_X86 831 + /* A quirk for https://www.amd.com/en/support/kb/faq/pa-410 */ 832 + if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD && 833 + priv->sm != ACPI_TPM2_COMMAND_BUFFER_WITH_PLUTON) { 834 + dev_info(dev, "Disabling hwrng\n"); 835 + chip->flags |= TPM_CHIP_FLAG_HWRNG_DISABLED; 836 + } 837 + #endif /* CONFIG_X86 */ 811 838 812 839 rc = tpm_chip_register(chip); 813 840