mirror of
https://github.com/torvalds/linux.git
synced 2026-10-16 04:39:02 +02:00
drm/amdgpu: 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
amdgpu_acpi_vfct_bios() to fail finding the VBIOS even though
the correct device entry exists.
Introduce amdgpu_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.
Reported-by: Oz Tiram <oz@shift-computing.de>
Closes: https://lore.kernel.org/amd-gfx/20260621173211.28443-1-oz@shift-computing.de/
Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
Link: https://patch.msgid.link/20260708193518.702584-2-mario.limonciello@amd.com
Signed-off-by: Mario Limonciello <mario.limonciello@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
(cherry picked from commit 11c1416720)
Cc: stable@vger.kernel.org
This commit is contained in:
parent
a2f895f3c8
commit
db7e810880
|
|
@ -372,6 +372,45 @@ static bool amdgpu_read_disabled_bios(struct amdgpu_device *adev)
|
|||
}
|
||||
|
||||
#ifdef CONFIG_ACPI
|
||||
/**
|
||||
* amdgpu_acpi_vfct_match() - Check if a VFCT entry matches the device
|
||||
* @adev: AMDGPU 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 amdgpu_acpi_vfct_match(struct amdgpu_device *adev,
|
||||
VFCT_IMAGE_HEADER *vhdr)
|
||||
{
|
||||
/* Vendor and device IDs must always match */
|
||||
if (vhdr->VendorID != adev->pdev->vendor ||
|
||||
vhdr->DeviceID != adev->pdev->device)
|
||||
return -ENODEV;
|
||||
|
||||
if (vhdr->PCIDevice != PCI_SLOT(adev->pdev->devfn) ||
|
||||
vhdr->PCIFunction != PCI_FUNC(adev->pdev->devfn))
|
||||
return -ENODEV;
|
||||
|
||||
/* Exact bus number match - preferred */
|
||||
if (vhdr->PCIBus == adev->pdev->bus->number)
|
||||
return 0;
|
||||
|
||||
/* Bus mismatch but device identity matches (PCI renumbering case) */
|
||||
dev_notice(adev->dev,
|
||||
"VFCT bus number mismatch: table %u != runtime %u, matching by device identity (vendor 0x%04x device 0x%04x)\n",
|
||||
vhdr->PCIBus, adev->pdev->bus->number,
|
||||
adev->pdev->vendor, adev->pdev->device);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static bool amdgpu_acpi_vfct_bios(struct amdgpu_device *adev)
|
||||
{
|
||||
struct acpi_table_header *hdr;
|
||||
|
|
@ -407,11 +446,7 @@ static bool amdgpu_acpi_vfct_bios(struct amdgpu_device *adev)
|
|||
}
|
||||
|
||||
if (vhdr->ImageLength &&
|
||||
vhdr->PCIBus == adev->pdev->bus->number &&
|
||||
vhdr->PCIDevice == PCI_SLOT(adev->pdev->devfn) &&
|
||||
vhdr->PCIFunction == PCI_FUNC(adev->pdev->devfn) &&
|
||||
vhdr->VendorID == adev->pdev->vendor &&
|
||||
vhdr->DeviceID == adev->pdev->device) {
|
||||
!amdgpu_acpi_vfct_match(adev, vhdr)) {
|
||||
adev->bios = kmemdup(&vbios->VbiosContent,
|
||||
vhdr->ImageLength,
|
||||
GFP_KERNEL);
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user