diff options
author | David Woodhouse <David.Woodhouse@intel.com> | 2014-03-07 14:34:38 +0000 |
---|---|---|
committer | David Woodhouse <David.Woodhouse@intel.com> | 2014-03-20 14:25:23 +0000 |
commit | e625b4a95d50fa2f2d2fd0ab4b9ac9d6b6c2474c (patch) | |
tree | fa115ce396353f7a11aef51dd42e0be764448b3e /drivers/iommu/dmar.c | |
parent | 86a54dcce6ccb0d4a5810ed8112011039d855bee (diff) | |
download | blackbird-op-linux-e625b4a95d50fa2f2d2fd0ab4b9ac9d6b6c2474c.tar.gz blackbird-op-linux-e625b4a95d50fa2f2d2fd0ab4b9ac9d6b6c2474c.zip |
iommu/vt-d: Parse ANDD records
Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
Diffstat (limited to 'drivers/iommu/dmar.c')
-rw-r--r-- | drivers/iommu/dmar.c | 27 |
1 files changed, 27 insertions, 0 deletions
diff --git a/drivers/iommu/dmar.c b/drivers/iommu/dmar.c index b19f9f4c3584..eb95020c2314 100644 --- a/drivers/iommu/dmar.c +++ b/drivers/iommu/dmar.c @@ -373,6 +373,26 @@ static void dmar_free_drhd(struct dmar_drhd_unit *dmaru) kfree(dmaru); } +static int __init dmar_parse_one_andd(struct acpi_dmar_header *header) +{ + struct acpi_dmar_andd *andd = (void *)header; + + /* Check for NUL termination within the designated length */ + if (strnlen(andd->object_name, header->length - 8) == header->length - 8) { + WARN_TAINT(1, TAINT_FIRMWARE_WORKAROUND, + "Your BIOS is broken; ANDD object name is not NUL-terminated\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)); + return -EINVAL; + } + pr_info("ANDD device: %x name: %s\n", andd->device_number, + andd->object_name); + + return 0; +} + #ifdef CONFIG_ACPI_NUMA static int __init dmar_parse_one_rhsa(struct acpi_dmar_header *header) @@ -436,6 +456,10 @@ dmar_table_print_dmar_entry(struct acpi_dmar_header *header) (unsigned long long)rhsa->base_address, rhsa->proximity_domain); break; + case ACPI_DMAR_TYPE_ANDD: + /* We don't print this here because we need to sanity-check + it first. So print it in dmar_parse_one_andd() instead. */ + break; } } @@ -521,6 +545,9 @@ parse_dmar_table(void) ret = dmar_parse_one_rhsa(entry_header); #endif break; + case ACPI_DMAR_TYPE_ANDD: + ret = dmar_parse_one_andd(entry_header); + break; default: pr_warn("Unknown DMAR structure type %d\n", entry_header->type); |