diff options
| author | Mario Limonciello <mario.limonciello@amd.com> | 2026-07-08 14:35:17 -0500 |
|---|---|---|
| committer | Alex Deucher <alexander.deucher@amd.com> | 2026-07-15 09:15:41 -0400 |
| commit | 4059e2f02c8a2a51ba78860775877d721df6a055 (patch) | |
| tree | ed3ea0b0a3661b3c9593c0dca228262745c7661c | |
| parent | 24071402a41a56dba3e215ca89c6b5d855c678ea (diff) | |
| download | linux-4059e2f02c8a2a51ba78860775877d721df6a055.tar.gz linux-4059e2f02c8a2a51ba78860775877d721df6a055.zip | |
drm/radeon: Fix VFCT bus number matching with soft filter
On systems where PCI bus renumbering occurs (e.g. pci=realloc,
resource conflicts), the runtime bus number may differ from the
BIOS POST bus number recorded in the VFCT table. This causes
radeon_acpi_vfct_bios() to fail finding the VBIOS even though
the correct device entry exists.
Introduce radeon_acpi_vfct_match() which treats the bus number
as a soft filter: vendor/device/function identity is the hard
requirement, while exact bus match is the preferred path. When
bus numbers disagree but device identity matches, accept the
VFCT entry and log a dev_notice for diagnostics. This mirrors the
equivalent amdgpu change.
Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
Link: https://patch.msgid.link/20260708193518.702584-5-mario.limonciello@amd.com
Signed-off-by: Mario Limonciello <mario.limonciello@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
| -rw-r--r-- | drivers/gpu/drm/radeon/radeon_bios.c | 45 |
1 files changed, 40 insertions, 5 deletions
diff --git a/drivers/gpu/drm/radeon/radeon_bios.c b/drivers/gpu/drm/radeon/radeon_bios.c index c6df799c3cf4..cc10880af096 100644 --- a/drivers/gpu/drm/radeon/radeon_bios.c +++ b/drivers/gpu/drm/radeon/radeon_bios.c @@ -596,6 +596,45 @@ static bool radeon_read_disabled_bios(struct radeon_device *rdev) return legacy_read_disabled_bios(rdev); } +/** + * radeon_acpi_vfct_match() - Check if a VFCT entry matches the device + * @rdev: Radeon device + * @vhdr: VFCT image header to check + * + * VFCT entries contain the PCI bus number as recorded during BIOS POST. + * On systems where the kernel renumbers PCI buses (e.g. pci=realloc or + * resource conflicts), the runtime bus number may differ from the POST + * value. Match by device identity (vendor + device + function) and use + * the bus number as a preference: exact bus match is preferred, but when + * the bus numbers disagree we accept the entry if the device identity + * matches. + * + * Returns: 0 on match, -ENODEV on no match + */ +static int radeon_acpi_vfct_match(struct radeon_device *rdev, + VFCT_IMAGE_HEADER *vhdr) +{ + /* Vendor and device IDs must always match */ + if (vhdr->VendorID != rdev->pdev->vendor || + vhdr->DeviceID != rdev->pdev->device) + return -ENODEV; + + if (vhdr->PCIDevice != PCI_SLOT(rdev->pdev->devfn) || + vhdr->PCIFunction != PCI_FUNC(rdev->pdev->devfn)) + return -ENODEV; + + /* Exact bus number match - preferred */ + if (vhdr->PCIBus == rdev->pdev->bus->number) + return 0; + + /* Bus mismatch but device identity matches (PCI renumbering case) */ + dev_notice(&rdev->pdev->dev, + "VFCT bus number mismatch: table %u != runtime %u, matching by device identity (vendor 0x%04x device 0x%04x)\n", + vhdr->PCIBus, rdev->pdev->bus->number, + rdev->pdev->vendor, rdev->pdev->device); + return 0; +} + #ifdef CONFIG_ACPI static bool radeon_acpi_vfct_bios(struct radeon_device *rdev) { @@ -633,11 +672,7 @@ static bool radeon_acpi_vfct_bios(struct radeon_device *rdev) } if (vhdr->ImageLength && - vhdr->PCIBus == rdev->pdev->bus->number && - vhdr->PCIDevice == PCI_SLOT(rdev->pdev->devfn) && - vhdr->PCIFunction == PCI_FUNC(rdev->pdev->devfn) && - vhdr->VendorID == rdev->pdev->vendor && - vhdr->DeviceID == rdev->pdev->device) { + !radeon_acpi_vfct_match(rdev, vhdr)) { rdev->bios = kmemdup(&vbios->VbiosContent, vhdr->ImageLength, GFP_KERNEL); |
