Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 58bac8cc authored by Jarkko Sakkinen's avatar Jarkko Sakkinen
Browse files

tpm: replace TPM_TRANSMIT_RAW with TPM_TRANSMIT_NESTED



As TPM_TRANSMIT_RAW always requires also not to take locks for obvious
reasons (deadlock), this commit renames the flag as TPM_TRANSMIT_NESTED
and prevents taking tpm_mutex when the flag is given to tpm_transmit().

Suggested-by: default avatarTomas Winkler <tomas.winkler@intel.com>
Signed-off-by: default avatarJarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
parent eccc9bb8
Loading
Loading
Loading
Loading
+6 −7
Original line number Diff line number Diff line
@@ -372,7 +372,7 @@ static int tpm_request_locality(struct tpm_chip *chip, unsigned int flags)
{
	int rc;

	if (flags & TPM_TRANSMIT_RAW)
	if (flags & TPM_TRANSMIT_NESTED)
		return 0;

	if (!chip->ops->request_locality)
@@ -391,7 +391,7 @@ static void tpm_relinquish_locality(struct tpm_chip *chip, unsigned int flags)
{
	int rc;

	if (flags & TPM_TRANSMIT_RAW)
	if (flags & TPM_TRANSMIT_NESTED)
		return;

	if (!chip->ops->relinquish_locality)
@@ -406,7 +406,7 @@ static void tpm_relinquish_locality(struct tpm_chip *chip, unsigned int flags)

static int tpm_cmd_ready(struct tpm_chip *chip, unsigned int flags)
{
	if (flags & TPM_TRANSMIT_RAW)
	if (flags & TPM_TRANSMIT_NESTED)
		return 0;

	if (!chip->ops->cmd_ready)
@@ -417,7 +417,7 @@ static int tpm_cmd_ready(struct tpm_chip *chip, unsigned int flags)

static int tpm_go_idle(struct tpm_chip *chip, unsigned int flags)
{
	if (flags & TPM_TRANSMIT_RAW)
	if (flags & TPM_TRANSMIT_NESTED)
		return 0;

	if (!chip->ops->go_idle)
@@ -466,10 +466,9 @@ static ssize_t tpm_try_transmit(struct tpm_chip *chip,
		return -E2BIG;
	}

	if (!(flags & TPM_TRANSMIT_UNLOCKED))
	if (!(flags & TPM_TRANSMIT_UNLOCKED) && !(flags & TPM_TRANSMIT_NESTED))
		mutex_lock(&chip->tpm_mutex);


	if (chip->ops->clk_enable != NULL)
		chip->ops->clk_enable(chip, true);

@@ -559,7 +558,7 @@ static ssize_t tpm_try_transmit(struct tpm_chip *chip,
	if (chip->ops->clk_enable != NULL)
		chip->ops->clk_enable(chip, false);

	if (!(flags & TPM_TRANSMIT_UNLOCKED))
	if (!(flags & TPM_TRANSMIT_UNLOCKED) && !(flags & TPM_TRANSMIT_NESTED))
		mutex_unlock(&chip->tpm_mutex);
	return rc ? rc : len;
}
+7 −7
Original line number Diff line number Diff line
@@ -513,16 +513,16 @@ extern const struct file_operations tpmrm_fops;
extern struct idr dev_nums_idr;

/**
 * enum tpm_transmit_flags
 * enum tpm_transmit_flags - flags for tpm_transmit()
 *
 * @TPM_TRANSMIT_UNLOCKED: used to lock sequence of tpm_transmit calls.
 * @TPM_TRANSMIT_RAW: prevent recursive calls into setup steps
 *                    (go idle, locality,..). Always use with UNLOCKED
 *                    as it will fail on double locking.
 * @TPM_TRANSMIT_UNLOCKED:	do not lock the chip
 * @TPM_TRANSMIT_NESTED:	discard setup steps (power management,
 *				locality) including locking (i.e. implicit
 *				UNLOCKED)
 */
enum tpm_transmit_flags {
	TPM_TRANSMIT_UNLOCKED	= BIT(0),
	TPM_TRANSMIT_RAW      = BIT(1),
	TPM_TRANSMIT_NESTED      = BIT(1),
};

ssize_t tpm_transmit(struct tpm_chip *chip, struct tpm_space *space,
+6 −10
Original line number Diff line number Diff line
@@ -39,8 +39,7 @@ static void tpm2_flush_sessions(struct tpm_chip *chip, struct tpm_space *space)
	for (i = 0; i < ARRAY_SIZE(space->session_tbl); i++) {
		if (space->session_tbl[i])
			tpm2_flush_context_cmd(chip, space->session_tbl[i],
					       TPM_TRANSMIT_UNLOCKED |
					       TPM_TRANSMIT_RAW);
					       TPM_TRANSMIT_NESTED);
	}
}

@@ -85,7 +84,7 @@ static int tpm2_load_context(struct tpm_chip *chip, u8 *buf,
	tpm_buf_append(&tbuf, &buf[*offset], body_size);

	rc = tpm_transmit_cmd(chip, NULL, tbuf.data, PAGE_SIZE, 4,
			      TPM_TRANSMIT_UNLOCKED | TPM_TRANSMIT_RAW, NULL);
			      TPM_TRANSMIT_NESTED, NULL);
	if (rc < 0) {
		dev_warn(&chip->dev, "%s: failed with a system error %d\n",
			 __func__, rc);
@@ -134,7 +133,7 @@ static int tpm2_save_context(struct tpm_chip *chip, u32 handle, u8 *buf,
	tpm_buf_append_u32(&tbuf, handle);

	rc = tpm_transmit_cmd(chip, NULL, tbuf.data, PAGE_SIZE, 0,
			      TPM_TRANSMIT_UNLOCKED | TPM_TRANSMIT_RAW, NULL);
			      TPM_TRANSMIT_NESTED, NULL);
	if (rc < 0) {
		dev_warn(&chip->dev, "%s: failed with a system error %d\n",
			 __func__, rc);
@@ -171,8 +170,7 @@ static void tpm2_flush_space(struct tpm_chip *chip)
	for (i = 0; i < ARRAY_SIZE(space->context_tbl); i++)
		if (space->context_tbl[i] && ~space->context_tbl[i])
			tpm2_flush_context_cmd(chip, space->context_tbl[i],
					       TPM_TRANSMIT_UNLOCKED |
					       TPM_TRANSMIT_RAW);
					       TPM_TRANSMIT_NESTED);

	tpm2_flush_sessions(chip, space);
}
@@ -379,8 +377,7 @@ static int tpm2_map_response_header(struct tpm_chip *chip, u32 cc, u8 *rsp,

	return 0;
out_no_slots:
	tpm2_flush_context_cmd(chip, phandle,
			       TPM_TRANSMIT_UNLOCKED | TPM_TRANSMIT_RAW);
	tpm2_flush_context_cmd(chip, phandle, TPM_TRANSMIT_NESTED);
	dev_warn(&chip->dev, "%s: out of slots for 0x%08X\n", __func__,
		 phandle);
	return -ENOMEM;
@@ -468,8 +465,7 @@ static int tpm2_save_space(struct tpm_chip *chip)
			return rc;

		tpm2_flush_context_cmd(chip, space->context_tbl[i],
				       TPM_TRANSMIT_UNLOCKED |
				       TPM_TRANSMIT_RAW);
				       TPM_TRANSMIT_NESTED);
		space->context_tbl[i] = ~0;
	}

+1 −1
Original line number Diff line number Diff line
@@ -418,7 +418,7 @@ static int vtpm_proxy_request_locality(struct tpm_chip *chip, int locality)
	proxy_dev->state |= STATE_DRIVER_COMMAND;

	rc = tpm_transmit_cmd(chip, NULL, buf.data, tpm_buf_length(&buf), 0,
			      TPM_TRANSMIT_UNLOCKED | TPM_TRANSMIT_RAW,
			      TPM_TRANSMIT_NESTED,
			      "attempting to set locality");

	proxy_dev->state &= ~STATE_DRIVER_COMMAND;