diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2009-06-10 19:19:14 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-06-10 19:19:14 -0400 |
commit | 3f6280ddf25fa656d0e17960588e52bee48a7547 (patch) | |
tree | 006854e51246e400c248a9722418bc7a7cce2dbf /arch | |
parent | 75063600fd7b27fe447112c27997f100b9e2f99b (diff) | |
parent | 92db1e6af747faa129e236d68386af26a0efc12b (diff) |
Merge branch 'iommu-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip
* 'iommu-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip: (61 commits)
amd-iommu: remove unnecessary "AMD IOMMU: " prefix
amd-iommu: detach device explicitly before attaching it to a new domain
amd-iommu: remove BUS_NOTIFY_BOUND_DRIVER handling
dma-debug: simplify logic in driver_filter()
dma-debug: disable/enable irqs only once in device_dma_allocations
dma-debug: use pr_* instead of printk(KERN_* ...)
dma-debug: code style fixes
dma-debug: comment style fixes
dma-debug: change hash_bucket_find from first-fit to best-fit
x86: enable GART-IOMMU only after setting up protection methods
amd_iommu: fix lock imbalance
dma-debug: add documentation for the driver filter
dma-debug: add dma_debug_driver kernel command line
dma-debug: add debugfs file for driver filter
dma-debug: add variables and checks for driver filter
dma-debug: fix debug_dma_sync_sg_for_cpu and debug_dma_sync_sg_for_device
dma-debug: use sg_dma_len accessor
dma-debug: use sg_dma_address accessor instead of using dma_address directly
amd-iommu: don't free dma adresses below 512MB with CONFIG_IOMMU_STRESS
amd-iommu: don't preallocate page tables with CONFIG_IOMMU_STRESS
...
Diffstat (limited to 'arch')
-rw-r--r-- | arch/x86/Kconfig.debug | 11 | ||||
-rw-r--r-- | arch/x86/include/asm/amd_iommu.h | 2 | ||||
-rw-r--r-- | arch/x86/include/asm/amd_iommu_types.h | 55 | ||||
-rw-r--r-- | arch/x86/kernel/amd_iommu.c | 500 | ||||
-rw-r--r-- | arch/x86/kernel/amd_iommu_init.c | 273 | ||||
-rw-r--r-- | arch/x86/kernel/pci-calgary_64.c | 54 | ||||
-rw-r--r-- | arch/x86/kernel/pci-gart_64.c | 55 | ||||
-rw-r--r-- | arch/x86/kernel/pci-swiotlb.c | 2 |
8 files changed, 622 insertions, 330 deletions
diff --git a/arch/x86/Kconfig.debug b/arch/x86/Kconfig.debug index d8359e73317f..33fac6bbe1c2 100644 --- a/arch/x86/Kconfig.debug +++ b/arch/x86/Kconfig.debug | |||
@@ -159,10 +159,17 @@ config IOMMU_DEBUG | |||
159 | options. See Documentation/x86_64/boot-options.txt for more | 159 | options. See Documentation/x86_64/boot-options.txt for more |
160 | details. | 160 | details. |
161 | 161 | ||
162 | config IOMMU_STRESS | ||
163 | bool "Enable IOMMU stress-test mode" | ||
164 | ---help--- | ||
165 | This option disables various optimizations in IOMMU related | ||
166 | code to do real stress testing of the IOMMU code. This option | ||
167 | will cause a performance drop and should only be enabled for | ||
168 | testing. | ||
169 | |||
162 | config IOMMU_LEAK | 170 | config IOMMU_LEAK |
163 | bool "IOMMU leak tracing" | 171 | bool "IOMMU leak tracing" |
164 | depends on DEBUG_KERNEL | 172 | depends on IOMMU_DEBUG && DMA_API_DEBUG |
165 | depends on IOMMU_DEBUG | ||
166 | ---help--- | 173 | ---help--- |
167 | Add a simple leak tracer to the IOMMU code. This is useful when you | 174 | Add a simple leak tracer to the IOMMU code. This is useful when you |
168 | are debugging a buggy device driver that leaks IOMMU mappings. | 175 | are debugging a buggy device driver that leaks IOMMU mappings. |
diff --git a/arch/x86/include/asm/amd_iommu.h b/arch/x86/include/asm/amd_iommu.h index f712344329bc..262e02820049 100644 --- a/arch/x86/include/asm/amd_iommu.h +++ b/arch/x86/include/asm/amd_iommu.h | |||
@@ -27,6 +27,8 @@ extern int amd_iommu_init(void); | |||
27 | extern int amd_iommu_init_dma_ops(void); | 27 | extern int amd_iommu_init_dma_ops(void); |
28 | extern void amd_iommu_detect(void); | 28 | extern void amd_iommu_detect(void); |
29 | extern irqreturn_t amd_iommu_int_handler(int irq, void *data); | 29 | extern irqreturn_t amd_iommu_int_handler(int irq, void *data); |
30 | extern void amd_iommu_flush_all_domains(void); | ||
31 | extern void amd_iommu_flush_all_devices(void); | ||
30 | #else | 32 | #else |
31 | static inline int amd_iommu_init(void) { return -ENODEV; } | 33 | static inline int amd_iommu_init(void) { return -ENODEV; } |
32 | static inline void amd_iommu_detect(void) { } | 34 | static inline void amd_iommu_detect(void) { } |
diff --git a/arch/x86/include/asm/amd_iommu_types.h b/arch/x86/include/asm/amd_iommu_types.h index 95c8cd9d22b5..0c878caaa0a2 100644 --- a/arch/x86/include/asm/amd_iommu_types.h +++ b/arch/x86/include/asm/amd_iommu_types.h | |||
@@ -194,6 +194,27 @@ | |||
194 | #define PD_DMA_OPS_MASK (1UL << 0) /* domain used for dma_ops */ | 194 | #define PD_DMA_OPS_MASK (1UL << 0) /* domain used for dma_ops */ |
195 | #define PD_DEFAULT_MASK (1UL << 1) /* domain is a default dma_ops | 195 | #define PD_DEFAULT_MASK (1UL << 1) /* domain is a default dma_ops |
196 | domain for an IOMMU */ | 196 | domain for an IOMMU */ |
197 | extern bool amd_iommu_dump; | ||
198 | #define DUMP_printk(format, arg...) \ | ||
199 | do { \ | ||
200 | if (amd_iommu_dump) \ | ||
201 | printk(KERN_INFO "AMD IOMMU: " format, ## arg); \ | ||
202 | } while(0); | ||
203 | |||
204 | /* | ||
205 | * Make iterating over all IOMMUs easier | ||
206 | */ | ||
207 | #define for_each_iommu(iommu) \ | ||
208 | list_for_each_entry((iommu), &amd_iommu_list, list) | ||
209 | #define for_each_iommu_safe(iommu, next) \ | ||
210 | list_for_each_entry_safe((iommu), (next), &amd_iommu_list, list) | ||
211 | |||
212 | #define APERTURE_RANGE_SHIFT 27 /* 128 MB */ | ||
213 | #define APERTURE_RANGE_SIZE (1ULL << APERTURE_RANGE_SHIFT) | ||
214 | #define APERTURE_RANGE_PAGES (APERTURE_RANGE_SIZE >> PAGE_SHIFT) | ||
215 | #define APERTURE_MAX_RANGES 32 /* allows 4GB of DMA address space */ | ||
216 | #define APERTURE_RANGE_INDEX(a) ((a) >> APERTURE_RANGE_SHIFT) | ||
217 | #define APERTURE_PAGE_INDEX(a) (((a) >> 21) & 0x3fULL) | ||
197 | 218 | ||
198 | /* | 219 | /* |
199 | * This structure contains generic data for IOMMU protection domains | 220 | * This structure contains generic data for IOMMU protection domains |
@@ -210,6 +231,26 @@ struct protection_domain { | |||
210 | }; | 231 | }; |
211 | 232 | ||
212 | /* | 233 | /* |
234 | * For dynamic growth the aperture size is split into ranges of 128MB of | ||
235 | * DMA address space each. This struct represents one such range. | ||
236 | */ | ||
237 | struct aperture_range { | ||
238 | |||
239 | /* address allocation bitmap */ | ||
240 | unsigned long *bitmap; | ||
241 | |||
242 | /* | ||
243 | * Array of PTE pages for the aperture. In this array we save all the | ||
244 | * leaf pages of the domain page table used for the aperture. This way | ||
245 | * we don't need to walk the page table to find a specific PTE. We can | ||
246 | * just calculate its address in constant time. | ||
247 | */ | ||
248 | u64 *pte_pages[64]; | ||
249 | |||
250 | unsigned long offset; | ||
251 | }; | ||
252 | |||
253 | /* | ||
213 | * Data container for a dma_ops specific protection domain | 254 | * Data container for a dma_ops specific protection domain |
214 | */ | 255 | */ |
215 | struct dma_ops_domain { | 256 | struct dma_ops_domain { |
@@ -222,18 +263,10 @@ struct dma_ops_domain { | |||
222 | unsigned long aperture_size; | 263 | unsigned long aperture_size; |
223 | 264 | ||
224 | /* address we start to search for free addresses */ | 265 | /* address we start to search for free addresses */ |
225 | unsigned long next_bit; | 266 | unsigned long next_address; |
226 | |||
227 | /* address allocation bitmap */ | ||
228 | unsigned long *bitmap; | ||
229 | 267 | ||
230 | /* | 268 | /* address space relevant data */ |
231 | * Array of PTE pages for the aperture. In this array we save all the | 269 | struct aperture_range *aperture[APERTURE_MAX_RANGES]; |
232 | * leaf pages of the domain page table used for the aperture. This way | ||
233 | * we don't need to walk the page table to find a specific PTE. We can | ||
234 | * just calculate its address in constant time. | ||
235 | */ | ||
236 | u64 **pte_pages; | ||
237 | 270 | ||
238 | /* This will be set to true when TLB needs to be flushed */ | 271 | /* This will be set to true when TLB needs to be flushed */ |
239 | bool need_flush; | 272 | bool need_flush; |
diff --git a/arch/x86/kernel/amd_iommu.c b/arch/x86/kernel/amd_iommu.c index a97db99dad52..1c60554537c3 100644 --- a/arch/x86/kernel/amd_iommu.c +++ b/arch/x86/kernel/amd_iommu.c | |||
@@ -55,7 +55,16 @@ struct iommu_cmd { | |||
55 | static int dma_ops_unity_map(struct dma_ops_domain *dma_dom, | 55 | static int dma_ops_unity_map(struct dma_ops_domain *dma_dom, |
56 | struct unity_map_entry *e); | 56 | struct unity_map_entry *e); |
57 | static struct dma_ops_domain *find_protection_domain(u16 devid); | 57 | static struct dma_ops_domain *find_protection_domain(u16 devid); |
58 | static u64* alloc_pte(struct protection_domain *dom, | ||
59 | unsigned long address, u64 | ||
60 | **pte_page, gfp_t gfp); | ||
61 | static void dma_ops_reserve_addresses(struct dma_ops_domain *dom, | ||
62 | unsigned long start_page, | ||
63 | unsigned int pages); | ||
58 | 64 | ||
65 | #ifndef BUS_NOTIFY_UNBOUND_DRIVER | ||
66 | #define BUS_NOTIFY_UNBOUND_DRIVER 0x0005 | ||
67 | #endif | ||
59 | 68 | ||
60 | #ifdef CONFIG_AMD_IOMMU_STATS | 69 | #ifdef CONFIG_AMD_IOMMU_STATS |
61 | 70 | ||
@@ -213,7 +222,7 @@ irqreturn_t amd_iommu_int_handler(int irq, void *data) | |||
213 | { | 222 | { |
214 | struct amd_iommu *iommu; | 223 | struct amd_iommu *iommu; |
215 | 224 | ||
216 | list_for_each_entry(iommu, &amd_iommu_list, list) | 225 | for_each_iommu(iommu) |
217 | iommu_poll_events(iommu); | 226 | iommu_poll_events(iommu); |
218 | 227 | ||
219 | return IRQ_HANDLED; | 228 | return IRQ_HANDLED; |
@@ -440,7 +449,7 @@ static void iommu_flush_domain(u16 domid) | |||
440 | __iommu_build_inv_iommu_pages(&cmd, CMD_INV_IOMMU_ALL_PAGES_ADDRESS, | 449 | __iommu_build_inv_iommu_pages(&cmd, CMD_INV_IOMMU_ALL_PAGES_ADDRESS, |
441 | domid, 1, 1); | 450 | domid, 1, 1); |
442 | 451 | ||
443 | list_for_each_entry(iommu, &amd_iommu_list, list) { | 452 | for_each_iommu(iommu) { |
444 | spin_lock_irqsave(&iommu->lock, flags); | 453 | spin_lock_irqsave(&iommu->lock, flags); |
445 | __iommu_queue_command(iommu, &cmd); | 454 | __iommu_queue_command(iommu, &cmd); |
446 | __iommu_completion_wait(iommu); | 455 | __iommu_completion_wait(iommu); |
@@ -449,6 +458,35 @@ static void iommu_flush_domain(u16 domid) | |||
449 | } | 458 | } |
450 | } | 459 | } |
451 | 460 | ||
461 | void amd_iommu_flush_all_domains(void) | ||
462 | { | ||
463 | int i; | ||
464 | |||
465 | for (i = 1; i < MAX_DOMAIN_ID; ++i) { | ||
466 | if (!test_bit(i, amd_iommu_pd_alloc_bitmap)) | ||
467 | continue; | ||
468 | iommu_flush_domain(i); | ||
469 | } | ||
470 | } | ||
471 | |||
472 | void amd_iommu_flush_all_devices(void) | ||
473 | { | ||
474 | struct amd_iommu *iommu; | ||
475 | int i; | ||
476 | |||
477 | for (i = 0; i <= amd_iommu_last_bdf; ++i) { | ||
478 | if (amd_iommu_pd_table[i] == NULL) | ||
479 | continue; | ||
480 | |||
481 | iommu = amd_iommu_rlookup_table[i]; | ||
482 | if (!iommu) | ||
483 | continue; | ||
484 | |||
485 | iommu_queue_inv_dev_entry(iommu, i); | ||
486 | iommu_completion_wait(iommu); | ||
487 | } | ||
488 | } | ||
489 | |||
452 | /**************************************************************************** | 490 | /**************************************************************************** |
453 | * | 491 | * |
454 | * The functions below are used the create the page table mappings for | 492 | * The functions below are used the create the page table mappings for |
@@ -468,7 +506,7 @@ static int iommu_map_page(struct protection_domain *dom, | |||
468 | unsigned long phys_addr, | 506 | unsigned long phys_addr, |
469 | int prot) | 507 | int prot) |
470 | { | 508 | { |
471 | u64 __pte, *pte, *page; | 509 | u64 __pte, *pte; |
472 | 510 | ||
473 | bus_addr = PAGE_ALIGN(bus_addr); | 511 | bus_addr = PAGE_ALIGN(bus_addr); |
474 | phys_addr = PAGE_ALIGN(phys_addr); | 512 | phys_addr = PAGE_ALIGN(phys_addr); |
@@ -477,27 +515,7 @@ static int iommu_map_page(struct protection_domain *dom, | |||
477 | if (bus_addr > IOMMU_MAP_SIZE_L3 || !(prot & IOMMU_PROT_MASK)) | 515 | if (bus_addr > IOMMU_MAP_SIZE_L3 || !(prot & IOMMU_PROT_MASK)) |
478 | return -EINVAL; | 516 | return -EINVAL; |
479 | 517 | ||
480 | pte = &dom->pt_root[IOMMU_PTE_L2_INDEX(bus_addr)]; | 518 | pte = alloc_pte(dom, bus_addr, NULL, GFP_KERNEL); |
481 | |||
482 | if (!IOMMU_PTE_PRESENT(*pte)) { | ||
483 | page = (u64 *)get_zeroed_page(GFP_KERNEL); | ||
484 | if (!page) | ||
485 | return -ENOMEM; | ||
486 | *pte = IOMMU_L2_PDE(virt_to_phys(page)); | ||
487 | } | ||
488 | |||
489 | pte = IOMMU_PTE_PAGE(*pte); | ||
490 | pte = &pte[IOMMU_PTE_L1_INDEX(bus_addr)]; | ||
491 | |||
492 | if (!IOMMU_PTE_PRESENT(*pte)) { | ||
493 | page = (u64 *)get_zeroed_page(GFP_KERNEL); | ||
494 | if (!page) | ||
495 | return -ENOMEM; | ||
496 | *pte = IOMMU_L1_PDE(virt_to_phys(page)); | ||
497 | } | ||
498 | |||
499 | pte = IOMMU_PTE_PAGE(*pte); | ||
500 | pte = &pte[IOMMU_PTE_L0_INDEX(bus_addr)]; | ||
501 | 519 | ||
502 | if (IOMMU_PTE_PRESENT(*pte)) | 520 | if (IOMMU_PTE_PRESENT(*pte)) |
503 | return -EBUSY; | 521 | return -EBUSY; |
@@ -595,7 +613,8 @@ static int dma_ops_unity_map(struct dma_ops_domain *dma_dom, | |||
595 | * as allocated in the aperture | 613 | * as allocated in the aperture |
596 | */ | 614 | */ |
597 | if (addr < dma_dom->aperture_size) | 615 | if (addr < dma_dom->aperture_size) |
598 | __set_bit(addr >> PAGE_SHIFT, dma_dom->bitmap); | 616 | __set_bit(addr >> PAGE_SHIFT, |
617 | dma_dom->aperture[0]->bitmap); | ||
599 | } | 618 | } |
600 | 619 | ||
601 | return 0; | 620 | return 0; |
@@ -632,42 +651,191 @@ static int init_unity_mappings_for_device(struct dma_ops_domain *dma_dom, | |||
632 | ****************************************************************************/ | 651 | ****************************************************************************/ |
633 | 652 | ||
634 | /* | 653 | /* |
635 | * The address allocator core function. | 654 | * The address allocator core functions. |
636 | * | 655 | * |
637 | * called with domain->lock held | 656 | * called with domain->lock held |
638 | */ | 657 | */ |
658 | |||
659 | /* | ||
660 | * This function checks if there is a PTE for a given dma address. If | ||
661 | * there is one, it returns the pointer to it. | ||
662 | */ | ||
663 | static u64* fetch_pte(struct protection_domain *domain, | ||
664 | unsigned long address) | ||
665 | { | ||
666 | u64 *pte; | ||
667 | |||
668 | pte = &domain->pt_root[IOMMU_PTE_L2_INDEX(address)]; | ||
669 | |||
670 | if (!IOMMU_PTE_PRESENT(*pte)) | ||
671 | return NULL; | ||
672 | |||
673 | pte = IOMMU_PTE_PAGE(*pte); | ||
674 | pte = &pte[IOMMU_PTE_L1_INDEX(address)]; | ||
675 | |||
676 | if (!IOMMU_PTE_PRESENT(*pte)) | ||
677 | return NULL; | ||
678 | |||
679 | pte = IOMMU_PTE_PAGE(*pte); | ||
680 | pte = &pte[IOMMU_PTE_L0_INDEX(address)]; | ||
681 | |||
682 | return pte; | ||
683 | } | ||
684 | |||
685 | /* | ||
686 | * This function is used to add a new aperture range to an existing | ||
687 | * aperture in case of dma_ops domain allocation or address allocation | ||
688 | * failure. | ||
689 | */ | ||
690 | static int alloc_new_range(struct amd_iommu *iommu, | ||
691 | struct dma_ops_domain *dma_dom, | ||
692 | bool populate, gfp_t gfp) | ||
693 | { | ||
694 | int index = dma_dom->aperture_size >> APERTURE_RANGE_SHIFT; | ||
695 | int i; | ||
696 | |||
697 | #ifdef CONFIG_IOMMU_STRESS | ||
698 | populate = false; | ||
699 | #endif | ||
700 | |||
701 | if (index >= APERTURE_MAX_RANGES) | ||
702 | return -ENOMEM; | ||
703 | |||
704 | dma_dom->aperture[index] = kzalloc(sizeof(struct aperture_range), gfp); | ||
705 | if (!dma_dom->aperture[index]) | ||
706 | return -ENOMEM; | ||
707 | |||
708 | dma_dom->aperture[index]->bitmap = (void *)get_zeroed_page(gfp); | ||
709 | if (!dma_dom->aperture[index]->bitmap) | ||
710 | goto out_free; | ||
711 | |||
712 | dma_dom->aperture[index]->offset = dma_dom->aperture_size; | ||
713 | |||
714 | if (populate) { | ||
715 | unsigned long address = dma_dom->aperture_size; | ||
716 | int i, num_ptes = APERTURE_RANGE_PAGES / 512; | ||
717 | u64 *pte, *pte_page; | ||
718 | |||
719 | for (i = 0; i < num_ptes; ++i) { | ||
720 | pte = alloc_pte(&dma_dom->domain, address, | ||
721 | &pte_page, gfp); | ||
722 | if (!pte) | ||
723 | goto out_free; | ||
724 | |||
725 | dma_dom->aperture[index]->pte_pages[i] = pte_page; | ||
726 | |||
727 | address += APERTURE_RANGE_SIZE / 64; | ||
728 | } | ||
729 | } | ||
730 | |||
731 | dma_dom->aperture_size += APERTURE_RANGE_SIZE; | ||
732 | |||
733 | /* Intialize the exclusion range if necessary */ | ||
734 | if (iommu->exclusion_start && | ||
735 | iommu->exclusion_start >= dma_dom->aperture[index]->offset && | ||
736 | iommu->exclusion_start < dma_dom->aperture_size) { | ||
737 | unsigned long startpage = iommu->exclusion_start >> PAGE_SHIFT; | ||
738 | int pages = iommu_num_pages(iommu->exclusion_start, | ||
739 | iommu->exclusion_length, | ||
740 | PAGE_SIZE); | ||
741 | dma_ops_reserve_addresses(dma_dom, startpage, pages); | ||
742 | } | ||
743 | |||
744 | /* | ||
745 | * Check for areas already mapped as present in the new aperture | ||
746 | * range and mark those pages as reserved in the allocator. Such | ||
747 | * mappings may already exist as a result of requested unity | ||
748 | * mappings for devices. | ||
749 | */ | ||
750 | for (i = dma_dom->aperture[index]->offset; | ||
751 | i < dma_dom->aperture_size; | ||
752 | i += PAGE_SIZE) { | ||
753 | u64 *pte = fetch_pte(&dma_dom->domain, i); | ||
754 | if (!pte || !IOMMU_PTE_PRESENT(*pte)) | ||
755 | continue; | ||
756 | |||
757 | dma_ops_reserve_addresses(dma_dom, i << PAGE_SHIFT, 1); | ||
758 | } | ||
759 | |||
760 | return 0; | ||
761 | |||
762 | out_free: | ||
763 | free_page((unsigned long)dma_dom->aperture[index]->bitmap); | ||
764 | |||
765 | kfree(dma_dom->aperture[index]); | ||
766 | dma_dom->aperture[index] = NULL; | ||
767 | |||
768 | return -ENOMEM; | ||
769 | } | ||
770 | |||
771 | static unsigned long dma_ops_area_alloc(struct device *dev, | ||
772 | struct dma_ops_domain *dom, | ||
773 | unsigned int pages, | ||
774 | unsigned long align_mask, | ||
775 | u64 dma_mask, | ||
776 | unsigned long start) | ||
777 | { | ||
778 | unsigned long next_bit = dom->next_address % APERTURE_RANGE_SIZE; | ||
779 | int max_index = dom->aperture_size >> APERTURE_RANGE_SHIFT; | ||
780 | int i = start >> APERTURE_RANGE_SHIFT; | ||
781 | unsigned long boundary_size; | ||
782 | unsigned long address = -1; | ||
783 | unsigned long limit; | ||
784 | |||
785 | next_bit >>= PAGE_SHIFT; | ||
786 | |||
787 | boundary_size = ALIGN(dma_get_seg_boundary(dev) + 1, | ||
788 | PAGE_SIZE) >> PAGE_SHIFT; | ||
789 | |||
790 | for (;i < max_index; ++i) { | ||
791 | unsigned long offset = dom->aperture[i]->offset >> PAGE_SHIFT; | ||
792 | |||
793 | if (dom->aperture[i]->offset >= dma_mask) | ||
794 | break; | ||
795 | |||
796 | limit = iommu_device_max_index(APERTURE_RANGE_PAGES, offset, | ||
797 | dma_mask >> PAGE_SHIFT); | ||
798 | |||
799 | address = iommu_area_alloc(dom->aperture[i]->bitmap, | ||
800 | limit, next_bit, pages, 0, | ||
801 | boundary_size, align_mask); | ||
802 | if (address != -1) { | ||
803 | address = dom->aperture[i]->offset + | ||
804 | (address << PAGE_SHIFT); | ||
805 | dom->next_address = address + (pages << PAGE_SHIFT); | ||
806 | break; | ||
807 | } | ||
808 | |||
809 | next_bit = 0; | ||
810 | } | ||
811 | |||
812 | return address; | ||
813 | } | ||
814 | |||
639 | static unsigned long dma_ops_alloc_addresses(struct device *dev, | 815 | static unsigned long dma_ops_alloc_addresses(struct device *dev, |
640 | struct dma_ops_domain *dom, | 816 | struct dma_ops_domain *dom, |
641 | unsigned int pages, | 817 | unsigned int pages, |
642 | unsigned long align_mask, | 818 | unsigned long align_mask, |
643 | u64 dma_mask) | 819 | u64 dma_mask) |
644 | { | 820 | { |
645 | unsigned long limit; | ||
646 | unsigned long address; | 821 | unsigned long address; |
647 | unsigned long boundary_size; | ||
648 | 822 | ||
649 | boundary_size = ALIGN(dma_get_seg_boundary(dev) + 1, | 823 | #ifdef CONFIG_IOMMU_STRESS |
650 | PAGE_SIZE) >> PAGE_SHIFT; | 824 | dom->next_address = 0; |
651 | limit = iommu_device_max_index(dom->aperture_size >> PAGE_SHIFT, 0, | 825 | dom->need_flush = true; |
652 | dma_mask >> PAGE_SHIFT); | 826 | #endif |
653 | 827 | ||
654 | if (dom->next_bit >= limit) { | 828 | address = dma_ops_area_alloc(dev, dom, pages, align_mask, |
655 | dom->next_bit = 0; | 829 | dma_mask, dom->next_address); |
656 | dom->need_flush = true; | ||
657 | } | ||
658 | 830 | ||
659 | address = iommu_area_alloc(dom->bitmap, limit, dom->next_bit, pages, | ||
660 | 0 , boundary_size, align_mask); | ||
661 | if (address == -1) { | 831 | if (address == -1) { |
662 | address = iommu_area_alloc(dom->bitmap, limit, 0, pages, | 832 | dom->next_address = 0; |
663 | 0, boundary_size, align_mask); | 833 | address = dma_ops_area_alloc(dev, dom, pages, align_mask, |
834 | dma_mask, 0); | ||
664 | dom->need_flush = true; | 835 | dom->need_flush = true; |
665 | } | 836 | } |
666 | 837 | ||
667 | if (likely(address != -1)) { | 838 | if (unlikely(address == -1)) |
668 | dom->next_bit = address + pages; | ||
669 | address <<= PAGE_SHIFT; | ||
670 | } else | ||
671 | address = bad_dma_address; | 839 | address = bad_dma_address; |
672 | 840 | ||
673 | WARN_ON((address + (PAGE_SIZE*pages)) > dom->aperture_size); | 841 | WARN_ON((address + (PAGE_SIZE*pages)) > dom->aperture_size); |
@@ -684,11 +852,23 @@ static void dma_ops_free_addresses(struct dma_ops_domain *dom, | |||
684 | unsigned long address, | 852 | unsigned long address, |
685 | unsigned int pages) | 853 | unsigned int pages) |
686 | { | 854 | { |
687 | address >>= PAGE_SHIFT; | 855 | unsigned i = address >> APERTURE_RANGE_SHIFT; |
688 | iommu_area_free(dom->bitmap, address, pages); | 856 | struct aperture_range *range = dom->aperture[i]; |
689 | 857 | ||
690 | if (address >= dom->next_bit) | 858 | BUG_ON(i >= APERTURE_MAX_RANGES || range == NULL); |
859 | |||
860 | #ifdef CONFIG_IOMMU_STRESS | ||
861 | if (i < 4) | ||
862 | return; | ||
863 | #endif | ||
864 | |||
865 | if (address >= dom->next_address) | ||
691 | dom->need_flush = true; | 866 | dom->need_flush = true; |
867 | |||
868 | address = (address % APERTURE_RANGE_SIZE) >> PAGE_SHIFT; | ||
869 | |||
870 | iommu_area_free(range->bitmap, address, pages); | ||
871 | |||
692 | } | 872 | } |
693 | 873 | ||
694 | /**************************************************************************** | 874 | /**************************************************************************** |
@@ -736,12 +916,16 @@ static void dma_ops_reserve_addresses(struct dma_ops_domain *dom, | |||
736 | unsigned long start_page, | 916 | unsigned long start_page, |
737 | unsigned int pages) | 917 | unsigned int pages) |
738 | { | 918 | { |
739 | unsigned int last_page = dom->aperture_size >> PAGE_SHIFT; | 919 | unsigned int i, last_page = dom->aperture_size >> PAGE_SHIFT; |
740 | 920 | ||
741 | if (start_page + pages > last_page) | 921 | if (start_page + pages > last_page) |
742 | pages = last_page - start_page; | 922 | pages = last_page - start_page; |
743 | 923 | ||
744 | iommu_area_reserve(dom->bitmap, start_page, pages); | 924 | for (i = start_page; i < start_page + pages; ++i) { |
925 | int index = i / APERTURE_RANGE_PAGES; | ||
926 | int page = i % APERTURE_RANGE_PAGES; | ||
927 | __set_bit(page, dom->aperture[index]->bitmap); | ||
928 | } | ||
745 | } | 929 | } |
746 | 930 | ||
747 | static void free_pagetable(struct protection_domain *domain) | 931 | static void free_pagetable(struct protection_domain *domain) |
@@ -780,14 +964,19 @@ static void free_pagetable(struct protection_domain *domain) | |||
780 | */ | 964 | */ |
781 | static void dma_ops_domain_free(struct dma_ops_domain *dom) | 965 | static void dma_ops_domain_free(struct dma_ops_domain *dom) |
782 | { | 966 | { |
967 | int i; | ||
968 | |||
783 | if (!dom) | 969 | if (!dom) |
784 | return; | 970 | return; |
785 | 971 | ||
786 | free_pagetable(&dom->domain); | 972 | free_pagetable(&dom->domain); |
787 | 973 | ||
788 | kfree(dom->pte_pages); | 974 | for (i = 0; i < APERTURE_MAX_RANGES; ++i) { |
789 | 975 | if (!dom->aperture[i]) | |
790 | kfree(dom->bitmap); | 976 | continue; |
977 | free_page((unsigned long)dom->aperture[i]->bitmap); | ||
978 | kfree(dom->aperture[i]); | ||
979 | } | ||
791 | 980 | ||
792 | kfree(dom); | 981 | kfree(dom); |
793 | } | 982 | } |
@@ -797,19 +986,9 @@ static void dma_ops_domain_free(struct dma_ops_domain *dom) | |||
797 | * It also intializes the page table and the address allocator data | 986 | * It also intializes the page table and the address allocator data |
798 | * structures required for the dma_ops interface | 987 | * structures required for the dma_ops interface |
799 | */ | 988 | */ |
800 | static struct dma_ops_domain *dma_ops_domain_alloc(struct amd_iommu *iommu, | 989 | static struct dma_ops_domain *dma_ops_domain_alloc(struct amd_iommu *iommu) |
801 | unsigned order) | ||
802 | { | 990 | { |
803 | struct dma_ops_domain *dma_dom; | 991 | struct dma_ops_domain *dma_dom; |
804 | unsigned i, num_pte_pages; | ||
805 | u64 *l2_pde; | ||
806 | u64 address; | ||
807 | |||
808 | /* | ||
809 | * Currently the DMA aperture must be between 32 MB and 1GB in size | ||
810 | */ | ||
811 | if ((order < 25) || (order > 30)) | ||
812 | return NULL; | ||
813 | 992 | ||
814 | dma_dom = kzalloc(sizeof(struct dma_ops_domain), GFP_KERNEL); | 993 | dma_dom = kzalloc(sizeof(struct dma_ops_domain), GFP_KERNEL); |
815 | if (!dma_dom) | 994 | if (!dma_dom) |
@@ -826,55 +1005,20 @@ static struct dma_ops_domain *dma_ops_domain_alloc(struct amd_iommu *iommu, | |||
826 | dma_dom->domain.priv = dma_dom; | 1005 | dma_dom->domain.priv = dma_dom; |
827 | if (!dma_dom->domain.pt_root) | 1006 | if (!dma_dom->domain.pt_root) |
828 | goto free_dma_dom; | 1007 | goto free_dma_dom; |
829 | dma_dom->aperture_size = (1ULL << order); | ||
830 | dma_dom->bitmap = kzalloc(dma_dom->aperture_size / (PAGE_SIZE * 8), | ||
831 | GFP_KERNEL); | ||
832 | if (!dma_dom->bitmap) | ||
833 | goto free_dma_dom; | ||
834 | /* | ||
835 | * mark the first page as allocated so we never return 0 as | ||
836 | * a valid dma-address. So we can use 0 as error value | ||
837 | */ | ||
838 | dma_dom->bitmap[0] = 1; | ||
839 | dma_dom->next_bit = 0; | ||
840 | 1008 | ||
841 | dma_dom->need_flush = false; | 1009 | dma_dom->need_flush = false; |
842 | dma_dom->target_dev = 0xffff; | 1010 | dma_dom->target_dev = 0xffff; |
843 | 1011 | ||
844 | /* Intialize the exclusion range if necessary */ | 1012 | if (alloc_new_range(iommu, dma_dom, true, GFP_KERNEL)) |
845 | if (iommu->exclusion_start && | 1013 | goto free_dma_dom; |
846 | iommu->exclusion_start < dma_dom->aperture_size) { | ||
847 | unsigned long startpage = iommu->exclusion_start >> PAGE_SHIFT; | ||
848 | int pages = iommu_num_pages(iommu->exclusion_start, | ||
849 | iommu->exclusion_length, | ||
850 | PAGE_SIZE); | ||
851 | dma_ops_reserve_addresses(dma_dom, startpage, pages); | ||
852 | } | ||
853 | 1014 | ||
854 | /* | 1015 | /* |
855 | * At the last step, build the page tables so we don't need to | 1016 | * mark the first page as allocated so we never return 0 as |
856 | * allocate page table pages in the dma_ops mapping/unmapping | 1017 | * a valid dma-address. So we can use 0 as error value |
857 | * path. | ||
858 | */ | 1018 | */ |
859 | num_pte_pages = dma_dom->aperture_size / (PAGE_SIZE * 512); | 1019 | dma_dom->aperture[0]->bitmap[0] = 1; |
860 | dma_dom->pte_pages = kzalloc(num_pte_pages * sizeof(void *), | 1020 | dma_dom->next_address = 0; |
861 | GFP_KERNEL); | ||
862 | if (!dma_dom->pte_pages) | ||
863 | goto free_dma_dom; | ||
864 | |||
865 | l2_pde = (u64 *)get_zeroed_page(GFP_KERNEL); | ||
866 | if (l2_pde == NULL) | ||
867 | goto free_dma_dom; | ||
868 | 1021 | ||
869 | dma_dom->domain.pt_root[0] = IOMMU_L2_PDE(virt_to_phys(l2_pde)); | ||
870 | |||
871 | for (i = 0; i < num_pte_pages; ++i) { | ||
872 | dma_dom->pte_pages[i] = (u64 *)get_zeroed_page(GFP_KERNEL); | ||
873 | if (!dma_dom->pte_pages[i]) | ||
874 | goto free_dma_dom; | ||
875 | address = virt_to_phys(dma_dom->pte_pages[i]); | ||
876 | l2_pde[i] = IOMMU_L1_PDE(address); | ||
877 | } | ||
878 | 1022 | ||
879 | return dma_dom; | 1023 | return dma_dom; |
880 | 1024 | ||
@@ -983,7 +1127,6 @@ static int device_change_notifier(struct notifier_block *nb, | |||
983 | struct protection_domain *domain; | 1127 | struct protection_domain *domain; |
984 | struct dma_ops_domain *dma_domain; | 1128 | struct dma_ops_domain *dma_domain; |
985 | struct amd_iommu *iommu; | 1129 | struct amd_iommu *iommu; |
986 | int order = amd_iommu_aperture_order; | ||
987 | unsigned long flags; | 1130 | unsigned long flags; |
988 | 1131 | ||
989 | if (devid > amd_iommu_last_bdf) | 1132 | if (devid > amd_iommu_last_bdf) |
@@ -1002,17 +1145,7 @@ static int device_change_notifier(struct notifier_block *nb, | |||
1002 | "to a non-dma-ops domain\n", dev_name(dev)); | 1145 | "to a non-dma-ops domain\n", dev_name(dev)); |
1003 | 1146 | ||
1004 | switch (action) { | 1147 | switch (action) { |
1005 | case BUS_NOTIFY_BOUND_DRIVER: | 1148 | case BUS_NOTIFY_UNBOUND_DRIVER: |
1006 | if (domain) | ||
1007 | goto out; | ||
1008 | dma_domain = find_protection_domain(devid); | ||
1009 | if (!dma_domain) | ||
1010 | dma_domain = iommu->default_dom; | ||
1011 | attach_device(iommu, &dma_domain->domain, devid); | ||
1012 | printk(KERN_INFO "AMD IOMMU: Using protection domain %d for " | ||
1013 | "device %s\n", dma_domain->domain.id, dev_name(dev)); | ||
1014 | break; | ||
1015 | case BUS_NOTIFY_UNBIND_DRIVER: | ||
1016 | if (!domain) | 1149 | if (!domain) |
1017 | goto out; | 1150 | goto out; |
1018 | detach_device(domain, devid); | 1151 | detach_device(domain, devid); |
@@ -1022,7 +1155,7 @@ static int device_change_notifier(struct notifier_block *nb, | |||
1022 | dma_domain = find_protection_domain(devid); | 1155 | dma_domain = find_protection_domain(devid); |
1023 | if (dma_domain) | 1156 | if (dma_domain) |
1024 | goto out; | 1157 | goto out; |
1025 | dma_domain = dma_ops_domain_alloc(iommu, order); | 1158 | dma_domain = dma_ops_domain_alloc(iommu); |
1026 | if (!dma_domain) | 1159 | if (!dma_domain) |
1027 | goto out; | 1160 | goto out; |
1028 | dma_domain->target_dev = devid; | 1161 | dma_domain->target_dev = devid; |
@@ -1133,8 +1266,8 @@ static int get_device_resources(struct device *dev, | |||
1133 | dma_dom = (*iommu)->default_dom; | 1266 | dma_dom = (*iommu)->default_dom; |
1134 | *domain = &dma_dom->domain; | 1267 | *domain = &dma_dom->domain; |
1135 | attach_device(*iommu, *domain, *bdf); | 1268 | attach_device(*iommu, *domain, *bdf); |
1136 | printk(KERN_INFO "AMD IOMMU: Using protection domain %d for " | 1269 | DUMP_printk("Using protection domain %d for device %s\n", |
1137 | "device %s\n", (*domain)->id, dev_name(dev)); | 1270 | (*domain)->id, dev_name(dev)); |
1138 | } | 1271 | } |
1139 | 1272 | ||
1140 | if (domain_for_device(_bdf) == NULL) | 1273 | if (domain_for_device(_bdf) == NULL) |
@@ -1144,6 +1277,66 @@ static int get_device_resources(struct device *dev, | |||
1144 | } | 1277 | } |
1145 | 1278 | ||
1146 | /* | 1279 | /* |
1280 | * If the pte_page is not yet allocated this function is called | ||
1281 | */ | ||
1282 | static u64* alloc_pte(struct protection_domain *dom, | ||
1283 | unsigned long address, u64 **pte_page, gfp_t gfp) | ||
1284 | { | ||
1285 | u64 *pte, *page; | ||
1286 | |||
1287 | pte = &dom->pt_root[IOMMU_PTE_L2_INDEX(address)]; | ||
1288 | |||
1289 | if (!IOMMU_PTE_PRESENT(*pte)) { | ||
1290 | page = (u64 *)get_zeroed_page(gfp); | ||
1291 | if (!page) | ||
1292 | return NULL; | ||
1293 | *pte = IOMMU_L2_PDE(virt_to_phys(page)); | ||
1294 | } | ||
1295 | |||
1296 | pte = IOMMU_PTE_PAGE(*pte); | ||
1297 | pte = &pte[IOMMU_PTE_L1_INDEX(address)]; | ||
1298 | |||
1299 | if (!IOMMU_PTE_PRESENT(*pte)) { | ||
1300 | page = (u64 *)get_zeroed_page(gfp); | ||
1301 | if (!page) | ||
1302 | return NULL; | ||
1303 | *pte = IOMMU_L1_PDE(virt_to_phys(page)); | ||
1304 | } | ||
1305 | |||
1306 | pte = IOMMU_PTE_PAGE(*pte); | ||
1307 | |||
1308 | if (pte_page) | ||
1309 | *pte_page = pte; | ||
1310 | |||
1311 | pte = &pte[IOMMU_PTE_L0_INDEX(address)]; | ||
1312 | |||
1313 | return pte; | ||
1314 | } | ||
1315 | |||
1316 | /* | ||
1317 | * This function fetches the PTE for a given address in the aperture | ||
1318 | */ | ||
1319 | static u64* dma_ops_get_pte(struct dma_ops_domain *dom, | ||
1320 | unsigned long address) | ||
1321 | { | ||
1322 | struct aperture_range *aperture; | ||
1323 | u64 *pte, *pte_page; | ||
1324 | |||
1325 | aperture = dom->aperture[APERTURE_RANGE_INDEX(address)]; | ||
1326 | if (!aperture) | ||
1327 | return NULL; | ||
1328 | |||
1329 | pte = aperture->pte_pages[APERTURE_PAGE_INDEX(address)]; | ||
1330 | if (!pte) { | ||
1331 | pte = alloc_pte(&dom->domain, address, &pte_page, GFP_ATOMIC); | ||
1332 | aperture->pte_pages[APERTURE_PAGE_INDEX(address)] = pte_page; | ||
1333 | } else | ||
1334 | pte += IOMMU_PTE_L0_INDEX(address); | ||
1335 | |||
1336 | return pte; | ||
1337 | } | ||
1338 | |||
1339 | /* | ||
1147 | * This is the generic map function. It maps one 4kb page at paddr to | 1340 | * This is the generic map function. It maps one 4kb page at paddr to |
1148 | * the given address in the DMA address space for the domain. | 1341 | * the given address in the DMA address space for the domain. |
1149 | */ | 1342 | */ |
@@ -1159,8 +1352,9 @@ static dma_addr_t dma_ops_domain_map(struct amd_iommu *iommu, | |||
1159 | 1352 | ||
1160 | paddr &= PAGE_MASK; | 1353 | paddr &= PAGE_MASK; |
1161 | 1354 | ||
1162 | pte = dom->pte_pages[IOMMU_PTE_L1_INDEX(address)]; | 1355 | pte = dma_ops_get_pte(dom, address); |
1163 | pte += IOMMU_PTE_L0_INDEX(address); | 1356 | if (!pte) |
1357 | return bad_dma_address; | ||
1164 | 1358 | ||
1165 | __pte = paddr | IOMMU_PTE_P | IOMMU_PTE_FC; | 1359 | __pte = paddr | IOMMU_PTE_P | IOMMU_PTE_FC; |
1166 | 1360 | ||
@@ -1185,14 +1379,20 @@ static void dma_ops_domain_unmap(struct amd_iommu *iommu, | |||
1185 | struct dma_ops_domain *dom, | 1379 | struct dma_ops_domain *dom, |
1186 | unsigned long address) | 1380 | unsigned long address) |
1187 | { | 1381 | { |
1382 | struct aperture_range *aperture; | ||
1188 | u64 *pte; | 1383 | u64 *pte; |
1189 | 1384 | ||
1190 | if (address >= dom->aperture_size) | 1385 | if (address >= dom->aperture_size) |
1191 | return; | 1386 | return; |
1192 | 1387 | ||
1193 | WARN_ON(address & ~PAGE_MASK || address >= dom->aperture_size); | 1388 | aperture = dom->aperture[APERTURE_RANGE_INDEX(address)]; |
1389 | if (!aperture) | ||
1390 | return; | ||
1391 | |||
1392 | pte = aperture->pte_pages[APERTURE_PAGE_INDEX(address)]; | ||
1393 | if (!pte) | ||
1394 | return; | ||
1194 | 1395 | ||
1195 | pte = dom->pte_pages[IOMMU_PTE_L1_INDEX(address)]; | ||
1196 | pte += IOMMU_PTE_L0_INDEX(address); | 1396 | pte += IOMMU_PTE_L0_INDEX(address); |
1197 | 1397 | ||
1198 | WARN_ON(!*pte); | 1398 | WARN_ON(!*pte); |
@@ -1216,7 +1416,7 @@ static dma_addr_t __map_single(struct device *dev, | |||
1216 | u64 dma_mask) | 1416 | u64 dma_mask) |
1217 | { | 1417 | { |
1218 | dma_addr_t offset = paddr & ~PAGE_MASK; | 1418 | dma_addr_t offset = paddr & ~PAGE_MASK; |
1219 | dma_addr_t address, start; | 1419 | dma_addr_t address, start, ret; |
1220 | unsigned int pages; | 1420 | unsigned int pages; |
1221 | unsigned long align_mask = 0; | 1421 | unsigned long align_mask = 0; |
1222 | int i; | 1422 | int i; |
@@ -1232,14 +1432,33 @@ static dma_addr_t __map_single(struct device *dev, | |||
1232 | if (align) | 1432 | if (align) |
1233 | align_mask = (1UL << get_order(size)) - 1; | 1433 | align_mask = (1UL << get_order(size)) - 1; |
1234 | 1434 | ||
1435 | retry: | ||
1235 | address = dma_ops_alloc_addresses(dev, dma_dom, pages, align_mask, | 1436 | address = dma_ops_alloc_addresses(dev, dma_dom, pages, align_mask, |
1236 | dma_mask); | 1437 | dma_mask); |
1237 | if (unlikely(address == bad_dma_address)) | 1438 | if (unlikely(address == bad_dma_address)) { |
1238 | goto out; | 1439 | /* |
1440 | * setting next_address here will let the address | ||
1441 | * allocator only scan the new allocated range in the | ||
1442 | * first run. This is a small optimization. | ||
1443 | */ | ||
1444 | dma_dom->next_address = dma_dom->aperture_size; | ||
1445 | |||
1446 | if (alloc_new_range(iommu, dma_dom, false, GFP_ATOMIC)) | ||
1447 | goto out; | ||
1448 | |||
1449 | /* | ||
1450 | * aperture was sucessfully enlarged by 128 MB, try | ||
1451 | * allocation again | ||
1452 | */ | ||
1453 | goto retry; | ||
1454 | } | ||
1239 | 1455 | ||
1240 | start = address; | 1456 | start = address; |
1241 | for (i = 0; i < pages; ++i) { | 1457 | for (i = 0; i < pages; ++i) { |
1242 | dma_ops_domain_map(iommu, dma_dom, start, paddr, dir); | 1458 | ret = dma_ops_domain_map(iommu, dma_dom, start, paddr, dir); |
1459 | if (ret == bad_dma_address) | ||
1460 | goto out_unmap; | ||
1461 | |||
1243 | paddr += PAGE_SIZE; | 1462 | paddr += PAGE_SIZE; |
1244 | start += PAGE_SIZE; | 1463 | start += PAGE_SIZE; |
1245 | } | 1464 | } |
@@ -1255,6 +1474,17 @@ static dma_addr_t __map_single(struct device *dev, | |||
1255 | 1474 | ||
1256 | out: | 1475 | out: |
1257 | return address; | 1476 | return address; |
1477 | |||
1478 | out_unmap: | ||
1479 | |||
1480 | for (--i; i >= 0; --i) { | ||
1481 | start -= PAGE_SIZE; | ||
1482 | dma_ops_domain_unmap(iommu, dma_dom, start); | ||
1483 | } | ||
1484 | |||
1485 | dma_ops_free_addresses(dma_dom, address, pages); | ||
1486 | |||
1487 | return bad_dma_address; | ||
1258 | } | 1488 | } |
1259 | 1489 | ||
1260 | /* | 1490 | /* |
@@ -1537,8 +1767,10 @@ static void *alloc_coherent(struct device *dev, size_t size, | |||
1537 | *dma_addr = __map_single(dev, iommu, domain->priv, paddr, | 1767 | *dma_addr = __map_single(dev, iommu, domain->priv, paddr, |
1538 | size, DMA_BIDIRECTIONAL, true, dma_mask); | 1768 | size, DMA_BIDIRECTIONAL, true, dma_mask); |
1539 | 1769 | ||
1540 | if (*dma_addr == bad_dma_address) | 1770 | if (*dma_addr == bad_dma_address) { |
1771 | spin_unlock_irqrestore(&domain->lock, flags); | ||
1541 | goto out_free; | 1772 | goto out_free; |
1773 | } | ||
1542 | 1774 | ||
1543 | iommu_completion_wait(iommu); | 1775 | iommu_completion_wait(iommu); |
1544 | 1776 | ||
@@ -1625,7 +1857,6 @@ static void prealloc_protection_domains(void) | |||
1625 | struct pci_dev *dev = NULL; | 1857 | struct pci_dev *dev = NULL; |
1626 | struct dma_ops_domain *dma_dom; | 1858 | struct dma_ops_domain *dma_dom; |
1627 | struct amd_iommu *iommu; | 1859 | struct amd_iommu *iommu; |
1628 | int order = amd_iommu_aperture_order; | ||
1629 | u16 devid; | 1860 | u16 devid; |
1630 | 1861 | ||
1631 | while ((dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) { | 1862 | while ((dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) { |
@@ -1638,7 +1869,7 @@ static void prealloc_protection_domains(void) | |||
1638 | iommu = amd_iommu_rlookup_table[devid]; | 1869 | iommu = amd_iommu_rlookup_table[devid]; |
1639 | if (!iommu) | 1870 | if (!iommu) |
1640 | continue; | 1871 | continue; |
1641 | dma_dom = dma_ops_domain_alloc(iommu, order); | 1872 | dma_dom = dma_ops_domain_alloc(iommu); |
1642 | if (!dma_dom) | 1873 | if (!dma_dom) |
1643 | continue; | 1874 | continue; |
1644 | init_unity_mappings_for_device(dma_dom, devid); | 1875 | init_unity_mappings_for_device(dma_dom, devid); |
@@ -1664,7 +1895,6 @@ static struct dma_map_ops amd_iommu_dma_ops = { | |||
1664 | int __init amd_iommu_init_dma_ops(void) | 1895 | int __init amd_iommu_init_dma_ops(void) |
1665 | { | 1896 | { |
1666 | struct amd_iommu *iommu; | 1897 | struct amd_iommu *iommu; |
1667 | int order = amd_iommu_aperture_order; | ||
1668 | int ret; | 1898 | int ret; |
1669 | 1899 | ||
1670 | /* | 1900 | /* |
@@ -1672,8 +1902,8 @@ int __init amd_iommu_init_dma_ops(void) | |||
1672 | * found in the system. Devices not assigned to any other | 1902 | * found in the system. Devices not assigned to any other |
1673 | * protection domain will be assigned to the default one. | 1903 | * protection domain will be assigned to the default one. |
1674 | */ | 1904 | */ |
1675 | list_for_each_entry(iommu, &amd_iommu_list, list) { | 1905 | for_each_iommu(iommu) { |
1676 | iommu->default_dom = dma_ops_domain_alloc(iommu, order); | 1906 | iommu->default_dom = dma_ops_domain_alloc(iommu); |
1677 | if (iommu->default_dom == NULL) | 1907 | if (iommu->default_dom == NULL) |
1678 | return -ENOMEM; | 1908 | return -ENOMEM; |
1679 | iommu->default_dom->domain.flags |= PD_DEFAULT_MASK; | 1909 | iommu->default_dom->domain.flags |= PD_DEFAULT_MASK; |
@@ -1710,7 +1940,7 @@ int __init amd_iommu_init_dma_ops(void) | |||
1710 | 1940 | ||
1711 | free_domains: | 1941 | free_domains: |
1712 | 1942 | ||
1713 | list_for_each_entry(iommu, &amd_iommu_list, list) { | 1943 | for_each_iommu(iommu) { |
1714 | if (iommu->default_dom) | 1944 | if (iommu->default_dom) |
1715 | dma_ops_domain_free(iommu->default_dom); | 1945 | dma_ops_domain_free(iommu->default_dom); |
1716 | } | 1946 | } |
@@ -1842,7 +2072,7 @@ static int amd_iommu_attach_device(struct iommu_domain *dom, | |||
1842 | 2072 | ||
1843 | old_domain = domain_for_device(devid); | 2073 | old_domain = domain_for_device(devid); |
1844 | if (old_domain) | 2074 | if (old_domain) |
1845 | return -EBUSY; | 2075 | detach_device(old_domain, devid); |
1846 | 2076 | ||
1847 | attach_device(iommu, domain, devid); | 2077 | attach_device(iommu, domain, devid); |
1848 | 2078 | ||
diff --git a/arch/x86/kernel/amd_iommu_init.c b/arch/x86/kernel/amd_iommu_init.c index 8c0be0902dac..238989ec077d 100644 --- a/arch/x86/kernel/amd_iommu_init.c +++ b/arch/x86/kernel/amd_iommu_init.c | |||
@@ -115,15 +115,21 @@ struct ivmd_header { | |||
115 | u64 range_length; | 115 | u64 range_length; |
116 | } __attribute__((packed)); | 116 | } __attribute__((packed)); |
117 | 117 | ||
118 | bool amd_iommu_dump; | ||
119 | |||
118 | static int __initdata amd_iommu_detected; | 120 | static int __initdata amd_iommu_detected; |
119 | 121 | ||
120 | u16 amd_iommu_last_bdf; /* largest PCI device id we have | 122 | u16 amd_iommu_last_bdf; /* largest PCI device id we have |
121 | to handle */ | 123 | to handle */ |
122 | LIST_HEAD(amd_iommu_unity_map); /* a list of required unity mappings | 124 | LIST_HEAD(amd_iommu_unity_map); /* a list of required unity mappings |
123 | we find in ACPI */ | 125 | we find in ACPI */ |
124 | unsigned amd_iommu_aperture_order = 26; /* size of aperture in power of 2 */ | 126 | #ifdef CONFIG_IOMMU_STRESS |
127 | bool amd_iommu_isolate = false; | ||
128 | #else | ||
125 | bool amd_iommu_isolate = true; /* if true, device isolation is | 129 | bool amd_iommu_isolate = true; /* if true, device isolation is |
126 | enabled */ | 130 | enabled */ |
131 | #endif | ||
132 | |||
127 | bool amd_iommu_unmap_flush; /* if true, flush on every unmap */ | 133 | bool amd_iommu_unmap_flush; /* if true, flush on every unmap */ |
128 | 134 | ||
129 | LIST_HEAD(amd_iommu_list); /* list of all AMD IOMMUs in the | 135 | LIST_HEAD(amd_iommu_list); /* list of all AMD IOMMUs in the |
@@ -175,7 +181,7 @@ static inline void update_last_devid(u16 devid) | |||
175 | static inline unsigned long tbl_size(int entry_size) | 181 | static inline unsigned long tbl_size(int entry_size) |
176 | { | 182 | { |
177 | unsigned shift = PAGE_SHIFT + | 183 | unsigned shift = PAGE_SHIFT + |
178 | get_order(amd_iommu_last_bdf * entry_size); | 184 | get_order(((int)amd_iommu_last_bdf + 1) * entry_size); |
179 | 185 | ||
180 | return 1UL << shift; | 186 | return 1UL << shift; |
181 | } | 187 | } |
@@ -193,7 +199,7 @@ static inline unsigned long tbl_size(int entry_size) | |||
193 | * This function set the exclusion range in the IOMMU. DMA accesses to the | 199 | * This function set the exclusion range in the IOMMU. DMA accesses to the |
194 | * exclusion range are passed through untranslated | 200 | * exclusion range are passed through untranslated |
195 | */ | 201 | */ |
196 | static void __init iommu_set_exclusion_range(struct amd_iommu *iommu) | 202 | static void iommu_set_exclusion_range(struct amd_iommu *iommu) |
197 | { | 203 | { |
198 | u64 start = iommu->exclusion_start & PAGE_MASK; | 204 | u64 start = iommu->exclusion_start & PAGE_MASK; |
199 | u64 limit = (start + iommu->exclusion_length) & PAGE_MASK; | 205 | u64 limit = (start + iommu->exclusion_length) & PAGE_MASK; |
@@ -225,7 +231,7 @@ static void __init iommu_set_device_table(struct amd_iommu *iommu) | |||
225 | } | 231 | } |
226 | 232 | ||
227 | /* Generic functions to enable/disable certain features of the IOMMU. */ | 233 | /* Generic functions to enable/disable certain features of the IOMMU. */ |
228 | static void __init iommu_feature_enable(struct amd_iommu *iommu, u8 bit) | 234 | static void iommu_feature_enable(struct amd_iommu *iommu, u8 bit) |
229 | { | 235 | { |
230 | u32 ctrl; | 236 | u32 ctrl; |
231 | 237 | ||
@@ -244,7 +250,7 @@ static void __init iommu_feature_disable(struct amd_iommu *iommu, u8 bit) | |||
244 | } | 250 | } |
245 | 251 | ||
246 | /* Function to enable the hardware */ | 252 | /* Function to enable the hardware */ |
247 | static void __init iommu_enable(struct amd_iommu *iommu) | 253 | static void iommu_enable(struct amd_iommu *iommu) |
248 | { | 254 | { |
249 | printk(KERN_INFO "AMD IOMMU: Enabling IOMMU at %s cap 0x%hx\n", | 255 | printk(KERN_INFO "AMD IOMMU: Enabling IOMMU at %s cap 0x%hx\n", |
250 | dev_name(&iommu->dev->dev), iommu->cap_ptr); | 256 | dev_name(&iommu->dev->dev), iommu->cap_ptr); |
@@ -252,11 +258,9 @@ static void __init iommu_enable(struct amd_iommu *iommu) | |||
252 | iommu_feature_enable(iommu, CONTROL_IOMMU_EN); | 258 | iommu_feature_enable(iommu, CONTROL_IOMMU_EN); |
253 | } | 259 | } |
254 | 260 | ||
255 | /* Function to enable IOMMU event logging and event interrupts */ | 261 | static void iommu_disable(struct amd_iommu *iommu) |
256 | static void __init iommu_enable_event_logging(struct amd_iommu *iommu) | ||
257 | { | 262 | { |
258 | iommu_feature_enable(iommu, CONTROL_EVT_LOG_EN); | 263 | iommu_feature_disable(iommu, CONTROL_IOMMU_EN); |
259 | iommu_feature_enable(iommu, CONTROL_EVT_INT_EN); | ||
260 | } | 264 | } |
261 | 265 | ||
262 | /* | 266 | /* |
@@ -413,25 +417,36 @@ static u8 * __init alloc_command_buffer(struct amd_iommu *iommu) | |||
413 | { | 417 | { |
414 | u8 *cmd_buf = (u8 *)__get_free_pages(GFP_KERNEL | __GFP_ZERO, | 418 | u8 *cmd_buf = (u8 *)__get_free_pages(GFP_KERNEL | __GFP_ZERO, |
415 | get_order(CMD_BUFFER_SIZE)); | 419 | get_order(CMD_BUFFER_SIZE)); |
416 | u64 entry; | ||
417 | 420 | ||
418 | if (cmd_buf == NULL) | 421 | if (cmd_buf == NULL) |
419 | return NULL; | 422 | return NULL; |
420 | 423 | ||
421 | iommu->cmd_buf_size = CMD_BUFFER_SIZE; | 424 | iommu->cmd_buf_size = CMD_BUFFER_SIZE; |
422 | 425 | ||
423 | entry = (u64)virt_to_phys(cmd_buf); | 426 | return cmd_buf; |
427 | } | ||
428 | |||
429 | /* | ||
430 | * This function writes the command buffer address to the hardware and | ||
431 | * enables it. | ||
432 | */ | ||
433 | static void iommu_enable_command_buffer(struct amd_iommu *iommu) | ||
434 | { | ||
435 | u64 entry; | ||
436 | |||
437 | BUG_ON(iommu->cmd_buf == NULL); | ||
438 | |||
439 | entry = (u64)virt_to_phys(iommu->cmd_buf); | ||
424 | entry |= MMIO_CMD_SIZE_512; | 440 | entry |= MMIO_CMD_SIZE_512; |
441 | |||
425 | memcpy_toio(iommu->mmio_base + MMIO_CMD_BUF_OFFSET, | 442 | memcpy_toio(iommu->mmio_base + MMIO_CMD_BUF_OFFSET, |
426 | &entry, sizeof(entry)); | 443 | &entry, sizeof(entry)); |
427 | 444 | ||
428 | /* set head and tail to zero manually */ | 445 | /* set head and tail to zero manually */ |
429 | writel(0x00, iommu->mmio_base + MMIO_CMD_HEAD_OFFSET); | 446 | writel(0x00, iommu->mmio_base + MMIO_CMD_HEAD_OFFSET); |
430 | writel(0x00, iommu->mmio_base + MMIO_CMD_TAIL_OFFSET); | 447 | writel(0x00, iommu->mmio_base + MMIO_CMD_TAIL_OFFSET); |
431 | 448 | ||
432 | iommu_feature_enable(iommu, CONTROL_CMDBUF_EN); | 449 | iommu_feature_enable(iommu, CONTROL_CMDBUF_EN); |
433 | |||
434 | return cmd_buf; | ||
435 | } | 450 | } |
436 | 451 | ||
437 | static void __init free_command_buffer(struct amd_iommu *iommu) | 452 | static void __init free_command_buffer(struct amd_iommu *iommu) |
@@ -443,20 +458,27 @@ static void __init free_command_buffer(struct amd_iommu *iommu) | |||
443 | /* allocates the memory where the IOMMU will log its events to */ | 458 | /* allocates the memory where the IOMMU will log its events to */ |
444 | static u8 * __init alloc_event_buffer(struct amd_iommu *iommu) | 459 | static u8 * __init alloc_event_buffer(struct amd_iommu *iommu) |
445 | { | 460 | { |
446 | u64 entry; | ||
447 | iommu->evt_buf = (u8 *)__get_free_pages(GFP_KERNEL | __GFP_ZERO, | 461 | iommu->evt_buf = (u8 *)__get_free_pages(GFP_KERNEL | __GFP_ZERO, |
448 | get_order(EVT_BUFFER_SIZE)); | 462 | get_order(EVT_BUFFER_SIZE)); |
449 | 463 | ||
450 | if (iommu->evt_buf == NULL) | 464 | if (iommu->evt_buf == NULL) |
451 | return NULL; | 465 | return NULL; |
452 | 466 | ||
467 | return iommu->evt_buf; | ||
468 | } | ||
469 | |||
470 | static void iommu_enable_event_buffer(struct amd_iommu *iommu) | ||
471 | { | ||
472 | u64 entry; | ||
473 | |||
474 | BUG_ON(iommu->evt_buf == NULL); | ||
475 | |||
453 | entry = (u64)virt_to_phys(iommu->evt_buf) | EVT_LEN_MASK; | 476 | entry = (u64)virt_to_phys(iommu->evt_buf) | EVT_LEN_MASK; |
477 | |||
454 | memcpy_toio(iommu->mmio_base + MMIO_EVT_BUF_OFFSET, | 478 | memcpy_toio(iommu->mmio_base + MMIO_EVT_BUF_OFFSET, |
455 | &entry, sizeof(entry)); | 479 | &entry, sizeof(entry)); |
456 | 480 | ||
457 | iommu->evt_buf_size = EVT_BUFFER_SIZE; | 481 | iommu_feature_enable(iommu, CONTROL_EVT_LOG_EN); |
458 | |||
459 | return iommu->evt_buf; | ||
460 | } | 482 | } |
461 | 483 | ||
462 | static void __init free_event_buffer(struct amd_iommu *iommu) | 484 | static void __init free_event_buffer(struct amd_iommu *iommu) |
@@ -596,32 +618,83 @@ static void __init init_iommu_from_acpi(struct amd_iommu *iommu, | |||
596 | p += sizeof(struct ivhd_header); | 618 | p += sizeof(struct ivhd_header); |
597 | end += h->length; | 619 | end += h->length; |
598 | 620 | ||
621 | |||
599 | while (p < end) { | 622 | while (p < end) { |
600 | e = (struct ivhd_entry *)p; | 623 | e = (struct ivhd_entry *)p; |
601 | switch (e->type) { | 624 | switch (e->type) { |
602 | case IVHD_DEV_ALL: | 625 | case IVHD_DEV_ALL: |
626 | |||
627 | DUMP_printk(" DEV_ALL\t\t\t first devid: %02x:%02x.%x" | ||
628 | " last device %02x:%02x.%x flags: %02x\n", | ||
629 | PCI_BUS(iommu->first_device), | ||
630 | PCI_SLOT(iommu->first_device), | ||
631 | PCI_FUNC(iommu->first_device), | ||
632 | PCI_BUS(iommu->last_device), | ||
633 | PCI_SLOT(iommu->last_device), | ||
634 | PCI_FUNC(iommu->last_device), | ||
635 | e->flags); | ||
636 | |||
603 | for (dev_i = iommu->first_device; | 637 | for (dev_i = iommu->first_device; |
604 | dev_i <= iommu->last_device; ++dev_i) | 638 | dev_i <= iommu->last_device; ++dev_i) |
605 | set_dev_entry_from_acpi(iommu, dev_i, | 639 | set_dev_entry_from_acpi(iommu, dev_i, |
606 | e->flags, 0); | 640 | e->flags, 0); |
607 | break; | 641 | break; |
608 | case IVHD_DEV_SELECT: | 642 | case IVHD_DEV_SELECT: |
643 | |||
644 | DUMP_printk(" DEV_SELECT\t\t\t devid: %02x:%02x.%x " | ||
645 | "flags: %02x\n", | ||
646 | PCI_BUS(e->devid), | ||
647 | PCI_SLOT(e->devid), | ||
648 | PCI_FUNC(e->devid), | ||
649 | e->flags); | ||
650 | |||
609 | devid = e->devid; | 651 | devid = e->devid; |
610 | set_dev_entry_from_acpi(iommu, devid, e->flags, 0); | 652 | set_dev_entry_from_acpi(iommu, devid, e->flags, 0); |
611 | break; | 653 | break; |
612 | case IVHD_DEV_SELECT_RANGE_START: | 654 | case IVHD_DEV_SELECT_RANGE_START: |
655 | |||
656 | DUMP_printk(" DEV_SELECT_RANGE_START\t " | ||
657 | "devid: %02x:%02x.%x flags: %02x\n", | ||
658 | PCI_BUS(e->devid), | ||
659 | PCI_SLOT(e->devid), | ||
660 | PCI_FUNC(e->devid), | ||
661 | e->flags); | ||
662 | |||
613 | devid_start = e->devid; | 663 | devid_start = e->devid; |
614 | flags = e->flags; | 664 | flags = e->flags; |
615 | ext_flags = 0; | 665 | ext_flags = 0; |
616 | alias = false; | 666 | alias = false; |
617 | break; | 667 | break; |
618 | case IVHD_DEV_ALIAS: | 668 | case IVHD_DEV_ALIAS: |
669 | |||
670 | DUMP_printk(" DEV_ALIAS\t\t\t devid: %02x:%02x.%x " | ||
671 | "flags: %02x devid_to: %02x:%02x.%x\n", | ||
672 | PCI_BUS(e->devid), | ||
673 | PCI_SLOT(e->devid), | ||
674 | PCI_FUNC(e->devid), | ||
675 | e->flags, | ||
676 | PCI_BUS(e->ext >> 8), | ||
677 | PCI_SLOT(e->ext >> 8), | ||
678 | PCI_FUNC(e->ext >> 8)); | ||
679 | |||
619 | devid = e->devid; | 680 | devid = e->devid; |
620 | devid_to = e->ext >> 8; | 681 | devid_to = e->ext >> 8; |
621 | set_dev_entry_from_acpi(iommu, devid, e->flags, 0); | 682 | set_dev_entry_from_acpi(iommu, devid_to, e->flags, 0); |
622 | amd_iommu_alias_table[devid] = devid_to; | 683 | amd_iommu_alias_table[devid] = devid_to; |
623 | break; | 684 | break; |
624 | case IVHD_DEV_ALIAS_RANGE: | 685 | case IVHD_DEV_ALIAS_RANGE: |
686 | |||
687 | DUMP_printk(" DEV_ALIAS_RANGE\t\t " | ||
688 | "devid: %02x:%02x.%x flags: %02x " | ||
689 | "devid_to: %02x:%02x.%x\n", | ||
690 | PCI_BUS(e->devid), | ||
691 | PCI_SLOT(e->devid), | ||
692 | PCI_FUNC(e->devid), | ||
693 | e->flags, | ||
694 | PCI_BUS(e->ext >> 8), | ||
695 | PCI_SLOT(e->ext >> 8), | ||
696 | PCI_FUNC(e->ext >> 8)); | ||
697 | |||
625 | devid_start = e->devid; | 698 | devid_start = e->devid; |
626 | flags = e->flags; | 699 | flags = e->flags; |
627 | devid_to = e->ext >> 8; | 700 | devid_to = e->ext >> 8; |
@@ -629,17 +702,39 @@ static void __init init_iommu_from_acpi(struct amd_iommu *iommu, | |||
629 | alias = true; | 702 | alias = true; |
630 | break; | 703 | break; |
631 | case IVHD_DEV_EXT_SELECT: | 704 | case IVHD_DEV_EXT_SELECT: |
705 | |||
706 | DUMP_printk(" DEV_EXT_SELECT\t\t devid: %02x:%02x.%x " | ||
707 | "flags: %02x ext: %08x\n", | ||
708 | PCI_BUS(e->devid), | ||
709 | PCI_SLOT(e->devid), | ||
710 | PCI_FUNC(e->devid), | ||
711 | e->flags, e->ext); | ||
712 | |||
632 | devid = e->devid; | 713 | devid = e->devid; |
633 | set_dev_entry_from_acpi(iommu, devid, e->flags, | 714 | set_dev_entry_from_acpi(iommu, devid, e->flags, |
634 | e->ext); | 715 | e->ext); |
635 | break; | 716 | break; |
636 | case IVHD_DEV_EXT_SELECT_RANGE: | 717 | case IVHD_DEV_EXT_SELECT_RANGE: |
718 | |||
719 | DUMP_printk(" DEV_EXT_SELECT_RANGE\t devid: " | ||
720 | "%02x:%02x.%x flags: %02x ext: %08x\n", | ||
721 | PCI_BUS(e->devid), | ||
722 | PCI_SLOT(e->devid), | ||
723 | PCI_FUNC(e->devid), | ||
724 | e->flags, e->ext); | ||
725 | |||
637 | devid_start = e->devid; | 726 | devid_start = e->devid; |
638 | flags = e->flags; | 727 | flags = e->flags; |
639 | ext_flags = e->ext; | 728 | ext_flags = e->ext; |
640 | alias = false; | 729 | alias = false; |
641 | break; | 730 | break; |
642 | case IVHD_DEV_RANGE_END: | 731 | case IVHD_DEV_RANGE_END: |
732 | |||
733 | DUMP_printk(" DEV_RANGE_END\t\t devid: %02x:%02x.%x\n", | ||
734 | PCI_BUS(e->devid), | ||
735 | PCI_SLOT(e->devid), | ||
736 | PCI_FUNC(e->devid)); | ||
737 | |||
643 | devid = e->devid; | 738 | devid = e->devid; |
644 | for (dev_i = devid_start; dev_i <= devid; ++dev_i) { | 739 | for (dev_i = devid_start; dev_i <= devid; ++dev_i) { |
645 | if (alias) | 740 | if (alias) |
@@ -679,7 +774,7 @@ static void __init free_iommu_all(void) | |||
679 | { | 774 | { |
680 | struct amd_iommu *iommu, *next; | 775 | struct amd_iommu *iommu, *next; |
681 | 776 | ||
682 | list_for_each_entry_safe(iommu, next, &amd_iommu_list, list) { | 777 | for_each_iommu_safe(iommu, next) { |
683 | list_del(&iommu->list); | 778 | list_del(&iommu->list); |
684 | free_iommu_one(iommu); | 779 | free_iommu_one(iommu); |
685 | kfree(iommu); | 780 | kfree(iommu); |
@@ -710,7 +805,6 @@ static int __init init_iommu_one(struct amd_iommu *iommu, struct ivhd_header *h) | |||
710 | if (!iommu->mmio_base) | 805 | if (!iommu->mmio_base) |
711 | return -ENOMEM; | 806 | return -ENOMEM; |
712 | 807 | ||
713 | iommu_set_device_table(iommu); | ||
714 | iommu->cmd_buf = alloc_command_buffer(iommu); | 808 | iommu->cmd_buf = alloc_command_buffer(iommu); |
715 | if (!iommu->cmd_buf) | 809 | if (!iommu->cmd_buf) |
716 | return -ENOMEM; | 810 | return -ENOMEM; |
@@ -746,6 +840,15 @@ static int __init init_iommu_all(struct acpi_table_header *table) | |||
746 | h = (struct ivhd_header *)p; | 840 | h = (struct ivhd_header *)p; |
747 | switch (*p) { | 841 | switch (*p) { |
748 | case ACPI_IVHD_TYPE: | 842 | case ACPI_IVHD_TYPE: |
843 | |||
844 | DUMP_printk("IOMMU: device: %02x:%02x.%01x cap: %04x " | ||
845 | "seg: %d flags: %01x info %04x\n", | ||
846 | PCI_BUS(h->devid), PCI_SLOT(h->devid), | ||
847 | PCI_FUNC(h->devid), h->cap_ptr, | ||
848 | h->pci_seg, h->flags, h->info); | ||
849 | DUMP_printk(" mmio-addr: %016llx\n", | ||
850 | h->mmio_phys); | ||
851 | |||
749 | iommu = kzalloc(sizeof(struct amd_iommu), GFP_KERNEL); | 852 | iommu = kzalloc(sizeof(struct amd_iommu), GFP_KERNEL); |
750 | if (iommu == NULL) | 853 | if (iommu == NULL) |
751 | return -ENOMEM; | 854 | return -ENOMEM; |
@@ -773,56 +876,9 @@ static int __init init_iommu_all(struct acpi_table_header *table) | |||
773 | * | 876 | * |
774 | ****************************************************************************/ | 877 | ****************************************************************************/ |
775 | 878 | ||
776 | static int __init iommu_setup_msix(struct amd_iommu *iommu) | ||
777 | { | ||
778 | struct amd_iommu *curr; | ||
779 | struct msix_entry entries[32]; /* only 32 supported by AMD IOMMU */ | ||
780 | int nvec = 0, i; | ||
781 | |||
782 | list_for_each_entry(curr, &amd_iommu_list, list) { | ||
783 | if (curr->dev == iommu->dev) { | ||
784 | entries[nvec].entry = curr->evt_msi_num; | ||
785 | entries[nvec].vector = 0; | ||
786 | curr->int_enabled = true; | ||
787 | nvec++; | ||
788 | } | ||
789 | } | ||
790 | |||
791 | if (pci_enable_msix(iommu->dev, entries, nvec)) { | ||
792 | pci_disable_msix(iommu->dev); | ||
793 | return 1; | ||
794 | } | ||
795 | |||
796 | for (i = 0; i < nvec; ++i) { | ||
797 | int r = request_irq(entries->vector, amd_iommu_int_handler, | ||
798 | IRQF_SAMPLE_RANDOM, | ||
799 | "AMD IOMMU", | ||
800 | NULL); | ||
801 | if (r) | ||
802 | goto out_free; | ||
803 | } | ||
804 | |||
805 | return 0; | ||
806 | |||
807 | out_free: | ||
808 | for (i -= 1; i >= 0; --i) | ||
809 | free_irq(entries->vector, NULL); | ||
810 | |||
811 | pci_disable_msix(iommu->dev); | ||
812 | |||
813 | return 1; | ||
814 | } | ||
815 | |||
816 | static int __init iommu_setup_msi(struct amd_iommu *iommu) | 879 | static int __init iommu_setup_msi(struct amd_iommu *iommu) |
817 | { | 880 | { |
818 | int r; | 881 | int r; |
819 | struct amd_iommu *curr; | ||
820 | |||
821 | list_for_each_entry(curr, &amd_iommu_list, list) { | ||
822 | if (curr->dev == iommu->dev) | ||
823 | curr->int_enabled = true; | ||
824 | } | ||
825 | |||
826 | 882 | ||
827 | if (pci_enable_msi(iommu->dev)) | 883 | if (pci_enable_msi(iommu->dev)) |
828 | return 1; | 884 | return 1; |
@@ -837,17 +893,18 @@ static int __init iommu_setup_msi(struct amd_iommu *iommu) | |||
837 | return 1; | 893 | return 1; |
838 | } | 894 | } |
839 | 895 | ||
896 | iommu->int_enabled = true; | ||
897 | iommu_feature_enable(iommu, CONTROL_EVT_INT_EN); | ||
898 | |||
840 | return 0; | 899 | return 0; |
841 | } | 900 | } |
842 | 901 | ||
843 | static int __init iommu_init_msi(struct amd_iommu *iommu) | 902 | static int iommu_init_msi(struct amd_iommu *iommu) |
844 | { | 903 | { |
845 | if (iommu->int_enabled) | 904 | if (iommu->int_enabled) |
846 | return 0; | 905 | return 0; |
847 | 906 | ||
848 | if (pci_find_capability(iommu->dev, PCI_CAP_ID_MSIX)) | 907 | if (pci_find_capability(iommu->dev, PCI_CAP_ID_MSI)) |
849 | return iommu_setup_msix(iommu); | ||
850 | else if (pci_find_capability(iommu->dev, PCI_CAP_ID_MSI)) | ||
851 | return iommu_setup_msi(iommu); | 908 | return iommu_setup_msi(iommu); |
852 | 909 | ||
853 | return 1; | 910 | return 1; |
@@ -899,6 +956,7 @@ static int __init init_exclusion_range(struct ivmd_header *m) | |||
899 | static int __init init_unity_map_range(struct ivmd_header *m) | 956 | static int __init init_unity_map_range(struct ivmd_header *m) |
900 | { | 957 | { |
901 | struct unity_map_entry *e = 0; | 958 | struct unity_map_entry *e = 0; |
959 | char *s; | ||
902 | 960 | ||
903 | e = kzalloc(sizeof(*e), GFP_KERNEL); | 961 | e = kzalloc(sizeof(*e), GFP_KERNEL); |
904 | if (e == NULL) | 962 | if (e == NULL) |
@@ -906,14 +964,19 @@ static int __init init_unity_map_range(struct ivmd_header *m) | |||
906 | 964 | ||
907 | switch (m->type) { | 965 | switch (m->type) { |
908 | default: | 966 | default: |
967 | kfree(e); | ||
968 | return 0; | ||
909 | case ACPI_IVMD_TYPE: | 969 | case ACPI_IVMD_TYPE: |
970 | s = "IVMD_TYPEi\t\t\t"; | ||
910 | e->devid_start = e->devid_end = m->devid; | 971 | e->devid_start = e->devid_end = m->devid; |
911 | break; | 972 | break; |
912 | case ACPI_IVMD_TYPE_ALL: | 973 | case ACPI_IVMD_TYPE_ALL: |
974 | s = "IVMD_TYPE_ALL\t\t"; | ||
913 | e->devid_start = 0; | 975 | e->devid_start = 0; |
914 | e->devid_end = amd_iommu_last_bdf; | 976 | e->devid_end = amd_iommu_last_bdf; |
915 | break; | 977 | break; |
916 | case ACPI_IVMD_TYPE_RANGE: | 978 | case ACPI_IVMD_TYPE_RANGE: |
979 | s = "IVMD_TYPE_RANGE\t\t"; | ||
917 | e->devid_start = m->devid; | 980 | e->devid_start = m->devid; |
918 | e->devid_end = m->aux; | 981 | e->devid_end = m->aux; |
919 | break; | 982 | break; |
@@ -922,6 +985,13 @@ static int __init init_unity_map_range(struct ivmd_header *m) | |||
922 | e->address_end = e->address_start + PAGE_ALIGN(m->range_length); | 985 | e->address_end = e->address_start + PAGE_ALIGN(m->range_length); |
923 | e->prot = m->flags >> 1; | 986 | e->prot = m->flags >> 1; |
924 | 987 | ||
988 | DUMP_printk("%s devid_start: %02x:%02x.%x devid_end: %02x:%02x.%x" | ||
989 | " range_start: %016llx range_end: %016llx flags: %x\n", s, | ||
990 | PCI_BUS(e->devid_start), PCI_SLOT(e->devid_start), | ||
991 | PCI_FUNC(e->devid_start), PCI_BUS(e->devid_end), | ||
992 | PCI_SLOT(e->devid_end), PCI_FUNC(e->devid_end), | ||
993 | e->address_start, e->address_end, m->flags); | ||
994 | |||
925 | list_add_tail(&e->list, &amd_iommu_unity_map); | 995 | list_add_tail(&e->list, &amd_iommu_unity_map); |
926 | 996 | ||
927 | return 0; | 997 | return 0; |
@@ -967,18 +1037,28 @@ static void init_device_table(void) | |||
967 | * This function finally enables all IOMMUs found in the system after | 1037 | * This function finally enables all IOMMUs found in the system after |
968 | * they have been initialized | 1038 | * they have been initialized |
969 | */ | 1039 | */ |
970 | static void __init enable_iommus(void) | 1040 | static void enable_iommus(void) |
971 | { | 1041 | { |
972 | struct amd_iommu *iommu; | 1042 | struct amd_iommu *iommu; |
973 | 1043 | ||
974 | list_for_each_entry(iommu, &amd_iommu_list, list) { | 1044 | for_each_iommu(iommu) { |
1045 | iommu_set_device_table(iommu); | ||
1046 | iommu_enable_command_buffer(iommu); | ||
1047 | iommu_enable_event_buffer(iommu); | ||
975 | iommu_set_exclusion_range(iommu); | 1048 | iommu_set_exclusion_range(iommu); |
976 | iommu_init_msi(iommu); | 1049 | iommu_init_msi(iommu); |
977 | iommu_enable_event_logging(iommu); | ||
978 | iommu_enable(iommu); | 1050 | iommu_enable(iommu); |
979 | } | 1051 | } |
980 | } | 1052 | } |
981 | 1053 | ||
1054 | static void disable_iommus(void) | ||
1055 | { | ||
1056 | struct amd_iommu *iommu; | ||
1057 | |||
1058 | for_each_iommu(iommu) | ||
1059 | iommu_disable(iommu); | ||
1060 | } | ||
1061 | |||
982 | /* | 1062 | /* |
983 | * Suspend/Resume support | 1063 | * Suspend/Resume support |
984 | * disable suspend until real resume implemented | 1064 | * disable suspend until real resume implemented |
@@ -986,12 +1066,31 @@ static void __init enable_iommus(void) | |||
986 | 1066 | ||
987 | static int amd_iommu_resume(struct sys_device *dev) | 1067 | static int amd_iommu_resume(struct sys_device *dev) |
988 | { | 1068 | { |
1069 | /* | ||
1070 | * Disable IOMMUs before reprogramming the hardware registers. | ||
1071 | * IOMMU is still enabled from the resume kernel. | ||
1072 | */ | ||
1073 | disable_iommus(); | ||
1074 | |||
1075 | /* re-load the hardware */ | ||
1076 | enable_iommus(); | ||
1077 | |||
1078 | /* | ||
1079 | * we have to flush after the IOMMUs are enabled because a | ||
1080 | * disabled IOMMU will never execute the commands we send | ||
1081 | */ | ||
1082 | amd_iommu_flush_all_domains(); | ||
1083 | amd_iommu_flush_all_devices(); | ||
1084 | |||
989 | return 0; | 1085 | return 0; |
990 | } | 1086 | } |
991 | 1087 | ||
992 | static int amd_iommu_suspend(struct sys_device *dev, pm_message_t state) | 1088 | static int amd_iommu_suspend(struct sys_device *dev, pm_message_t state) |
993 | { | 1089 | { |
994 | return -EINVAL; | 1090 | /* disable IOMMUs to go out of the way for BIOS */ |
1091 | disable_iommus(); | ||
1092 | |||
1093 | return 0; | ||
995 | } | 1094 | } |
996 | 1095 | ||
997 | static struct sysdev_class amd_iommu_sysdev_class = { | 1096 | static struct sysdev_class amd_iommu_sysdev_class = { |
@@ -1137,9 +1236,6 @@ int __init amd_iommu_init(void) | |||
1137 | 1236 | ||
1138 | enable_iommus(); | 1237 | enable_iommus(); |
1139 | 1238 | ||
1140 | printk(KERN_INFO "AMD IOMMU: aperture size is %d MB\n", | ||
1141 | (1 << (amd_iommu_aperture_order-20))); | ||
1142 | |||
1143 | printk(KERN_INFO "AMD IOMMU: device isolation "); | 1239 | printk(KERN_INFO "AMD IOMMU: device isolation "); |
1144 | if (amd_iommu_isolate) | 1240 | if (amd_iommu_isolate) |
1145 | printk("enabled\n"); | 1241 | printk("enabled\n"); |
@@ -1211,6 +1307,13 @@ void __init amd_iommu_detect(void) | |||
1211 | * | 1307 | * |
1212 | ****************************************************************************/ | 1308 | ****************************************************************************/ |
1213 | 1309 | ||
1310 | static int __init parse_amd_iommu_dump(char *str) | ||
1311 | { | ||
1312 | amd_iommu_dump = true; | ||
1313 | |||
1314 | return 1; | ||
1315 | } | ||
1316 | |||
1214 | static int __init parse_amd_iommu_options(char *str) | 1317 | static int __init parse_amd_iommu_options(char *str) |
1215 | { | 1318 | { |
1216 | for (; *str; ++str) { | 1319 | for (; *str; ++str) { |
@@ -1225,15 +1328,5 @@ static int __init parse_amd_iommu_options(char *str) | |||
1225 | return 1; | 1328 | return 1; |
1226 | } | 1329 | } |
1227 | 1330 | ||
1228 | static int __init parse_amd_iommu_size_options(char *str) | 1331 | __setup("amd_iommu_dump", parse_amd_iommu_dump); |
1229 | { | ||
1230 | unsigned order = PAGE_SHIFT + get_order(memparse(str, &str)); | ||
1231 | |||
1232 | if ((order > 24) && (order < 31)) | ||
1233 | amd_iommu_aperture_order = order; | ||
1234 | |||
1235 | return 1; | ||
1236 | } | ||
1237 | |||
1238 | __setup("amd_iommu=", parse_amd_iommu_options); | 1332 | __setup("amd_iommu=", parse_amd_iommu_options); |
1239 | __setup("amd_iommu_size=", parse_amd_iommu_size_options); | ||
diff --git a/arch/x86/kernel/pci-calgary_64.c b/arch/x86/kernel/pci-calgary_64.c index 755c21e906f3..971a3bec47a8 100644 --- a/arch/x86/kernel/pci-calgary_64.c +++ b/arch/x86/kernel/pci-calgary_64.c | |||
@@ -186,37 +186,6 @@ static struct cal_chipset_ops calioc2_chip_ops = { | |||
186 | 186 | ||
187 | static struct calgary_bus_info bus_info[MAX_PHB_BUS_NUM] = { { NULL, 0, 0 }, }; | 187 | static struct calgary_bus_info bus_info[MAX_PHB_BUS_NUM] = { { NULL, 0, 0 }, }; |
188 | 188 | ||
189 | /* enable this to stress test the chip's TCE cache */ | ||
190 | #ifdef CONFIG_IOMMU_DEBUG | ||
191 | static int debugging = 1; | ||
192 | |||
193 | static inline unsigned long verify_bit_range(unsigned long* bitmap, | ||
194 | int expected, unsigned long start, unsigned long end) | ||
195 | { | ||
196 | unsigned long idx = start; | ||
197 | |||
198 | BUG_ON(start >= end); | ||
199 | |||
200 | while (idx < end) { | ||
201 | if (!!test_bit(idx, bitmap) != expected) | ||
202 | return idx; | ||
203 | ++idx; | ||
204 | } | ||
205 | |||
206 | /* all bits have the expected value */ | ||
207 | return ~0UL; | ||
208 | } | ||
209 | #else /* debugging is disabled */ | ||
210 | static int debugging; | ||
211 | |||
212 | static inline unsigned long verify_bit_range(unsigned long* bitmap, | ||
213 | int expected, unsigned long start, unsigned long end) | ||
214 | { | ||
215 | return ~0UL; | ||
216 | } | ||
217 | |||
218 | #endif /* CONFIG_IOMMU_DEBUG */ | ||
219 | |||
220 | static inline int translation_enabled(struct iommu_table *tbl) | 189 | static inline int translation_enabled(struct iommu_table *tbl) |
221 | { | 190 | { |
222 | /* only PHBs with translation enabled have an IOMMU table */ | 191 | /* only PHBs with translation enabled have an IOMMU table */ |
@@ -228,7 +197,6 @@ static void iommu_range_reserve(struct iommu_table *tbl, | |||
228 | { | 197 | { |
229 | unsigned long index; | 198 | unsigned long index; |
230 | unsigned long end; | 199 | unsigned long end; |
231 | unsigned long badbit; | ||
232 | unsigned long flags; | 200 | unsigned long flags; |
233 | 201 | ||
234 | index = start_addr >> PAGE_SHIFT; | 202 | index = start_addr >> PAGE_SHIFT; |
@@ -243,14 +211,6 @@ static void iommu_range_reserve(struct iommu_table *tbl, | |||
243 | 211 | ||
244 | spin_lock_irqsave(&tbl->it_lock, flags); | 212 | spin_lock_irqsave(&tbl->it_lock, flags); |
245 | 213 | ||
246 | badbit = verify_bit_range(tbl->it_map, 0, index, end); | ||
247 | if (badbit != ~0UL) { | ||
248 | if (printk_ratelimit()) | ||
249 | printk(KERN_ERR "Calgary: entry already allocated at " | ||
250 | "0x%lx tbl %p dma 0x%lx npages %u\n", | ||
251 | badbit, tbl, start_addr, npages); | ||
252 | } | ||
253 | |||
254 | iommu_area_reserve(tbl->it_map, index, npages); | 214 | iommu_area_reserve(tbl->it_map, index, npages); |
255 | 215 | ||
256 | spin_unlock_irqrestore(&tbl->it_lock, flags); | 216 | spin_unlock_irqrestore(&tbl->it_lock, flags); |
@@ -326,7 +286,6 @@ static void iommu_free(struct iommu_table *tbl, dma_addr_t dma_addr, | |||
326 | unsigned int npages) | 286 | unsigned int npages) |
327 | { | 287 | { |
328 | unsigned long entry; | 288 | unsigned long entry; |
329 | unsigned long badbit; | ||
330 | unsigned long badend; | 289 | unsigned long badend; |
331 | unsigned long flags; | 290 | unsigned long flags; |
332 | 291 | ||
@@ -346,14 +305,6 @@ static void iommu_free(struct iommu_table *tbl, dma_addr_t dma_addr, | |||
346 | 305 | ||
347 | spin_lock_irqsave(&tbl->it_lock, flags); | 306 | spin_lock_irqsave(&tbl->it_lock, flags); |
348 | 307 | ||
349 | badbit = verify_bit_range(tbl->it_map, 1, entry, entry + npages); | ||
350 | if (badbit != ~0UL) { | ||
351 | if (printk_ratelimit()) | ||
352 | printk(KERN_ERR "Calgary: bit is off at 0x%lx " | ||
353 | "tbl %p dma 0x%Lx entry 0x%lx npages %u\n", | ||
354 | badbit, tbl, dma_addr, entry, npages); | ||
355 | } | ||
356 | |||
357 | iommu_area_free(tbl->it_map, entry, npages); | 308 | iommu_area_free(tbl->it_map, entry, npages); |
358 | 309 | ||
359 | spin_unlock_irqrestore(&tbl->it_lock, flags); | 310 | spin_unlock_irqrestore(&tbl->it_lock, flags); |
@@ -1488,9 +1439,8 @@ void __init detect_calgary(void) | |||
1488 | iommu_detected = 1; | 1439 | iommu_detected = 1; |
1489 | calgary_detected = 1; | 1440 | calgary_detected = 1; |
1490 | printk(KERN_INFO "PCI-DMA: Calgary IOMMU detected.\n"); | 1441 | printk(KERN_INFO "PCI-DMA: Calgary IOMMU detected.\n"); |
1491 | printk(KERN_INFO "PCI-DMA: Calgary TCE table spec is %d, " | 1442 | printk(KERN_INFO "PCI-DMA: Calgary TCE table spec is %d\n", |
1492 | "CONFIG_IOMMU_DEBUG is %s.\n", specified_table_size, | 1443 | specified_table_size); |
1493 | debugging ? "enabled" : "disabled"); | ||
1494 | 1444 | ||
1495 | /* swiotlb for devices that aren't behind the Calgary. */ | 1445 | /* swiotlb for devices that aren't behind the Calgary. */ |
1496 | if (max_pfn > MAX_DMA32_PFN) | 1446 | if (max_pfn > MAX_DMA32_PFN) |
diff --git a/arch/x86/kernel/pci-gart_64.c b/arch/x86/kernel/pci-gart_64.c index b284b58c035c..cfd9f9063896 100644 --- a/arch/x86/kernel/pci-gart_64.c +++ b/arch/x86/kernel/pci-gart_64.c | |||
@@ -144,48 +144,21 @@ static void flush_gart(void) | |||
144 | } | 144 | } |
145 | 145 | ||
146 | #ifdef CONFIG_IOMMU_LEAK | 146 | #ifdef CONFIG_IOMMU_LEAK |
147 | |||
148 | #define SET_LEAK(x) \ | ||
149 | do { \ | ||
150 | if (iommu_leak_tab) \ | ||
151 | iommu_leak_tab[x] = __builtin_return_address(0);\ | ||
152 | } while (0) | ||
153 | |||
154 | #define CLEAR_LEAK(x) \ | ||
155 | do { \ | ||
156 | if (iommu_leak_tab) \ | ||
157 | iommu_leak_tab[x] = NULL; \ | ||
158 | } while (0) | ||
159 | |||
160 | /* Debugging aid for drivers that don't free their IOMMU tables */ | 147 | /* Debugging aid for drivers that don't free their IOMMU tables */ |
161 | static void **iommu_leak_tab; | ||
162 | static int leak_trace; | 148 | static int leak_trace; |
163 | static int iommu_leak_pages = 20; | 149 | static int iommu_leak_pages = 20; |
164 | 150 | ||
165 | static void dump_leak(void) | 151 | static void dump_leak(void) |
166 | { | 152 | { |
167 | int i; | ||
168 | static int dump; | 153 | static int dump; |
169 | 154 | ||
170 | if (dump || !iommu_leak_tab) | 155 | if (dump) |
171 | return; | 156 | return; |
172 | dump = 1; | 157 | dump = 1; |
173 | show_stack(NULL, NULL); | ||
174 | 158 | ||
175 | /* Very crude. dump some from the end of the table too */ | 159 | show_stack(NULL, NULL); |
176 | printk(KERN_DEBUG "Dumping %d pages from end of IOMMU:\n", | 160 | debug_dma_dump_mappings(NULL); |
177 | iommu_leak_pages); | ||
178 | for (i = 0; i < iommu_leak_pages; i += 2) { | ||
179 | printk(KERN_DEBUG "%lu: ", iommu_pages-i); | ||
180 | printk_address((unsigned long) iommu_leak_tab[iommu_pages-i], | ||
181 | 0); | ||
182 | printk(KERN_CONT "%c", (i+1)%2 == 0 ? '\n' : ' '); | ||
183 | } | ||
184 | printk(KERN_DEBUG "\n"); | ||
185 | } | 161 | } |
186 | #else | ||
187 | # define SET_LEAK(x) | ||
188 | # define CLEAR_LEAK(x) | ||
189 | #endif | 162 | #endif |
190 | 163 | ||
191 | static void iommu_full(struct device *dev, size_t size, int dir) | 164 | static void iommu_full(struct device *dev, size_t size, int dir) |
@@ -248,7 +221,6 @@ static dma_addr_t dma_map_area(struct device *dev, dma_addr_t phys_mem, | |||
248 | 221 | ||
249 | for (i = 0; i < npages; i++) { | 222 | for (i = 0; i < npages; i++) { |
250 | iommu_gatt_base[iommu_page + i] = GPTE_ENCODE(phys_mem); | 223 | iommu_gatt_base[iommu_page + i] = GPTE_ENCODE(phys_mem); |
251 | SET_LEAK(iommu_page + i); | ||
252 | phys_mem += PAGE_SIZE; | 224 | phys_mem += PAGE_SIZE; |
253 | } | 225 | } |
254 | return iommu_bus_base + iommu_page*PAGE_SIZE + (phys_mem & ~PAGE_MASK); | 226 | return iommu_bus_base + iommu_page*PAGE_SIZE + (phys_mem & ~PAGE_MASK); |
@@ -294,7 +266,6 @@ static void gart_unmap_page(struct device *dev, dma_addr_t dma_addr, | |||
294 | npages = iommu_num_pages(dma_addr, size, PAGE_SIZE); | 266 | npages = iommu_num_pages(dma_addr, size, PAGE_SIZE); |
295 | for (i = 0; i < npages; i++) { | 267 | for (i = 0; i < npages; i++) { |
296 | iommu_gatt_base[iommu_page + i] = gart_unmapped_entry; | 268 | iommu_gatt_base[iommu_page + i] = gart_unmapped_entry; |
297 | CLEAR_LEAK(iommu_page + i); | ||
298 | } | 269 | } |
299 | free_iommu(iommu_page, npages); | 270 | free_iommu(iommu_page, npages); |
300 | } | 271 | } |
@@ -377,7 +348,6 @@ static int __dma_map_cont(struct device *dev, struct scatterlist *start, | |||
377 | pages = iommu_num_pages(s->offset, s->length, PAGE_SIZE); | 348 | pages = iommu_num_pages(s->offset, s->length, PAGE_SIZE); |
378 | while (pages--) { | 349 | while (pages--) { |
379 | iommu_gatt_base[iommu_page] = GPTE_ENCODE(addr); | 350 | iommu_gatt_base[iommu_page] = GPTE_ENCODE(addr); |
380 | SET_LEAK(iommu_page); | ||
381 | addr += PAGE_SIZE; | 351 | addr += PAGE_SIZE; |
382 | iommu_page++; | 352 | iommu_page++; |
383 | } | 353 | } |
@@ -688,8 +658,6 @@ static __init int init_k8_gatt(struct agp_kern_info *info) | |||
688 | 658 | ||
689 | agp_gatt_table = gatt; | 659 | agp_gatt_table = gatt; |
690 | 660 | ||
691 | enable_gart_translations(); | ||
692 | |||
693 | error = sysdev_class_register(&gart_sysdev_class); | 661 | error = sysdev_class_register(&gart_sysdev_class); |
694 | if (!error) | 662 | if (!error) |
695 | error = sysdev_register(&device_gart); | 663 | error = sysdev_register(&device_gart); |
@@ -801,11 +769,12 @@ void __init gart_iommu_init(void) | |||
801 | 769 | ||
802 | #ifdef CONFIG_IOMMU_LEAK | 770 | #ifdef CONFIG_IOMMU_LEAK |
803 | if (leak_trace) { | 771 | if (leak_trace) { |
804 | iommu_leak_tab = (void *)__get_free_pages(GFP_KERNEL|__GFP_ZERO, | 772 | int ret; |
805 | get_order(iommu_pages*sizeof(void *))); | 773 | |
806 | if (!iommu_leak_tab) | 774 | ret = dma_debug_resize_entries(iommu_pages); |
775 | if (ret) | ||
807 | printk(KERN_DEBUG | 776 | printk(KERN_DEBUG |
808 | "PCI-DMA: Cannot allocate leak trace area\n"); | 777 | "PCI-DMA: Cannot trace all the entries\n"); |
809 | } | 778 | } |
810 | #endif | 779 | #endif |
811 | 780 | ||
@@ -845,6 +814,14 @@ void __init gart_iommu_init(void) | |||
845 | * the pages as Not-Present: | 814 | * the pages as Not-Present: |
846 | */ | 815 | */ |
847 | wbinvd(); | 816 | wbinvd(); |
817 | |||
818 | /* | ||
819 | * Now all caches are flushed and we can safely enable | ||
820 | * GART hardware. Doing it early leaves the possibility | ||
821 | * of stale cache entries that can lead to GART PTE | ||
822 | * errors. | ||
823 | */ | ||
824 | enable_gart_translations(); | ||
848 | 825 | ||
849 | /* | 826 | /* |
850 | * Try to workaround a bug (thanks to BenH): | 827 | * Try to workaround a bug (thanks to BenH): |
diff --git a/arch/x86/kernel/pci-swiotlb.c b/arch/x86/kernel/pci-swiotlb.c index 221a3853e268..a1712f2b50f1 100644 --- a/arch/x86/kernel/pci-swiotlb.c +++ b/arch/x86/kernel/pci-swiotlb.c | |||
@@ -28,7 +28,7 @@ dma_addr_t swiotlb_phys_to_bus(struct device *hwdev, phys_addr_t paddr) | |||
28 | return paddr; | 28 | return paddr; |
29 | } | 29 | } |
30 | 30 | ||
31 | phys_addr_t swiotlb_bus_to_phys(dma_addr_t baddr) | 31 | phys_addr_t swiotlb_bus_to_phys(struct device *hwdev, dma_addr_t baddr) |
32 | { | 32 | { |
33 | return baddr; | 33 | return baddr; |
34 | } | 34 | } |