diff options
author | David Woodhouse <David.Woodhouse@intel.com> | 2014-03-07 09:34:38 -0500 |
---|---|---|
committer | David Woodhouse <David.Woodhouse@intel.com> | 2014-03-20 10:25:23 -0400 |
commit | e625b4a95d50fa2f2d2fd0ab4b9ac9d6b6c2474c (patch) | |
tree | fa115ce396353f7a11aef51dd42e0be764448b3e /drivers/iommu | |
parent | 86a54dcce6ccb0d4a5810ed8112011039d855bee (diff) |
iommu/vt-d: Parse ANDD records
Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
Diffstat (limited to 'drivers/iommu')
-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) | |||
373 | kfree(dmaru); | 373 | kfree(dmaru); |
374 | } | 374 | } |
375 | 375 | ||
376 | static int __init dmar_parse_one_andd(struct acpi_dmar_header *header) | ||
377 | { | ||
378 | struct acpi_dmar_andd *andd = (void *)header; | ||
379 | |||
380 | /* Check for NUL termination within the designated length */ | ||
381 | if (strnlen(andd->object_name, header->length - 8) == header->length - 8) { | ||
382 | WARN_TAINT(1, TAINT_FIRMWARE_WORKAROUND, | ||
383 | "Your BIOS is broken; ANDD object name is not NUL-terminated\n" | ||
384 | "BIOS vendor: %s; Ver: %s; Product Version: %s\n", | ||
385 | dmi_get_system_info(DMI_BIOS_VENDOR), | ||
386 | dmi_get_system_info(DMI_BIOS_VERSION), | ||
387 | dmi_get_system_info(DMI_PRODUCT_VERSION)); | ||
388 | return -EINVAL; | ||
389 | } | ||
390 | pr_info("ANDD device: %x name: %s\n", andd->device_number, | ||
391 | andd->object_name); | ||
392 | |||
393 | return 0; | ||
394 | } | ||
395 | |||
376 | #ifdef CONFIG_ACPI_NUMA | 396 | #ifdef CONFIG_ACPI_NUMA |
377 | static int __init | 397 | static int __init |
378 | dmar_parse_one_rhsa(struct acpi_dmar_header *header) | 398 | dmar_parse_one_rhsa(struct acpi_dmar_header *header) |
@@ -436,6 +456,10 @@ dmar_table_print_dmar_entry(struct acpi_dmar_header *header) | |||
436 | (unsigned long long)rhsa->base_address, | 456 | (unsigned long long)rhsa->base_address, |
437 | rhsa->proximity_domain); | 457 | rhsa->proximity_domain); |
438 | break; | 458 | break; |
459 | case ACPI_DMAR_TYPE_ANDD: | ||
460 | /* We don't print this here because we need to sanity-check | ||
461 | it first. So print it in dmar_parse_one_andd() instead. */ | ||
462 | break; | ||
439 | } | 463 | } |
440 | } | 464 | } |
441 | 465 | ||
@@ -521,6 +545,9 @@ parse_dmar_table(void) | |||
521 | ret = dmar_parse_one_rhsa(entry_header); | 545 | ret = dmar_parse_one_rhsa(entry_header); |
522 | #endif | 546 | #endif |
523 | break; | 547 | break; |
548 | case ACPI_DMAR_TYPE_ANDD: | ||
549 | ret = dmar_parse_one_andd(entry_header); | ||
550 | break; | ||
524 | default: | 551 | default: |
525 | pr_warn("Unknown DMAR structure type %d\n", | 552 | pr_warn("Unknown DMAR structure type %d\n", |
526 | entry_header->type); | 553 | entry_header->type); |