lkml.org 
[lkml]   [2020]   [Jul]   [7]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 5.4 20/65] tpm: Fix TIS locality timeout problems
    Date
    From: James Bottomley <James.Bottomley@HansenPartnership.com>

    commit 7862840219058436b80029a0263fd1ef065fb1b3 upstream.

    It has been reported that some TIS based TPMs are giving unexpected
    errors when using the O_NONBLOCK path of the TPM device. The problem
    is that some TPMs don't like it when you get and then relinquish a
    locality (as the tpm_try_get_ops()/tpm_put_ops() pair does) without
    sending a command. This currently happens all the time in the
    O_NONBLOCK write path. Fix this by moving the tpm_try_get_ops()
    further down the code to after the O_NONBLOCK determination is made.
    This is safe because the priv->buffer_mutex still protects the priv
    state being modified.

    BugLink: https://bugzilla.kernel.org/show_bug.cgi?id=206275
    Fixes: d23d12484307 ("tpm: fix invalid locking in NONBLOCKING mode")
    Reported-by: Mario Limonciello <Mario.Limonciello@dell.com>
    Tested-by: Alex Guzman <alex@guzman.io>
    Cc: stable@vger.kernel.org
    Reviewed-by: Jerry Snitselaar <jsnitsel@redhat.com>
    Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
    Reviewed-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
    Signed-off-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

    ---
    drivers/char/tpm/tpm-dev-common.c | 19 +++++++++----------
    1 file changed, 9 insertions(+), 10 deletions(-)

    --- a/drivers/char/tpm/tpm-dev-common.c
    +++ b/drivers/char/tpm/tpm-dev-common.c
    @@ -189,15 +189,6 @@ ssize_t tpm_common_write(struct file *fi
    goto out;
    }

    - /* atomic tpm command send and result receive. We only hold the ops
    - * lock during this period so that the tpm can be unregistered even if
    - * the char dev is held open.
    - */
    - if (tpm_try_get_ops(priv->chip)) {
    - ret = -EPIPE;
    - goto out;
    - }
    -
    priv->response_length = 0;
    priv->response_read = false;
    *off = 0;
    @@ -211,11 +202,19 @@ ssize_t tpm_common_write(struct file *fi
    if (file->f_flags & O_NONBLOCK) {
    priv->command_enqueued = true;
    queue_work(tpm_dev_wq, &priv->async_work);
    - tpm_put_ops(priv->chip);
    mutex_unlock(&priv->buffer_mutex);
    return size;
    }

    + /* atomic tpm command send and result receive. We only hold the ops
    + * lock during this period so that the tpm can be unregistered even if
    + * the char dev is held open.
    + */
    + if (tpm_try_get_ops(priv->chip)) {
    + ret = -EPIPE;
    + goto out;
    + }
    +
    ret = tpm_dev_transmit(priv->chip, priv->space, priv->data_buffer,
    sizeof(priv->data_buffer));
    tpm_put_ops(priv->chip);

    \
     
     \ /
      Last update: 2020-07-07 17:21    [W:5.083 / U:0.044 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site