]> asedeno.scripts.mit.edu Git - linux.git/commitdiff
Merge branch 'for-linus' of git://git.linaro.org/people/mszyprowski/linux-dma-mapping
authorLinus Torvalds <torvalds@linux-foundation.org>
Thu, 5 Apr 2012 00:13:43 +0000 (17:13 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Thu, 5 Apr 2012 00:13:43 +0000 (17:13 -0700)
Pull DMA mapping branch from Marek Szyprowski:
 "Short summary for the whole series:

  A few limitations have been identified in the current dma-mapping
  design and its implementations for various architectures.  There exist
  more than one function for allocating and freeing the buffers:
  currently these 3 are used dma_{alloc, free}_coherent,
  dma_{alloc,free}_writecombine, dma_{alloc,free}_noncoherent.

  For most of the systems these calls are almost equivalent and can be
  interchanged.  For others, especially the truly non-coherent ones
  (like ARM), the difference can be easily noticed in overall driver
  performance.  Sadly not all architectures provide implementations for
  all of them, so the drivers might need to be adapted and cannot be
  easily shared between different architectures.  The provided patches
  unify all these functions and hide the differences under the already
  existing dma attributes concept.  The thread with more references is
  available here:

    http://www.spinics.net/lists/linux-sh/msg09777.html

  These patches are also a prerequisite for unifying DMA-mapping
  implementation on ARM architecture with the common one provided by
  dma_map_ops structure and extending it with IOMMU support.  More
  information is available in the following thread:

    http://thread.gmane.org/gmane.linux.kernel.cross-arch/12819

  More works on dma-mapping framework are planned, especially in the
  area of buffer sharing and managing the shared mappings (together with
  the recently introduced dma_buf interface: commit d15bd7ee445d
  "dma-buf: Introduce dma buffer sharing mechanism").

  The patches in the current set introduce a new alloc/free methods
  (with support for memory attributes) in dma_map_ops structure, which
  will later replace dma_alloc_coherent and dma_alloc_writecombine
  functions."

People finally started piping up with support for merging this, so I'm
merging it as the last of the pending stuff from the merge window.
Looks like pohmelfs is going to wait for 3.5 and more external support
for merging.

* 'for-linus' of git://git.linaro.org/people/mszyprowski/linux-dma-mapping:
  common: DMA-mapping: add NON-CONSISTENT attribute
  common: DMA-mapping: add WRITE_COMBINE attribute
  common: dma-mapping: introduce mmap method
  common: dma-mapping: remove old alloc_coherent and free_coherent methods
  Hexagon: adapt for dma_map_ops changes
  Unicore32: adapt for dma_map_ops changes
  Microblaze: adapt for dma_map_ops changes
  SH: adapt for dma_map_ops changes
  Alpha: adapt for dma_map_ops changes
  SPARC: adapt for dma_map_ops changes
  PowerPC: adapt for dma_map_ops changes
  MIPS: adapt for dma_map_ops changes
  X86 & IA64: adapt for dma_map_ops changes
  common: dma-mapping: introduce generic alloc() and free() methods

1  2 
arch/ia64/hp/common/sba_iommu.c
arch/powerpc/kernel/ibmebus.c
arch/powerpc/kernel/vio.c
arch/x86/kernel/pci-calgary_64.c
arch/x86/kernel/pci-dma.c
drivers/iommu/amd_iommu.c
drivers/iommu/intel-iommu.c
include/linux/dma-mapping.h

index f6ea3a3b4a842e8e0099d967f07a647786fff7d0,e5eb9c4b2198673b25f9b4f5eceabbb368359ca6..bcda5b2d121a624ee784f81843a13c155b7865a8
@@@ -43,6 -43,7 +43,6 @@@
  #include <asm/io.h>
  #include <asm/page.h>         /* PAGE_OFFSET */
  #include <asm/dma.h>
 -#include <asm/system.h>               /* wmb() */
  
  #include <asm/acpi-ext.h>
  
@@@ -1129,7 -1130,8 +1129,8 @@@ void sba_unmap_single_attrs(struct devi
   * See Documentation/DMA-API-HOWTO.txt
   */
  static void *
- sba_alloc_coherent (struct device *dev, size_t size, dma_addr_t *dma_handle, gfp_t flags)
+ sba_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_handle,
+                  gfp_t flags, struct dma_attrs *attrs)
  {
        struct ioc *ioc;
        void *addr;
   *
   * See Documentation/DMA-API-HOWTO.txt
   */
- static void sba_free_coherent (struct device *dev, size_t size, void *vaddr,
-                              dma_addr_t dma_handle)
+ static void sba_free_coherent(struct device *dev, size_t size, void *vaddr,
+                             dma_addr_t dma_handle, struct dma_attrs *attrs)
  {
        sba_unmap_single_attrs(dev, dma_handle, size, 0, NULL);
        free_pages((unsigned long) vaddr, get_order(size));
@@@ -2212,8 -2214,8 +2213,8 @@@ sba_page_override(char *str
  __setup("sbapagesize=",sba_page_override);
  
  struct dma_map_ops sba_dma_ops = {
-       .alloc_coherent         = sba_alloc_coherent,
-       .free_coherent          = sba_free_coherent,
+       .alloc                  = sba_alloc_coherent,
+       .free                   = sba_free_coherent,
        .map_page               = sba_map_page,
        .unmap_page             = sba_unmap_page,
        .map_sg                 = sba_map_sg_attrs,
index 79bb282e650161d8478887fde87cb9d99e00c97f,716d9181b5654dfc5c4bd797396e5398e1b7a033..b01d14eeca8da2633711d2b114a860a257eea427
@@@ -65,7 -65,8 +65,8 @@@ static struct of_device_id __initdata i
  static void *ibmebus_alloc_coherent(struct device *dev,
                                    size_t size,
                                    dma_addr_t *dma_handle,
-                                   gfp_t flag)
+                                   gfp_t flag,
+                                   struct dma_attrs *attrs)
  {
        void *mem;
  
@@@ -77,7 -78,8 +78,8 @@@
  
  static void ibmebus_free_coherent(struct device *dev,
                                  size_t size, void *vaddr,
-                                 dma_addr_t dma_handle)
+                                 dma_addr_t dma_handle,
+                                 struct dma_attrs *attrs)
  {
        kfree(vaddr);
  }
@@@ -136,8 -138,8 +138,8 @@@ static u64 ibmebus_dma_get_required_mas
  }
  
  static struct dma_map_ops ibmebus_dma_ops = {
-       .alloc_coherent     = ibmebus_alloc_coherent,
-       .free_coherent      = ibmebus_free_coherent,
+       .alloc              = ibmebus_alloc_coherent,
+       .free               = ibmebus_free_coherent,
        .map_sg             = ibmebus_map_sg,
        .unmap_sg           = ibmebus_unmap_sg,
        .dma_supported      = ibmebus_dma_supported,
@@@ -713,7 -715,7 +715,7 @@@ static struct dev_pm_ops ibmebus_bus_de
  
  struct bus_type ibmebus_bus_type = {
        .name      = "ibmebus",
 -      .uevent    = of_device_uevent,
 +      .uevent    = of_device_uevent_modalias,
        .bus_attrs = ibmebus_bus_attrs,
        .match     = ibmebus_bus_bus_match,
        .probe     = ibmebus_bus_device_probe,
index b2f7c8480bf6e853704ba20cb4787db7cb519a91,2d49c32b9dd3497cdc98c1a5aa94de416223a665..a3a99901c8ecf4a1929815329a72a54146017603
  #include <asm/abs_addr.h>
  #include <asm/page.h>
  #include <asm/hvcall.h>
 -#include <asm/iseries/vio.h>
 -#include <asm/iseries/hv_types.h>
 -#include <asm/iseries/hv_lp_config.h>
 -#include <asm/iseries/hv_call_xm.h>
 -#include <asm/iseries/iommu.h>
  
  static struct bus_type vio_bus_type;
  
@@@ -482,7 -487,8 +482,8 @@@ static void vio_cmo_balance(struct work
  }
  
  static void *vio_dma_iommu_alloc_coherent(struct device *dev, size_t size,
-                                           dma_addr_t *dma_handle, gfp_t flag)
+                                         dma_addr_t *dma_handle, gfp_t flag,
+                                         struct dma_attrs *attrs)
  {
        struct vio_dev *viodev = to_vio_dev(dev);
        void *ret;
                return NULL;
        }
  
-       ret = dma_iommu_ops.alloc_coherent(dev, size, dma_handle, flag);
+       ret = dma_iommu_ops.alloc(dev, size, dma_handle, flag, attrs);
        if (unlikely(ret == NULL)) {
                vio_cmo_dealloc(viodev, roundup(size, PAGE_SIZE));
                atomic_inc(&viodev->cmo.allocs_failed);
  }
  
  static void vio_dma_iommu_free_coherent(struct device *dev, size_t size,
-                                         void *vaddr, dma_addr_t dma_handle)
+                                       void *vaddr, dma_addr_t dma_handle,
+                                       struct dma_attrs *attrs)
  {
        struct vio_dev *viodev = to_vio_dev(dev);
  
-       dma_iommu_ops.free_coherent(dev, size, vaddr, dma_handle);
+       dma_iommu_ops.free(dev, size, vaddr, dma_handle, attrs);
  
        vio_cmo_dealloc(viodev, roundup(size, PAGE_SIZE));
  }
@@@ -607,8 -614,8 +609,8 @@@ static u64 vio_dma_get_required_mask(st
  }
  
  struct dma_map_ops vio_dma_mapping_ops = {
-       .alloc_coherent    = vio_dma_iommu_alloc_coherent,
-       .free_coherent     = vio_dma_iommu_free_coherent,
+       .alloc             = vio_dma_iommu_alloc_coherent,
+       .free              = vio_dma_iommu_free_coherent,
        .map_sg            = vio_dma_iommu_map_sg,
        .unmap_sg          = vio_dma_iommu_unmap_sg,
        .map_page          = vio_dma_iommu_map_page,
@@@ -1037,6 -1044,7 +1039,6 @@@ static void vio_cmo_sysfs_init(void
        vio_bus_type.bus_attrs = vio_cmo_bus_attrs;
  }
  #else /* CONFIG_PPC_SMLPAR */
 -/* Dummy functions for iSeries platform */
  int vio_cmo_entitlement_update(size_t new_entitlement) { return 0; }
  void vio_cmo_set_dev_desired(struct vio_dev *viodev, size_t desired) {}
  static int vio_cmo_bus_probe(struct vio_dev *viodev) { return 0; }
@@@ -1054,6 -1062,9 +1056,6 @@@ static struct iommu_table *vio_build_io
        struct iommu_table *tbl;
        unsigned long offset, size;
  
 -      if (firmware_has_feature(FW_FEATURE_ISERIES))
 -              return vio_build_iommu_table_iseries(dev);
 -
        dma_window = of_get_property(dev->dev.of_node,
                                  "ibm,my-dma-window", NULL);
        if (!dma_window)
@@@ -1159,21 -1170,17 +1161,21 @@@ static int vio_bus_remove(struct devic
   * vio_register_driver: - Register a new vio driver
   * @drv:      The vio_driver structure to be registered.
   */
 -int vio_register_driver(struct vio_driver *viodrv)
 +int __vio_register_driver(struct vio_driver *viodrv, struct module *owner,
 +                        const char *mod_name)
  {
 -      printk(KERN_DEBUG "%s: driver %s registering\n", __func__,
 -              viodrv->driver.name);
 +      pr_debug("%s: driver %s registering\n", __func__, viodrv->name);
  
        /* fill in 'struct driver' fields */
 +      viodrv->driver.name = viodrv->name;
 +      viodrv->driver.pm = viodrv->pm;
        viodrv->driver.bus = &vio_bus_type;
 +      viodrv->driver.owner = owner;
 +      viodrv->driver.mod_name = mod_name;
  
        return driver_register(&viodrv->driver);
  }
 -EXPORT_SYMBOL(vio_register_driver);
 +EXPORT_SYMBOL(__vio_register_driver);
  
  /**
   * vio_unregister_driver - Remove registration of vio driver.
@@@ -1190,7 -1197,8 +1192,7 @@@ static void __devinit vio_dev_release(s
  {
        struct iommu_table *tbl = get_iommu_table_base(dev);
  
 -      /* iSeries uses a common table for all vio devices */
 -      if (!firmware_has_feature(FW_FEATURE_ISERIES) && tbl)
 +      if (tbl)
                iommu_free_table(tbl, dev->of_node ?
                        dev->of_node->full_name : dev_name(dev));
        of_node_put(dev->of_node);
@@@ -1238,6 -1246,12 +1240,6 @@@ struct vio_dev *vio_register_device_nod
        viodev->name = of_node->name;
        viodev->type = of_node->type;
        viodev->unit_address = *unit_address;
 -      if (firmware_has_feature(FW_FEATURE_ISERIES)) {
 -              unit_address = of_get_property(of_node,
 -                              "linux,unit_address", NULL);
 -              if (unit_address != NULL)
 -                      viodev->unit_address = *unit_address;
 -      }
        viodev->dev.of_node = of_node_get(of_node);
  
        if (firmware_has_feature(FW_FEATURE_CMO))
index 6ac5782f4d6bf6cfb90666bc5288aad548d0c04f,07b587c5a2d24ebab473962debdf4c9c6461b16d..d0b2fb9ccbb16e1e9dc09afe32cb48fa38bfe81c
@@@ -42,6 -42,7 +42,6 @@@
  #include <asm/calgary.h>
  #include <asm/tce.h>
  #include <asm/pci-direct.h>
 -#include <asm/system.h>
  #include <asm/dma.h>
  #include <asm/rio.h>
  #include <asm/bios_ebda.h>
@@@ -430,7 -431,7 +430,7 @@@ static void calgary_unmap_page(struct d
  }
  
  static void* calgary_alloc_coherent(struct device *dev, size_t size,
-       dma_addr_t *dma_handle, gfp_t flag)
+       dma_addr_t *dma_handle, gfp_t flag, struct dma_attrs *attrs)
  {
        void *ret = NULL;
        dma_addr_t mapping;
@@@ -463,7 -464,8 +463,8 @@@ error
  }
  
  static void calgary_free_coherent(struct device *dev, size_t size,
-                                 void *vaddr, dma_addr_t dma_handle)
+                                 void *vaddr, dma_addr_t dma_handle,
+                                 struct dma_attrs *attrs)
  {
        unsigned int npages;
        struct iommu_table *tbl = find_iommu_table(dev);
  }
  
  static struct dma_map_ops calgary_dma_ops = {
-       .alloc_coherent = calgary_alloc_coherent,
-       .free_coherent = calgary_free_coherent,
+       .alloc = calgary_alloc_coherent,
+       .free = calgary_free_coherent,
        .map_sg = calgary_map_sg,
        .unmap_sg = calgary_unmap_sg,
        .map_page = calgary_map_page,
index 28e5e06fcba484c7520c718fb3cd9d961a103988,75e1cc19e630cd0a92455208edb2a285d1abe61c..3003250ac51dbcdc5be17a2fa37a84d9aae4a4e1
@@@ -96,7 -96,8 +96,8 @@@ void __init pci_iommu_alloc(void
        }
  }
  void *dma_generic_alloc_coherent(struct device *dev, size_t size,
-                                dma_addr_t *dma_addr, gfp_t flag)
+                                dma_addr_t *dma_addr, gfp_t flag,
+                                struct dma_attrs *attrs)
  {
        unsigned long dma_mask;
        struct page *page;
@@@ -262,11 -263,10 +263,11 @@@ rootfs_initcall(pci_iommu_init)
  
  static __devinit void via_no_dac(struct pci_dev *dev)
  {
 -      if ((dev->class >> 8) == PCI_CLASS_BRIDGE_PCI && forbid_dac == 0) {
 +      if (forbid_dac == 0) {
                dev_info(&dev->dev, "disabling DAC on VIA PCI bridge\n");
                forbid_dac = 1;
        }
  }
 -DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA, PCI_ANY_ID, via_no_dac);
 +DECLARE_PCI_FIXUP_CLASS_FINAL(PCI_VENDOR_ID_VIA, PCI_ANY_ID,
 +                              PCI_CLASS_BRIDGE_PCI, 8, via_no_dac);
  #endif
index ae2ec929e52f3e4ba76159e4df9448a6e315b115,daa333f97b78ba8f7989f900e1babb2fb0d86e8d..a5bee8e2dfce7904b637f8fd3d9871c75b7824a5
@@@ -2707,7 -2707,8 +2707,8 @@@ static void unmap_sg(struct device *dev
   * The exported alloc_coherent function for dma_ops.
   */
  static void *alloc_coherent(struct device *dev, size_t size,
-                           dma_addr_t *dma_addr, gfp_t flag)
+                           dma_addr_t *dma_addr, gfp_t flag,
+                           struct dma_attrs *attrs)
  {
        unsigned long flags;
        void *virt_addr;
@@@ -2765,7 -2766,8 +2766,8 @@@ out_free
   * The exported free_coherent function for dma_ops.
   */
  static void free_coherent(struct device *dev, size_t size,
-                         void *virt_addr, dma_addr_t dma_addr)
+                         void *virt_addr, dma_addr_t dma_addr,
+                         struct dma_attrs *attrs)
  {
        unsigned long flags;
        struct protection_domain *domain;
@@@ -2804,7 -2806,7 +2806,7 @@@ static int amd_iommu_dma_supported(stru
   * we don't need to preallocate the protection domains anymore.
   * For now we have to.
   */
 -static void prealloc_protection_domains(void)
 +static void __init prealloc_protection_domains(void)
  {
        struct iommu_dev_data *dev_data;
        struct dma_ops_domain *dma_dom;
  }
  
  static struct dma_map_ops amd_iommu_dma_ops = {
-       .alloc_coherent = alloc_coherent,
-       .free_coherent = free_coherent,
+       .alloc = alloc_coherent,
+       .free = free_coherent,
        .map_page = map_page,
        .unmap_page = unmap_page,
        .map_sg = map_sg,
index 132f93b0515488a41ada28353e9de872e2c4f333,e39bfdc055c39cb20c377306c47bcbc034807fc1..f93d5ac8f81c0b2ff02b6f97b2ae079b8b3f80a7
@@@ -48,6 -48,8 +48,6 @@@
  #define ROOT_SIZE             VTD_PAGE_SIZE
  #define CONTEXT_SIZE          VTD_PAGE_SIZE
  
 -#define IS_BRIDGE_HOST_DEVICE(pdev) \
 -                          ((pdev->class >> 8) == PCI_CLASS_BRIDGE_HOST)
  #define IS_GFX_DEVICE(pdev) ((pdev->class >> 16) == PCI_BASE_CLASS_DISPLAY)
  #define IS_ISA_DEVICE(pdev) ((pdev->class >> 8) == PCI_CLASS_BRIDGE_ISA)
  #define IS_AZALIA(pdev) ((pdev)->vendor == 0x8086 && (pdev)->device == 0x3a3e)
@@@ -354,18 -356,10 +354,18 @@@ static int hw_pass_through = 1
  /* si_domain contains mulitple devices */
  #define DOMAIN_FLAG_STATIC_IDENTITY   (1 << 2)
  
 +/* define the limit of IOMMUs supported in each domain */
 +#ifdef        CONFIG_X86
 +# define      IOMMU_UNITS_SUPPORTED   MAX_IO_APICS
 +#else
 +# define      IOMMU_UNITS_SUPPORTED   64
 +#endif
 +
  struct dmar_domain {
        int     id;                     /* domain id */
        int     nid;                    /* node id */
 -      unsigned long iommu_bmp;        /* bitmap of iommus this domain uses*/
 +      DECLARE_BITMAP(iommu_bmp, IOMMU_UNITS_SUPPORTED);
 +                                      /* bitmap of iommus this domain uses*/
  
        struct list_head devices;       /* all devices' list */
        struct iova_domain iovad;       /* iova's that belong to this domain */
@@@ -577,7 -571,7 +577,7 @@@ static struct intel_iommu *domain_get_i
        BUG_ON(domain->flags & DOMAIN_FLAG_VIRTUAL_MACHINE);
        BUG_ON(domain->flags & DOMAIN_FLAG_STATIC_IDENTITY);
  
 -      iommu_id = find_first_bit(&domain->iommu_bmp, g_num_of_iommus);
 +      iommu_id = find_first_bit(domain->iommu_bmp, g_num_of_iommus);
        if (iommu_id < 0 || iommu_id >= g_num_of_iommus)
                return NULL;
  
@@@ -590,7 -584,7 +590,7 @@@ static void domain_update_iommu_coheren
  
        domain->iommu_coherency = 1;
  
 -      for_each_set_bit(i, &domain->iommu_bmp, g_num_of_iommus) {
 +      for_each_set_bit(i, domain->iommu_bmp, g_num_of_iommus) {
                if (!ecap_coherent(g_iommus[i]->ecap)) {
                        domain->iommu_coherency = 0;
                        break;
@@@ -604,7 -598,7 +604,7 @@@ static void domain_update_iommu_snoopin
  
        domain->iommu_snooping = 1;
  
 -      for_each_set_bit(i, &domain->iommu_bmp, g_num_of_iommus) {
 +      for_each_set_bit(i, domain->iommu_bmp, g_num_of_iommus) {
                if (!ecap_sc_support(g_iommus[i]->ecap)) {
                        domain->iommu_snooping = 0;
                        break;
@@@ -1247,7 -1241,7 +1247,7 @@@ static int iommu_init_domains(struct in
        unsigned long nlongs;
  
        ndomains = cap_ndoms(iommu->cap);
 -      pr_debug("IOMMU %d: Number of Domains supportd <%ld>\n", iommu->seq_id,
 +      pr_debug("IOMMU %d: Number of Domains supported <%ld>\n", iommu->seq_id,
                        ndomains);
        nlongs = BITS_TO_LONGS(ndomains);
  
@@@ -1340,7 -1334,7 +1340,7 @@@ static struct dmar_domain *alloc_domain
                return NULL;
  
        domain->nid = -1;
 -      memset(&domain->iommu_bmp, 0, sizeof(unsigned long));
 +      memset(domain->iommu_bmp, 0, sizeof(domain->iommu_bmp));
        domain->flags = 0;
  
        return domain;
@@@ -1366,7 -1360,7 +1366,7 @@@ static int iommu_attach_domain(struct d
  
        domain->id = num;
        set_bit(num, iommu->domain_ids);
 -      set_bit(iommu->seq_id, &domain->iommu_bmp);
 +      set_bit(iommu->seq_id, domain->iommu_bmp);
        iommu->domains[num] = domain;
        spin_unlock_irqrestore(&iommu->lock, flags);
  
@@@ -1391,7 -1385,7 +1391,7 @@@ static void iommu_detach_domain(struct 
  
        if (found) {
                clear_bit(num, iommu->domain_ids);
 -              clear_bit(iommu->seq_id, &domain->iommu_bmp);
 +              clear_bit(iommu->seq_id, domain->iommu_bmp);
                iommu->domains[num] = NULL;
        }
        spin_unlock_irqrestore(&iommu->lock, flags);
@@@ -1533,7 -1527,7 +1533,7 @@@ static void domain_exit(struct dmar_dom
        dma_pte_free_pagetable(domain, 0, DOMAIN_MAX_PFN(domain->gaw));
  
        for_each_active_iommu(iommu, drhd)
 -              if (test_bit(iommu->seq_id, &domain->iommu_bmp))
 +              if (test_bit(iommu->seq_id, domain->iommu_bmp))
                        iommu_detach_domain(domain, iommu);
  
        free_domain_mem(domain);
@@@ -1659,7 -1653,7 +1659,7 @@@ static int domain_context_mapping_one(s
        spin_unlock_irqrestore(&iommu->lock, flags);
  
        spin_lock_irqsave(&domain->iommu_lock, flags);
 -      if (!test_and_set_bit(iommu->seq_id, &domain->iommu_bmp)) {
 +      if (!test_and_set_bit(iommu->seq_id, domain->iommu_bmp)) {
                domain->iommu_count++;
                if (domain->iommu_count == 1)
                        domain->nid = iommu->node;
@@@ -2375,18 -2369,18 +2375,18 @@@ static int __init iommu_prepare_static_
                return -EFAULT;
  
        for_each_pci_dev(pdev) {
 -              /* Skip Host/PCI Bridge devices */
 -              if (IS_BRIDGE_HOST_DEVICE(pdev))
 -                      continue;
                if (iommu_should_identity_map(pdev, 1)) {
 -                      printk(KERN_INFO "IOMMU: %s identity mapping for device %s\n",
 -                             hw ? "hardware" : "software", pci_name(pdev));
 -
                        ret = domain_add_dev_info(si_domain, pdev,
 -                                                   hw ? CONTEXT_TT_PASS_THROUGH :
 -                                                   CONTEXT_TT_MULTI_LEVEL);
 -                      if (ret)
 +                                           hw ? CONTEXT_TT_PASS_THROUGH :
 +                                                CONTEXT_TT_MULTI_LEVEL);
 +                      if (ret) {
 +                              /* device not associated with an iommu */
 +                              if (ret == -ENODEV)
 +                                      continue;
                                return ret;
 +                      }
 +                      pr_info("IOMMU: %s identity mapping for device %s\n",
 +                              hw ? "hardware" : "software", pci_name(pdev));
                }
        }
  
@@@ -2408,17 -2402,12 +2408,17 @@@ static int __init init_dmars(void
         * endfor
         */
        for_each_drhd_unit(drhd) {
 -              g_num_of_iommus++;
                /*
                 * lock not needed as this is only incremented in the single
                 * threaded kernel __init code path all other access are read
                 * only
                 */
 +              if (g_num_of_iommus < IOMMU_UNITS_SUPPORTED) {
 +                      g_num_of_iommus++;
 +                      continue;
 +              }
 +              printk_once(KERN_ERR "intel-iommu: exceeded %d IOMMUs\n",
 +                        IOMMU_UNITS_SUPPORTED);
        }
  
        g_iommus = kcalloc(g_num_of_iommus, sizeof(struct intel_iommu *),
@@@ -2949,7 -2938,8 +2949,8 @@@ static void intel_unmap_page(struct dev
  }
  
  static void *intel_alloc_coherent(struct device *hwdev, size_t size,
-                                 dma_addr_t *dma_handle, gfp_t flags)
+                                 dma_addr_t *dma_handle, gfp_t flags,
+                                 struct dma_attrs *attrs)
  {
        void *vaddr;
        int order;
  }
  
  static void intel_free_coherent(struct device *hwdev, size_t size, void *vaddr,
-                               dma_addr_t dma_handle)
+                               dma_addr_t dma_handle, struct dma_attrs *attrs)
  {
        int order;
  
@@@ -3126,8 -3116,8 +3127,8 @@@ static int intel_mapping_error(struct d
  }
  
  struct dma_map_ops intel_dma_ops = {
-       .alloc_coherent = intel_alloc_coherent,
-       .free_coherent = intel_free_coherent,
+       .alloc = intel_alloc_coherent,
+       .free = intel_free_coherent,
        .map_sg = intel_map_sg,
        .unmap_sg = intel_unmap_sg,
        .map_page = intel_map_page,
@@@ -3759,7 -3749,7 +3760,7 @@@ static void domain_remove_one_dev_info(
        if (found == 0) {
                unsigned long tmp_flags;
                spin_lock_irqsave(&domain->iommu_lock, tmp_flags);
 -              clear_bit(iommu->seq_id, &domain->iommu_bmp);
 +              clear_bit(iommu->seq_id, domain->iommu_bmp);
                domain->iommu_count--;
                domain_update_iommu_cap(domain);
                spin_unlock_irqrestore(&domain->iommu_lock, tmp_flags);
@@@ -3801,7 -3791,7 +3802,7 @@@ static void vm_domain_remove_all_dev_in
                 */
                spin_lock_irqsave(&domain->iommu_lock, flags2);
                if (test_and_clear_bit(iommu->seq_id,
 -                                     &domain->iommu_bmp)) {
 +                                     domain->iommu_bmp)) {
                        domain->iommu_count--;
                        domain_update_iommu_cap(domain);
                }
@@@ -3826,7 -3816,7 +3827,7 @@@ static struct dmar_domain *iommu_alloc_
  
        domain->id = vm_domid++;
        domain->nid = -1;
 -      memset(&domain->iommu_bmp, 0, sizeof(unsigned long));
 +      memset(domain->iommu_bmp, 0, sizeof(domain->iommu_bmp));
        domain->flags = DOMAIN_FLAG_VIRTUAL_MACHINE;
  
        return domain;
index 5a736af3cc7a3623574794554ab510c29c596a30,b903a20867f789dc7765c9e5591e374096e046ca..dfc099e56a66187ba9d223eea924da5650e462bf
@@@ -9,10 -9,15 +9,15 @@@
  #include <linux/scatterlist.h>
  
  struct dma_map_ops {
-       void* (*alloc_coherent)(struct device *dev, size_t size,
-                               dma_addr_t *dma_handle, gfp_t gfp);
-       void (*free_coherent)(struct device *dev, size_t size,
-                             void *vaddr, dma_addr_t dma_handle);
+       void* (*alloc)(struct device *dev, size_t size,
+                               dma_addr_t *dma_handle, gfp_t gfp,
+                               struct dma_attrs *attrs);
+       void (*free)(struct device *dev, size_t size,
+                             void *vaddr, dma_addr_t dma_handle,
+                             struct dma_attrs *attrs);
+       int (*mmap)(struct device *, struct vm_area_struct *,
+                         void *, dma_addr_t, size_t, struct dma_attrs *attrs);
        dma_addr_t (*map_page)(struct device *dev, struct page *page,
                               unsigned long offset, size_t size,
                               enum dma_data_direction dir,
@@@ -77,7 -82,7 +82,7 @@@ static inline u64 dma_get_mask(struct d
        return DMA_BIT_MASK(32);
  }
  
 -#ifdef ARCH_HAS_DMA_SET_COHERENT_MASK
 +#ifdef CONFIG_ARCH_HAS_DMA_SET_COHERENT_MASK
  int dma_set_coherent_mask(struct device *dev, u64 mask);
  #else
  static inline int dma_set_coherent_mask(struct device *dev, u64 mask)