aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/iommu/amd_iommu.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/iommu/amd_iommu.c')
-rw-r--r--drivers/iommu/amd_iommu.c19
1 files changed, 13 insertions, 6 deletions
diff --git a/drivers/iommu/amd_iommu.c b/drivers/iommu/amd_iommu.c
index 87ba23a75b38..2a7b78bb98b4 100644
--- a/drivers/iommu/amd_iommu.c
+++ b/drivers/iommu/amd_iommu.c
@@ -1991,16 +1991,13 @@ static void do_attach(struct iommu_dev_data *dev_data,
1991 1991
1992static void do_detach(struct iommu_dev_data *dev_data) 1992static void do_detach(struct iommu_dev_data *dev_data)
1993{ 1993{
1994 struct protection_domain *domain = dev_data->domain;
1994 struct amd_iommu *iommu; 1995 struct amd_iommu *iommu;
1995 u16 alias; 1996 u16 alias;
1996 1997
1997 iommu = amd_iommu_rlookup_table[dev_data->devid]; 1998 iommu = amd_iommu_rlookup_table[dev_data->devid];
1998 alias = dev_data->alias; 1999 alias = dev_data->alias;
1999 2000
2000 /* decrease reference counters */
2001 dev_data->domain->dev_iommu[iommu->index] -= 1;
2002 dev_data->domain->dev_cnt -= 1;
2003
2004 /* Update data structures */ 2001 /* Update data structures */
2005 dev_data->domain = NULL; 2002 dev_data->domain = NULL;
2006 list_del(&dev_data->list); 2003 list_del(&dev_data->list);
@@ -2010,6 +2007,16 @@ static void do_detach(struct iommu_dev_data *dev_data)
2010 2007
2011 /* Flush the DTE entry */ 2008 /* Flush the DTE entry */
2012 device_flush_dte(dev_data); 2009 device_flush_dte(dev_data);
2010
2011 /* Flush IOTLB */
2012 domain_flush_tlb_pde(domain);
2013
2014 /* Wait for the flushes to finish */
2015 domain_flush_complete(domain);
2016
2017 /* decrease reference counters - needs to happen after the flushes */
2018 domain->dev_iommu[iommu->index] -= 1;
2019 domain->dev_cnt -= 1;
2013} 2020}
2014 2021
2015/* 2022/*
@@ -2617,13 +2624,13 @@ out_unmap:
2617 bus_addr = address + s->dma_address + (j << PAGE_SHIFT); 2624 bus_addr = address + s->dma_address + (j << PAGE_SHIFT);
2618 iommu_unmap_page(domain, bus_addr, PAGE_SIZE); 2625 iommu_unmap_page(domain, bus_addr, PAGE_SIZE);
2619 2626
2620 if (--mapped_pages) 2627 if (--mapped_pages == 0)
2621 goto out_free_iova; 2628 goto out_free_iova;
2622 } 2629 }
2623 } 2630 }
2624 2631
2625out_free_iova: 2632out_free_iova:
2626 free_iova_fast(&dma_dom->iovad, address, npages); 2633 free_iova_fast(&dma_dom->iovad, address >> PAGE_SHIFT, npages);
2627 2634
2628out_err: 2635out_err:
2629 return 0; 2636 return 0;