Commit 99d46450 authored by Jarkko Sakkinen's avatar Jarkko Sakkinen
Browse files

tpm: Prevent hwrng from activating during resume



Set TPM_CHIP_FLAG_SUSPENDED in tpm_pm_suspend() and reset in
tpm_pm_resume(). While the flag is set, tpm_hwrng() gives back zero
bytes. This prevents hwrng from racing during resume.

Cc: stable@vger.kernel.org
Fixes: 6e592a06 ("tpm: Move Linux RNG connection to hwrng")
Reviewed-by: default avatarJerry Snitselaar <jsnitsel@redhat.com>
Signed-off-by: default avatarJarkko Sakkinen <jarkko@kernel.org>
parent 1398aa80
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -571,6 +571,10 @@ 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);

	/* Give back zero bytes, as TPM chip has not yet fully resumed: */
	if (chip->flags & TPM_CHIP_FLAG_SUSPENDED)
		return 0;

	return tpm_get_random(chip, data, max);
}

+10 −0
Original line number Diff line number Diff line
@@ -412,6 +412,8 @@ int tpm_pm_suspend(struct device *dev)
	}

suspended:
	chip->flags |= TPM_CHIP_FLAG_SUSPENDED;

	if (rc)
		dev_err(dev, "Ignoring error %d while suspending\n", rc);
	return 0;
@@ -429,6 +431,14 @@ int tpm_pm_resume(struct device *dev)
	if (chip == NULL)
		return -ENODEV;

	chip->flags &= ~TPM_CHIP_FLAG_SUSPENDED;

	/*
	 * Guarantee that SUSPENDED is written last, so that hwrng does not
	 * activate before the chip has been fully resumed.
	 */
	wmb();

	return 0;
}
EXPORT_SYMBOL_GPL(tpm_pm_resume);
+1 −0
Original line number Diff line number Diff line
@@ -282,6 +282,7 @@ enum tpm_chip_flags {
	TPM_CHIP_FLAG_ALWAYS_POWERED		= BIT(5),
	TPM_CHIP_FLAG_FIRMWARE_POWER_MANAGED	= BIT(6),
	TPM_CHIP_FLAG_FIRMWARE_UPGRADE		= BIT(7),
	TPM_CHIP_FLAG_SUSPENDED			= BIT(8),
};

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