aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pci/dmar.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/pci/dmar.c')
-rw-r--r--drivers/pci/dmar.c110
1 files changed, 95 insertions, 15 deletions
diff --git a/drivers/pci/dmar.c b/drivers/pci/dmar.c
index 6cdc931f7c17..83aae4747594 100644
--- a/drivers/pci/dmar.c
+++ b/drivers/pci/dmar.c
@@ -339,6 +339,35 @@ found:
339} 339}
340#endif 340#endif
341 341
342#ifdef CONFIG_ACPI_NUMA
343static int __init
344dmar_parse_one_rhsa(struct acpi_dmar_header *header)
345{
346 struct acpi_dmar_rhsa *rhsa;
347 struct dmar_drhd_unit *drhd;
348
349 rhsa = (struct acpi_dmar_rhsa *)header;
350 for_each_drhd_unit(drhd) {
351 if (drhd->reg_base_addr == rhsa->base_address) {
352 int node = acpi_map_pxm_to_node(rhsa->proximity_domain);
353
354 if (!node_online(node))
355 node = -1;
356 drhd->iommu->node = node;
357 return 0;
358 }
359 }
360 WARN(1, "Your BIOS is broken; RHSA refers to non-existent DMAR unit at %llx\n"
361 "BIOS vendor: %s; Ver: %s; Product Version: %s\n",
362 drhd->reg_base_addr,
363 dmi_get_system_info(DMI_BIOS_VENDOR),
364 dmi_get_system_info(DMI_BIOS_VERSION),
365 dmi_get_system_info(DMI_PRODUCT_VERSION));
366
367 return 0;
368}
369#endif
370
342static void __init 371static void __init
343dmar_table_print_dmar_entry(struct acpi_dmar_header *header) 372dmar_table_print_dmar_entry(struct acpi_dmar_header *header)
344{ 373{
@@ -458,7 +487,9 @@ parse_dmar_table(void)
458#endif 487#endif
459 break; 488 break;
460 case ACPI_DMAR_HARDWARE_AFFINITY: 489 case ACPI_DMAR_HARDWARE_AFFINITY:
461 /* We don't do anything with RHSA (yet?) */ 490#ifdef CONFIG_ACPI_NUMA
491 ret = dmar_parse_one_rhsa(entry_header);
492#endif
462 break; 493 break;
463 default: 494 default:
464 printk(KERN_WARNING PREFIX 495 printk(KERN_WARNING PREFIX
@@ -582,6 +613,8 @@ int __init dmar_table_init(void)
582 return 0; 613 return 0;
583} 614}
584 615
616static int bios_warned;
617
585int __init check_zero_address(void) 618int __init check_zero_address(void)
586{ 619{
587 struct acpi_table_dmar *dmar; 620 struct acpi_table_dmar *dmar;
@@ -601,6 +634,9 @@ int __init check_zero_address(void)
601 } 634 }
602 635
603 if (entry_header->type == ACPI_DMAR_TYPE_HARDWARE_UNIT) { 636 if (entry_header->type == ACPI_DMAR_TYPE_HARDWARE_UNIT) {
637 void __iomem *addr;
638 u64 cap, ecap;
639
604 drhd = (void *)entry_header; 640 drhd = (void *)entry_header;
605 if (!drhd->address) { 641 if (!drhd->address) {
606 /* Promote an attitude of violence to a BIOS engineer today */ 642 /* Promote an attitude of violence to a BIOS engineer today */
@@ -609,17 +645,40 @@ int __init check_zero_address(void)
609 dmi_get_system_info(DMI_BIOS_VENDOR), 645 dmi_get_system_info(DMI_BIOS_VENDOR),
610 dmi_get_system_info(DMI_BIOS_VERSION), 646 dmi_get_system_info(DMI_BIOS_VERSION),
611 dmi_get_system_info(DMI_PRODUCT_VERSION)); 647 dmi_get_system_info(DMI_PRODUCT_VERSION));
612#ifdef CONFIG_DMAR 648 bios_warned = 1;
613 dmar_disabled = 1; 649 goto failed;
614#endif 650 }
615 return 0; 651
652 addr = early_ioremap(drhd->address, VTD_PAGE_SIZE);
653 if (!addr ) {
654 printk("IOMMU: can't validate: %llx\n", drhd->address);
655 goto failed;
656 }
657 cap = dmar_readq(addr + DMAR_CAP_REG);
658 ecap = dmar_readq(addr + DMAR_ECAP_REG);
659 early_iounmap(addr, VTD_PAGE_SIZE);
660 if (cap == (uint64_t)-1 && ecap == (uint64_t)-1) {
661 /* Promote an attitude of violence to a BIOS engineer today */
662 WARN(1, "Your BIOS is broken; DMAR reported at address %llx returns all ones!\n"
663 "BIOS vendor: %s; Ver: %s; Product Version: %s\n",
664 drhd->address,
665 dmi_get_system_info(DMI_BIOS_VENDOR),
666 dmi_get_system_info(DMI_BIOS_VERSION),
667 dmi_get_system_info(DMI_PRODUCT_VERSION));
668 bios_warned = 1;
669 goto failed;
616 } 670 }
617 break;
618 } 671 }
619 672
620 entry_header = ((void *)entry_header + entry_header->length); 673 entry_header = ((void *)entry_header + entry_header->length);
621 } 674 }
622 return 1; 675 return 1;
676
677failed:
678#ifdef CONFIG_DMAR
679 dmar_disabled = 1;
680#endif
681 return 0;
623} 682}
624 683
625void __init detect_intel_iommu(void) 684void __init detect_intel_iommu(void)
@@ -670,6 +729,18 @@ int alloc_iommu(struct dmar_drhd_unit *drhd)
670 int agaw = 0; 729 int agaw = 0;
671 int msagaw = 0; 730 int msagaw = 0;
672 731
732 if (!drhd->reg_base_addr) {
733 if (!bios_warned) {
734 WARN(1, "Your BIOS is broken; DMAR reported at address zero!\n"
735 "BIOS vendor: %s; Ver: %s; Product Version: %s\n",
736 dmi_get_system_info(DMI_BIOS_VENDOR),
737 dmi_get_system_info(DMI_BIOS_VERSION),
738 dmi_get_system_info(DMI_PRODUCT_VERSION));
739 bios_warned = 1;
740 }
741 return -EINVAL;
742 }
743
673 iommu = kzalloc(sizeof(*iommu), GFP_KERNEL); 744 iommu = kzalloc(sizeof(*iommu), GFP_KERNEL);
674 if (!iommu) 745 if (!iommu)
675 return -ENOMEM; 746 return -ENOMEM;
@@ -686,13 +757,16 @@ int alloc_iommu(struct dmar_drhd_unit *drhd)
686 iommu->ecap = dmar_readq(iommu->reg + DMAR_ECAP_REG); 757 iommu->ecap = dmar_readq(iommu->reg + DMAR_ECAP_REG);
687 758
688 if (iommu->cap == (uint64_t)-1 && iommu->ecap == (uint64_t)-1) { 759 if (iommu->cap == (uint64_t)-1 && iommu->ecap == (uint64_t)-1) {
689 /* Promote an attitude of violence to a BIOS engineer today */ 760 if (!bios_warned) {
690 WARN(1, "Your BIOS is broken; DMAR reported at address %llx returns all ones!\n" 761 /* Promote an attitude of violence to a BIOS engineer today */
691 "BIOS vendor: %s; Ver: %s; Product Version: %s\n", 762 WARN(1, "Your BIOS is broken; DMAR reported at address %llx returns all ones!\n"
692 drhd->reg_base_addr, 763 "BIOS vendor: %s; Ver: %s; Product Version: %s\n",
693 dmi_get_system_info(DMI_BIOS_VENDOR), 764 drhd->reg_base_addr,
694 dmi_get_system_info(DMI_BIOS_VERSION), 765 dmi_get_system_info(DMI_BIOS_VENDOR),
695 dmi_get_system_info(DMI_PRODUCT_VERSION)); 766 dmi_get_system_info(DMI_BIOS_VERSION),
767 dmi_get_system_info(DMI_PRODUCT_VERSION));
768 bios_warned = 1;
769 }
696 goto err_unmap; 770 goto err_unmap;
697 } 771 }
698 772
@@ -715,6 +789,8 @@ int alloc_iommu(struct dmar_drhd_unit *drhd)
715 iommu->agaw = agaw; 789 iommu->agaw = agaw;
716 iommu->msagaw = msagaw; 790 iommu->msagaw = msagaw;
717 791
792 iommu->node = -1;
793
718 /* the registers might be more than one page */ 794 /* the registers might be more than one page */
719 map_size = max_t(int, ecap_max_iotlb_offset(iommu->ecap), 795 map_size = max_t(int, ecap_max_iotlb_offset(iommu->ecap),
720 cap_max_fault_reg_offset(iommu->cap)); 796 cap_max_fault_reg_offset(iommu->cap));
@@ -1056,6 +1132,7 @@ static void __dmar_enable_qi(struct intel_iommu *iommu)
1056int dmar_enable_qi(struct intel_iommu *iommu) 1132int dmar_enable_qi(struct intel_iommu *iommu)
1057{ 1133{
1058 struct q_inval *qi; 1134 struct q_inval *qi;
1135 struct page *desc_page;
1059 1136
1060 if (!ecap_qis(iommu->ecap)) 1137 if (!ecap_qis(iommu->ecap))
1061 return -ENOENT; 1138 return -ENOENT;
@@ -1072,13 +1149,16 @@ int dmar_enable_qi(struct intel_iommu *iommu)
1072 1149
1073 qi = iommu->qi; 1150 qi = iommu->qi;
1074 1151
1075 qi->desc = (void *)(get_zeroed_page(GFP_ATOMIC)); 1152
1076 if (!qi->desc) { 1153 desc_page = alloc_pages_node(iommu->node, GFP_ATOMIC | __GFP_ZERO, 0);
1154 if (!desc_page) {
1077 kfree(qi); 1155 kfree(qi);
1078 iommu->qi = 0; 1156 iommu->qi = 0;
1079 return -ENOMEM; 1157 return -ENOMEM;
1080 } 1158 }
1081 1159
1160 qi->desc = page_address(desc_page);
1161
1082 qi->desc_status = kmalloc(QI_LENGTH * sizeof(int), GFP_ATOMIC); 1162 qi->desc_status = kmalloc(QI_LENGTH * sizeof(int), GFP_ATOMIC);
1083 if (!qi->desc_status) { 1163 if (!qi->desc_status) {
1084 free_page((unsigned long) qi->desc); 1164 free_page((unsigned long) qi->desc);