tpm: fix TIS locality timeout problems
Subsystems (2)
James Bottomley
maintainerPATCH v2 1/1 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.
--- drivers/char/tpm/tpm-dev-common.c | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-)
drivers/char/tpm/tpm-dev-common.c +9 -10
@@ -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);
Signature · 1 line
2.26.2
Quoted 10 lines · James Bottomley
It has been reported that some TIS based TPMs are giving unexpected errors when using the
O_NONBLOCKpath 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 theO_NONBLOCKwrite path. Fix this by moving thetpm_try_get_ops()further down the code to after theO_NONBLOCKdetermination is made. This is safe because thepriv->buffer_mutexstill protects the priv state being modified.
Quoted 7 lines
Fixes d23d12484307 ("tpm: fix invalid locking in NONBLOCKING mode")Reported-by Mario Limonciello <[email protected]>Tested-by Alex Guzman <[email protected]>Reviewed-by Jerry Snitselaar <[email protected]>Signed-off-by James Bottomley <[email protected]>
Thanks a lot! Merging this soon.
/Jarko