linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] PCI: hide mysterious 8MB 64-bit pref BAR on Intel Arc PCIe Switch
@ 2025-07-21 17:30 Icenowy Zheng
  2025-07-21 20:24 ` Bjorn Helgaas
  2025-07-21 21:52 ` Vivian Wang
  0 siblings, 2 replies; 4+ messages in thread
From: Icenowy Zheng @ 2025-07-21 17:30 UTC (permalink / raw)
  To: Bjorn Helgaas, Lucas De Marchi, Thomas Hellström,
	Rodrigo Vivi
  Cc: linux-pci, intel-xe, linux-kernel, Han Gao, Vivian Wang,
	Icenowy Zheng

The upstream port device of Intel Arc series dGPUs' internal PCIe switch
contains a mysterious 8MB 64-bit prefetchable BAR. All reads to memory
mapped to that BAR returns 0xFFFFFFFF and writes have no effect.

When the PCI bus isn't configured by any firmware (e.g. a PCIe
controller solely initialized by Linux kernel), the PCI space allocation
algorithm of Linux will allocate the main VRAM BAR of Arc dGPU device at
base+0, and then the 8MB BAR at base+256M, which prevents the main VRAM
BAR gets resized. As the functionality and performance of Arc dGPU will
get severely restricted with small BAR, this makes a problem.

Hide the mysterious 8MB BAR to Linux PCI subsystem, to allow resizing
the VRAM BAR to VRAM size with the Linux PCI space allocation algorithm.

Signed-off-by: Icenowy Zheng <uwu@icenowy.me>
---
 drivers/pci/quirks.c | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)

diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
index d7f4ee634263..df304bfec6e9 100644
--- a/drivers/pci/quirks.c
+++ b/drivers/pci/quirks.c
@@ -3650,6 +3650,22 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x37d0, quirk_broken_intx_masking);
 DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x37d1, quirk_broken_intx_masking);
 DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x37d2, quirk_broken_intx_masking);
 
+/*
+ * Intel Arc dGPUs' internal switch upstream port contains a mysterious 8MB
+ * 64-bit prefetchable BAR that blocks resize of main dGPU VRAM BAR with
+ * Linux's PCI space allocation algorithm.
+ */
+static void quirk_intel_xe_upstream(struct pci_dev *pdev)
+{
+	memset(&pdev->resource[0], 0, sizeof(pdev->resource[0]));
+}
+/* Intel Arc A380 PCI Express Switch Upstream Port */
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x4fa1, quirk_intel_xe_upstream);
+/* Intel Arc A770 PCI Express Switch Upstream Port */
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x4fa0, quirk_intel_xe_upstream);
+/* Intel Arc B580 PCI Express Switch Upstream Port */
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0xe2ff, quirk_intel_xe_upstream);
+
 static u16 mellanox_broken_intx_devs[] = {
 	PCI_DEVICE_ID_MELLANOX_HERMON_SDR,
 	PCI_DEVICE_ID_MELLANOX_HERMON_DDR,
-- 
2.50.1


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* Re: [PATCH] PCI: hide mysterious 8MB 64-bit pref BAR on Intel Arc PCIe Switch
  2025-07-21 17:30 [PATCH] PCI: hide mysterious 8MB 64-bit pref BAR on Intel Arc PCIe Switch Icenowy Zheng
@ 2025-07-21 20:24 ` Bjorn Helgaas
  2025-07-22 12:56   ` Ilpo Järvinen
  2025-07-21 21:52 ` Vivian Wang
  1 sibling, 1 reply; 4+ messages in thread
From: Bjorn Helgaas @ 2025-07-21 20:24 UTC (permalink / raw)
  To: Icenowy Zheng
  Cc: Bjorn Helgaas, Lucas De Marchi, Thomas Hellström,
	Rodrigo Vivi, linux-pci, intel-xe, linux-kernel, Han Gao,
	Vivian Wang, Ilpo Järvinen

[+cc Ilpo]

On Tue, Jul 22, 2025 at 01:30:57AM +0800, Icenowy Zheng wrote:
> The upstream port device of Intel Arc series dGPUs' internal PCIe switch
> contains a mysterious 8MB 64-bit prefetchable BAR. All reads to memory
> mapped to that BAR returns 0xFFFFFFFF and writes have no effect.
> 
> When the PCI bus isn't configured by any firmware (e.g. a PCIe
> controller solely initialized by Linux kernel), the PCI space allocation
> algorithm of Linux will allocate the main VRAM BAR of Arc dGPU device at
> base+0, and then the 8MB BAR at base+256M, which prevents the main VRAM
> BAR gets resized. As the functionality and performance of Arc dGPU will
> get severely restricted with small BAR, this makes a problem.
> 
> Hide the mysterious 8MB BAR to Linux PCI subsystem, to allow resizing
> the VRAM BAR to VRAM size with the Linux PCI space allocation algorithm.

There's no reason a switch upstream port should not have a BAR.  I
suspect this BAR probably does have a legitimate purpose, and it's
only "mysterious" because we don't know how to use it.

This sounds like it may be a deficiency in the Linux BAR assignment
code.  Any other device could have a similar problem.  

> Signed-off-by: Icenowy Zheng <uwu@icenowy.me>
> ---
>  drivers/pci/quirks.c | 16 ++++++++++++++++
>  1 file changed, 16 insertions(+)
> 
> diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
> index d7f4ee634263..df304bfec6e9 100644
> --- a/drivers/pci/quirks.c
> +++ b/drivers/pci/quirks.c
> @@ -3650,6 +3650,22 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x37d0, quirk_broken_intx_masking);
>  DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x37d1, quirk_broken_intx_masking);
>  DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x37d2, quirk_broken_intx_masking);
>  
> +/*
> + * Intel Arc dGPUs' internal switch upstream port contains a mysterious 8MB
> + * 64-bit prefetchable BAR that blocks resize of main dGPU VRAM BAR with
> + * Linux's PCI space allocation algorithm.
> + */
> +static void quirk_intel_xe_upstream(struct pci_dev *pdev)
> +{
> +	memset(&pdev->resource[0], 0, sizeof(pdev->resource[0]));

This doesn't touch the BAR itself, so we may be leaving the BAR
decoding accesses, which could lead to an address conflict.  It also
prevents a driver for the upstream port from using the BAR.

> +}
> +/* Intel Arc A380 PCI Express Switch Upstream Port */
> +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x4fa1, quirk_intel_xe_upstream);
> +/* Intel Arc A770 PCI Express Switch Upstream Port */
> +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x4fa0, quirk_intel_xe_upstream);
> +/* Intel Arc B580 PCI Express Switch Upstream Port */
> +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0xe2ff, quirk_intel_xe_upstream);
> +
>  static u16 mellanox_broken_intx_devs[] = {
>  	PCI_DEVICE_ID_MELLANOX_HERMON_SDR,
>  	PCI_DEVICE_ID_MELLANOX_HERMON_DDR,
> -- 
> 2.50.1
> 

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH] PCI: hide mysterious 8MB 64-bit pref BAR on Intel Arc PCIe Switch
  2025-07-21 17:30 [PATCH] PCI: hide mysterious 8MB 64-bit pref BAR on Intel Arc PCIe Switch Icenowy Zheng
  2025-07-21 20:24 ` Bjorn Helgaas
@ 2025-07-21 21:52 ` Vivian Wang
  1 sibling, 0 replies; 4+ messages in thread
From: Vivian Wang @ 2025-07-21 21:52 UTC (permalink / raw)
  To: Icenowy Zheng, Bjorn Helgaas, Lucas De Marchi,
	Thomas Hellström, Rodrigo Vivi
  Cc: linux-pci, intel-xe, linux-kernel, Han Gao

On 7/22/25 01:30, Icenowy Zheng wrote:

> The upstream port device of Intel Arc series dGPUs' internal PCIe switch
> contains a mysterious 8MB 64-bit prefetchable BAR. All reads to memory
> mapped to that BAR returns 0xFFFFFFFF and writes have no effect.

Reading all-ones is certainly not a good indication that this BAR does
nothing. My guess would be that maybe it's some write-only registers
like MSI doorbells.

AMD has docs on how their GPUs have a tiny doorbell default-2M 64bit
pref BAR [1], which I find interesting, even though very indirect as
evidence.

[1]: https://rocm.docs.amd.com/en/latest/how-to/Bar-Memory.html#bar-configuration-for-amd-gpus

> When the PCI bus isn't configured by any firmware (e.g. a PCIe
> controller solely initialized by Linux kernel), the PCI space allocation
> algorithm of Linux will allocate the main VRAM BAR of Arc dGPU device at
> base+0, and then the 8MB BAR at base+256M, which prevents the main VRAM
> BAR gets resized. As the functionality and performance of Arc dGPU will
> get severely restricted with small BAR, this makes a problem.

While trying to look around for if any documentation is available on the
"mysterious BAR", I found that this problem has indeed been discovered
before with no satisfactory resolution. Linking for posterity:

[2]: https://issues.redhat.com/browse/RHEL-3672
[3]: https://github.com/raspberrypi/linux/issues/6621

If my doorbell theory was correct, and that this is analogous for
amdgpu, there is this interesting comment in
drivers/gpu/drm/amd/amdgpu/amdgpu_device.c since commit d6895ad39f3b
("drm/amdgpu: resize VRAM BAR for CPU access v6"):

  /* Free the VRAM and doorbell BAR, we most likely need to move both. */

That seems to be the right way *if* it makes sense that the "mysterious
BAR" is supposed to be managed by the GPU driver. Of course, only
someone from Intel can confirm for sure what's going on...

Vivian "dramforever" Wang

> Hide the mysterious 8MB BAR to Linux PCI subsystem, to allow resizing
> the VRAM BAR to VRAM size with the Linux PCI space allocation algorithm.
>
> Signed-off-by: Icenowy Zheng <uwu@icenowy.me>
> ---
>  drivers/pci/quirks.c | 16 ++++++++++++++++
>  1 file changed, 16 insertions(+)
>
> diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
> index d7f4ee634263..df304bfec6e9 100644
> --- a/drivers/pci/quirks.c
> +++ b/drivers/pci/quirks.c
> @@ -3650,6 +3650,22 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x37d0, quirk_broken_intx_masking);
>  DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x37d1, quirk_broken_intx_masking);
>  DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x37d2, quirk_broken_intx_masking);
>  
> +/*
> + * Intel Arc dGPUs' internal switch upstream port contains a mysterious 8MB
> + * 64-bit prefetchable BAR that blocks resize of main dGPU VRAM BAR with
> + * Linux's PCI space allocation algorithm.
> + */
> +static void quirk_intel_xe_upstream(struct pci_dev *pdev)
> +{
> +	memset(&pdev->resource[0], 0, sizeof(pdev->resource[0]));
> +}
> +/* Intel Arc A380 PCI Express Switch Upstream Port */
> +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x4fa1, quirk_intel_xe_upstream);
> +/* Intel Arc A770 PCI Express Switch Upstream Port */
> +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x4fa0, quirk_intel_xe_upstream);
> +/* Intel Arc B580 PCI Express Switch Upstream Port */
> +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0xe2ff, quirk_intel_xe_upstream);
> +
>  static u16 mellanox_broken_intx_devs[] = {
>  	PCI_DEVICE_ID_MELLANOX_HERMON_SDR,
>  	PCI_DEVICE_ID_MELLANOX_HERMON_DDR,


^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH] PCI: hide mysterious 8MB 64-bit pref BAR on Intel Arc PCIe Switch
  2025-07-21 20:24 ` Bjorn Helgaas
@ 2025-07-22 12:56   ` Ilpo Järvinen
  0 siblings, 0 replies; 4+ messages in thread
From: Ilpo Järvinen @ 2025-07-22 12:56 UTC (permalink / raw)
  To: Bjorn Helgaas
  Cc: Icenowy Zheng, Bjorn Helgaas, Lucas De Marchi,
	Thomas Hellström, Rodrigo Vivi, linux-pci, intel-xe, LKML,
	Han Gao, Vivian Wang

On Mon, 21 Jul 2025, Bjorn Helgaas wrote:

> [+cc Ilpo]
> 
> On Tue, Jul 22, 2025 at 01:30:57AM +0800, Icenowy Zheng wrote:
> > The upstream port device of Intel Arc series dGPUs' internal PCIe switch
> > contains a mysterious 8MB 64-bit prefetchable BAR. All reads to memory
> > mapped to that BAR returns 0xFFFFFFFF and writes have no effect.
> > 
> > When the PCI bus isn't configured by any firmware (e.g. a PCIe
> > controller solely initialized by Linux kernel), the PCI space allocation
> > algorithm of Linux will allocate the main VRAM BAR of Arc dGPU device at
> > base+0, and then the 8MB BAR at base+256M, which prevents the main VRAM
> > BAR gets resized.

__resource_resize_store() tries to release all resoures with the same 
flags as the resource to be resized. But it seems the release doesn't work 
across devices.

I don't like that flags check anyway, I'd want to replace all such black 
magic with a function that consistently determines the bridge window a 
resouce is assigned to. I've a series to that effect but it doesn't cover 
resize cases yet and it requires more testing anyway to confirm it doesn't 
change any parent windows resources get assigned to.

So IMO, the correct logic on resize would be to:

1) Get the relevant upstream bridge window
2) Release all child resource of that bridge window. But that will 
require further checks whether all those resources (from foreign PCI devs) 
can be released which might run a foul with dev lock ordering.

...So it might turn out hard to implement in practice.

> > As the functionality and performance of Arc dGPU will
> > get severely restricted with small BAR, this makes a problem.
> > 
> > Hide the mysterious 8MB BAR to Linux PCI subsystem, to allow resizing
> > the VRAM BAR to VRAM size with the Linux PCI space allocation algorithm.
> 
> There's no reason a switch upstream port should not have a BAR.  I
> suspect this BAR probably does have a legitimate purpose, and it's
> only "mysterious" because we don't know how to use it.
> 
> This sounds like it may be a deficiency in the Linux BAR assignment
> code.  Any other device could have a similar problem.  

I'm still working also with the resource fitting logic to make it consider 
resizable BARs when sizing the resource which would address this problem 
another way.

> > Signed-off-by: Icenowy Zheng <uwu@icenowy.me>
> > ---
> >  drivers/pci/quirks.c | 16 ++++++++++++++++
> >  1 file changed, 16 insertions(+)
> > 
> > diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
> > index d7f4ee634263..df304bfec6e9 100644
> > --- a/drivers/pci/quirks.c
> > +++ b/drivers/pci/quirks.c
> > @@ -3650,6 +3650,22 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x37d0, quirk_broken_intx_masking);
> >  DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x37d1, quirk_broken_intx_masking);
> >  DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x37d2, quirk_broken_intx_masking);
> >  
> > +/*
> > + * Intel Arc dGPUs' internal switch upstream port contains a mysterious 8MB
> > + * 64-bit prefetchable BAR that blocks resize of main dGPU VRAM BAR with
> > + * Linux's PCI space allocation algorithm.
> > + */
> > +static void quirk_intel_xe_upstream(struct pci_dev *pdev)
> > +{
> > +	memset(&pdev->resource[0], 0, sizeof(pdev->resource[0]));
> 
> This doesn't touch the BAR itself, so we may be leaving the BAR
> decoding accesses, which could lead to an address conflict.  It also
> prevents a driver for the upstream port from using the BAR.
> 
> > +}
> > +/* Intel Arc A380 PCI Express Switch Upstream Port */
> > +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x4fa1, quirk_intel_xe_upstream);
> > +/* Intel Arc A770 PCI Express Switch Upstream Port */
> > +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x4fa0, quirk_intel_xe_upstream);
> > +/* Intel Arc B580 PCI Express Switch Upstream Port */
> > +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0xe2ff, quirk_intel_xe_upstream);
> > +
> >  static u16 mellanox_broken_intx_devs[] = {
> >  	PCI_DEVICE_ID_MELLANOX_HERMON_SDR,
> >  	PCI_DEVICE_ID_MELLANOX_HERMON_DDR,
> > -- 
> > 2.50.1
> > 
> 

-- 
 i.


^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2025-07-22 12:56 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-07-21 17:30 [PATCH] PCI: hide mysterious 8MB 64-bit pref BAR on Intel Arc PCIe Switch Icenowy Zheng
2025-07-21 20:24 ` Bjorn Helgaas
2025-07-22 12:56   ` Ilpo Järvinen
2025-07-21 21:52 ` Vivian Wang

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).