tpm: Fix TIS locality timeout problems
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>
This commit is contained in:
parent
563e9491f0
commit
5d6b46a94d
@ -189,15 +189,6 @@ ssize_t tpm_common_write(struct file *file, const char __user *buf,
|
||||
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 *file, const char __user *buf,
|
||||
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);
|
||||
|
Loading…
Reference in New Issue
Block a user