summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorWolfram Sang <wsa+renesas@sang-engineering.com>2024-03-05 11:42:56 +0100
committerUlf Hansson <ulf.hansson@linaro.org>2024-03-05 12:49:18 +0100
commite8d1b41e69d72c62865bebe8f441163ec00b3d44 (patch)
treec62292762953c88d47878ed51af14f75b9adfc43 /drivers
parent09e23823ae9a3e2d5d20f2e1efe0d6e48cef9129 (diff)
mmc: tmio: avoid concurrent runs of mmc_request_done()
With the to-be-fixed commit, the reset_work handler cleared 'host->mrq' outside of the spinlock protected critical section. That leaves a small race window during execution of 'tmio_mmc_reset()' where the done_work handler could grab a pointer to the now invalid 'host->mrq'. Both would use it to call mmc_request_done() causing problems (see link below). However, 'host->mrq' cannot simply be cleared earlier inside the critical section. That would allow new mrqs to come in asynchronously while the actual reset of the controller still needs to be done. So, like 'tmio_mmc_set_ios()', an ERR_PTR is used to prevent new mrqs from coming in but still avoiding concurrency between work handlers. Reported-by: Dirk Behme <dirk.behme@de.bosch.com> Closes: https://lore.kernel.org/all/20240220061356.3001761-1-dirk.behme@de.bosch.com/ Fixes: df3ef2d3c92c ("mmc: protect the tmio_mmc driver against a theoretical race") Signed-off-by: Wolfram Sang <wsa+renesas@sang-engineering.com> Tested-by: Dirk Behme <dirk.behme@de.bosch.com> Reviewed-by: Dirk Behme <dirk.behme@de.bosch.com> Cc: stable@vger.kernel.org # 3.0+ Link: https://lore.kernel.org/r/20240305104423.3177-2-wsa+renesas@sang-engineering.com Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/mmc/host/tmio_mmc_core.c2
1 files changed, 2 insertions, 0 deletions
diff --git a/drivers/mmc/host/tmio_mmc_core.c b/drivers/mmc/host/tmio_mmc_core.c
index be7f18fd4836..c253d176db69 100644
--- a/drivers/mmc/host/tmio_mmc_core.c
+++ b/drivers/mmc/host/tmio_mmc_core.c
@@ -259,6 +259,8 @@ static void tmio_mmc_reset_work(struct work_struct *work)
else
mrq->cmd->error = -ETIMEDOUT;
+ /* No new calls yet, but disallow concurrent tmio_mmc_done_work() */
+ host->mrq = ERR_PTR(-EBUSY);
host->cmd = NULL;
host->data = NULL;