aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pci/dmar.c
diff options
context:
space:
mode:
authorDavid Woodhouse <David.Woodhouse@intel.com>2008-10-20 15:16:53 -0400
committerDavid Woodhouse <David.Woodhouse@intel.com>2008-10-20 15:19:36 -0400
commitb364776ad1208a71f0c53578c84619a395412a8d (patch)
treed6050e5db6298095324ccb8af7d477684485d52e /drivers/pci/dmar.c
parent6da0b38f4433fb0f24615449d7966471b6e5eae0 (diff)
parent6c8909b42fee1be67647bcd2518161a0fa8ca533 (diff)
Merge branch 'master' of master.kernel.org:/pub/scm/linux/kernel/git/torvalds/linux-2.6
Conflicts: drivers/pci/intel-iommu.c
Diffstat (limited to 'drivers/pci/dmar.c')
-rw-r--r--drivers/pci/dmar.c119
1 files changed, 87 insertions, 32 deletions
diff --git a/drivers/pci/dmar.c b/drivers/pci/dmar.c
index e842e756308a..7b3751136e63 100644
--- a/drivers/pci/dmar.c
+++ b/drivers/pci/dmar.c
@@ -188,12 +188,11 @@ dmar_parse_one_drhd(struct acpi_dmar_header *header)
188 return 0; 188 return 0;
189} 189}
190 190
191static int __init 191static int __init dmar_parse_dev(struct dmar_drhd_unit *dmaru)
192dmar_parse_dev(struct dmar_drhd_unit *dmaru)
193{ 192{
194 struct acpi_dmar_hardware_unit *drhd; 193 struct acpi_dmar_hardware_unit *drhd;
195 static int include_all; 194 static int include_all;
196 int ret; 195 int ret = 0;
197 196
198 drhd = (struct acpi_dmar_hardware_unit *) dmaru->hdr; 197 drhd = (struct acpi_dmar_hardware_unit *) dmaru->hdr;
199 198
@@ -277,14 +276,15 @@ dmar_table_print_dmar_entry(struct acpi_dmar_header *header)
277 drhd = (struct acpi_dmar_hardware_unit *)header; 276 drhd = (struct acpi_dmar_hardware_unit *)header;
278 printk (KERN_INFO PREFIX 277 printk (KERN_INFO PREFIX
279 "DRHD (flags: 0x%08x)base: 0x%016Lx\n", 278 "DRHD (flags: 0x%08x)base: 0x%016Lx\n",
280 drhd->flags, drhd->address); 279 drhd->flags, (unsigned long long)drhd->address);
281 break; 280 break;
282 case ACPI_DMAR_TYPE_RESERVED_MEMORY: 281 case ACPI_DMAR_TYPE_RESERVED_MEMORY:
283 rmrr = (struct acpi_dmar_reserved_memory *)header; 282 rmrr = (struct acpi_dmar_reserved_memory *)header;
284 283
285 printk (KERN_INFO PREFIX 284 printk (KERN_INFO PREFIX
286 "RMRR base: 0x%016Lx end: 0x%016Lx\n", 285 "RMRR base: 0x%016Lx end: 0x%016Lx\n",
287 rmrr->base_address, rmrr->end_address); 286 (unsigned long long)rmrr->base_address,
287 (unsigned long long)rmrr->end_address);
288 break; 288 break;
289 } 289 }
290} 290}
@@ -304,7 +304,7 @@ parse_dmar_table(void)
304 if (!dmar) 304 if (!dmar)
305 return -ENODEV; 305 return -ENODEV;
306 306
307 if (dmar->width < PAGE_SHIFT_4K - 1) { 307 if (dmar->width < PAGE_SHIFT - 1) {
308 printk(KERN_WARNING PREFIX "Invalid DMAR haw\n"); 308 printk(KERN_WARNING PREFIX "Invalid DMAR haw\n");
309 return -EINVAL; 309 return -EINVAL;
310 } 310 }
@@ -455,8 +455,8 @@ void __init detect_intel_iommu(void)
455 455
456 ret = early_dmar_detect(); 456 ret = early_dmar_detect();
457 457
458#ifdef CONFIG_DMAR
459 { 458 {
459#ifdef CONFIG_INTR_REMAP
460 struct acpi_table_dmar *dmar; 460 struct acpi_table_dmar *dmar;
461 /* 461 /*
462 * for now we will disable dma-remapping when interrupt 462 * for now we will disable dma-remapping when interrupt
@@ -465,28 +465,18 @@ void __init detect_intel_iommu(void)
465 * is added, we will not need this any more. 465 * is added, we will not need this any more.
466 */ 466 */
467 dmar = (struct acpi_table_dmar *) dmar_tbl; 467 dmar = (struct acpi_table_dmar *) dmar_tbl;
468 if (ret && cpu_has_x2apic && dmar->flags & 0x1) { 468 if (ret && cpu_has_x2apic && dmar->flags & 0x1)
469 printk(KERN_INFO 469 printk(KERN_INFO
470 "Queued invalidation will be enabled to support " 470 "Queued invalidation will be enabled to support "
471 "x2apic and Intr-remapping.\n"); 471 "x2apic and Intr-remapping.\n");
472 printk(KERN_INFO 472#endif
473 "Disabling IOMMU detection, because of missing "
474 "queued invalidation support for IOTLB "
475 "invalidation\n");
476 printk(KERN_INFO
477 "Use \"nox2apic\", if you want to use Intel "
478 " IOMMU for DMA-remapping and don't care about "
479 " x2apic support\n");
480
481 dmar_disabled = 1;
482 return;
483 }
484 473
474#ifdef CONFIG_DMAR
485 if (ret && !no_iommu && !iommu_detected && !swiotlb && 475 if (ret && !no_iommu && !iommu_detected && !swiotlb &&
486 !dmar_disabled) 476 !dmar_disabled)
487 iommu_detected = 1; 477 iommu_detected = 1;
488 }
489#endif 478#endif
479 }
490} 480}
491 481
492 482
@@ -503,7 +493,7 @@ int alloc_iommu(struct dmar_drhd_unit *drhd)
503 493
504 iommu->seq_id = iommu_allocated++; 494 iommu->seq_id = iommu_allocated++;
505 495
506 iommu->reg = ioremap(drhd->reg_base_addr, PAGE_SIZE_4K); 496 iommu->reg = ioremap(drhd->reg_base_addr, VTD_PAGE_SIZE);
507 if (!iommu->reg) { 497 if (!iommu->reg) {
508 printk(KERN_ERR "IOMMU: can't map the region\n"); 498 printk(KERN_ERR "IOMMU: can't map the region\n");
509 goto error; 499 goto error;
@@ -514,8 +504,8 @@ int alloc_iommu(struct dmar_drhd_unit *drhd)
514 /* the registers might be more than one page */ 504 /* the registers might be more than one page */
515 map_size = max_t(int, ecap_max_iotlb_offset(iommu->ecap), 505 map_size = max_t(int, ecap_max_iotlb_offset(iommu->ecap),
516 cap_max_fault_reg_offset(iommu->cap)); 506 cap_max_fault_reg_offset(iommu->cap));
517 map_size = PAGE_ALIGN_4K(map_size); 507 map_size = VTD_PAGE_ALIGN(map_size);
518 if (map_size > PAGE_SIZE_4K) { 508 if (map_size > VTD_PAGE_SIZE) {
519 iounmap(iommu->reg); 509 iounmap(iommu->reg);
520 iommu->reg = ioremap(drhd->reg_base_addr, map_size); 510 iommu->reg = ioremap(drhd->reg_base_addr, map_size);
521 if (!iommu->reg) { 511 if (!iommu->reg) {
@@ -526,8 +516,10 @@ int alloc_iommu(struct dmar_drhd_unit *drhd)
526 516
527 ver = readl(iommu->reg + DMAR_VER_REG); 517 ver = readl(iommu->reg + DMAR_VER_REG);
528 pr_debug("IOMMU %llx: ver %d:%d cap %llx ecap %llx\n", 518 pr_debug("IOMMU %llx: ver %d:%d cap %llx ecap %llx\n",
529 drhd->reg_base_addr, DMAR_VER_MAJOR(ver), DMAR_VER_MINOR(ver), 519 (unsigned long long)drhd->reg_base_addr,
530 iommu->cap, iommu->ecap); 520 DMAR_VER_MAJOR(ver), DMAR_VER_MINOR(ver),
521 (unsigned long long)iommu->cap,
522 (unsigned long long)iommu->ecap);
531 523
532 spin_lock_init(&iommu->register_lock); 524 spin_lock_init(&iommu->register_lock);
533 525
@@ -580,11 +572,11 @@ void qi_submit_sync(struct qi_desc *desc, struct intel_iommu *iommu)
580 572
581 hw = qi->desc; 573 hw = qi->desc;
582 574
583 spin_lock(&qi->q_lock); 575 spin_lock_irqsave(&qi->q_lock, flags);
584 while (qi->free_cnt < 3) { 576 while (qi->free_cnt < 3) {
585 spin_unlock(&qi->q_lock); 577 spin_unlock_irqrestore(&qi->q_lock, flags);
586 cpu_relax(); 578 cpu_relax();
587 spin_lock(&qi->q_lock); 579 spin_lock_irqsave(&qi->q_lock, flags);
588 } 580 }
589 581
590 index = qi->free_head; 582 index = qi->free_head;
@@ -605,15 +597,22 @@ void qi_submit_sync(struct qi_desc *desc, struct intel_iommu *iommu)
605 qi->free_head = (qi->free_head + 2) % QI_LENGTH; 597 qi->free_head = (qi->free_head + 2) % QI_LENGTH;
606 qi->free_cnt -= 2; 598 qi->free_cnt -= 2;
607 599
608 spin_lock_irqsave(&iommu->register_lock, flags); 600 spin_lock(&iommu->register_lock);
609 /* 601 /*
610 * update the HW tail register indicating the presence of 602 * update the HW tail register indicating the presence of
611 * new descriptors. 603 * new descriptors.
612 */ 604 */
613 writel(qi->free_head << 4, iommu->reg + DMAR_IQT_REG); 605 writel(qi->free_head << 4, iommu->reg + DMAR_IQT_REG);
614 spin_unlock_irqrestore(&iommu->register_lock, flags); 606 spin_unlock(&iommu->register_lock);
615 607
616 while (qi->desc_status[wait_index] != QI_DONE) { 608 while (qi->desc_status[wait_index] != QI_DONE) {
609 /*
610 * We will leave the interrupts disabled, to prevent interrupt
611 * context to queue another cmd while a cmd is already submitted
612 * and waiting for completion on this cpu. This is to avoid
613 * a deadlock where the interrupt context can wait indefinitely
614 * for free slots in the queue.
615 */
617 spin_unlock(&qi->q_lock); 616 spin_unlock(&qi->q_lock);
618 cpu_relax(); 617 cpu_relax();
619 spin_lock(&qi->q_lock); 618 spin_lock(&qi->q_lock);
@@ -622,7 +621,7 @@ void qi_submit_sync(struct qi_desc *desc, struct intel_iommu *iommu)
622 qi->desc_status[index] = QI_DONE; 621 qi->desc_status[index] = QI_DONE;
623 622
624 reclaim_free_desc(qi); 623 reclaim_free_desc(qi);
625 spin_unlock(&qi->q_lock); 624 spin_unlock_irqrestore(&qi->q_lock, flags);
626} 625}
627 626
628/* 627/*
@@ -638,6 +637,62 @@ void qi_global_iec(struct intel_iommu *iommu)
638 qi_submit_sync(&desc, iommu); 637 qi_submit_sync(&desc, iommu);
639} 638}
640 639
640int qi_flush_context(struct intel_iommu *iommu, u16 did, u16 sid, u8 fm,
641 u64 type, int non_present_entry_flush)
642{
643
644 struct qi_desc desc;
645
646 if (non_present_entry_flush) {
647 if (!cap_caching_mode(iommu->cap))
648 return 1;
649 else
650 did = 0;
651 }
652
653 desc.low = QI_CC_FM(fm) | QI_CC_SID(sid) | QI_CC_DID(did)
654 | QI_CC_GRAN(type) | QI_CC_TYPE;
655 desc.high = 0;
656
657 qi_submit_sync(&desc, iommu);
658
659 return 0;
660
661}
662
663int qi_flush_iotlb(struct intel_iommu *iommu, u16 did, u64 addr,
664 unsigned int size_order, u64 type,
665 int non_present_entry_flush)
666{
667 u8 dw = 0, dr = 0;
668
669 struct qi_desc desc;
670 int ih = 0;
671
672 if (non_present_entry_flush) {
673 if (!cap_caching_mode(iommu->cap))
674 return 1;
675 else
676 did = 0;
677 }
678
679 if (cap_write_drain(iommu->cap))
680 dw = 1;
681
682 if (cap_read_drain(iommu->cap))
683 dr = 1;
684
685 desc.low = QI_IOTLB_DID(did) | QI_IOTLB_DR(dr) | QI_IOTLB_DW(dw)
686 | QI_IOTLB_GRAN(type) | QI_IOTLB_TYPE;
687 desc.high = QI_IOTLB_ADDR(addr) | QI_IOTLB_IH(ih)
688 | QI_IOTLB_AM(size_order);
689
690 qi_submit_sync(&desc, iommu);
691
692 return 0;
693
694}
695
641/* 696/*
642 * Enable Queued Invalidation interface. This is a must to support 697 * Enable Queued Invalidation interface. This is a must to support
643 * interrupt-remapping. Also used by DMA-remapping, which replaces 698 * interrupt-remapping. Also used by DMA-remapping, which replaces