mirror of
https://github.com/torvalds/linux.git
synced 2026-09-24 06:24:02 +02:00
iommu/amd: Dynamically verify Southbridge IOAPIC via PCI config space
check_ioapic_information() verifies whether the BIOS has provided a valid device ID for the Southbridge (SB) IOAPIC in the IVRS table. Currently, if the SB IOAPIC entry in the IVRS table does not match a historically hardcoded device ID (00:14.0), interrupt remapping is forcibly disabled. This hardcoded expectation does not scale to newer architectures. For example, recent Hygon Gen 4 servers use 00:0b.0 for the SB IOAPIC, which originally caused the validation to fail and interrupt remapping to be disabled until this device ID was added upstream. Instead of maintaining per-vendor/per-generation hardcoded device IDs, dynamically verify the SB IOAPIC by reading its PCI configuration space. Because the SB IOAPIC is embedded within the FCH (Fusion Controller Hub) and shares its device ID, we can inspect the PCI class code of the given device ID to confirm it is an actual FCH device (a SMBus controller or ISA Bridge). Signed-off-by: Wei Wang <wei.w.wang@hotmail.com> Tested-by: Yongwei Xu <xuyongwei@open-hieco.net> Reviewed-by: Vasant Hegde <vasant.hegde@amd.com> Signed-off-by: Joerg Roedel <joerg.roedel@amd.com>
This commit is contained in:
parent
04fee302fa
commit
16f52863b2
|
|
@ -3085,11 +3085,21 @@ static void __init free_iommu_resources(void)
|
|||
free_pci_segments();
|
||||
}
|
||||
|
||||
/* SB IOAPIC is always on this device in AMD systems */
|
||||
#define IOAPIC_SB_DEVID ((0x00 << 8) | PCI_DEVFN(0x14, 0))
|
||||
static bool __init check_sb_ioapic(int devid)
|
||||
{
|
||||
u8 bus = PCI_BUS_NUM(devid);
|
||||
u8 devfn = devid & 0xff;
|
||||
u16 val;
|
||||
|
||||
/* SB IOAPIC for Hygon family 18h model 4h is on the device 0xb */
|
||||
#define IOAPIC_SB_DEVID_FAM18H_M4H ((0x00 << 8) | PCI_DEVFN(0xb, 0))
|
||||
val = read_pci_config_16(bus, PCI_SLOT(devfn), PCI_FUNC(devfn),
|
||||
PCI_CLASS_DEVICE);
|
||||
|
||||
/*
|
||||
* The SB IOAPIC is integrated into the FCH (Southbridge), which is
|
||||
* exposed as an SMBus or ISA bridge in PCI config space.
|
||||
*/
|
||||
return val == PCI_CLASS_SERIAL_SMBUS || val == PCI_CLASS_BRIDGE_ISA;
|
||||
}
|
||||
|
||||
/*
|
||||
* The Southbridge IOAPIC is assigned a GSI Base of 0 (handling interrupts
|
||||
|
|
@ -3140,12 +3150,7 @@ static bool __init check_ioapic_information(void)
|
|||
pr_err("%s: IOAPIC[%d] not in IVRS table\n",
|
||||
fw_bug, id);
|
||||
ret = false;
|
||||
} else if (id == sb_apicid && (devid == IOAPIC_SB_DEVID ||
|
||||
(boot_cpu_data.x86_vendor == X86_VENDOR_HYGON &&
|
||||
boot_cpu_data.x86 == 0x18 &&
|
||||
boot_cpu_data.x86_model >= 0x4 &&
|
||||
boot_cpu_data.x86_model <= 0xf &&
|
||||
devid == IOAPIC_SB_DEVID_FAM18H_M4H))) {
|
||||
} else if (id == sb_apicid && check_sb_ioapic(devid)) {
|
||||
has_sb_ioapic = true;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user