From a3fbfae82b4cb3ff9928e29f34c64d0507cad874 Mon Sep 17 00:00:00 2001 From: Jarkko Sakkinen Date: Mon, 5 Nov 2018 02:07:56 +0200 Subject: tpm: take TPM chip power gating out of tpm_transmit() Call tpm_chip_start() and tpm_chip_stop() in * tpm_chip_register() * tpm_class_shutdown() * tpm_del_char_device() * tpm_pm_suspend() * tpm_try_get_ops() and tpm_put_ops() * tpm2_del_space() And remove these calls from tpm_transmit(). The core reason for this change is that in tpm_vtpm_proxy a locality change requires a virtual TPM command (a command made up just for that driver). The consequence of this is that this commit removes the remaining nested calls. Signed-off-by: Jarkko Sakkinen Reviewed-by: Stefan Berger Tested-by: Stefan Berger Reviewed-by: Jerry Snitselaar Reviewed-by: James Bottomley Tested-by: Alexander Steffen --- drivers/char/tpm/tpm-chip.c | 38 ++++++++++++++++++++++---------------- drivers/char/tpm/tpm-interface.c | 18 +++++++++--------- drivers/char/tpm/tpm.h | 9 --------- drivers/char/tpm/tpm2-space.c | 5 ++++- drivers/char/tpm/tpm_tis_core.c | 4 ++++ drivers/char/tpm/tpm_vtpm_proxy.c | 3 +-- 6 files changed, 40 insertions(+), 37 deletions(-) (limited to 'drivers/char') diff --git a/drivers/char/tpm/tpm-chip.c b/drivers/char/tpm/tpm-chip.c index ed673c7216a0..1dbc7f45e2b4 100644 --- a/drivers/char/tpm/tpm-chip.c +++ b/drivers/char/tpm/tpm-chip.c @@ -41,9 +41,6 @@ static int tpm_request_locality(struct tpm_chip *chip, unsigned int flags) { int rc; - if (flags & TPM_TRANSMIT_NESTED) - return 0; - if (!chip->ops->request_locality) return 0; @@ -59,9 +56,6 @@ static void tpm_relinquish_locality(struct tpm_chip *chip, unsigned int flags) { int rc; - if (flags & TPM_TRANSMIT_NESTED) - return; - if (!chip->ops->relinquish_locality) return; @@ -74,9 +68,6 @@ 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_NESTED) - return 0; - if (!chip->ops->cmd_ready) return 0; @@ -85,9 +76,6 @@ 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_NESTED) - return 0; - if (!chip->ops->go_idle) return 0; @@ -167,11 +155,17 @@ int tpm_try_get_ops(struct tpm_chip *chip) down_read(&chip->ops_sem); if (!chip->ops) - goto out_lock; + goto out_ops; mutex_lock(&chip->tpm_mutex); + rc = tpm_chip_start(chip, 0); + if (rc) + goto out_lock; + return 0; out_lock: + mutex_unlock(&chip->tpm_mutex); +out_ops: up_read(&chip->ops_sem); put_device(&chip->dev); return rc; @@ -187,6 +181,7 @@ EXPORT_SYMBOL_GPL(tpm_try_get_ops); */ void tpm_put_ops(struct tpm_chip *chip) { + tpm_chip_stop(chip, 0); mutex_unlock(&chip->tpm_mutex); up_read(&chip->ops_sem); put_device(&chip->dev); @@ -302,7 +297,10 @@ static int tpm_class_shutdown(struct device *dev) if (chip->flags & TPM_CHIP_FLAG_TPM2) { down_write(&chip->ops_sem); - tpm2_shutdown(chip, TPM2_SU_CLEAR); + if (!tpm_chip_start(chip, 0)) { + tpm2_shutdown(chip, TPM2_SU_CLEAR); + tpm_chip_stop(chip, 0); + } chip->ops = NULL; up_write(&chip->ops_sem); } @@ -481,8 +479,12 @@ static void tpm_del_char_device(struct tpm_chip *chip) /* Make the driver uncallable. */ down_write(&chip->ops_sem); - if (chip->flags & TPM_CHIP_FLAG_TPM2) - tpm2_shutdown(chip, TPM2_SU_CLEAR); + if (chip->flags & TPM_CHIP_FLAG_TPM2) { + if (!tpm_chip_start(chip, 0)) { + tpm2_shutdown(chip, TPM2_SU_CLEAR); + tpm_chip_stop(chip, 0); + } + } chip->ops = NULL; up_write(&chip->ops_sem); } @@ -564,7 +566,11 @@ int tpm_chip_register(struct tpm_chip *chip) { int rc; + rc = tpm_chip_start(chip, 0); + if (rc) + return rc; rc = tpm_auto_startup(chip); + tpm_chip_stop(chip, 0); if (rc) return rc; diff --git a/drivers/char/tpm/tpm-interface.c b/drivers/char/tpm/tpm-interface.c index 038a4767d9d6..744f1b96128e 100644 --- a/drivers/char/tpm/tpm-interface.c +++ b/drivers/char/tpm/tpm-interface.c @@ -177,13 +177,7 @@ ssize_t tpm_transmit(struct tpm_chip *chip, u8 *buf, size_t bufsiz, memcpy(save, buf, save_size); for (;;) { - ret = tpm_chip_start(chip, flags); - if (ret) - return ret; - ret = tpm_try_transmit(chip, buf, bufsiz, flags); - - tpm_chip_stop(chip, flags); if (ret < 0) break; rc = be32_to_cpu(header->return_code); @@ -420,10 +414,16 @@ int tpm_pm_suspend(struct device *dev) if (chip->flags & TPM_CHIP_FLAG_ALWAYS_POWERED) return 0; - if (chip->flags & TPM_CHIP_FLAG_TPM2) - tpm2_shutdown(chip, TPM2_SU_STATE); - else + if (chip->flags & TPM_CHIP_FLAG_TPM2) { + mutex_lock(&chip->tpm_mutex); + if (!tpm_chip_start(chip, 0)) { + tpm2_shutdown(chip, TPM2_SU_STATE); + tpm_chip_stop(chip, 0); + } + mutex_unlock(&chip->tpm_mutex); + } else { rc = tpm1_pm_suspend(chip, tpm_suspend_pcr); + } return rc; } diff --git a/drivers/char/tpm/tpm.h b/drivers/char/tpm/tpm.h index 2d6d934f1c8b..53e4208759ee 100644 --- a/drivers/char/tpm/tpm.h +++ b/drivers/char/tpm/tpm.h @@ -485,15 +485,6 @@ extern const struct file_operations tpm_fops; extern const struct file_operations tpmrm_fops; extern struct idr dev_nums_idr; -/** - * enum tpm_transmit_flags - flags for tpm_transmit() - * - * %TPM_TRANSMIT_NESTED: discard setup steps (power management, locality) - */ -enum tpm_transmit_flags { - TPM_TRANSMIT_NESTED = BIT(0), -}; - ssize_t tpm_transmit(struct tpm_chip *chip, u8 *buf, size_t bufsiz, unsigned int flags); ssize_t tpm_transmit_cmd(struct tpm_chip *chip, struct tpm_buf *buf, diff --git a/drivers/char/tpm/tpm2-space.c b/drivers/char/tpm/tpm2-space.c index 8a8754a0f964..6cc7bb442162 100644 --- a/drivers/char/tpm/tpm2-space.c +++ b/drivers/char/tpm/tpm2-space.c @@ -60,7 +60,10 @@ int tpm2_init_space(struct tpm_space *space) void tpm2_del_space(struct tpm_chip *chip, struct tpm_space *space) { mutex_lock(&chip->tpm_mutex); - tpm2_flush_sessions(chip, space); + if (!tpm_chip_start(chip, 0)) { + tpm2_flush_sessions(chip, space); + tpm_chip_stop(chip, 0); + } mutex_unlock(&chip->tpm_mutex); kfree(space->context_buf); kfree(space->session_buf); diff --git a/drivers/char/tpm/tpm_tis_core.c b/drivers/char/tpm/tpm_tis_core.c index c6b0c6d541a5..e33a10491f07 100644 --- a/drivers/char/tpm/tpm_tis_core.c +++ b/drivers/char/tpm/tpm_tis_core.c @@ -916,7 +916,11 @@ int tpm_tis_core_init(struct device *dev, struct tpm_tis_data *priv, int irq, intmask &= ~TPM_GLOBAL_INT_ENABLE; tpm_tis_write32(priv, TPM_INT_ENABLE(priv->locality), intmask); + rc = tpm_chip_start(chip, 0); + if (rc) + goto out_err; rc = tpm2_probe(chip); + tpm_chip_stop(chip, 0); if (rc) goto out_err; diff --git a/drivers/char/tpm/tpm_vtpm_proxy.c b/drivers/char/tpm/tpm_vtpm_proxy.c index 8678c4bba38a..9aa6a3baa491 100644 --- a/drivers/char/tpm/tpm_vtpm_proxy.c +++ b/drivers/char/tpm/tpm_vtpm_proxy.c @@ -416,8 +416,7 @@ static int vtpm_proxy_request_locality(struct tpm_chip *chip, int locality) proxy_dev->state |= STATE_DRIVER_COMMAND; - rc = tpm_transmit_cmd(chip, &buf, 0, TPM_TRANSMIT_NESTED, - "attempting to set locality"); + rc = tpm_transmit_cmd(chip, &buf, 0, 0, "attempting to set locality"); proxy_dev->state &= ~STATE_DRIVER_COMMAND; -- cgit