mirror of
https://github.com/torvalds/linux.git
synced 2026-07-27 17:47:41 +02:00
tpm: tpm_tis_spi: Use wait_woken() in wait_for_tmp_stat()
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>
This commit is contained in:
parent
595ca21f79
commit
c0c9cfb3b7
|
|
@ -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)
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user