From 9e865fb880ec9857d90babcc2693c549a6c2b826 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20=C5=BBygowski?= Date: Tue, 9 Sep 2025 10:09:32 +0200 Subject: [PATCH] amdblocks/acpi/ivrs: Fix IVRS generation for multiple IOMMUs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit More complex systems, such as servers, have multiple IOMMUs. For example, Turin CPUs have a total of 4 IOMMUs per socket. Abort IVHD generation only if IOMMU is not present on domain 0. For other domains simply continue the loop, so that other domains have their IOMMUs described properly in the IVRS. To keep simple systems working as before, IVHD generation is aborted, if IOMMU is not present in domain 0. TEST=See IOMMUs on domains 1,3,4,6 being skipped during IVHD generation instead of IVHD generation being aborted on domain 1 on Gigabyte MZ33-AR1 console log. Change-Id: Icd3a51621908dc3ee5c85aa1e5814f3b3ac69007 Signed-off-by: Michał Żygowski Reviewed-on: https://review.coreboot.org/c/coreboot/+/89111 Reviewed-by: Patrick Rudolph Tested-by: build bot (Jenkins) --- src/soc/amd/common/block/acpi/ivrs.c | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/src/soc/amd/common/block/acpi/ivrs.c b/src/soc/amd/common/block/acpi/ivrs.c index 48c3965926..c3af6285a6 100644 --- a/src/soc/amd/common/block/acpi/ivrs.c +++ b/src/soc/amd/common/block/acpi/ivrs.c @@ -171,7 +171,7 @@ static unsigned long acpi_ivhd_misc(unsigned long current, struct device *dev) /* * Add all possible PCI devices in the domain that can generate transactions * processed by IOMMU. Start with device :01.0 - */ + */ current = ivhd_dev_range(current, PCI_DEVFN(0, 3) | (dev->downstream->secondary << 8), 0xff | (dev->downstream->subordinate << 8), 0); @@ -311,6 +311,7 @@ static unsigned long acpi_fill_ivrs(acpi_ivrs_t *ivrs, unsigned long current) struct device *iommu_dev; struct device *nb_dev; struct device *dev = NULL; + unsigned int domain; if (ivrs == NULL) { printk(BIOS_WARNING, "%s: ivrs is NULL\n", __func__); @@ -322,15 +323,22 @@ static unsigned long acpi_fill_ivrs(acpi_ivrs_t *ivrs, unsigned long current) while ((dev = dev_find_path(dev, DEVICE_PATH_DOMAIN)) != NULL) { nb_dev = pcidev_path_behind(dev->downstream, PCI_DEVFN(0, 0)); iommu_dev = pcidev_path_behind(dev->downstream, PCI_DEVFN(0, 2)); + domain = dev_get_domain_id(dev); if (!nb_dev) { - printk(BIOS_WARNING, "%s: Northbridge device not present!\n", __func__); - printk(BIOS_WARNING, "%s: IVRS table not generated...\n", __func__); - return (unsigned long)ivrs; + printk(BIOS_WARNING, "%s: Northbridge device not present on domain %u!\n", __func__, domain); + if (domain == 0) { + printk(BIOS_WARNING, "%s: IVRS table not generated...\n", __func__); + return (unsigned long)ivrs; + } + continue; } if (!iommu_dev) { - printk(BIOS_WARNING, "%s: IOMMU device not found\n", __func__); - return (unsigned long)ivrs; + printk(BIOS_WARNING, "%s: IOMMU device not found on domain %u\n", __func__, dev_get_domain_id(dev)); + if (domain == 0) + return (unsigned long)ivrs; + + continue; } ivhd->type = IVHD_BLOCK_TYPE_LEGACY__FIXED;