aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/x86/kernel/amd_iommu.c26
-rw-r--r--arch/x86/kernel/amd_iommu_init.c7
-rw-r--r--include/asm-x86/amd_iommu_types.h3
3 files changed, 31 insertions, 5 deletions
diff --git a/arch/x86/kernel/amd_iommu.c b/arch/x86/kernel/amd_iommu.c
index 691e023695ad..679f2a8e22ee 100644
--- a/arch/x86/kernel/amd_iommu.c
+++ b/arch/x86/kernel/amd_iommu.c
@@ -203,6 +203,14 @@ static int iommu_flush_pages(struct amd_iommu *iommu, u16 domid,
203 return 0; 203 return 0;
204} 204}
205 205
206/* Flush the whole IO/TLB for a given protection domain */
207static void iommu_flush_tlb(struct amd_iommu *iommu, u16 domid)
208{
209 u64 address = CMD_INV_IOMMU_ALL_PAGES_ADDRESS;
210
211 iommu_queue_inv_iommu_pages(iommu, address, domid, 0, 1);
212}
213
206/**************************************************************************** 214/****************************************************************************
207 * 215 *
208 * The functions below are used the create the page table mappings for 216 * The functions below are used the create the page table mappings for
@@ -386,14 +394,18 @@ static unsigned long dma_ops_alloc_addresses(struct device *dev,
386 PAGE_SIZE) >> PAGE_SHIFT; 394 PAGE_SIZE) >> PAGE_SHIFT;
387 limit = limit < size ? limit : size; 395 limit = limit < size ? limit : size;
388 396
389 if (dom->next_bit >= limit) 397 if (dom->next_bit >= limit) {
390 dom->next_bit = 0; 398 dom->next_bit = 0;
399 dom->need_flush = true;
400 }
391 401
392 address = iommu_area_alloc(dom->bitmap, limit, dom->next_bit, pages, 402 address = iommu_area_alloc(dom->bitmap, limit, dom->next_bit, pages,
393 0 , boundary_size, 0); 403 0 , boundary_size, 0);
394 if (address == -1) 404 if (address == -1) {
395 address = iommu_area_alloc(dom->bitmap, limit, 0, pages, 405 address = iommu_area_alloc(dom->bitmap, limit, 0, pages,
396 0, boundary_size, 0); 406 0, boundary_size, 0);
407 dom->need_flush = true;
408 }
397 409
398 if (likely(address != -1)) { 410 if (likely(address != -1)) {
399 dom->next_bit = address + pages; 411 dom->next_bit = address + pages;
@@ -553,6 +565,8 @@ static struct dma_ops_domain *dma_ops_domain_alloc(struct amd_iommu *iommu,
553 dma_dom->bitmap[0] = 1; 565 dma_dom->bitmap[0] = 1;
554 dma_dom->next_bit = 0; 566 dma_dom->next_bit = 0;
555 567
568 dma_dom->need_flush = false;
569
556 /* Intialize the exclusion range if necessary */ 570 /* Intialize the exclusion range if necessary */
557 if (iommu->exclusion_start && 571 if (iommu->exclusion_start &&
558 iommu->exclusion_start < dma_dom->aperture_size) { 572 iommu->exclusion_start < dma_dom->aperture_size) {
@@ -795,7 +809,10 @@ static dma_addr_t __map_single(struct device *dev,
795 } 809 }
796 address += offset; 810 address += offset;
797 811
798 if (unlikely(iommu_has_npcache(iommu))) 812 if (unlikely(dma_dom->need_flush && !iommu_fullflush)) {
813 iommu_flush_tlb(iommu, dma_dom->domain.id);
814 dma_dom->need_flush = false;
815 } else if (unlikely(iommu_has_npcache(iommu)))
799 iommu_flush_pages(iommu, dma_dom->domain.id, address, size); 816 iommu_flush_pages(iommu, dma_dom->domain.id, address, size);
800 817
801out: 818out:
@@ -829,7 +846,8 @@ static void __unmap_single(struct amd_iommu *iommu,
829 846
830 dma_ops_free_addresses(dma_dom, dma_addr, pages); 847 dma_ops_free_addresses(dma_dom, dma_addr, pages);
831 848
832 iommu_flush_pages(iommu, dma_dom->domain.id, dma_addr, size); 849 if (iommu_fullflush)
850 iommu_flush_pages(iommu, dma_dom->domain.id, dma_addr, size);
833} 851}
834 852
835/* 853/*
diff --git a/arch/x86/kernel/amd_iommu_init.c b/arch/x86/kernel/amd_iommu_init.c
index a69cc0f52042..f2fa8dc81beb 100644
--- a/arch/x86/kernel/amd_iommu_init.c
+++ b/arch/x86/kernel/amd_iommu_init.c
@@ -995,6 +995,11 @@ int __init amd_iommu_init(void)
995 else 995 else
996 printk("disabled\n"); 996 printk("disabled\n");
997 997
998 if (iommu_fullflush)
999 printk(KERN_INFO "AMD IOMMU: IO/TLB flush on unmap enabled\n");
1000 else
1001 printk(KERN_INFO "AMD IOMMU: Lazy IO/TLB flushing enabled\n");
1002
998out: 1003out:
999 return ret; 1004 return ret;
1000 1005
@@ -1057,7 +1062,7 @@ void __init amd_iommu_detect(void)
1057static int __init parse_amd_iommu_options(char *str) 1062static int __init parse_amd_iommu_options(char *str)
1058{ 1063{
1059 for (; *str; ++str) { 1064 for (; *str; ++str) {
1060 if (strcmp(str, "isolate") == 0) 1065 if (strncmp(str, "isolate", 7) == 0)
1061 amd_iommu_isolate = 1; 1066 amd_iommu_isolate = 1;
1062 } 1067 }
1063 1068
diff --git a/include/asm-x86/amd_iommu_types.h b/include/asm-x86/amd_iommu_types.h
index dcc812067394..dcc472445ffd 100644
--- a/include/asm-x86/amd_iommu_types.h
+++ b/include/asm-x86/amd_iommu_types.h
@@ -196,6 +196,9 @@ struct dma_ops_domain {
196 * just calculate its address in constant time. 196 * just calculate its address in constant time.
197 */ 197 */
198 u64 **pte_pages; 198 u64 **pte_pages;
199
200 /* This will be set to true when TLB needs to be flushed */
201 bool need_flush;
199}; 202};
200 203
201/* 204/*