drivers/mmc/host/omap_hsmmc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
omap_hsmmc_prepare_data() converts the command busy timeout to nanoseconds
with:
timeout = req->cmd->busy_timeout * NSEC_PER_MSEC;
busy_timeout is an unsigned int (milliseconds) and timeout is a u64, but
NSEC_PER_MSEC is 1000000L. On 32-bit builds the multiplication is
performed in 32-bit arithmetic and wraps for busy_timeout values above
~4294 ms, before the result is assigned to the u64.
The driver does not set mmc->max_busy_timeout, so the core does not cap the
busy timeout, and commands such as erase or SANITIZE (MMC_SANITIZE_TIMEOUT_MS
is 240000 ms) can pass a busy_timeout far larger than 4294 ms. The wrapped,
much smaller ns value is then programmed via set_data_timeout(), so the data
timeout is set too short and the operation can time out prematurely.
Cast busy_timeout to u64 before the multiplication so the conversion is done
in 64-bit arithmetic.
Fixes: 8cc9a3e73de1 ("mmc: host: omap_hsmmc: use generic_cmd6_time to program timeout value for CMD6")
Cc: stable@vger.kernel.org
Signed-off-by: Zhan Xusheng <zhanxusheng@xiaomi.com>
---
drivers/mmc/host/omap_hsmmc.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
index 58c881f2725b..3356ac5a1fa0 100644
--- a/drivers/mmc/host/omap_hsmmc.c
+++ b/drivers/mmc/host/omap_hsmmc.c
@@ -1357,7 +1357,7 @@ omap_hsmmc_prepare_data(struct omap_hsmmc_host *host, struct mmc_request *req)
if (req->data == NULL) {
OMAP_HSMMC_WRITE(host->base, BLK, 0);
if (req->cmd->flags & MMC_RSP_BUSY) {
- timeout = req->cmd->busy_timeout * NSEC_PER_MSEC;
+ timeout = (u64)req->cmd->busy_timeout * NSEC_PER_MSEC;
/*
* Set an arbitrary 100ms data timeout for commands with
--
2.43.0
On Tue, Aug 4, 2026 at 4:25 AM Zhan Xusheng <zhanxusheng1024@gmail.com> wrote:
>
> omap_hsmmc_prepare_data() converts the command busy timeout to nanoseconds
> with:
>
> timeout = req->cmd->busy_timeout * NSEC_PER_MSEC;
>
> busy_timeout is an unsigned int (milliseconds) and timeout is a u64, but
> NSEC_PER_MSEC is 1000000L. On 32-bit builds the multiplication is
> performed in 32-bit arithmetic and wraps for busy_timeout values above
> ~4294 ms, before the result is assigned to the u64.
>
> The driver does not set mmc->max_busy_timeout, so the core does not cap the
> busy timeout, and commands such as erase or SANITIZE (MMC_SANITIZE_TIMEOUT_MS
> is 240000 ms) can pass a busy_timeout far larger than 4294 ms. The wrapped,
> much smaller ns value is then programmed via set_data_timeout(), so the data
> timeout is set too short and the operation can time out prematurely.
>
> Cast busy_timeout to u64 before the multiplication so the conversion is done
> in 64-bit arithmetic.
>
> Fixes: 8cc9a3e73de1 ("mmc: host: omap_hsmmc: use generic_cmd6_time to program timeout value for CMD6")
> Cc: stable@vger.kernel.org
> Signed-off-by: Zhan Xusheng <zhanxusheng@xiaomi.com>
Applied for fixes, thanks!
Kind regards
Uffe
> ---
> drivers/mmc/host/omap_hsmmc.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
> index 58c881f2725b..3356ac5a1fa0 100644
> --- a/drivers/mmc/host/omap_hsmmc.c
> +++ b/drivers/mmc/host/omap_hsmmc.c
> @@ -1357,7 +1357,7 @@ omap_hsmmc_prepare_data(struct omap_hsmmc_host *host, struct mmc_request *req)
> if (req->data == NULL) {
> OMAP_HSMMC_WRITE(host->base, BLK, 0);
> if (req->cmd->flags & MMC_RSP_BUSY) {
> - timeout = req->cmd->busy_timeout * NSEC_PER_MSEC;
> + timeout = (u64)req->cmd->busy_timeout * NSEC_PER_MSEC;
>
> /*
> * Set an arbitrary 100ms data timeout for commands with
> --
> 2.43.0
>
© 2016 - 2026 Red Hat, Inc.