Commit 8043e222 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull tpm fixes from Jarkko Sakkinen:
 "A few more bug fixes"

* tag 'tpmdd-v6.5-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/jarkko/linux-tpmdd:
  tpm/tpm_tis: Disable interrupts for Lenovo P620 devices
  tpm: Disable RNG for all AMD fTPMs
  sysctl: set variable key_sysctls storage-class-specifier to static
  tpm/tpm_tis: Disable interrupts for TUXEDO InfinityBook S 15/17 Gen7
parents a027b2ec e117e7ad
Loading
Loading
Loading
Loading
+2 −66
Original line number Diff line number Diff line
@@ -510,70 +510,6 @@ 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)
{
	u32 val1, val2;
	u64 version;
	int ret;

	if (!(chip->flags & TPM_CHIP_FLAG_TPM2))
		return false;

	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 {
		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)
{
	return false;
}
#endif /* CONFIG_X86 */

static int tpm_hwrng_read(struct hwrng *rng, void *data, size_t max, bool wait)
{
	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)
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))
	    chip->flags & TPM_CHIP_FLAG_HWRNG_DISABLED)
		return 0;

	snprintf(chip->hwrng_name, sizeof(chip->hwrng_name),
@@ -719,7 +655,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))
	    !(chip->flags & TPM_CHIP_FLAG_HWRNG_DISABLED))
		hwrng_unregister(&chip->hwrng);
	tpm_bios_log_teardown(chip);
	if (chip->flags & TPM_CHIP_FLAG_TPM2 && !tpm_is_firmware_upgrade(chip))
+30 −0
Original line number Diff line number Diff line
@@ -463,6 +463,28 @@ static bool crb_req_canceled(struct tpm_chip *chip, u8 status)
	return (cancel & CRB_CANCEL_INVOKE) == CRB_CANCEL_INVOKE;
}

static int crb_check_flags(struct tpm_chip *chip)
{
	u32 val;
	int ret;

	ret = crb_request_locality(chip, 0);
	if (ret)
		return ret;

	ret = tpm2_get_tpm_pt(chip, TPM2_PT_MANUFACTURER, &val, NULL);
	if (ret)
		goto release;

	if (val == 0x414D4400U /* AMD */)
		chip->flags |= TPM_CHIP_FLAG_HWRNG_DISABLED;

release:
	crb_relinquish_locality(chip, 0);

	return ret;
}

static const struct tpm_class_ops tpm_crb = {
	.flags = TPM_OPS_AUTO_STARTUP,
	.status = crb_status,
@@ -800,6 +822,14 @@ static int crb_acpi_add(struct acpi_device *device)
	chip->acpi_dev_handle = device->handle;
	chip->flags = TPM_CHIP_FLAG_TPM2;

	rc = tpm_chip_bootstrap(chip);
	if (rc)
		goto out;

	rc = crb_check_flags(chip);
	if (rc)
		goto out;

	rc = tpm_chip_register(chip);

out:
+16 −0
Original line number Diff line number Diff line
@@ -162,6 +162,22 @@ static const struct dmi_system_id tpm_tis_dmi_table[] = {
			DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad L590"),
		},
	},
	{
		.callback = tpm_tis_disable_irq,
		.ident = "ThinkStation P620",
		.matches = {
			DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
			DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkStation P620"),
		},
	},
	{
		.callback = tpm_tis_disable_irq,
		.ident = "TUXEDO InfinityBook S 15/17 Gen7",
		.matches = {
			DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"),
			DMI_MATCH(DMI_PRODUCT_NAME, "TUXEDO InfinityBook S 15/17 Gen7"),
		},
	},
	{
		.callback = tpm_tis_disable_irq,
		.ident = "UPX-TGL",
+1 −0
Original line number Diff line number Diff line
@@ -283,6 +283,7 @@ enum tpm_chip_flags {
	TPM_CHIP_FLAG_FIRMWARE_POWER_MANAGED	= BIT(6),
	TPM_CHIP_FLAG_FIRMWARE_UPGRADE		= BIT(7),
	TPM_CHIP_FLAG_SUSPENDED			= BIT(8),
	TPM_CHIP_FLAG_HWRNG_DISABLED		= BIT(9),
};

#define to_tpm_chip(d) container_of(d, struct tpm_chip, dev)
+1 −1
Original line number Diff line number Diff line
@@ -9,7 +9,7 @@
#include <linux/sysctl.h>
#include "internal.h"

struct ctl_table key_sysctls[] = {
static struct ctl_table key_sysctls[] = {
	{
		.procname = "maxkeys",
		.data = &key_quota_maxkeys,