Skip to content

Commit

Permalink
intel-iommu: Apply BIOS sanity checks for interrupt remapping too.
Browse files Browse the repository at this point in the history
The BIOS errors where an IOMMU is reported either at zero or a bogus
address are causing problems even when the IOMMU is disabled -- because
interrupt remapping uses the same hardware. Ensure that the checks get
applied for the interrupt remapping initialisation too.

Cc: [email protected]
Signed-off-by: David Woodhouse <[email protected]>
  • Loading branch information
David Woodhouse authored and David Woodhouse committed Dec 8, 2009
1 parent 2c99220 commit 6ecbf01
Showing 1 changed file with 26 additions and 7 deletions.
33 changes: 26 additions & 7 deletions drivers/pci/dmar.c
Original file line number Diff line number Diff line change
Expand Up @@ -613,6 +613,8 @@ int __init dmar_table_init(void)
return 0;
}

static int bios_warned;

int __init check_zero_address(void)
{
struct acpi_table_dmar *dmar;
Expand Down Expand Up @@ -643,6 +645,7 @@ int __init check_zero_address(void)
dmi_get_system_info(DMI_BIOS_VENDOR),
dmi_get_system_info(DMI_BIOS_VERSION),
dmi_get_system_info(DMI_PRODUCT_VERSION));
bios_warned = 1;
goto failed;
}

Expand All @@ -662,6 +665,7 @@ int __init check_zero_address(void)
dmi_get_system_info(DMI_BIOS_VENDOR),
dmi_get_system_info(DMI_BIOS_VERSION),
dmi_get_system_info(DMI_PRODUCT_VERSION));
bios_warned = 1;
goto failed;
}
}
Expand Down Expand Up @@ -722,6 +726,18 @@ int alloc_iommu(struct dmar_drhd_unit *drhd)
int agaw = 0;
int msagaw = 0;

if (!drhd->reg_base_addr) {
if (!bios_warned) {
WARN(1, "Your BIOS is broken; DMAR reported at address zero!\n"
"BIOS vendor: %s; Ver: %s; Product Version: %s\n",
dmi_get_system_info(DMI_BIOS_VENDOR),
dmi_get_system_info(DMI_BIOS_VERSION),
dmi_get_system_info(DMI_PRODUCT_VERSION));
bios_warned = 1;
}
return -EINVAL;
}

iommu = kzalloc(sizeof(*iommu), GFP_KERNEL);
if (!iommu)
return -ENOMEM;
Expand All @@ -738,13 +754,16 @@ int alloc_iommu(struct dmar_drhd_unit *drhd)
iommu->ecap = dmar_readq(iommu->reg + DMAR_ECAP_REG);

if (iommu->cap == (uint64_t)-1 && iommu->ecap == (uint64_t)-1) {
/* Promote an attitude of violence to a BIOS engineer today */
WARN(1, "Your BIOS is broken; DMAR reported at address %llx returns all ones!\n"
"BIOS vendor: %s; Ver: %s; Product Version: %s\n",
drhd->reg_base_addr,
dmi_get_system_info(DMI_BIOS_VENDOR),
dmi_get_system_info(DMI_BIOS_VERSION),
dmi_get_system_info(DMI_PRODUCT_VERSION));
if (!bios_warned) {
/* Promote an attitude of violence to a BIOS engineer today */
WARN(1, "Your BIOS is broken; DMAR reported at address %llx returns all ones!\n"
"BIOS vendor: %s; Ver: %s; Product Version: %s\n",
drhd->reg_base_addr,
dmi_get_system_info(DMI_BIOS_VENDOR),
dmi_get_system_info(DMI_BIOS_VERSION),
dmi_get_system_info(DMI_PRODUCT_VERSION));
bios_warned = 1;
}
goto err_unmap;
}

Expand Down

0 comments on commit 6ecbf01

Please sign in to comment.