mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2026-09-22 09:34:56 +02:00
tpm: tpm_tis_spi: Use wait_woken() in wait_for_tmp_stat()
commitc0c9cfb3b7upstream. wait_event_interruptible_timeout() evaluates its condition after setting the current task state to TASK_INTERRUPTIBLE. With CONFIG_DEBUG_ATOMIC_SLEEP this triggers a warning when the IRQ wait path is used: tpm_tis_status() tpm_tis_spi_read_bytes() tpm_tis_spi_transfer_full() spi_bus_lock() mutex_lock() Address this with the following measures: 1. Call wait_tpm_stat_cond() only while tasking is running. 2. Use wait_woken() to wait for changes. Cc: stable@vger.kernel.org # v4.19+ Cc: Linus Walleij <linusw@kernel.org> Reported-by: Stefan Wahren <wahrenst@gmx.net> Closes: https://lore.kernel.org/linux-integrity/6964bec7-3dbb-453b-89ef-9b990217a8b9@gmx.net/ Fixes:1a339b658d("tpm_tis_spi: Pass the SPI IRQ down to the driver") Reviewed-by: Linus Walleij <linusw@kernel.org> Tested-by: Stefan Wahren <wahrenst@gmx.net> Signed-off-by: Jarkko Sakkinen <jarkko@kernel.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
committed by
Greg Kroah-Hartman
parent
424130169d
commit
6b068a9795
@@ -66,8 +66,8 @@ static int wait_for_tpm_stat(struct tpm_chip *chip, u8 mask,
|
||||
bool check_cancel)
|
||||
{
|
||||
struct tpm_tis_data *priv = dev_get_drvdata(&chip->dev);
|
||||
DEFINE_WAIT_FUNC(wait, woken_wake_function);
|
||||
unsigned long stop;
|
||||
long rc;
|
||||
u8 status;
|
||||
bool canceled = false;
|
||||
u8 sts_mask;
|
||||
@@ -87,23 +87,30 @@ static int wait_for_tpm_stat(struct tpm_chip *chip, u8 mask,
|
||||
/* process status changes with irq support */
|
||||
if (sts_mask) {
|
||||
ret = -ETIME;
|
||||
add_wait_queue(queue, &wait);
|
||||
again:
|
||||
if (wait_for_tpm_stat_cond(chip, sts_mask, check_cancel,
|
||||
&canceled)) {
|
||||
ret = canceled ? -ECANCELED : 0;
|
||||
goto out;
|
||||
}
|
||||
|
||||
timeout = stop - jiffies;
|
||||
if ((long)timeout <= 0)
|
||||
return -ETIME;
|
||||
rc = wait_event_interruptible_timeout(*queue,
|
||||
wait_for_tpm_stat_cond(chip, sts_mask, check_cancel,
|
||||
&canceled),
|
||||
timeout);
|
||||
if (rc > 0) {
|
||||
if (canceled)
|
||||
return -ECANCELED;
|
||||
ret = 0;
|
||||
}
|
||||
if (rc == -ERESTARTSYS && freezing(current)) {
|
||||
clear_thread_flag(TIF_SIGPENDING);
|
||||
goto again;
|
||||
goto out;
|
||||
|
||||
if (signal_pending(current)) {
|
||||
if (freezing(current)) {
|
||||
clear_thread_flag(TIF_SIGPENDING);
|
||||
goto again;
|
||||
}
|
||||
goto out;
|
||||
}
|
||||
|
||||
wait_woken(&wait, TASK_INTERRUPTIBLE, timeout);
|
||||
goto again;
|
||||
out:
|
||||
remove_wait_queue(queue, &wait);
|
||||
}
|
||||
|
||||
if (ret)
|
||||
|
||||
Reference in New Issue
Block a user