Merge branches 'x86/vt-d', 'x86/amd', 'arm/smmu', 'arm/omap', 'generic-dma-ops' and...
[linux-block.git] / drivers / iommu / amd_iommu.c
index 09c9e45f7fa2ec99751f752f4ff6fe30ccd7dfeb..73740b969e62461d5f2b73204899225a048e3a94 100644 (file)
@@ -1,20 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0-only
 /*
  * Copyright (C) 2007-2010 Advanced Micro Devices, Inc.
  * Author: Joerg Roedel <jroedel@suse.de>
  *         Leo Duran <leo.duran@amd.com>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 as published
- * by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
  */
 
 #define pr_fmt(fmt)     "AMD-Vi: " fmt
@@ -631,9 +619,9 @@ retry:
                pasid = ((event[0] >> 16) & 0xFFFF)
                        | ((event[1] << 6) & 0xF0000);
                tag = event[1] & 0x03FF;
-               dev_err(dev, "Event logged [INVALID_PPR_REQUEST device=%02x:%02x.%x pasid=0x%05x address=0x%llx flags=0x%04x]\n",
+               dev_err(dev, "Event logged [INVALID_PPR_REQUEST device=%02x:%02x.%x pasid=0x%05x address=0x%llx flags=0x%04x tag=0x%03x]\n",
                        PCI_BUS_NUM(devid), PCI_SLOT(devid), PCI_FUNC(devid),
-                       pasid, address, flags);
+                       pasid, address, flags, tag);
                break;
        default:
                dev_err(dev, "Event logged [UNKNOWN event[0]=0x%08x event[1]=0x%08x event[2]=0x%08x event[3]=0x%08x\n",
@@ -1307,6 +1295,16 @@ static void domain_flush_complete(struct protection_domain *domain)
        }
 }
 
+/* Flush the not present cache if it exists */
+static void domain_flush_np_cache(struct protection_domain *domain,
+               dma_addr_t iova, size_t size)
+{
+       if (unlikely(amd_iommu_np_cache)) {
+               domain_flush_pages(domain, iova, size);
+               domain_flush_complete(domain);
+       }
+}
+
 
 /*
  * This function flushes the DTEs for all devices in domain
@@ -2389,10 +2387,7 @@ static dma_addr_t __map_single(struct device *dev,
        }
        address += offset;
 
-       if (unlikely(amd_iommu_np_cache)) {
-               domain_flush_pages(&dma_dom->domain, address, size);
-               domain_flush_complete(&dma_dom->domain);
-       }
+       domain_flush_np_cache(&dma_dom->domain, address, size);
 
 out:
        return address;
@@ -2571,6 +2566,9 @@ static int map_sg(struct device *dev, struct scatterlist *sglist,
                s->dma_length   = s->length;
        }
 
+       if (s)
+               domain_flush_np_cache(domain, s->dma_address, s->dma_length);
+
        return nelems;
 
 out_unmap:
@@ -2609,7 +2607,7 @@ static void unmap_sg(struct device *dev, struct scatterlist *sglist,
        struct protection_domain *domain;
        struct dma_ops_domain *dma_dom;
        unsigned long startaddr;
-       int npages = 2;
+       int npages;
 
        domain = get_domain(dev);
        if (IS_ERR(domain))
@@ -3051,6 +3049,8 @@ static int amd_iommu_map(struct iommu_domain *dom, unsigned long iova,
        ret = iommu_map_page(domain, iova, paddr, page_size, prot, GFP_KERNEL);
        mutex_unlock(&domain->api_lock);
 
+       domain_flush_np_cache(domain, iova, page_size);
+
        return ret;
 }