Messages in this thread Patch in this message | | | From | Filippo Sironi <> | Subject | [PATCH 2/5] iommu/amd: Hold the domain lock when calling __map_single | Date | Tue, 10 Sep 2019 19:49:22 +0200 |
| |
__map_single makes several calls to __domain_flush_pages, which traverses the device list that is protected by the domain lock.
Also, this is in line with the comment on top of __map_single, which says that the domain lock should be held when calling.
Signed-off-by: Filippo Sironi <sironi@amazon.de> --- drivers/iommu/amd_iommu.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-)
diff --git a/drivers/iommu/amd_iommu.c b/drivers/iommu/amd_iommu.c index f026a8c2b218..8e3664821b3c 100644 --- a/drivers/iommu/amd_iommu.c +++ b/drivers/iommu/amd_iommu.c @@ -2482,6 +2482,8 @@ static dma_addr_t map_page(struct device *dev, struct page *page, struct protection_domain *domain; struct dma_ops_domain *dma_dom; u64 dma_mask; + unsigned long flags; + dma_addr_t dma_addr; domain = get_domain(dev); if (PTR_ERR(domain) == -EINVAL) @@ -2492,7 +2494,10 @@ static dma_addr_t map_page(struct device *dev, struct page *page, dma_mask = *dev->dma_mask; dma_dom = to_dma_ops_domain(domain); - return __map_single(dev, dma_dom, paddr, size, dir, dma_mask); + spin_lock_irqsave(&domain->lock, flags); + dma_addr = __map_single(dev, dma_dom, paddr, size, dir, dma_mask); + spin_unlock_irqrestore(&domain->lock, flags); + return dma_addr; } /* @@ -2663,6 +2668,7 @@ static void *alloc_coherent(struct device *dev, size_t size, struct protection_domain *domain; struct dma_ops_domain *dma_dom; struct page *page; + unsigned long flags; domain = get_domain(dev); if (PTR_ERR(domain) == -EINVAL) { @@ -2692,8 +2698,10 @@ static void *alloc_coherent(struct device *dev, size_t size, if (!dma_mask) dma_mask = *dev->dma_mask; + spin_lock_irqsave(&domain->lock, flags); *dma_addr = __map_single(dev, dma_dom, page_to_phys(page), size, DMA_BIDIRECTIONAL, dma_mask); + spin_unlock_irqrestore(&domain->lock, flags); if (*dma_addr == DMA_MAPPING_ERROR) goto out_free; -- 2.7.4
| |