* Re: [PATCH] PCI/VGA: Fix boot device detection after framebuffer relocation
2026-10-28 9:46 [PATCH] PCI/VGA: Fix boot device detection after framebuffer relocation wuqianhai
@ 2026-10-28 23:15 ` Bjorn Helgaas
2026-10-29 3:39 ` wuqianhai
2026-10-29 7:54 ` Thomas Zimmermann
2026-10-29 3:34 ` [PATCH v2] PCI/VGA: Enable firmware default device detection on LoongArch wuqianhai
` (2 subsequent siblings)
3 siblings, 2 replies; 8+ messages in thread
From: Bjorn Helgaas @ 2026-10-28 23:15 UTC (permalink / raw)
To: wuqianhai
Cc: bhelgaas, linux-pci, linux-kernel, tzimmermann, javierm, dri-devel
On Wed, Oct 28, 2026 at 05:46:34PM +0800, wuqianhai@loongson.cn wrote:
> From: wuqianhai <wuqianhai@loongson.cn>
>
> PCI resource assignment can relocate the firmware framebuffer BAR, which
> leaves the base address in screen_info stale. The VGA arbiter then calls
> screen_info_pci_dev() from vga_is_firmware_default(), which fails to match
> the framebuffer against any PCI device's BARs. As a result, the boot VGA
> device is not recognized and the arbiter may select the wrong default
> device.
>
> Fix this by calling screen_info_apply_fixups() in vga_arb_device_init()
> before adding the VGA devices. This relocates lfb_base to the assigned
> BAR address so that vga_is_firmware_default() matches the boot device
> again.
>
> Tested on a LoongArch platform, with vga_is_firmware_default()
> additionally enabled for CONFIG_LOONGARCH via local changes.
>
> Fixes: 337bf13aa9ddab8ae47f2677ab75cf69ae33437b ("PCI/VGA: Replace vga_is_firmware_default() with a screen info check")
> Signed-off-by: wuqianhai <wuqianhai@loongson.cn>
> ---
> drivers/pci/vgaarb.c | 8 ++++++++
> 1 file changed, 8 insertions(+)
>
> diff --git a/drivers/pci/vgaarb.c b/drivers/pci/vgaarb.c
> index 3e58b2c05c85..aca594651f58 100644
> --- a/drivers/pci/vgaarb.c
> +++ b/drivers/pci/vgaarb.c
> @@ -1527,6 +1527,14 @@ static int __init vga_arb_device_init(void)
> int rc;
> struct pci_dev *pdev;
>
> + /*
> + * PCI resource assignment may have relocated the firmware
> + * framebuffer BAR. Update screen_info's lfb_base so that
> + * vga_is_firmware_default() can match it against the boot
> + * device's relocated resource.
> + */
> + screen_info_apply_fixups();
I'm really confused about this. vga_is_firmware_default() relies on
screen_info_pci_dev(&sysfb_primary_display.screen):
vga_is_firmware_default
screen_info_pci_dev(&sysfb_primary_display.screen)
numres = screen_info_resources(&sysfb_primary_display.screen, res, ...)
for (i = 0; i < numres; ++i)
pdev = __screen_info_pci_dev(&res[i])
screen_info_resources() returns resource structs with PCI bus
addresses in them. These are not valid CPU addresses, so that seems
broken on any system where bus addresses are not the same as CPU
addresses.
screen_info_fixup_lfb() and screen_info_apply_fixups() may fix the
issue you see, but I think the way this happens is questionable.
screen_info_fixup_lfb() captures the framebuffer PCI bus address in
screen_info_lfb_res_start. Then screen_info_apply_fixups() compares
that PCI bus address with the CPU address in pdev->resource[]. That's
broken on any system where bus addresses are not the same as CPU
addresses. I think it's also broken because screen_info_lfb_res_start
may not be at the beginning of the BAR.
I think screen_info_fixup_lfb() should only capture the pci_dev, the
BAR number, and the framebuffer offset into the BAR. When we need the
CPU or bus address, we can always compute it from those values.
> rc = misc_register(&vga_arb_device);
> if (rc < 0)
> pr_err("error %d registering device\n", rc);
> --
> 2.34.1
>
^ permalink raw reply [flat|nested] 8+ messages in thread* Re: [PATCH] PCI/VGA: Fix boot device detection after framebuffer relocation
2026-10-28 23:15 ` Bjorn Helgaas
@ 2026-10-29 3:39 ` wuqianhai
2026-10-29 7:54 ` Thomas Zimmermann
1 sibling, 0 replies; 8+ messages in thread
From: wuqianhai @ 2026-10-29 3:39 UTC (permalink / raw)
To: helgaas; +Cc: tzimmermann, linux-pci, linux-kernel
Hi Bjorn,
Thanks for the detailed analysis.
You're right that screen_info_fixup_lfb()/screen_info_apply_fixups()
stores a PCI bus address in screen_info_lfb_res_start and compares it
with the CPU address in pdev->resource[].start, which is broken on
systems where bus and CPU addresses differ.
On LoongArch, though, bus and CPU addresses are identical: with modern
firmware, acpi_prepare_root_resources() takes the PCIH path and leaves
the window offset at 0 (see commit 49f33840dcc9). So the existing
screen_info_apply_fixups() works correctly for LoongArch, and the
address-space confusion you describe does not trigger there.
I've sent a v2 that:
- enables vga_is_firmware_default() for LoongArch,
- restricts the screen_info_apply_fixups() call to LoongArch so x86 and
other architectures are unaffected,
- makes VGA_ARB select SYSFB on LoongArch to avoid the undefined
reference when CONFIG_SCREEN_INFO is not set.
The general bus != CPU problem in screen_info_pci.c is still worth
fixing for ARM and friends, but I'd rather keep that separate from this
LoongArch enablement. Happy to help with that follow-up if useful.
Regards,
wuqianhai
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH] PCI/VGA: Fix boot device detection after framebuffer relocation
2026-10-28 23:15 ` Bjorn Helgaas
2026-10-29 3:39 ` wuqianhai
@ 2026-10-29 7:54 ` Thomas Zimmermann
1 sibling, 0 replies; 8+ messages in thread
From: Thomas Zimmermann @ 2026-10-29 7:54 UTC (permalink / raw)
To: Bjorn Helgaas, wuqianhai
Cc: bhelgaas, linux-pci, linux-kernel, javierm, dri-devel
Hi
Am 29.10.26 um 00:15 schrieb Bjorn Helgaas:
> On Wed, Oct 28, 2026 at 05:46:34PM +0800, wuqianhai@loongson.cn wrote:
>> From: wuqianhai <wuqianhai@loongson.cn>
>>
>> PCI resource assignment can relocate the firmware framebuffer BAR, which
>> leaves the base address in screen_info stale. The VGA arbiter then calls
>> screen_info_pci_dev() from vga_is_firmware_default(), which fails to match
>> the framebuffer against any PCI device's BARs. As a result, the boot VGA
>> device is not recognized and the arbiter may select the wrong default
>> device.
>>
>> Fix this by calling screen_info_apply_fixups() in vga_arb_device_init()
>> before adding the VGA devices. This relocates lfb_base to the assigned
>> BAR address so that vga_is_firmware_default() matches the boot device
>> again.
>>
>> Tested on a LoongArch platform, with vga_is_firmware_default()
>> additionally enabled for CONFIG_LOONGARCH via local changes.
>>
>> Fixes: 337bf13aa9ddab8ae47f2677ab75cf69ae33437b ("PCI/VGA: Replace vga_is_firmware_default() with a screen info check")
>> Signed-off-by: wuqianhai <wuqianhai@loongson.cn>
>> ---
>> drivers/pci/vgaarb.c | 8 ++++++++
>> 1 file changed, 8 insertions(+)
>>
>> diff --git a/drivers/pci/vgaarb.c b/drivers/pci/vgaarb.c
>> index 3e58b2c05c85..aca594651f58 100644
>> --- a/drivers/pci/vgaarb.c
>> +++ b/drivers/pci/vgaarb.c
>> @@ -1527,6 +1527,14 @@ static int __init vga_arb_device_init(void)
>> int rc;
>> struct pci_dev *pdev;
>>
>> + /*
>> + * PCI resource assignment may have relocated the firmware
>> + * framebuffer BAR. Update screen_info's lfb_base so that
>> + * vga_is_firmware_default() can match it against the boot
>> + * device's relocated resource.
>> + */
>> + screen_info_apply_fixups();
> I'm really confused about this. vga_is_firmware_default() relies on
> screen_info_pci_dev(&sysfb_primary_display.screen):
>
> vga_is_firmware_default
> screen_info_pci_dev(&sysfb_primary_display.screen)
> numres = screen_info_resources(&sysfb_primary_display.screen, res, ...)
> for (i = 0; i < numres; ++i)
> pdev = __screen_info_pci_dev(&res[i])
>
> screen_info_resources() returns resource structs with PCI bus
> addresses in them. These are not valid CPU addresses, so that seems
> broken on any system where bus addresses are not the same as CPU
> addresses.
What we get from the firmware for the framebuffer is a memory range.
If the underlying PCI memory gets relocated during the boot, we need
to update the framebuffer data accordingly. This has worked well for the
last 20 yrs.
>
> screen_info_fixup_lfb() and screen_info_apply_fixups() may fix the
> issue you see, but I think the way this happens is questionable.
>
> screen_info_fixup_lfb() captures the framebuffer PCI bus address in
> screen_info_lfb_res_start. Then screen_info_apply_fixups() compares
> that PCI bus address with the CPU address in pdev->resource[]. That's
> broken on any system where bus addresses are not the same as CPU
> addresses. I think it's also broken because screen_info_lfb_res_start
> may not be at the beginning of the BAR.
>
> I think screen_info_fixup_lfb() should only capture the pci_dev, the
> BAR number, and the framebuffer offset into the BAR. When we need the
> CPU or bus address, we can always compute it from those values.
This is not sufficient, I think. We did this until a while ago and got
problems with relocated bars. IIRC aarch64 had a number of affected
systems. See commit 2f29b5c23101 ("video: screen_info: Relocate
framebuffers behind PCI bridges") for details.
I'm happy to improve that code though, if we can do something better.
Best regards
Thomas
>
>> rc = misc_register(&vga_arb_device);
>> if (rc < 0)
>> pr_err("error %d registering device\n", rc);
>> --
>> 2.34.1
>>
--
--
Thomas Zimmermann
Graphics Driver Developer
SUSE Software Solutions Germany GmbH
Frankenstr. 146, 90461 Nürnberg, Germany, www.suse.com
GF: Stefan Gaiser, Jochen Jaser, Abhinav Puri, (HRB 36809, AG Nürnberg)
^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH v2] PCI/VGA: Enable firmware default device detection on LoongArch
2026-10-28 9:46 [PATCH] PCI/VGA: Fix boot device detection after framebuffer relocation wuqianhai
2026-10-28 23:15 ` Bjorn Helgaas
@ 2026-10-29 3:34 ` wuqianhai
2026-10-29 8:10 ` Thomas Zimmermann
2026-10-29 7:00 ` [PATCH] PCI/VGA: Fix boot device detection after framebuffer relocation kernel test robot
2026-10-29 13:30 ` kernel test robot
3 siblings, 1 reply; 8+ messages in thread
From: wuqianhai @ 2026-10-29 3:34 UTC (permalink / raw)
To: bhelgaas
Cc: wuqianhai, linux-pci, linux-kernel, tzimmermann, javierm, dri-devel
From: wuqianhai <wuqianhai@loongson.cn>
On LoongArch, PCI resource assignment completes during subsys_initcall
(acpi_init), before vga_arb_device_init() runs. By that time the
firmware framebuffer BAR may already have been relocated, leaving
screen_info's lfb_base stale. Enable vga_is_firmware_default() for
LoongArch and refresh screen_info in vga_arb_device_init() before the
boot device is matched.
Unlike x86, sysfb_primary_display is only defined when CONFIG_SYSFB is
enabled on LoongArch, so have VGA_ARB select SYSFB there.
Signed-off-by: wuqianhai <wuqianhai@loongson.cn>
---
Changes in v2:
- Add VGA_ARB's select of SYSFB for LoongArch to avoid an undefined
reference when CONFIG_SCREEN_INFO is not set.
- Restrict the screen_info_apply_fixups() call to CONFIG_LOONGARCH so
x86 and other architectures are unaffected.
- Enable vga_is_firmware_default() for LoongArch.
---
drivers/pci/Kconfig | 1 +
drivers/pci/vgaarb.c | 12 +++++++++++-
2 files changed, 12 insertions(+), 1 deletion(-)
diff --git a/drivers/pci/Kconfig b/drivers/pci/Kconfig
index 0c7408509ba2..55cc60f5d312 100644
--- a/drivers/pci/Kconfig
+++ b/drivers/pci/Kconfig
@@ -256,6 +256,7 @@ config VGA_ARB
default y
depends on !S390
select SCREEN_INFO if X86
+ select SYSFB if LOONGARCH
help
Some "legacy" VGA devices implemented on PCI typically have the same
hard-decoded addresses as they did on ISA. When multiple PCI devices
diff --git a/drivers/pci/vgaarb.c b/drivers/pci/vgaarb.c
index 3e58b2c05c85..1b7e915629f9 100644
--- a/drivers/pci/vgaarb.c
+++ b/drivers/pci/vgaarb.c
@@ -566,7 +566,7 @@ EXPORT_SYMBOL(vga_put);
static bool vga_is_firmware_default(struct pci_dev *pdev)
{
-#if defined CONFIG_X86
+#if defined(CONFIG_X86) || defined(CONFIG_LOONGARCH)
return pdev == screen_info_pci_dev(&sysfb_primary_display.screen);
#else
return false;
@@ -1527,6 +1527,16 @@ static int __init vga_arb_device_init(void)
int rc;
struct pci_dev *pdev;
+#if defined(CONFIG_LOONGARCH)
+ /*
+ * On LoongArch, PCI resource assignment completes during
+ * subsys_initcall (acpi_init), before the VGA arbiter runs. Refresh
+ * screen_info so vga_is_firmware_default() can match the relocated
+ * BAR.
+ */
+ screen_info_apply_fixups();
+#endif
+
rc = misc_register(&vga_arb_device);
if (rc < 0)
pr_err("error %d registering device\n", rc);
--
2.34.1
^ permalink raw reply [flat|nested] 8+ messages in thread* Re: [PATCH v2] PCI/VGA: Enable firmware default device detection on LoongArch
2026-10-29 3:34 ` [PATCH v2] PCI/VGA: Enable firmware default device detection on LoongArch wuqianhai
@ 2026-10-29 8:10 ` Thomas Zimmermann
0 siblings, 0 replies; 8+ messages in thread
From: Thomas Zimmermann @ 2026-10-29 8:10 UTC (permalink / raw)
To: wuqianhai, bhelgaas; +Cc: linux-pci, linux-kernel, javierm, dri-devel
Hi
Am 29.10.26 um 04:34 schrieb wuqianhai@loongson.cn:
> From: wuqianhai <wuqianhai@loongson.cn>
>
> On LoongArch, PCI resource assignment completes during subsys_initcall
> (acpi_init), before vga_arb_device_init() runs. By that time the
> firmware framebuffer BAR may already have been relocated, leaving
> screen_info's lfb_base stale. Enable vga_is_firmware_default() for
> LoongArch and refresh screen_info in vga_arb_device_init() before the
> boot device is matched.
>
> Unlike x86, sysfb_primary_display is only defined when CONFIG_SYSFB is
> enabled on LoongArch, so have VGA_ARB select SYSFB there.
>
> Signed-off-by: wuqianhai <wuqianhai@loongson.cn>
> ---
> Changes in v2:
> - Add VGA_ARB's select of SYSFB for LoongArch to avoid an undefined
> reference when CONFIG_SCREEN_INFO is not set.
> - Restrict the screen_info_apply_fixups() call to CONFIG_LOONGARCH so
> x86 and other architectures are unaffected.
> - Enable vga_is_firmware_default() for LoongArch.
> ---
> drivers/pci/Kconfig | 1 +
> drivers/pci/vgaarb.c | 12 +++++++++++-
> 2 files changed, 12 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/pci/Kconfig b/drivers/pci/Kconfig
> index 0c7408509ba2..55cc60f5d312 100644
> --- a/drivers/pci/Kconfig
> +++ b/drivers/pci/Kconfig
> @@ -256,6 +256,7 @@ config VGA_ARB
> default y
> depends on !S390
> select SCREEN_INFO if X86
> + select SYSFB if LOONGARCH
> help
> Some "legacy" VGA devices implemented on PCI typically have the same
> hard-decoded addresses as they did on ISA. When multiple PCI devices
> diff --git a/drivers/pci/vgaarb.c b/drivers/pci/vgaarb.c
> index 3e58b2c05c85..1b7e915629f9 100644
> --- a/drivers/pci/vgaarb.c
> +++ b/drivers/pci/vgaarb.c
> @@ -566,7 +566,7 @@ EXPORT_SYMBOL(vga_put);
>
> static bool vga_is_firmware_default(struct pci_dev *pdev)
> {
> -#if defined CONFIG_X86
> +#if defined(CONFIG_X86) || defined(CONFIG_LOONGARCH)
> return pdev == screen_info_pci_dev(&sysfb_primary_display.screen);
> #else
> return false;
> @@ -1527,6 +1527,16 @@ static int __init vga_arb_device_init(void)
> int rc;
> struct pci_dev *pdev;
>
> +#if defined(CONFIG_LOONGARCH)
> + /*
> + * On LoongArch, PCI resource assignment completes during
> + * subsys_initcall (acpi_init), before the VGA arbiter runs. Refresh
> + * screen_info so vga_is_firmware_default() can match the relocated
> + * BAR.
> + */
> + screen_info_apply_fixups();
> +#endif
No per-arch defines in generic code. All the setup should work the same
on all architectures. All global screen-info state should be maintained
by drivers/firmware/sysfb.c. Otherwise the framebuffer setup gets even
more convoluted than it already is.
My question is why does vga_is_firmware_default() run before
sysfb_init()? [1] Does acpi_init call into it? [1]
https://elixir.bootlin.com/linux/v7.3/source/drivers/firmware/sysfb.c#L225
Apart from that, we can decouple screen_info_apply_fixups() from
sysfb_init(). After relocation happens, the PCI code could call the
helper directly and let it update the global screen_info.
Best regards
Thomas
> +
> rc = misc_register(&vga_arb_device);
> if (rc < 0)
> pr_err("error %d registering device\n", rc);
--
--
Thomas Zimmermann
Graphics Driver Developer
SUSE Software Solutions Germany GmbH
Frankenstr. 146, 90461 Nürnberg, Germany, www.suse.com
GF: Stefan Gaiser, Jochen Jaser, Abhinav Puri, (HRB 36809, AG Nürnberg)
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH] PCI/VGA: Fix boot device detection after framebuffer relocation
2026-10-28 9:46 [PATCH] PCI/VGA: Fix boot device detection after framebuffer relocation wuqianhai
2026-10-28 23:15 ` Bjorn Helgaas
2026-10-29 3:34 ` [PATCH v2] PCI/VGA: Enable firmware default device detection on LoongArch wuqianhai
@ 2026-10-29 7:00 ` kernel test robot
2026-10-29 13:30 ` kernel test robot
3 siblings, 0 replies; 8+ messages in thread
From: kernel test robot @ 2026-10-29 7:00 UTC (permalink / raw)
To: wuqianhai, bhelgaas
Cc: llvm, oe-kbuild-all, wuqianhai, linux-pci, linux-kernel,
tzimmermann, javierm, dri-devel
Hi,
kernel test robot noticed the following build errors:
[auto build test ERROR on pci/next]
[also build test ERROR on pci/for-linus linus/master v7.3 next-20261028]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]
url: https://github.com/intel-lab-lkp/linux/commits/wuqianhai-loongson-cn/PCI-VGA-Fix-boot-device-detection-after-framebuffer-relocation/20261028-174634
base: https://git.kernel.org/pub/scm/linux/kernel/git/pci/pci.git next
patch link: https://lore.kernel.org/r/20261028094634.766723-1-wuqianhai%40loongson.cn
patch subject: [PATCH] PCI/VGA: Fix boot device detection after framebuffer relocation
config: loongarch-allnoconfig (https://download.01.org/0day-ci/archive/20261029/202610291418.tlsEIHSu-lkp@intel.com/config)
compiler: clang version 20.1.8 (https://github.com/llvm/llvm-project 87f0227cb60147a26a1eeb4fb06e3b505e9c7261)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20261029/202610291418.tlsEIHSu-lkp@intel.com/reproduce)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202610291418.tlsEIHSu-lkp@intel.com/
All errors (new ones prefixed by >>):
>> ld.lld: error: undefined symbol: screen_info_apply_fixups
>>> referenced by vgaarb.c
>>> drivers/pci/vgaarb.o:(vga_arb_device_init) in archive vmlinux.a
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH] PCI/VGA: Fix boot device detection after framebuffer relocation
2026-10-28 9:46 [PATCH] PCI/VGA: Fix boot device detection after framebuffer relocation wuqianhai
` (2 preceding siblings ...)
2026-10-29 7:00 ` [PATCH] PCI/VGA: Fix boot device detection after framebuffer relocation kernel test robot
@ 2026-10-29 13:30 ` kernel test robot
3 siblings, 0 replies; 8+ messages in thread
From: kernel test robot @ 2026-10-29 13:30 UTC (permalink / raw)
To: wuqianhai, bhelgaas
Cc: oe-kbuild-all, wuqianhai, linux-pci, linux-kernel, tzimmermann,
javierm, dri-devel
Hi,
kernel test robot noticed the following build errors:
[auto build test ERROR on pci/next]
[also build test ERROR on pci/for-linus linus/master v7.3 next-20261028]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]
url: https://github.com/intel-lab-lkp/linux/commits/wuqianhai-loongson-cn/PCI-VGA-Fix-boot-device-detection-after-framebuffer-relocation/20261028-174634
base: https://git.kernel.org/pub/scm/linux/kernel/git/pci/pci.git next
patch link: https://lore.kernel.org/r/20261028094634.766723-1-wuqianhai%40loongson.cn
patch subject: [PATCH] PCI/VGA: Fix boot device detection after framebuffer relocation
config: microblaze-defconfig (https://download.01.org/0day-ci/archive/20261029/202610292159.Ls5pkJAS-lkp@intel.com/config)
compiler: microblaze-linux-gcc (GCC) 16.2.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20261029/202610292159.Ls5pkJAS-lkp@intel.com/reproduce)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202610292159.Ls5pkJAS-lkp@intel.com/
All errors (new ones prefixed by >>):
microblaze-linux-ld: drivers/pci/vgaarb.o: in function `vga_arb_device_init':
>> drivers/pci/vgaarb.c:1536:(.init.text+0x10): undefined reference to `screen_info_apply_fixups'
vim +1536 drivers/pci/vgaarb.c
1524
1525 static int __init vga_arb_device_init(void)
1526 {
1527 int rc;
1528 struct pci_dev *pdev;
1529
1530 /*
1531 * PCI resource assignment may have relocated the firmware
1532 * framebuffer BAR. Update screen_info's lfb_base so that
1533 * vga_is_firmware_default() can match it against the boot
1534 * device's relocated resource.
1535 */
> 1536 screen_info_apply_fixups();
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
^ permalink raw reply [flat|nested] 8+ messages in thread