* [PATCH] PCI/VGA: Fix boot device detection after framebuffer relocation
@ 2026-10-28 9:46 wuqianhai
2026-10-28 10:11 ` sashiko-bot
` (3 more replies)
0 siblings, 4 replies; 9+ messages in thread
From: wuqianhai @ 2026-10-28 9:46 UTC (permalink / raw)
To: bhelgaas
Cc: wuqianhai, linux-pci, linux-kernel, tzimmermann, javierm,
dri-devel
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();
+
rc = misc_register(&vga_arb_device);
if (rc < 0)
pr_err("error %d registering device\n", rc);
--
2.34.1
^ permalink raw reply related [flat|nested] 9+ 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 10:11 ` sashiko-bot 2026-10-28 23:15 ` Bjorn Helgaas ` (2 subsequent siblings) 3 siblings, 0 replies; 9+ messages in thread From: sashiko-bot @ 2026-10-28 10:11 UTC (permalink / raw) To: wuqianhai; +Cc: linux-pci, dri-devel Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider: - [High] PCI/VGA: premature and duplicate screen_info_apply_fixups() in vga_arb_device_init() - [Medium] PCI/VGA: undefined reference to screen_info_apply_fixups() when !SCREEN_INFO -- commit da40d2d05299ef123ed4789d2ecb58829165fbe3 Author: wuqianhai <wuqianhai@loongson.cn> PCI/VGA: Fix boot device detection after framebuffer relocation This commit calls screen_info_apply_fixups() in vga_arb_device_init() so that screen_info's lfb_base is updated before VGA devices are registered and checked by vga_is_firmware_default(). > diff --git a/drivers/pci/vgaarb.c b/drivers/pci/vgaarb.c > index 3e58b2c05c854..aca594651f580 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(); [Severity: Medium] Will calling screen_info_apply_fixups() unconditionally in vga_arb_device_init() fail to link when CONFIG_PCI=y, CONFIG_VGA_ARB=y, and CONFIG_SCREEN_INFO=n? In drivers/pci/Kconfig, VGA_ARB only selects SCREEN_INFO on x86: drivers/pci/Kconfig: config VGA_ARB bool "VGA Arbitration" if EXPERT default y depends on !S390 select SCREEN_INFO if X86 which matches the CONFIG_X86 guard in vga_is_firmware_default(): drivers/pci/vgaarb.c:vga_is_firmware_default() { #if defined CONFIG_X86 return pdev == screen_info_pci_dev(&sysfb_primary_display.screen); #else return false; #endif } However, include/linux/screen_info.h declares screen_info_apply_fixups() as an external function whenever CONFIG_PCI is enabled, while drivers/video/Makefile only builds screen_info_pci.o when CONFIG_SCREEN_INFO is enabled: include/linux/screen_info.h: #if defined(CONFIG_PCI) void screen_info_apply_fixups(void); struct pci_dev *screen_info_pci_dev(const struct screen_info *si); #else static inline void screen_info_apply_fixups(void) { } drivers/video/Makefile: obj-$(CONFIG_SCREEN_INFO) += screen_info.o ... screen_info-$(CONFIG_PCI) += screen_info_pci.o On non-x86 architectures with CONFIG_PCI=y, CONFIG_VGA_ARB=y, and CONFIG_SCREEN_INFO=n, doesn't this result in an undefined reference to screen_info_apply_fixups()? [Severity: High] Also, is subsys_initcall_sync(vga_arb_device_init) the right place in the initcall sequence to call screen_info_apply_fixups()? Upstream vga_is_firmware_default() in drivers/pci/vgaarb.c only calls screen_info_pci_dev() under CONFIG_X86. On x86, subsys_initcall(pci_subsys_init) runs pcibios_resource_survey() -> pcibios_allocate_dev_resources(). When the firmware framebuffer BAR has a resource conflict and awaits reassignment, pcibios_allocate_dev_resources() saves the firmware address and resets r->start to 0 while keeping resource_size(r) intact: arch/x86/pci/i386.c:pcibios_allocate_dev_resources() { ... /* We'll assign a new address later */ pcibios_save_fw_addr(dev, idx, r->start); r->end -= r->start; r->start = 0; ... } The new BAR address on x86 is not assigned until fs_initcall(pcibios_assign_resources) -> pci_assign_unassigned_resources(), which runs after subsys_initcall_sync(vga_arb_device_init). When screen_info_apply_fixups() runs at subsys_initcall_sync while a conflicting BAR has pr->start == 0, pr->start != screen_info_lfb_res_start is true and __screen_info_relocation_is_valid(si, pr) succeeds because resource_size(pr) is unchanged: drivers/video/screen_info_pci.c:screen_info_apply_fixups() { if (screen_info_lfb_pdev) { struct resource *pr = &screen_info_lfb_pdev->resource[screen_info_lfb_bar]; if (pr->start != screen_info_lfb_res_start) { if (__screen_info_relocation_is_valid(si, pr)) { __screen_info_set_lfb_base(si, pr->start + screen_info_lfb_offset); pr_info("Relocating firmware framebuffer to offset %pa[d] within %pr\n", &screen_info_lfb_offset, pr); } ... } } } Wouldn't this clobber si->lfb_base to 0 + screen_info_lfb_offset with a [mem 0x00000000-...] message before fs_initcall(pcibios_assign_resources) assigns the actual BAR address, while still failing to match in vga_is_firmware_default()? Similarly, for PCI host bridges probed at device_initcall via pci_host_probe(), vga_arb_device_init() runs before the PCI bus is scanned and before VGA devices are added via pci_notify(). Finally, since screen_info_apply_fixups() does not update screen_info_lfb_res_start or clear screen_info_lfb_pdev after applying the fixup, won't calling it in both vga_arb_device_init() and device_initcall(sysfb_init) in drivers/firmware/sysfb.c cause the relocation and log messages to run twice? -- Sashiko AI review · https://sashiko.dev/#/patchset/20261028094634.766723-1-wuqianhai@loongson.cn?part=1 ^ permalink raw reply [flat|nested] 9+ 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 10:11 ` sashiko-bot @ 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 2026-10-29 7:00 ` [PATCH] PCI/VGA: Fix boot device detection after framebuffer relocation kernel test robot 3 siblings, 2 replies; 9+ 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] 9+ 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; 9+ 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] 9+ 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; 9+ 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] 9+ 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 10:11 ` sashiko-bot 2026-10-28 23:15 ` Bjorn Helgaas @ 2026-10-29 3:34 ` wuqianhai 2026-10-29 3:58 ` sashiko-bot 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 3 siblings, 2 replies; 9+ 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 related [flat|nested] 9+ 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 3:58 ` sashiko-bot 2026-10-29 8:10 ` Thomas Zimmermann 1 sibling, 0 replies; 9+ messages in thread From: sashiko-bot @ 2026-10-29 3:58 UTC (permalink / raw) To: wuqianhai; +Cc: linux-pci, dri-devel Thank you for your contribution! Sashiko AI review found 3 potential issue(s) to consider: - [High] PCI/VGA: pci_fixup_vgadev() overrides vga_is_firmware_default() on LoongArch - [Medium] PCI/VGA: duplicate non-idempotent screen_info_apply_fixups() call on LoongArch - [Medium] PCI/VGA: vga_is_firmware_default() fails to match Loongson integrated DC -- commit 6de860408bce3c5a20f5a4c23b073eafdc942117 Author: wuqianhai <wuqianhai@loongson.cn> PCI/VGA: Enable firmware default device detection on LoongArch This commit enables vga_is_firmware_default() on LoongArch, selects CONFIG_SYSFB from CONFIG_VGA_ARB for LoongArch, and calls screen_info_apply_fixups() in vga_arb_device_init() so relocated firmware framebuffer BARs can be matched when selecting the default boot VGA device. > diff --git a/drivers/pci/vgaarb.c b/drivers/pci/vgaarb.c > index 3e58b2c05c854..1b7e915629f97 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); [Severity: High] On LoongArch systems with a Loongson display controller (PCI device IDs 0x7a06, 0x7a36, or 0x7a46) and one or more discrete VGA devices, will pci_fixup_vgadev() in arch/loongarch/pci/pci.c later overwrite the firmware default VGA device selected here? During ACPI boot on LoongArch, PCI enumeration runs in subsys_initcall(acpi_init), and vga_arb_device_init() runs next at subsys_initcall_sync: vga_arb_device_init() vga_arbiter_add_pci_device() vga_is_boot_device() vga_is_firmware_default() vga_set_default_device(pdev) After vga_arb_device_init() finishes, pci_apply_final_quirks() in drivers/pci/quirks.c runs at fs_initcall_sync and invokes the DECLARE_PCI_FIXUP_FINAL hooks in arch/loongarch/pci/pci.c: static void pci_fixup_vgadev(struct pci_dev *pdev) { struct pci_dev *devp = NULL; while ((devp = pci_get_class(PCI_CLASS_DISPLAY_VGA << 8, devp))) { if (devp->vendor != PCI_VENDOR_ID_LOONGSON) { vga_set_default_device(devp); dev_info(&pdev->dev, "Overriding boot device as %X:%X\n", devp->vendor, devp->device); } } } DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_LOONGSON, PCI_DEVICE_ID_LOONGSON_DC1, pci_fixup_vgadev); DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_LOONGSON, PCI_DEVICE_ID_LOONGSON_DC2, pci_fixup_vgadev); DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_LOONGSON, PCI_DEVICE_ID_LOONGSON_DC3, pci_fixup_vgadev); Because pci_fixup_vgadev() unconditionally calls vga_set_default_device(devp) for every non-Loongson VGA device without checking whether a firmware default device was already chosen, won't it clobber vga_default whenever firmware selected a Loongson display device or the first of multiple non-Loongson discrete GPUs as the primary display? [Severity: Medium] Also in vga_is_firmware_default() in drivers/pci/vgaarb.c, can this pointer comparison ever match when the firmware framebuffer resides on Loongson integrated graphics (such as on LS7A1000, LS7A2000, or LS2K2000)? As shown in lsdc_get_dedicated_vram() in drivers/gpu/drm/loongson/lsdc_drv.c, the integrated graphics subsystem is split across two PCI functions: /* * The GPU has 00:06.0 as its BDF, while the DC has 00:06.1 * This is true for the LS7A1000, LS7A2000 and LS2K2000. */ pdev_gpu = pci_get_domain_bus_and_slot(pci_domain_nr(pdev_dc->bus), pdev_dc->bus->number, PCI_DEVFN(6, 0)); ... base = pci_resource_start(pdev_gpu, 2); size = pci_resource_len(pdev_gpu, 2); When the firmware framebuffer is placed in integrated VRAM, screen_info_pci_dev(&sysfb_primary_display.screen) matches BAR 2 of the companion GPU device at 00:06.0 (PCI_DEVICE_ID_LOONGSON_GPU1/2/3). However, vga_arb_device_init() and pci_notify() filter devices using pci_is_vga(pdev), so only the VGA-class Display Controller function at 00:06.1 (PCI_DEVICE_ID_LOONGSON_DC1/2/3, whose BAR 0 only maps MMIO registers) is passed to vga_is_firmware_default(pdev). Doesn't comparing pdev (00:06.1) against screen_info_pci_dev() (00:06.0) always evaluate to false for the integrated display controller? > #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 [Severity: Medium] With CONFIG_VGA_ARB selecting CONFIG_SYSFB on LoongArch, calling screen_info_apply_fixups() here in vga_arb_device_init() at subsys_initcall_sync means screen_info_apply_fixups() will be called a second time when sysfb_init() in drivers/firmware/sysfb.c runs at device_initcall: drivers/firmware/sysfb.c:sysfb_init() { ... screen_info_apply_fixups(); mutex_lock(&disable_lock); if (disabled) goto unlock_mutex; ... } Looking at screen_info_apply_fixups() in drivers/video/screen_info_pci.c: void screen_info_apply_fixups(void) { struct screen_info *si = &sysfb_primary_display.screen; if (screen_info_lfb_pdev) { struct resource *pr = &screen_info_lfb_pdev->resource[screen_info_lfb_bar]; if (pr->start != screen_info_lfb_res_start) { if (__screen_info_relocation_is_valid(si, pr)) { __screen_info_set_lfb_base(si, pr->start + screen_info_lfb_offset); pr_info("Relocating firmware framebuffer to offset %pa[d] within %pr\n", &screen_info_lfb_offset, pr); } else { pr_warn("Invalid relocating, disabling firmware framebuffer\n"); } } } } Because screen_info_apply_fixups() neither updates screen_info_lfb_res_start nor clears screen_info_lfb_pdev after applying the fixup, won't the second call in sysfb_init() re-run the relocation logic and print a duplicate message whenever the framebuffer BAR was relocated, or emit a spurious warning if a built-in GPU driver probed earlier in device_initcall and resized the BAR after calling sysfb_disable()? -- Sashiko AI review · https://sashiko.dev/#/patchset/20261029033440.973077-1-wuqianhai@loongson.cn?part=1 ^ permalink raw reply [flat|nested] 9+ 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 3:58 ` sashiko-bot @ 2026-10-29 8:10 ` Thomas Zimmermann 1 sibling, 0 replies; 9+ 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] 9+ 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 3:34 ` [PATCH v2] PCI/VGA: Enable firmware default device detection on LoongArch wuqianhai @ 2026-10-29 7:00 ` kernel test robot 3 siblings, 0 replies; 9+ 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] 9+ messages in thread
end of thread, other threads:[~2026-10-29 8:10 UTC | newest] Thread overview: 9+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2026-10-28 9:46 [PATCH] PCI/VGA: Fix boot device detection after framebuffer relocation wuqianhai 2026-10-28 10:11 ` sashiko-bot 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 2026-10-29 3:58 ` sashiko-bot 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
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox