* [PATCH v4 0/4] p2sb: Fix unexpected P2SB device disappearance
@ 2024-11-28 0:28 Shin'ichiro Kawasaki
2024-11-28 0:28 ` [PATCH v4 1/4] p2sb: Factor out p2sb_read_from_cache() Shin'ichiro Kawasaki
` (5 more replies)
0 siblings, 6 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 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/
Changes from v3:
* 4th patch: Added the missing ret=0 initialization in p2sb_cache_resources()
* Added Reviewed-by tags
* Link to v3: https://lore.kernel.org/platform-driver-x86/20241127060055.357498-1-shinichiro.kawasaki@wdc.com/
Changes from v2:
* Renamed the global flag from p2sb_hidden to p2sb_hidden_by_bios
* Moved P2SB hide and unhide code to p2sb_scan_and_cache()
* Introduced two helper functions which are called from p2sb_bar()
* Separated the preliminary refactoring work to 3 new patches
* Link to v2: https://lore.kernel.org/platform-driver-x86/20241125042326.304780-1-shinichiro.kawasaki@wdc.com/
Changes from v1:
* Put back P2SBC_HIDE flag reference code in the rescan_remove lock region
* Do not cache resources when the P2SB device is not hidden
* Added the Reported-by tag
* Link to v1: https://lore.kernel.org/platform-driver-x86/20241120064055.245969-1-shinichiro.kawasaki@wdc.com/
Shin'ichiro Kawasaki (4):
p2sb: Factor out p2sb_read_from_cache()
p2sb: Introduce the global flag p2sb_hidden_by_bios
p2sb: Move P2SB hide and unhide code to p2sb_scan_and_cache()
p2sb: Do not scan and remove the P2SB device when it is unhidden
drivers/platform/x86/p2sb.c | 79 ++++++++++++++++++++++++++-----------
1 file changed, 56 insertions(+), 23 deletions(-)
--
2.47.0
^ permalink raw reply [flat|nested] 7+ messages in thread
* [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
end of thread, other threads:[~2024-12-12 19:02 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
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 ` [PATCH v4 3/4] p2sb: Move P2SB hide and unhide code to p2sb_scan_and_cache() 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
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)
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox