summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMario Limonciello <mario.limonciello@amd.com>2026-07-08 14:35:17 -0500
committerAlex Deucher <alexander.deucher@amd.com>2026-07-15 09:15:41 -0400
commit4059e2f02c8a2a51ba78860775877d721df6a055 (patch)
treeed3ea0b0a3661b3c9593c0dca228262745c7661c
parent24071402a41a56dba3e215ca89c6b5d855c678ea (diff)
downloadlinux-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.c45
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);