Re: [PATCH 1/2] mmc: via-sdmmc: stop card-detect handling on probe failure

Ulf Hansson <[email protected]> Mon, 27 Jul 2026 18:25:07 +0200
Newsgroups org.kernel.vger.linux-mmc,org.kernel.vger.linux-kernel,org.kernel.vger.stable
Message-ID <CAPx+jO8kyok_cYyUPFMviOC9KsUbAhT5t4jbTGYqcO1sHZNCag@mail.gmail.com>
On Thu, Jul 23, 2026 at 1:28=E2=80=AFPM Fan Wu <[email protected]> wrote:
>
> request_irq() registers the SD card-detect interrupt and the probe enable=
s
> it before mmc_add_host() runs. If mmc_add_host() fails, the error path on=
ly
> unmaps the registers and returns: the interrupt stays registered, so the
> handler keeps running against the host once it is freed. via_sdc_isr()
> dereferences sdhost and its MMIO base and schedules carddet_work, which
> via_sdc_card_detect() also runs against freed memory through its
> container_of() dereference.
>
> Add a probe-error path that disables and frees the interrupt and cancels
> carddet_work before unmapping. carddet_work can re-enable the device
> interrupt via via_reset_pcictrl(), which restores PCIINTCTRL, so mask it
> again after cancelling the work.
>
> This issue was found by an in-house static analysis tool and confirmed by
> manual code review.
>
> Fixes: e4e46fb61e3b ("mmc: via-sdmmc: fix return value check of mmc_add_h=
ost()")
> Cc: [email protected]
> Assisted-by: Codex:gpt-5.6
> Signed-off-by: Fan Wu <[email protected]>

Applied for next, thanks!

Kind regards
Uffe


> ---
>  drivers/mmc/host/via-sdmmc.c | 8 +++++++-
>  1 file changed, 7 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/mmc/host/via-sdmmc.c b/drivers/mmc/host/via-sdmmc.c
> index c628b3bbfd7a..5228a1fe0495 100644
> --- a/drivers/mmc/host/via-sdmmc.c
> +++ b/drivers/mmc/host/via-sdmmc.c
> @@ -1154,10 +1154,16 @@ static int via_sd_probe(struct pci_dev *pcidev,
>
>         ret =3D mmc_add_host(mmc);
>         if (ret)
> -               goto unmap;
> +               goto free_irq;
>
>         return 0;
>
> +free_irq:
> +       writeb(0x0, sdhost->pcictrl_mmiobase + VIA_CRDR_PCIINTCTRL);
> +       free_irq(pcidev->irq, sdhost);
> +       cancel_work_sync(&sdhost->carddet_work);
> +       /* carddet_work may re-enable the interrupt via via_reset_pcictrl=
(). */
> +       writeb(0x0, sdhost->pcictrl_mmiobase + VIA_CRDR_PCIINTCTRL);
>  unmap:
>         iounmap(sdhost->mmiobase);
>  release:
> --
> 2.34.1