* [PATCH v4 1/4] p2sb: Factor out p2sb_read_from_cache()
2024-11-28 0:28 [PATCH v4 0/4] p2sb: Fix unexpected P2SB device disappearance Shin'ichiro Kawasaki
@ 2024-11-28 0:28 ` Shin'ichiro Kawasaki
2024-11-28 0:28 ` [PATCH v4 2/4] p2sb: Introduce the global flag p2sb_hidden_by_bios Shin'ichiro Kawasaki
` (4 subsequent siblings)
5 siblings, 0 replies; 7+ messages in thread
From: Shin'ichiro Kawasaki @ 2024-11-28 0:28 UTC (permalink / raw)
To: platform-driver-x86, Hans de Goede, Andy Shevchenko
Cc: ilpo.jarvinen, danielwa, Shin'ichiro Kawasaki
To prepare for the following fix, factor out the code to read the P2SB
resource from the cache to the new function p2sb_read_from_cache().
Signed-off-by: Shin'ichiro Kawasaki <shinichiro.kawasaki@wdc.com>
Reviewed-by: Hans de Goede <hdegoede@redhat.com>
---
drivers/platform/x86/p2sb.c | 28 +++++++++++++++++-----------
1 file changed, 17 insertions(+), 11 deletions(-)
diff --git a/drivers/platform/x86/p2sb.c b/drivers/platform/x86/p2sb.c
index 31f38309b389..aa34b8a69bc1 100644
--- a/drivers/platform/x86/p2sb.c
+++ b/drivers/platform/x86/p2sb.c
@@ -171,6 +171,22 @@ static int p2sb_cache_resources(void)
return ret;
}
+static int p2sb_read_from_cache(struct pci_bus *bus, unsigned int devfn,
+ struct resource *mem)
+{
+ struct p2sb_res_cache *cache = &p2sb_resources[PCI_FUNC(devfn)];
+
+ if (cache->bus_dev_id != bus->dev.id)
+ return -ENODEV;
+
+ if (!p2sb_valid_resource(&cache->res))
+ return -ENOENT;
+
+ memcpy(mem, &cache->res, sizeof(*mem));
+
+ return 0;
+}
+
/**
* p2sb_bar - Get Primary to Sideband (P2SB) bridge device BAR
* @bus: PCI bus to communicate with
@@ -187,8 +203,6 @@ static int p2sb_cache_resources(void)
*/
int p2sb_bar(struct pci_bus *bus, unsigned int devfn, struct resource *mem)
{
- struct p2sb_res_cache *cache;
-
bus = p2sb_get_bus(bus);
if (!bus)
return -ENODEV;
@@ -196,15 +210,7 @@ int p2sb_bar(struct pci_bus *bus, unsigned int devfn, struct resource *mem)
if (!devfn)
p2sb_get_devfn(&devfn);
- cache = &p2sb_resources[PCI_FUNC(devfn)];
- if (cache->bus_dev_id != bus->dev.id)
- return -ENODEV;
-
- if (!p2sb_valid_resource(&cache->res))
- return -ENOENT;
-
- memcpy(mem, &cache->res, sizeof(*mem));
- return 0;
+ return p2sb_read_from_cache(bus, devfn, mem);
}
EXPORT_SYMBOL_GPL(p2sb_bar);
--
2.47.0
^ permalink raw reply related [flat|nested] 7+ messages in thread* [PATCH v4 2/4] p2sb: Introduce the global flag p2sb_hidden_by_bios
2024-11-28 0:28 [PATCH v4 0/4] p2sb: Fix unexpected P2SB device disappearance Shin'ichiro Kawasaki
2024-11-28 0:28 ` [PATCH v4 1/4] p2sb: Factor out p2sb_read_from_cache() Shin'ichiro Kawasaki
@ 2024-11-28 0:28 ` Shin'ichiro Kawasaki
2024-11-28 0:28 ` [PATCH v4 3/4] p2sb: Move P2SB hide and unhide code to p2sb_scan_and_cache() Shin'ichiro Kawasaki
` (3 subsequent siblings)
5 siblings, 0 replies; 7+ messages in thread
From: Shin'ichiro Kawasaki @ 2024-11-28 0:28 UTC (permalink / raw)
To: platform-driver-x86, Hans de Goede, Andy Shevchenko
Cc: ilpo.jarvinen, danielwa, Shin'ichiro Kawasaki
To prepare for the following fix, introduce the global flag
p2sb_hidden_by_bios. Check if the BIOS hides the P2SB device and store
the result in the flag. This allows to refer to the check result across
functions.
Signed-off-by: Shin'ichiro Kawasaki <shinichiro.kawasaki@wdc.com>
Reviewed-by: Hans de Goede <hdegoede@redhat.com>
---
drivers/platform/x86/p2sb.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/drivers/platform/x86/p2sb.c b/drivers/platform/x86/p2sb.c
index aa34b8a69bc1..273ac90c8fbd 100644
--- a/drivers/platform/x86/p2sb.c
+++ b/drivers/platform/x86/p2sb.c
@@ -42,6 +42,7 @@ struct p2sb_res_cache {
};
static struct p2sb_res_cache p2sb_resources[NR_P2SB_RES_CACHE];
+static bool p2sb_hidden_by_bios;
static void p2sb_get_devfn(unsigned int *devfn)
{
@@ -157,13 +158,14 @@ static int p2sb_cache_resources(void)
* Unhide the P2SB device here, if needed.
*/
pci_bus_read_config_dword(bus, devfn_p2sb, P2SBC, &value);
- if (value & P2SBC_HIDE)
+ p2sb_hidden_by_bios = value & P2SBC_HIDE;
+ if (p2sb_hidden_by_bios)
pci_bus_write_config_dword(bus, devfn_p2sb, P2SBC, 0);
ret = p2sb_scan_and_cache(bus, devfn_p2sb);
/* Hide the P2SB device, if it was hidden */
- if (value & P2SBC_HIDE)
+ if (p2sb_hidden_by_bios)
pci_bus_write_config_dword(bus, devfn_p2sb, P2SBC, P2SBC_HIDE);
pci_unlock_rescan_remove();
--
2.47.0
^ permalink raw reply related [flat|nested] 7+ messages in thread* [PATCH v4 3/4] p2sb: Move P2SB hide and unhide code to p2sb_scan_and_cache()
2024-11-28 0:28 [PATCH v4 0/4] p2sb: Fix unexpected P2SB device disappearance Shin'ichiro Kawasaki
2024-11-28 0:28 ` [PATCH v4 1/4] p2sb: Factor out p2sb_read_from_cache() Shin'ichiro Kawasaki
2024-11-28 0:28 ` [PATCH v4 2/4] p2sb: Introduce the global flag p2sb_hidden_by_bios Shin'ichiro Kawasaki
@ 2024-11-28 0:28 ` Shin'ichiro Kawasaki
2024-11-28 0:28 ` [PATCH v4 4/4] p2sb: Do not scan and remove the P2SB device when it is unhidden Shin'ichiro Kawasaki
` (2 subsequent siblings)
5 siblings, 0 replies; 7+ messages in thread
From: Shin'ichiro Kawasaki @ 2024-11-28 0:28 UTC (permalink / raw)
To: platform-driver-x86, Hans de Goede, Andy Shevchenko
Cc: ilpo.jarvinen, danielwa, Shin'ichiro Kawasaki
To prepare for the following fix, move the code to hide and unhide the
P2SB device from p2sb_cache_resources() to p2sb_scan_and_cache().
Signed-off-by: Shin'ichiro Kawasaki <shinichiro.kawasaki@wdc.com>
Reviewed-by: Hans de Goede <hdegoede@redhat.com>
---
drivers/platform/x86/p2sb.c | 23 ++++++++++++-----------
1 file changed, 12 insertions(+), 11 deletions(-)
diff --git a/drivers/platform/x86/p2sb.c b/drivers/platform/x86/p2sb.c
index 273ac90c8fbd..0bc6b21c4c20 100644
--- a/drivers/platform/x86/p2sb.c
+++ b/drivers/platform/x86/p2sb.c
@@ -97,6 +97,14 @@ static void p2sb_scan_and_cache_devfn(struct pci_bus *bus, unsigned int devfn)
static int p2sb_scan_and_cache(struct pci_bus *bus, unsigned int devfn)
{
+ /*
+ * The BIOS prevents the P2SB device from being enumerated by the PCI
+ * subsystem, so we need to unhide and hide it back to lookup the BAR.
+ * Unhide the P2SB device here, if needed.
+ */
+ if (p2sb_hidden_by_bios)
+ pci_bus_write_config_dword(bus, devfn, P2SBC, 0);
+
/* Scan the P2SB device and cache its BAR0 */
p2sb_scan_and_cache_devfn(bus, devfn);
@@ -104,6 +112,10 @@ static int p2sb_scan_and_cache(struct pci_bus *bus, unsigned int devfn)
if (devfn == P2SB_DEVFN_GOLDMONT)
p2sb_scan_and_cache_devfn(bus, SPI_DEVFN_GOLDMONT);
+ /* Hide the P2SB device, if it was hidden */
+ if (p2sb_hidden_by_bios)
+ pci_bus_write_config_dword(bus, devfn, P2SBC, P2SBC_HIDE);
+
if (!p2sb_valid_resource(&p2sb_resources[PCI_FUNC(devfn)].res))
return -ENOENT;
@@ -152,22 +164,11 @@ static int p2sb_cache_resources(void)
*/
pci_lock_rescan_remove();
- /*
- * The BIOS prevents the P2SB device from being enumerated by the PCI
- * subsystem, so we need to unhide and hide it back to lookup the BAR.
- * Unhide the P2SB device here, if needed.
- */
pci_bus_read_config_dword(bus, devfn_p2sb, P2SBC, &value);
p2sb_hidden_by_bios = value & P2SBC_HIDE;
- if (p2sb_hidden_by_bios)
- pci_bus_write_config_dword(bus, devfn_p2sb, P2SBC, 0);
ret = p2sb_scan_and_cache(bus, devfn_p2sb);
- /* Hide the P2SB device, if it was hidden */
- if (p2sb_hidden_by_bios)
- pci_bus_write_config_dword(bus, devfn_p2sb, P2SBC, P2SBC_HIDE);
-
pci_unlock_rescan_remove();
return ret;
--
2.47.0
^ permalink raw reply related [flat|nested] 7+ messages in thread* [PATCH v4 4/4] p2sb: Do not scan and remove the P2SB device when it is unhidden
2024-11-28 0:28 [PATCH v4 0/4] p2sb: Fix unexpected P2SB device disappearance Shin'ichiro Kawasaki
` (2 preceding siblings ...)
2024-11-28 0:28 ` [PATCH v4 3/4] p2sb: Move P2SB hide and unhide code to p2sb_scan_and_cache() Shin'ichiro Kawasaki
@ 2024-11-28 0:28 ` Shin'ichiro Kawasaki
2024-12-10 14:39 ` [PATCH v4 0/4] p2sb: Fix unexpected P2SB device disappearance Ilpo Järvinen
2024-12-12 19:02 ` Daniel Walker (danielwa)
5 siblings, 0 replies; 7+ messages in thread
From: Shin'ichiro Kawasaki @ 2024-11-28 0:28 UTC (permalink / raw)
To: platform-driver-x86, Hans de Goede, Andy Shevchenko
Cc: ilpo.jarvinen, danielwa, Shin'ichiro Kawasaki
When drivers access P2SB device resources, it calls p2sb_bar(). Before
the commit 5913320eb0b3 ("platform/x86: p2sb: Allow p2sb_bar() calls
during PCI device probe"), p2sb_bar() obtained the resources and then
called pci_stop_and_remove_bus_device() for clean up. Then the P2SB
device disappeared. The commit 5913320eb0b3 introduced the P2SB device
resource cache feature in the boot process. During the resource cache,
pci_stop_and_remove_bus_device() is called for the P2SB device, then the
P2SB device disappears regardless of whether p2sb_bar() is called or
not. Such P2SB device disappearance caused a confusion [1]. To avoid the
confusion, avoid the pci_stop_and_remove_bus_device() call when the BIOS
does not hide the P2SB device.
For that purpose, cache the P2SB device resources only if the BIOS hides
the P2SB device. Call p2sb_scan_and_cache() only if p2sb_hidden_by_bios
is true. This allows removing two branches from p2sb_scan_and_cache().
When p2sb_bar() is called, get the resources from the cache if the P2SB
device is hidden. Otherwise, read the resources from the unhidden P2SB
device.
Reported-by: "Daniel Walker (danielwa)" <danielwa@cisco.com>
Closes: https://lore.kernel.org/lkml/ZzTI+biIUTvFT6NC@goliath/ [1]
Fixes: 5913320eb0b3 ("platform/x86: p2sb: Allow p2sb_bar() calls during PCI device probe")
Signed-off-by: Shin'ichiro Kawasaki <shinichiro.kawasaki@wdc.com>
Reviewed-by: Hans de Goede <hdegoede@redhat.com>
---
drivers/platform/x86/p2sb.c | 42 +++++++++++++++++++++++++++++--------
1 file changed, 33 insertions(+), 9 deletions(-)
diff --git a/drivers/platform/x86/p2sb.c b/drivers/platform/x86/p2sb.c
index 0bc6b21c4c20..c56650b9ff96 100644
--- a/drivers/platform/x86/p2sb.c
+++ b/drivers/platform/x86/p2sb.c
@@ -100,10 +100,8 @@ static int p2sb_scan_and_cache(struct pci_bus *bus, unsigned int devfn)
/*
* The BIOS prevents the P2SB device from being enumerated by the PCI
* subsystem, so we need to unhide and hide it back to lookup the BAR.
- * Unhide the P2SB device here, if needed.
*/
- if (p2sb_hidden_by_bios)
- pci_bus_write_config_dword(bus, devfn, P2SBC, 0);
+ pci_bus_write_config_dword(bus, devfn, P2SBC, 0);
/* Scan the P2SB device and cache its BAR0 */
p2sb_scan_and_cache_devfn(bus, devfn);
@@ -112,9 +110,7 @@ static int p2sb_scan_and_cache(struct pci_bus *bus, unsigned int devfn)
if (devfn == P2SB_DEVFN_GOLDMONT)
p2sb_scan_and_cache_devfn(bus, SPI_DEVFN_GOLDMONT);
- /* Hide the P2SB device, if it was hidden */
- if (p2sb_hidden_by_bios)
- pci_bus_write_config_dword(bus, devfn, P2SBC, P2SBC_HIDE);
+ pci_bus_write_config_dword(bus, devfn, P2SBC, P2SBC_HIDE);
if (!p2sb_valid_resource(&p2sb_resources[PCI_FUNC(devfn)].res))
return -ENOENT;
@@ -141,7 +137,7 @@ static int p2sb_cache_resources(void)
u32 value = P2SBC_HIDE;
struct pci_bus *bus;
u16 class;
- int ret;
+ int ret = 0;
/* Get devfn for P2SB device itself */
p2sb_get_devfn(&devfn_p2sb);
@@ -167,7 +163,12 @@ static int p2sb_cache_resources(void)
pci_bus_read_config_dword(bus, devfn_p2sb, P2SBC, &value);
p2sb_hidden_by_bios = value & P2SBC_HIDE;
- ret = p2sb_scan_and_cache(bus, devfn_p2sb);
+ /*
+ * If the BIOS does not hide the P2SB device then its resources
+ * are accesilble. Cache them only if the P2SB device is hidden.
+ */
+ if (p2sb_hidden_by_bios)
+ ret = p2sb_scan_and_cache(bus, devfn_p2sb);
pci_unlock_rescan_remove();
@@ -190,6 +191,26 @@ static int p2sb_read_from_cache(struct pci_bus *bus, unsigned int devfn,
return 0;
}
+static int p2sb_read_from_dev(struct pci_bus *bus, unsigned int devfn,
+ struct resource *mem)
+{
+ struct pci_dev *pdev;
+ int ret = 0;
+
+ pdev = pci_get_slot(bus, devfn);
+ if (!pdev)
+ return -ENODEV;
+
+ if (p2sb_valid_resource(pci_resource_n(pdev, 0)))
+ p2sb_read_bar0(pdev, mem);
+ else
+ ret = -ENOENT;
+
+ pci_dev_put(pdev);
+
+ return ret;
+}
+
/**
* p2sb_bar - Get Primary to Sideband (P2SB) bridge device BAR
* @bus: PCI bus to communicate with
@@ -213,7 +234,10 @@ int p2sb_bar(struct pci_bus *bus, unsigned int devfn, struct resource *mem)
if (!devfn)
p2sb_get_devfn(&devfn);
- return p2sb_read_from_cache(bus, devfn, mem);
+ if (p2sb_hidden_by_bios)
+ return p2sb_read_from_cache(bus, devfn, mem);
+
+ return p2sb_read_from_dev(bus, devfn, mem);
}
EXPORT_SYMBOL_GPL(p2sb_bar);
--
2.47.0
^ permalink raw reply related [flat|nested] 7+ messages in thread* Re: [PATCH v4 0/4] p2sb: Fix unexpected P2SB device disappearance
2024-11-28 0:28 [PATCH v4 0/4] p2sb: Fix unexpected P2SB device disappearance Shin'ichiro Kawasaki
` (3 preceding siblings ...)
2024-11-28 0:28 ` [PATCH v4 4/4] p2sb: Do not scan and remove the P2SB device when it is unhidden Shin'ichiro Kawasaki
@ 2024-12-10 14:39 ` Ilpo Järvinen
2024-12-12 19:02 ` Daniel Walker (danielwa)
5 siblings, 0 replies; 7+ messages in thread
From: Ilpo Järvinen @ 2024-12-10 14:39 UTC (permalink / raw)
To: platform-driver-x86, Hans de Goede, Andy Shevchenko,
Shin'ichiro Kawasaki
Cc: danielwa
On Thu, 28 Nov 2024 09:28:32 +0900, Shin'ichiro Kawasaki wrote:
> When the BIOS does not hide the P2SB device, it is expected to be visible from
> userspace. However, the P2SB device disappears since the commit 5913320eb0b3
> ("platform/x86: p2sb: Allow p2sb_bar() calls during PCI device probe") [1]. This
> series addresses the problem. The first three patches are preliminary
> refactoring for the fix. The last patch resolves the issue by caching the P2SB
> device resources only if the BIOS hides the P2SB device.
>
> [...]
Thank you for your contribution, it has been applied to my local
review-ilpo-fixes branch. Note it will show up in the public
platform-drivers-x86/review-ilpo-fixes branch only once I've pushed my
local branch there, which might take a while.
The list of commits applied:
[1/4] p2sb: Factor out p2sb_read_from_cache()
commit: 9244524d60ddea55f4df54c51200e8fef2032447
[2/4] p2sb: Introduce the global flag p2sb_hidden_by_bios
commit: ae3e6ebc5ab046d434c05c58a3e3f7e94441fec2
[3/4] p2sb: Move P2SB hide and unhide code to p2sb_scan_and_cache()
commit: 0286070c74ee48391fc07f7f617460479472d221
[4/4] p2sb: Do not scan and remove the P2SB device when it is unhidden
commit: 360c400d0f568636c1b98d1d5f9f49aa3d420c70
--
i.
^ permalink raw reply [flat|nested] 7+ messages in thread* Re: [PATCH v4 0/4] p2sb: Fix unexpected P2SB device disappearance
2024-11-28 0:28 [PATCH v4 0/4] p2sb: Fix unexpected P2SB device disappearance Shin'ichiro Kawasaki
` (4 preceding siblings ...)
2024-12-10 14:39 ` [PATCH v4 0/4] p2sb: Fix unexpected P2SB device disappearance Ilpo Järvinen
@ 2024-12-12 19:02 ` Daniel Walker (danielwa)
5 siblings, 0 replies; 7+ messages in thread
From: Daniel Walker (danielwa) @ 2024-12-12 19:02 UTC (permalink / raw)
To: Shin'ichiro Kawasaki
Cc: platform-driver-x86@vger.kernel.org, Hans de Goede,
Andy Shevchenko, ilpo.jarvinen@linux.intel.com
On Thu, Nov 28, 2024 at 09:28:32AM +0900, Shin'ichiro Kawasaki wrote:
> When the BIOS does not hide the P2SB device, it is expected to be visible from
> userspace. However, the P2SB device disappears since the commit 5913320eb0b3
> ("platform/x86: p2sb: Allow p2sb_bar() calls during PCI device probe") [1]. This
> series addresses the problem. The first three patches are preliminary
> refactoring for the fix. The last patch resolves the issue by caching the P2SB
> device resources only if the BIOS hides the P2SB device.
>
> [1] https://lore.kernel.org/lkml/ZzTI+biIUTvFT6NC@goliath/
>
I tested the complete series and it restores the previously hidden device. In
other words it's working for me.
Daniel
^ permalink raw reply [flat|nested] 7+ messages in thread