Skip to content

Commit

Permalink
tpm: replace msleep() with usleep_range() in TPM 1.2/2.0 generic drivers
Browse files Browse the repository at this point in the history
The patch simply replaces all msleep function calls with usleep_range calls
in the generic drivers.

Tested with an Infineon TPM 1.2, using the generic tpm-tis module, for a
thousand PCR extends, we see results going from 1m57s unpatched to 40s
with the new patch. We obtain similar results when using the original and
patched tpm_infineon driver, which is also part of the patch.
Similarly with a STM TPM 2.0, using the CRB driver, it takes about 20ms per
extend unpatched and around 7ms with the new patch.

Note that the PCR consistency is untouched with this patch, each TPM has
been tested with 10 million extends and the aggregated PCR value is
continuously verified to be correct.

As an extension of this work, this could potentially and easily be applied
to other vendor's drivers. Still, these changes are not included in the
proposed patch as they are untested.

Signed-off-by: Hamza Attak <[email protected]>
Reviewed-by: Jarkko Sakkinen <[email protected]>
Tested-by: Jarkko Sakkinen <[email protected]>
Signed-off-by: Jarkko Sakkinen <[email protected]>
Signed-off-by: James Morris <[email protected]>
  • Loading branch information
Hamza Attak authored and James Morris committed Sep 24, 2017
1 parent 5d0e4d7 commit 9f3fc7b
Show file tree
Hide file tree
Showing 5 changed files with 21 additions and 14 deletions.
10 changes: 5 additions & 5 deletions drivers/char/tpm/tpm-interface.c
Original file line number Diff line number Diff line change
Expand Up @@ -455,7 +455,7 @@ ssize_t tpm_transmit(struct tpm_chip *chip, struct tpm_space *space,
goto out;
}

msleep(TPM_TIMEOUT); /* CHECK */
tpm_msleep(TPM_TIMEOUT);
rmb();
} while (time_before(jiffies, stop));

Expand Down Expand Up @@ -970,7 +970,7 @@ int tpm_do_selftest(struct tpm_chip *chip)
dev_info(
&chip->dev, HW_ERR
"TPM command timed out during continue self test");
msleep(delay_msec);
tpm_msleep(delay_msec);
continue;
}

Expand All @@ -985,7 +985,7 @@ int tpm_do_selftest(struct tpm_chip *chip)
}
if (rc != TPM_WARN_DOING_SELFTEST)
return rc;
msleep(delay_msec);
tpm_msleep(delay_msec);
} while (--loops > 0);

return rc;
Expand Down Expand Up @@ -1085,7 +1085,7 @@ int wait_for_tpm_stat(struct tpm_chip *chip, u8 mask, unsigned long timeout,
}
} else {
do {
msleep(TPM_TIMEOUT);
tpm_msleep(TPM_TIMEOUT);
status = chip->ops->status(chip);
if ((status & mask) == mask)
return 0;
Expand Down Expand Up @@ -1150,7 +1150,7 @@ int tpm_pm_suspend(struct device *dev)
*/
if (rc != TPM_WARN_RETRY)
break;
msleep(TPM_TIMEOUT_RETRY);
tpm_msleep(TPM_TIMEOUT_RETRY);
}

if (rc)
Expand Down
9 changes: 8 additions & 1 deletion drivers/char/tpm/tpm.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,8 @@ enum tpm_const {

enum tpm_timeout {
TPM_TIMEOUT = 5, /* msecs */
TPM_TIMEOUT_RETRY = 100 /* msecs */
TPM_TIMEOUT_RETRY = 100, /* msecs */
TPM_TIMEOUT_RANGE_US = 300 /* usecs */
};

/* TPM addresses */
Expand Down Expand Up @@ -527,6 +528,12 @@ int tpm_pm_resume(struct device *dev);
int wait_for_tpm_stat(struct tpm_chip *chip, u8 mask, unsigned long timeout,
wait_queue_head_t *queue, bool check_cancel);

static inline void tpm_msleep(unsigned int delay_msec)
{
usleep_range(delay_msec * 1000,
(delay_msec * 1000) + TPM_TIMEOUT_RANGE_US);
};

struct tpm_chip *tpm_chip_find_get(int chip_num);
__must_check int tpm_try_get_ops(struct tpm_chip *chip);
void tpm_put_ops(struct tpm_chip *chip);
Expand Down
2 changes: 1 addition & 1 deletion drivers/char/tpm/tpm2-cmd.c
Original file line number Diff line number Diff line change
Expand Up @@ -899,7 +899,7 @@ static int tpm2_do_selftest(struct tpm_chip *chip)
if (rc != TPM2_RC_TESTING)
break;

msleep(delay_msec);
tpm_msleep(delay_msec);
}

return rc;
Expand Down
6 changes: 3 additions & 3 deletions drivers/char/tpm/tpm_infineon.c
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,7 @@ static int wait(struct tpm_chip *chip, int wait_for_bit)
/* check the status-register if wait_for_bit is set */
if (status & 1 << wait_for_bit)
break;
msleep(TPM_MSLEEP_TIME);
tpm_msleep(TPM_MSLEEP_TIME);
}
if (i == TPM_MAX_TRIES) { /* timeout occurs */
if (wait_for_bit == STAT_XFE)
Expand Down Expand Up @@ -226,7 +226,7 @@ static void tpm_wtx(struct tpm_chip *chip)
wait_and_send(chip, TPM_CTRL_WTX);
wait_and_send(chip, 0x00);
wait_and_send(chip, 0x00);
msleep(TPM_WTX_MSLEEP_TIME);
tpm_msleep(TPM_WTX_MSLEEP_TIME);
}

static void tpm_wtx_abort(struct tpm_chip *chip)
Expand All @@ -237,7 +237,7 @@ static void tpm_wtx_abort(struct tpm_chip *chip)
wait_and_send(chip, 0x00);
wait_and_send(chip, 0x00);
number_of_wtx = 0;
msleep(TPM_WTX_MSLEEP_TIME);
tpm_msleep(TPM_WTX_MSLEEP_TIME);
}

static int tpm_inf_recv(struct tpm_chip *chip, u8 * buf, size_t count)
Expand Down
8 changes: 4 additions & 4 deletions drivers/char/tpm/tpm_tis_core.c
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ static int wait_startup(struct tpm_chip *chip, int l)

if (access & TPM_ACCESS_VALID)
return 0;
msleep(TPM_TIMEOUT);
tpm_msleep(TPM_TIMEOUT);
} while (time_before(jiffies, stop));
return -1;
}
Expand Down Expand Up @@ -117,7 +117,7 @@ static int request_locality(struct tpm_chip *chip, int l)
do {
if (check_locality(chip, l))
return l;
msleep(TPM_TIMEOUT);
tpm_msleep(TPM_TIMEOUT);
} while (time_before(jiffies, stop));
}
return -1;
Expand Down Expand Up @@ -164,7 +164,7 @@ static int get_burstcount(struct tpm_chip *chip)
burstcnt = (value >> 8) & 0xFFFF;
if (burstcnt)
return burstcnt;
msleep(TPM_TIMEOUT);
tpm_msleep(TPM_TIMEOUT);
} while (time_before(jiffies, stop));
return -EBUSY;
}
Expand Down Expand Up @@ -396,7 +396,7 @@ static int tpm_tis_send(struct tpm_chip *chip, u8 *buf, size_t len)
priv->irq = irq;
chip->flags |= TPM_CHIP_FLAG_IRQ;
if (!priv->irq_tested)
msleep(1);
tpm_msleep(1);
if (!priv->irq_tested)
disable_interrupts(chip);
priv->irq_tested = true;
Expand Down

0 comments on commit 9f3fc7b

Please sign in to comment.