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.c123
1 files changed, 105 insertions, 18 deletions
diff --git a/drivers/pci/dmar.c b/drivers/pci/dmar.c
index b952ebc7a78b..33ead97f0c4b 100644
--- a/drivers/pci/dmar.c
+++ b/drivers/pci/dmar.c
@@ -35,6 +35,7 @@
35#include <linux/interrupt.h> 35#include <linux/interrupt.h>
36#include <linux/tboot.h> 36#include <linux/tboot.h>
37#include <linux/dmi.h> 37#include <linux/dmi.h>
38#include <linux/slab.h>
38 39
39#define PREFIX "DMAR: " 40#define PREFIX "DMAR: "
40 41
@@ -320,7 +321,7 @@ found:
320 for (bus = dev->bus; bus; bus = bus->parent) { 321 for (bus = dev->bus; bus; bus = bus->parent) {
321 struct pci_dev *bridge = bus->self; 322 struct pci_dev *bridge = bus->self;
322 323
323 if (!bridge || !bridge->is_pcie || 324 if (!bridge || !pci_is_pcie(bridge) ||
324 bridge->pcie_type == PCI_EXP_TYPE_PCI_BRIDGE) 325 bridge->pcie_type == PCI_EXP_TYPE_PCI_BRIDGE)
325 return 0; 326 return 0;
326 327
@@ -339,6 +340,35 @@ found:
339} 340}
340#endif 341#endif
341 342
343#ifdef CONFIG_ACPI_NUMA
344static int __init
345dmar_parse_one_rhsa(struct acpi_dmar_header *header)
346{
347 struct acpi_dmar_rhsa *rhsa;
348 struct dmar_drhd_unit *drhd;
349
350 rhsa = (struct acpi_dmar_rhsa *)header;
351 for_each_drhd_unit(drhd) {
352 if (drhd->reg_base_addr == rhsa->base_address) {
353 int node = acpi_map_pxm_to_node(rhsa->proximity_domain);
354
355 if (!node_online(node))
356 node = -1;
357 drhd->iommu->node = node;
358 return 0;
359 }
360 }
361 WARN(1, "Your BIOS is broken; RHSA refers to non-existent DMAR unit at %llx\n"
362 "BIOS vendor: %s; Ver: %s; Product Version: %s\n",
363 drhd->reg_base_addr,
364 dmi_get_system_info(DMI_BIOS_VENDOR),
365 dmi_get_system_info(DMI_BIOS_VERSION),
366 dmi_get_system_info(DMI_PRODUCT_VERSION));
367
368 return 0;
369}
370#endif
371
342static void __init 372static void __init
343dmar_table_print_dmar_entry(struct acpi_dmar_header *header) 373dmar_table_print_dmar_entry(struct acpi_dmar_header *header)
344{ 374{
@@ -458,7 +488,9 @@ parse_dmar_table(void)
458#endif 488#endif
459 break; 489 break;
460 case ACPI_DMAR_HARDWARE_AFFINITY: 490 case ACPI_DMAR_HARDWARE_AFFINITY:
461 /* We don't do anything with RHSA (yet?) */ 491#ifdef CONFIG_ACPI_NUMA
492 ret = dmar_parse_one_rhsa(entry_header);
493#endif
462 break; 494 break;
463 default: 495 default:
464 printk(KERN_WARNING PREFIX 496 printk(KERN_WARNING PREFIX
@@ -582,6 +614,8 @@ int __init dmar_table_init(void)
582 return 0; 614 return 0;
583} 615}
584 616
617static int bios_warned;
618
585int __init check_zero_address(void) 619int __init check_zero_address(void)
586{ 620{
587 struct acpi_table_dmar *dmar; 621 struct acpi_table_dmar *dmar;
@@ -601,6 +635,9 @@ int __init check_zero_address(void)
601 } 635 }
602 636
603 if (entry_header->type == ACPI_DMAR_TYPE_HARDWARE_UNIT) { 637 if (entry_header->type == ACPI_DMAR_TYPE_HARDWARE_UNIT) {
638 void __iomem *addr;
639 u64 cap, ecap;
640
604 drhd = (void *)entry_header; 641 drhd = (void *)entry_header;
605 if (!drhd->address) { 642 if (!drhd->address) {
606 /* Promote an attitude of violence to a BIOS engineer today */ 643 /* Promote an attitude of violence to a BIOS engineer today */
@@ -609,17 +646,40 @@ int __init check_zero_address(void)
609 dmi_get_system_info(DMI_BIOS_VENDOR), 646 dmi_get_system_info(DMI_BIOS_VENDOR),
610 dmi_get_system_info(DMI_BIOS_VERSION), 647 dmi_get_system_info(DMI_BIOS_VERSION),
611 dmi_get_system_info(DMI_PRODUCT_VERSION)); 648 dmi_get_system_info(DMI_PRODUCT_VERSION));
612#ifdef CONFIG_DMAR 649 bios_warned = 1;
613 dmar_disabled = 1; 650 goto failed;
614#endif 651 }
615 return 0; 652
653 addr = early_ioremap(drhd->address, VTD_PAGE_SIZE);
654 if (!addr ) {
655 printk("IOMMU: can't validate: %llx\n", drhd->address);
656 goto failed;
657 }
658 cap = dmar_readq(addr + DMAR_CAP_REG);
659 ecap = dmar_readq(addr + DMAR_ECAP_REG);
660 early_iounmap(addr, VTD_PAGE_SIZE);
661 if (cap == (uint64_t)-1 && ecap == (uint64_t)-1) {
662 /* Promote an attitude of violence to a BIOS engineer today */
663 WARN(1, "Your BIOS is broken; DMAR reported at address %llx returns all ones!\n"
664 "BIOS vendor: %s; Ver: %s; Product Version: %s\n",
665 drhd->address,
666 dmi_get_system_info(DMI_BIOS_VENDOR),
667 dmi_get_system_info(DMI_BIOS_VERSION),
668 dmi_get_system_info(DMI_PRODUCT_VERSION));
669 bios_warned = 1;
670 goto failed;
616 } 671 }
617 break;
618 } 672 }
619 673
620 entry_header = ((void *)entry_header + entry_header->length); 674 entry_header = ((void *)entry_header + entry_header->length);
621 } 675 }
622 return 1; 676 return 1;
677
678failed:
679#ifdef CONFIG_DMAR
680 dmar_disabled = 1;
681#endif
682 return 0;
623} 683}
624 684
625void __init detect_intel_iommu(void) 685void __init detect_intel_iommu(void)
@@ -645,9 +705,15 @@ void __init detect_intel_iommu(void)
645 "x2apic and Intr-remapping.\n"); 705 "x2apic and Intr-remapping.\n");
646#endif 706#endif
647#ifdef CONFIG_DMAR 707#ifdef CONFIG_DMAR
648 if (ret && !no_iommu && !iommu_detected && !swiotlb && 708 if (ret && !no_iommu && !iommu_detected && !dmar_disabled) {
649 !dmar_disabled)
650 iommu_detected = 1; 709 iommu_detected = 1;
710 /* Make sure ACS will be enabled */
711 pci_request_acs();
712 }
713#endif
714#ifdef CONFIG_X86
715 if (ret)
716 x86_init.iommu.iommu_init = intel_iommu_init;
651#endif 717#endif
652 } 718 }
653 early_acpi_os_unmap_memory(dmar_tbl, dmar_tbl_size); 719 early_acpi_os_unmap_memory(dmar_tbl, dmar_tbl_size);
@@ -664,6 +730,18 @@ int alloc_iommu(struct dmar_drhd_unit *drhd)
664 int agaw = 0; 730 int agaw = 0;
665 int msagaw = 0; 731 int msagaw = 0;
666 732
733 if (!drhd->reg_base_addr) {
734 if (!bios_warned) {
735 WARN(1, "Your BIOS is broken; DMAR reported at address zero!\n"
736 "BIOS vendor: %s; Ver: %s; Product Version: %s\n",
737 dmi_get_system_info(DMI_BIOS_VENDOR),
738 dmi_get_system_info(DMI_BIOS_VERSION),
739 dmi_get_system_info(DMI_PRODUCT_VERSION));
740 bios_warned = 1;
741 }
742 return -EINVAL;
743 }
744
667 iommu = kzalloc(sizeof(*iommu), GFP_KERNEL); 745 iommu = kzalloc(sizeof(*iommu), GFP_KERNEL);
668 if (!iommu) 746 if (!iommu)
669 return -ENOMEM; 747 return -ENOMEM;
@@ -680,13 +758,16 @@ int alloc_iommu(struct dmar_drhd_unit *drhd)
680 iommu->ecap = dmar_readq(iommu->reg + DMAR_ECAP_REG); 758 iommu->ecap = dmar_readq(iommu->reg + DMAR_ECAP_REG);
681 759
682 if (iommu->cap == (uint64_t)-1 && iommu->ecap == (uint64_t)-1) { 760 if (iommu->cap == (uint64_t)-1 && iommu->ecap == (uint64_t)-1) {
683 /* Promote an attitude of violence to a BIOS engineer today */ 761 if (!bios_warned) {
684 WARN(1, "Your BIOS is broken; DMAR reported at address %llx returns all ones!\n" 762 /* Promote an attitude of violence to a BIOS engineer today */
685 "BIOS vendor: %s; Ver: %s; Product Version: %s\n", 763 WARN(1, "Your BIOS is broken; DMAR reported at address %llx returns all ones!\n"
686 drhd->reg_base_addr, 764 "BIOS vendor: %s; Ver: %s; Product Version: %s\n",
687 dmi_get_system_info(DMI_BIOS_VENDOR), 765 drhd->reg_base_addr,
688 dmi_get_system_info(DMI_BIOS_VERSION), 766 dmi_get_system_info(DMI_BIOS_VENDOR),
689 dmi_get_system_info(DMI_PRODUCT_VERSION)); 767 dmi_get_system_info(DMI_BIOS_VERSION),
768 dmi_get_system_info(DMI_PRODUCT_VERSION));
769 bios_warned = 1;
770 }
690 goto err_unmap; 771 goto err_unmap;
691 } 772 }
692 773
@@ -709,6 +790,8 @@ int alloc_iommu(struct dmar_drhd_unit *drhd)
709 iommu->agaw = agaw; 790 iommu->agaw = agaw;
710 iommu->msagaw = msagaw; 791 iommu->msagaw = msagaw;
711 792
793 iommu->node = -1;
794
712 /* the registers might be more than one page */ 795 /* the registers might be more than one page */
713 map_size = max_t(int, ecap_max_iotlb_offset(iommu->ecap), 796 map_size = max_t(int, ecap_max_iotlb_offset(iommu->ecap),
714 cap_max_fault_reg_offset(iommu->cap)); 797 cap_max_fault_reg_offset(iommu->cap));
@@ -1050,6 +1133,7 @@ static void __dmar_enable_qi(struct intel_iommu *iommu)
1050int dmar_enable_qi(struct intel_iommu *iommu) 1133int dmar_enable_qi(struct intel_iommu *iommu)
1051{ 1134{
1052 struct q_inval *qi; 1135 struct q_inval *qi;
1136 struct page *desc_page;
1053 1137
1054 if (!ecap_qis(iommu->ecap)) 1138 if (!ecap_qis(iommu->ecap))
1055 return -ENOENT; 1139 return -ENOENT;
@@ -1066,13 +1150,16 @@ int dmar_enable_qi(struct intel_iommu *iommu)
1066 1150
1067 qi = iommu->qi; 1151 qi = iommu->qi;
1068 1152
1069 qi->desc = (void *)(get_zeroed_page(GFP_ATOMIC)); 1153
1070 if (!qi->desc) { 1154 desc_page = alloc_pages_node(iommu->node, GFP_ATOMIC | __GFP_ZERO, 0);
1155 if (!desc_page) {
1071 kfree(qi); 1156 kfree(qi);
1072 iommu->qi = 0; 1157 iommu->qi = 0;
1073 return -ENOMEM; 1158 return -ENOMEM;
1074 } 1159 }
1075 1160
1161 qi->desc = page_address(desc_page);
1162
1076 qi->desc_status = kmalloc(QI_LENGTH * sizeof(int), GFP_ATOMIC); 1163 qi->desc_status = kmalloc(QI_LENGTH * sizeof(int), GFP_ATOMIC);
1077 if (!qi->desc_status) { 1164 if (!qi->desc_status) {
1078 free_page((unsigned long) qi->desc); 1165 free_page((unsigned long) qi->desc);