[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <426645d40776198e0fcc942f4a6cac4433c7a9aa.camel@redhat.com>
Date: Tue, 09 Jul 2024 10:56:26 +0200
From: Philipp Stanner <pstanner@...hat.com>
To: Ashish Kalra <Ashish.Kalra@....com>
Cc: airlied@...il.com, bhelgaas@...gle.com, dakr@...hat.com,
daniel@...ll.ch, dri-devel@...ts.freedesktop.org, hdegoede@...hat.com,
linux-kernel@...r.kernel.org, linux-pci@...r.kernel.org,
maarten.lankhorst@...ux.intel.com, mripard@...nel.org, sam@...nborg.org,
tzimmermann@...e.de, thomas.lendacky@....com, mario.limonciello@....com
Subject: Re: [PATCH v9 10/13] PCI: Give pci_intx() its own devres callback
>From c24bd5b66e798a341caf183fb7cdbdf235502d90 Mon Sep 17 00:00:00 2001
From: Philipp Stanner <pstanner@...hat.com>
Date: Tue, 9 Jul 2024 09:45:48 +0200
Subject: [PATCH] PCI: Fix pcim_intx() recursive calls
pci_intx() calls into pcim_intx() in managed mode, i.e., when
pcim_enable_device() had been called. This recursive call causes a bug
by re-registering the device resource in the release callback.
This is the same phenomenon that made it necessary to implement some
functionality a second time, see __pcim_request_region().
Implement __pcim_intx() to bypass the hybrid nature of pci_intx() on
driver detach.
Fixes: https://lore.kernel.org/all/20240708214656.4721-1-Ashish.Kalra@amd.com/
Reported-by: Ashish Kalra <Ashish.Kalra@....com>
Signed-off-by: Philipp Stanner <pstanner@...hat.com>
---
Hi Ashish,
I hacked down this fix that should be applyable on top.
Could you maybe have a first quick look whether this fixes the issue?
---
drivers/pci/devres.c | 33 +++++++++++++++++++++------------
1 file changed, 21 insertions(+), 12 deletions(-)
diff --git a/drivers/pci/devres.c b/drivers/pci/devres.c
index 2f0379a4e58f..dcef049b72fe 100644
--- a/drivers/pci/devres.c
+++ b/drivers/pci/devres.c
@@ -408,12 +408,31 @@ static inline bool mask_contains_bar(int mask, int bar)
return mask & BIT(bar);
}
+/*
+ * This is a copy of pci_intx() used to bypass the problem of occuring
+ * recursive function calls due to the hybrid nature of pci_intx().
+ */
+static void __pcim_intx(struct pci_dev *pdev, int enable)
+{
+ u16 pci_command, new;
+
+ pci_read_config_word(pdev, PCI_COMMAND, &pci_command);
+
+ if (enable)
+ new = pci_command & ~PCI_COMMAND_INTX_DISABLE;
+ else
+ new = pci_command | PCI_COMMAND_INTX_DISABLE;
+
+ if (new != pci_command)
+ pci_write_config_word(pdev, PCI_COMMAND, new);
+}
+
static void pcim_intx_restore(struct device *dev, void *data)
{
struct pci_dev *pdev = to_pci_dev(dev);
struct pcim_intx_devres *res = data;
- pci_intx(pdev, res->orig_intx);
+ __pcim_intx(pdev, res->orig_intx);
}
static struct pcim_intx_devres *get_or_create_intx_devres(struct device *dev)
@@ -443,7 +462,6 @@ static struct pcim_intx_devres *get_or_create_intx_devres(struct device *dev)
*/
int pcim_intx(struct pci_dev *pdev, int enable)
{
- u16 pci_command, new;
struct pcim_intx_devres *res;
res = get_or_create_intx_devres(&pdev->dev);
@@ -451,16 +469,7 @@ int pcim_intx(struct pci_dev *pdev, int enable)
return -ENOMEM;
res->orig_intx = !enable;
-
- pci_read_config_word(pdev, PCI_COMMAND, &pci_command);
-
- if (enable)
- new = pci_command & ~PCI_COMMAND_INTX_DISABLE;
- else
- new = pci_command | PCI_COMMAND_INTX_DISABLE;
-
- if (new != pci_command)
- pci_write_config_word(pdev, PCI_COMMAND, new);
+ __pcim_intx(pdev, enable);
return 0;
}
--
2.45.0
Powered by blists - more mailing lists