tpm: take TPM chip power gating out of tpm_transmit()
authorJarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
Mon, 5 Nov 2018 00:07:56 +0000 (02:07 +0200)
committerJarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
Wed, 13 Feb 2019 07:48:40 +0000 (09:48 +0200)
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 <jarkko.sakkinen@linux.intel.com>
Reviewed-by: Stefan Berger <stefanb@linux.ibm.com>
Tested-by: Stefan Berger <stefanb@linux.ibm.com>
Reviewed-by: Jerry Snitselaar <jsnitsel@redhat.com>
Reviewed-by: James Bottomley <James.Bottomley@HansenPartnership.com>
Tested-by: Alexander Steffen <Alexander.Steffen@infineon.com>
drivers/char/tpm/tpm-chip.c
drivers/char/tpm/tpm-interface.c
drivers/char/tpm/tpm.h
drivers/char/tpm/tpm2-space.c
drivers/char/tpm/tpm_tis_core.c
drivers/char/tpm/tpm_vtpm_proxy.c

index ed673c7..1dbc7f4 100644 (file)
@@ -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;
 
index 038a476..744f1b9 100644 (file)
@@ -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;
 }
index 2d6d934..53e4208 100644 (file)
@@ -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,
index 8a8754a..6cc7bb4 100644 (file)
@@ -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);
index c6b0c6d..e33a104 100644 (file)
@@ -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;
 
index 8678c4b..9aa6a3b 100644 (file)
@@ -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;