Skip to content

Commit 7862840

Browse files
James BottomleyJarkko Sakkinen
authored andcommitted
tpm: Fix TIS locality timeout problems
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: d23d124 ("tpm: fix invalid locking in NONBLOCKING mode") Reported-by: Mario Limonciello <[email protected]> Tested-by: Alex Guzman <[email protected]> Cc: [email protected] Reviewed-by: Jerry Snitselaar <[email protected]> Signed-off-by: James Bottomley <[email protected]> Reviewed-by: Jarkko Sakkinen <[email protected]> Signed-off-by: Jarkko Sakkinen <[email protected]>
1 parent cd77006 commit 7862840

File tree

1 file changed

+9
-10
lines changed

1 file changed

+9
-10
lines changed

drivers/char/tpm/tpm-dev-common.c

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -189,15 +189,6 @@ ssize_t tpm_common_write(struct file *file, const char __user *buf,
189189
goto out;
190190
}
191191

192-
/* atomic tpm command send and result receive. We only hold the ops
193-
* lock during this period so that the tpm can be unregistered even if
194-
* the char dev is held open.
195-
*/
196-
if (tpm_try_get_ops(priv->chip)) {
197-
ret = -EPIPE;
198-
goto out;
199-
}
200-
201192
priv->response_length = 0;
202193
priv->response_read = false;
203194
*off = 0;
@@ -211,11 +202,19 @@ ssize_t tpm_common_write(struct file *file, const char __user *buf,
211202
if (file->f_flags & O_NONBLOCK) {
212203
priv->command_enqueued = true;
213204
queue_work(tpm_dev_wq, &priv->async_work);
214-
tpm_put_ops(priv->chip);
215205
mutex_unlock(&priv->buffer_mutex);
216206
return size;
217207
}
218208

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

0 commit comments

Comments
 (0)