From: Bjorn Helgaas <helgaas@kernel.org>
To: Nicolin Chen <nicolinc@nvidia.com>
Cc: bhelgaas@google.com, joerg.roedel@amd.com, kevin.tian@intel.com,
jgg@nvidia.com, linux-pci@vger.kernel.org,
linux-kernel@vger.kernel.org, xueshuai@linux.alibaba.com
Subject: Re: [PATCH rc] PCI: Fix nested pci_dev_reset_iommu_prepare/done()
Date: Wed, 18 Mar 2026 17:57:05 -0500 [thread overview]
Message-ID: <20260318225705.GA479639@bhelgaas> (raw)
In-Reply-To: <20260318220028.1146905-1-nicolinc@nvidia.com>
On Wed, Mar 18, 2026 at 03:00:28PM -0700, Nicolin Chen wrote:
> Shuai found that cxl_reset_bus_function() calls pci_reset_bus_function()
> internally while both are calling pci_dev_reset_iommu_prepare/done().
>
> This results in a nested pci_dev_reset_iommu_prepare/done() call:
> cxl_reset_bus_function():
> pci_dev_reset_iommu_prepare(); // outer
> pci_reset_bus_function():
> pci_dev_reset_iommu_prepare(); // inner (re-entry)
> ...
> pci_dev_reset_iommu_done(); // inner
> pci_dev_reset_iommu_done(); // outer
>
> However, pci_dev_reset_iommu_prepare() doesn't allow a re-entry for now.
>
> Digging further, I found that most functions in pci_dev_specific_reset()
> except reset_ivb_igd() are calling pcie_flr() that has nested those two
> functions as well.
>
> Drop the outer callbacks in:
> - cxl_reset_bus_function()
> - pci_dev_specific_reset()
>
> Replace with adding the callbacks in:
> + reset_ivb_igd()
This needs to say clearly what the issue is. Deadlock? Crash?
Corruption?
I guess it's a deadlock when the second call to
pci_dev_reset_iommu_prepare() acquires the group->mutex?
Since f5b16b802174 appeared in v7.0-rc1 (merged by Joerg), I guess
this fix also needs to be in v7.0 -- please confirm.
> Fixes: f5b16b802174 ("PCI: Suspend iommu function prior to resetting a device")
> Cc: stable@vger.kernel.org
> Reported-by: Shuai Xue <xueshuai@linux.alibaba.com>
> Closes: https://lore.kernel.org/all/absKsk7qQOwzhpzv@Asurada-Nvidia/
> Signed-off-by: Nicolin Chen <nicolinc@nvidia.com>
> ---
> drivers/pci/pci.c | 7 -------
> drivers/pci/quirks.c | 29 +++++++++++------------------
> 2 files changed, 11 insertions(+), 25 deletions(-)
>
> diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
> index 8479c2e1f74f..8f1fd083a84c 100644
> --- a/drivers/pci/pci.c
> +++ b/drivers/pci/pci.c
> @@ -4958,12 +4958,6 @@ static int cxl_reset_bus_function(struct pci_dev *dev, bool probe)
> if (rc)
> return -ENOTTY;
>
> - rc = pci_dev_reset_iommu_prepare(dev);
> - if (rc) {
> - pci_err(dev, "failed to stop IOMMU for a PCI reset: %d\n", rc);
> - return rc;
> - }
> -
> if (reg & PCI_DVSEC_CXL_PORT_CTL_UNMASK_SBR) {
> val = reg;
> } else {
> @@ -4978,7 +4972,6 @@ static int cxl_reset_bus_function(struct pci_dev *dev, bool probe)
> pci_write_config_word(bridge, dvsec + PCI_DVSEC_CXL_PORT_CTL,
> reg);
>
> - pci_dev_reset_iommu_done(dev);
> return rc;
> }
>
> diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
> index 48946cca4be7..d1d210bc2a15 100644
> --- a/drivers/pci/quirks.c
> +++ b/drivers/pci/quirks.c
> @@ -3973,6 +3973,7 @@ static int reset_ivb_igd(struct pci_dev *dev, bool probe)
> void __iomem *mmio_base;
> unsigned long timeout;
> u32 val;
> + int ret;
>
> if (probe)
> return 0;
> @@ -3981,6 +3982,12 @@ static int reset_ivb_igd(struct pci_dev *dev, bool probe)
> if (!mmio_base)
> return -ENOMEM;
>
> + ret = pci_dev_reset_iommu_prepare(dev);
> + if (ret) {
> + pci_err(dev, "failed to stop IOMMU for a PCI reset: %d\n", ret);
> + goto out_iounmap;
> + }
> +
> iowrite32(0x00000002, mmio_base + MSG_CTL);
>
> /*
> @@ -4006,8 +4013,10 @@ static int reset_ivb_igd(struct pci_dev *dev, bool probe)
> reset_complete:
> iowrite32(0x00000002, mmio_base + NSDE_PWR_STATE);
>
> + pci_dev_reset_iommu_done(dev);
> +out_iounmap:
> pci_iounmap(dev, mmio_base);
> - return 0;
> + return ret;
> }
>
> /* Device-specific reset method for Chelsio T4-based adapters */
> @@ -4257,22 +4266,6 @@ static const struct pci_dev_reset_methods pci_dev_reset_methods[] = {
> { 0 }
> };
>
> -static int __pci_dev_specific_reset(struct pci_dev *dev, bool probe,
> - const struct pci_dev_reset_methods *i)
> -{
> - int ret;
> -
> - ret = pci_dev_reset_iommu_prepare(dev);
> - if (ret) {
> - pci_err(dev, "failed to stop IOMMU for a PCI reset: %d\n", ret);
> - return ret;
> - }
> -
> - ret = i->reset(dev, probe);
> - pci_dev_reset_iommu_done(dev);
> - return ret;
> -}
> -
> /*
> * These device-specific reset methods are here rather than in a driver
> * because when a host assigns a device to a guest VM, the host may need
> @@ -4287,7 +4280,7 @@ int pci_dev_specific_reset(struct pci_dev *dev, bool probe)
> i->vendor == (u16)PCI_ANY_ID) &&
> (i->device == dev->device ||
> i->device == (u16)PCI_ANY_ID))
> - return __pci_dev_specific_reset(dev, probe, i);
> + return i->reset(dev, probe);
> }
>
> return -ENOTTY;
> --
> 2.34.1
>
next prev parent reply other threads:[~2026-03-18 22:57 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-03-18 22:00 [PATCH rc] PCI: Fix nested pci_dev_reset_iommu_prepare/done() Nicolin Chen
2026-03-18 22:57 ` Bjorn Helgaas [this message]
2026-03-18 23:35 ` Nicolin Chen
2026-03-19 2:22 ` Tian, Kevin
2026-03-19 2:42 ` Nicolin Chen
2026-03-19 3:00 ` Tian, Kevin
2026-03-19 3:06 ` Nicolin Chen
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260318225705.GA479639@bhelgaas \
--to=helgaas@kernel.org \
--cc=bhelgaas@google.com \
--cc=jgg@nvidia.com \
--cc=joerg.roedel@amd.com \
--cc=kevin.tian@intel.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-pci@vger.kernel.org \
--cc=nicolinc@nvidia.com \
--cc=xueshuai@linux.alibaba.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.