Merge git://git.infradead.org/~dwmw2/iommu-2.6.31
authorLinus Torvalds <torvalds@linux-foundation.org>
Tue, 23 Jun 2009 04:38:22 +0000 (21:38 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Tue, 23 Jun 2009 04:38:22 +0000 (21:38 -0700)
* git://git.infradead.org/~dwmw2/iommu-2.6.31:
  intel-iommu: Fix one last ia64 build problem in Pass Through Support
  VT-d: support the device IOTLB
  VT-d: cleanup iommu_flush_iotlb_psi and flush_unmaps
  VT-d: add device IOTLB invalidation support
  VT-d: parse ATSR in DMA Remapping Reporting Structure
  PCI: handle Virtual Function ATS enabling
  PCI: support the ATS capability
  intel-iommu: dmar_set_interrupt return error value
  intel-iommu: Tidy up iommu->gcmd handling
  intel-iommu: Fix tiny theoretical race in write-buffer flush.
  intel-iommu: Clean up handling of "caching mode" vs. IOTLB flushing.
  intel-iommu: Clean up handling of "caching mode" vs. context flushing.
  VT-d: fix invalid domain id for KVM context flush
  Fix !CONFIG_DMAR build failure introduced by Intel IOMMU Pass Through Support
  Intel IOMMU Pass Through Support

Fix up trivial conflicts in drivers/pci/{intel-iommu.c,intr_remapping.c}

1  2 
Documentation/kernel-parameters.txt
arch/ia64/kernel/pci-dma.c
arch/x86/kernel/pci-dma.c
arch/x86/kernel/pci-swiotlb.c
drivers/pci/intel-iommu.c
drivers/pci/intr_remapping.c
drivers/pci/iov.c
include/linux/dmar.h
include/linux/pci.h
include/linux/pci_regs.h

@@@ -17,12 -17,6 +17,12 @@@ are specified on the kernel command lin
  
        usbcore.blinkenlights=1
  
 +Hyphens (dashes) and underscores are equivalent in parameter names, so
 +      log_buf_len=1M print-fatal-signals=1
 +can also be entered as
 +      log-buf-len=1M print_fatal_signals=1
 +
 +
  This document may not be entirely up to date and comprehensive. The command
  "modinfo -p ${modulename}" shows a current list of all parameters of a loadable
  module. Loadable modules, after being loaded into the running kernel, also
@@@ -48,7 -42,6 +48,7 @@@ parameter is applicable
        EFI     EFI Partitioning (GPT) is enabled
        EIDE    EIDE/ATAPI support is enabled.
        FB      The frame buffer device is enabled.
 +      GCOV    GCOV profiling is enabled.
        HW      Appropriate hardware is enabled.
        IA-64   IA-64 architecture is enabled.
        IMA     Integrity measurement architecture is enabled.
@@@ -57,6 -50,7 +57,6 @@@
        ISAPNP  ISA PnP code is enabled.
        ISDN    Appropriate ISDN support is enabled.
        JOY     Appropriate joystick support is enabled.
 -      KMEMTRACE kmemtrace is enabled.
        LIBATA  Libata driver is enabled
        LP      Printer support is enabled.
        LOOP    Loopback device support is enabled.
@@@ -329,6 -323,11 +329,6 @@@ and is between 256 and 4096 characters
                                    flushed before they will be reused, which
                                    is a lot of faster
  
 -      amd_iommu_size= [HW,X86-64]
 -                      Define the size of the aperture for the AMD IOMMU
 -                      driver. Possible values are:
 -                      '32M', '64M' (default), '128M', '256M', '512M', '1G'
 -
        amijoy.map=     [HW,JOY] Amiga joystick support
                        Map of devices attached to JOY0DAT and JOY1DAT
                        Format: <a>,<b>
                        not play well with APC CPU idle - disable it if you have
                        APC and your system crashes randomly.
  
 -      apic=           [APIC,i386] Advanced Programmable Interrupt Controller
 +      apic=           [APIC,X86-32] Advanced Programmable Interrupt Controller
                        Change the output verbosity whilst booting
                        Format: { quiet (default) | verbose | debug }
                        Change the amount of debugging information output
                        Also note the kernel might malfunction if you disable
                        some critical bits.
  
 +      cmo_free_hint=  [PPC] Format: { yes | no }
 +                      Specify whether pages are marked as being inactive
 +                      when they are freed.  This is used in CMO environments
 +                      to determine OS memory pressure for page stealing by
 +                      a hypervisor.
 +                      Default: yes
 +
        code_bytes      [X86] How many bytes of object code to print
                        in an oops report.
                        Range: 0 - 8192
                        console=brl,ttyS0
                For now, only VisioBraille is supported.
  
 +      consoleblank=   [KNL] The console blank (screen saver) timeout in
 +                      seconds. Defaults to 10*60 = 10mins. A value of 0
 +                      disables the blank timer.
 +
        coredump_filter=
                        [KNL] Change the default value for
                        /proc/<pid>/coredump_filter.
                        DMA-API debugging code disables itself because the
                        architectural default is too low.
  
 +      dma_debug_driver=<driver_name>
 +                      With this option the DMA-API debugging driver
 +                      filter feature can be enabled at boot time. Just
 +                      pass the driver to filter for as the parameter.
 +                      The filter can be disabled or changed to another
 +                      driver later using sysfs.
 +
        dscc4.setup=    [NET]
  
        dtc3181e=       [HW,SCSI]
                        to discrete, to make X server driver able to add WB
                        entry later. This parameter enables that.
  
 -      enable_timer_pin_1 [i386,x86-64]
 +      enable_timer_pin_1 [X86]
                        Enable PIN 1 of APIC timer
                        Can be useful to work around chipset bugs
                        (in particular on some ATI chipsets).
                        ia64_pal_cache_flush instead of SAL_CACHE_FLUSH.
  
        ftrace=[tracer]
 -                      [ftrace] will set and start the specified tracer
 +                      [FTRACE] will set and start the specified tracer
                        as early as possible in order to facilitate early
                        boot debugging.
  
        ftrace_dump_on_oops
 -                      [ftrace] will dump the trace buffers on oops.
 +                      [FTRACE] will dump the trace buffers on oops.
 +
 +      ftrace_filter=[function-list]
 +                      [FTRACE] Limit the functions traced by the function
 +                      tracer at boot up. function-list is a comma separated
 +                      list of functions. This list can be changed at run
 +                      time by the set_ftrace_filter file in the debugfs
 +                      tracing directory. 
 +
 +      ftrace_notrace=[function-list]
 +                      [FTRACE] Do not trace the functions specified in
 +                      function-list. This list can be changed at run time
 +                      by the set_ftrace_notrace file in the debugfs
 +                      tracing directory.
  
        gamecon.map[2|3]=
                        [HW,JOY] Multisystem joystick and NES/SNES/PSX pad
                        Format: off | on
                        default: on
  
 +      gcov_persist=   [GCOV] When non-zero (default), profiling data for
 +                      kernel modules is saved and remains accessible via
 +                      debugfs, even when the module is unloaded/reloaded.
 +                      When zero, profiling data is discarded and associated
 +                      debugfs files are removed at module unload time.
 +
        gdth=           [HW,SCSI]
                        See header of drivers/scsi/gdth.c.
  
  
        hashdist=       [KNL,NUMA] Large hashes allocated during boot
                        are distributed across NUMA nodes.  Defaults on
 -                      for IA-64, off otherwise.
 +                      for 64bit NUMA, off otherwise.
                        Format: 0 | 1 (for off | on)
  
        hcl=            [IA-64] SGI's Hardware Graph compatibility layer
  
        ide-core.nodma= [HW] (E)IDE subsystem
                        Format: =0.0 to prevent dma on hda, =0.1 hdb =1.0 hdc
 -                      .vlb_clock .pci_clock .noflush .noprobe .nowerr .cdrom
 -                      .chs .ignore_cable are additional options
 -                      See Documentation/ide/ide.txt.
 -
 -      idebus=         [HW] (E)IDE subsystem - VLB/PCI bus speed
 +                      .vlb_clock .pci_clock .noflush .nohpa .noprobe .nowerr
 +                      .cdrom .chs .ignore_cable are additional options
                        See Documentation/ide/ide.txt.
  
        ide-pci-generic.all-generic-ide [HW] (E)IDE subsystem
                        Formt: { "sha1" | "md5" }
                        default: "sha1"
  
 +      ima_tcb         [IMA]
 +                      Load a policy which meets the needs of the Trusted
 +                      Computing Base.  This means IMA will measure all
 +                      programs exec'd, files mmap'd for exec, and all files
 +                      opened for read by uid=0.
 +
        in2000=         [HW,SCSI]
                        See header of drivers/scsi/in2000.c.
  
                nomerge
                forcesac
                soft
+               pt      [x86, IA64]
  
        io7=            [HW] IO7 for Marvel based alpha systems
                        See comment before marvel_specify_io7 in
                        use the HighMem zone if it exists, and the Normal
                        zone if it does not.
  
 -      kmemtrace.enable=       [KNL,KMEMTRACE] Format: { yes | no }
 -                              Controls whether kmemtrace is enabled
 -                              at boot-time.
 -
 -      kmemtrace.subbufs=n     [KNL,KMEMTRACE] Overrides the number of
 -                      subbufs kmemtrace's relay channel has. Set this
 -                      higher than default (KMEMTRACE_N_SUBBUFS in code) if
 -                      you experience buffer overruns.
 -
        kgdboc=         [HW] kgdb over consoles.
                        Requires a tty driver that supports console polling.
 -                      (only serial suported for now)
 +                      (only serial supported for now)
                        Format: <serial_device>[,baud]
  
        kmac=           [MIPS] korina ethernet MAC address.
                        Configure the RouterBoard 532 series on-chip
                        Ethernet adapter MAC address.
  
 +      kmemleak=       [KNL] Boot-time kmemleak enable/disable
 +                      Valid arguments: on, off
 +                      Default: on
 +
        kstack=N        [X86] Print N words from the kernel stack
                        in oops dumps.
  
        min_addr=nn[KMG]        [KNL,BOOT,ia64] All physical memory below this
                        physical address is ignored.
  
 +      mini2440=       [ARM,HW,KNL]
 +                      Format:[0..2][b][c][t]
 +                      Default: "0tb"
 +                      MINI2440 configuration specification:
 +                      0 - The attached screen is the 3.5" TFT
 +                      1 - The attached screen is the 7" TFT
 +                      2 - The VGA Shield is attached (1024x768)
 +                      Leaving out the screen size parameter will not load
 +                      the TFT driver, and the framebuffer will be left
 +                      unconfigured.
 +                      b - Enable backlight. The TFT backlight pin will be
 +                      linked to the kernel VESA blanking code and a GPIO
 +                      LED. This parameter is not necessary when using the
 +                      VGA shield.
 +                      c - Enable the s3c camera interface.
 +                      t - Reserved for enabling touchscreen support. The
 +                      touchscreen support is not enabled in the mainstream
 +                      kernel as of 2.6.30, a preliminary port can be found
 +                      in the "bleeding edge" mini2440 support kernel at
 +                      http://repo.or.cz/w/linux-2.6/mini2440.git
 +
        mminit_loglevel=
                        [KNL] When CONFIG_DEBUG_MEMORY_INIT is set, this
                        parameter allows control of the logging verbosity for
        mtdparts=       [MTD]
                        See drivers/mtd/cmdlinepart.c.
  
 +      onenand.bdry=   [HW,MTD] Flex-OneNAND Boundary Configuration
 +
 +                      Format: [die0_boundary][,die0_lock][,die1_boundary][,die1_lock]
 +
 +                      boundary - index of last SLC block on Flex-OneNAND.
 +                                 The remaining blocks are configured as MLC blocks.
 +                      lock     - Configure if Flex-OneNAND boundary should be locked.
 +                                 Once locked, the boundary cannot be changed.
 +                                 1 indicates lock status, 0 indicates unlock status.
 +
        mtdset=         [ARM]
                        ARM/S3C2412 JIVE boot control
  
                        ('y', default) or cooked coordinates ('n')
  
        mtrr_chunk_size=nn[KMG] [X86]
 -                      used for mtrr cleanup. It is largest continous chunk
 +                      used for mtrr cleanup. It is largest continuous chunk
                        that could hold holes aka. UC entries.
  
        mtrr_gran_size=nn[KMG] [X86]
                        register save and restore. The kernel will only save
                        legacy floating-point registers on task switch.
  
 +      noxsave         [BUGS=X86] Disables x86 extended register state save
 +                      and restore using xsave. The kernel will fallback to
 +                      enabling legacy floating-point and sse state.
 +
        nohlt           [BUGS=ARM,SH] Tells the kernel that the sleep(SH) or
                        wfi(ARM) instruction doesn't work correctly and not to
                        use it. This is also useful when using JTAG debugger.
        noinitrd        [RAM] Tells the kernel not to load any configured
                        initial RAM disk.
  
 +      nointremap      [X86-64, Intel-IOMMU] Do not enable interrupt
 +                      remapping.
 +
        nointroute      [IA-64]
  
        nojitter        [IA64] Disables jitter checking for ITC timers.
  
        nowb            [ARM]
  
 +      nox2apic        [X86-64,APIC] Do not enable x2APIC mode.
 +
        nptcg=          [IA64] Override max number of concurrent global TLB
                        purges which is reported from either PAL_VM_SUMMARY or
                        SAL PALO.
        oprofile.timer= [HW]
                        Use timer interrupt instead of performance counters
  
 +      oprofile.cpu_type=      Force an oprofile cpu type
 +                      This might be useful if you have an older oprofile
 +                      userland or if you want common events.
 +                      Format: { archperfmon }
 +                      archperfmon: [X86] Force use of architectural
 +                              perfmon on Intel CPUs instead of the
 +                              CPU specific event set.
 +
        osst=           [HW,SCSI] SCSI Tape Driver
                        Format: <buffer_size>,<write_threshold>
                        See also Documentation/scsi/st.txt.
                                root domains (aka PCI segments, in ACPI-speak).
                nommconf        [X86] Disable use of MMCONFIG for PCI
                                Configuration
 +              check_enable_amd_mmconf [X86] check for and enable
 +                              properly configured MMIO access to PCI
 +                              config space on AMD family 10h CPU
                nomsi           [MSI] If the PCI_MSI kernel config parameter is
                                enabled, this kernel boot option can be used to
                                disable the use of MSI interrupts system-wide.
                                IRQ routing is enabled.
                noacpi          [X86] Do not use ACPI for IRQ routing
                                or for PCI scanning.
 -              use_crs         [X86] Use _CRS for PCI resource
 +              nocrs           [X86] Don't use _CRS for PCI resource
                                allocation.
                routeirq        Do IRQ routing for all PCI devices.
                                This is normally done in pci_enable_device(),
                                PAGE_SIZE is used as alignment.
                                PCI-PCI bridge can be specified, if resource
                                windows need to be expanded.
 +              ecrc=           Enable/disable PCIe ECRC (transaction layer
 +                              end-to-end CRC checking).
 +                              bios: Use BIOS/firmware settings. This is the
 +                              the default.
 +                              off: Turn ECRC off
 +                              on: Turn ECRC on.
  
        pcie_aspm=      [PCIE] Forcibly enable or disable PCIe Active State Power
                        Management.
@@@ -32,6 -32,8 +32,8 @@@ int force_iommu __read_mostly = 1
  int force_iommu __read_mostly;
  #endif
  
+ int iommu_pass_through;
  /* Dummy device used for NULL arguments (normally ISA). Better would
     be probably a smaller DMA mask, but this is bug-to-bug compatible
     to i386. */
@@@ -91,7 -93,7 +93,7 @@@ int iommu_dma_supported(struct device *
           type. Normally this doesn't make any difference, but gives
           more gentle handling of IOMMU overflow. */
        if (iommu_sac_force && (mask >= DMA_BIT_MASK(40))) {
 -              dev_info(dev, "Force SAC with mask %lx\n", mask);
 +              dev_info(dev, "Force SAC with mask %llx\n", mask);
                return 0;
        }
  
@@@ -32,6 -32,8 +32,8 @@@ int no_iommu __read_mostly
  /* Set this to 1 if there is a HW IOMMU in the system */
  int iommu_detected __read_mostly = 0;
  
+ int iommu_pass_through;
  dma_addr_t bad_dma_address __read_mostly = 0;
  EXPORT_SYMBOL(bad_dma_address);
  
@@@ -209,6 -211,10 +211,10 @@@ static __init int iommu_setup(char *p
  #ifdef CONFIG_SWIOTLB
                if (!strncmp(p, "soft", 4))
                        swiotlb = 1;
+               if (!strncmp(p, "pt", 2)) {
+                       iommu_pass_through = 1;
+                       return 1;
+               }
  #endif
  
                gart_parse_options(p);
@@@ -290,8 -296,6 +296,8 @@@ static int __init pci_iommu_init(void
  void pci_iommu_shutdown(void)
  {
        gart_iommu_shutdown();
 +
 +      amd_iommu_shutdown();
  }
  /* Must execute after PCI subsystem */
  fs_initcall(pci_iommu_init);
@@@ -28,7 -28,7 +28,7 @@@ dma_addr_t swiotlb_phys_to_bus(struct d
        return paddr;
  }
  
 -phys_addr_t swiotlb_bus_to_phys(dma_addr_t baddr)
 +phys_addr_t swiotlb_bus_to_phys(struct device *hwdev, dma_addr_t baddr)
  {
        return baddr;
  }
@@@ -71,7 -71,8 +71,8 @@@ void __init pci_swiotlb_init(void
  {
        /* don't initialize swiotlb if iommu=off (no_iommu=1) */
  #ifdef CONFIG_X86_64
-       if (!iommu_detected && !no_iommu && max_pfn > MAX_DMA32_PFN)
+       if ((!iommu_detected && !no_iommu && max_pfn > MAX_DMA32_PFN) ||
+               iommu_pass_through)
               swiotlb = 1;
  #endif
        if (swiotlb_force)
  
  #define DEFAULT_DOMAIN_ADDRESS_WIDTH 48
  
+ #define MAX_AGAW_WIDTH 64
  #define DOMAIN_MAX_ADDR(gaw) ((((u64)1) << gaw) - 1)
  
  #define IOVA_PFN(addr)                ((addr) >> PAGE_SHIFT)
  #define DMA_32BIT_PFN         IOVA_PFN(DMA_BIT_MASK(32))
  #define DMA_64BIT_PFN         IOVA_PFN(DMA_BIT_MASK(64))
  
 +#ifndef PHYSICAL_PAGE_MASK
 +#define PHYSICAL_PAGE_MASK PAGE_MASK
 +#endif
 +
  /* global iommu list, set NULL for ignored DMAR units */
  static struct intel_iommu **g_iommus;
  
@@@ -131,8 -129,6 +133,6 @@@ static inline void context_set_fault_en
        context->lo &= (((u64)-1) << 2) | 1;
  }
  
- #define CONTEXT_TT_MULTI_LEVEL 0
  static inline void context_set_translation_type(struct context_entry *context,
                                                unsigned long value)
  {
@@@ -256,6 -252,7 +256,7 @@@ struct device_domain_info 
        u8 bus;                 /* PCI bus number */
        u8 devfn;               /* PCI devfn number */
        struct pci_dev *dev; /* it's NULL for PCIE-to-PCI bridge */
+       struct intel_iommu *iommu; /* IOMMU used by this device */
        struct dmar_domain *domain; /* pointer to domain */
  };
  
@@@ -401,17 -398,13 +402,13 @@@ void free_iova_mem(struct iova *iova
  
  static inline int width_to_agaw(int width);
  
- /* calculate agaw for each iommu.
-  * "SAGAW" may be different across iommus, use a default agaw, and
-  * get a supported less agaw for iommus that don't support the default agaw.
-  */
- int iommu_calculate_agaw(struct intel_iommu *iommu)
+ static int __iommu_calculate_agaw(struct intel_iommu *iommu, int max_gaw)
  {
        unsigned long sagaw;
        int agaw = -1;
  
        sagaw = cap_sagaw(iommu->cap);
-       for (agaw = width_to_agaw(DEFAULT_DOMAIN_ADDRESS_WIDTH);
+       for (agaw = width_to_agaw(max_gaw);
             agaw >= 0; agaw--) {
                if (test_bit(agaw, &sagaw))
                        break;
        return agaw;
  }
  
+ /*
+  * Calculate max SAGAW for each iommu.
+  */
+ int iommu_calculate_max_sagaw(struct intel_iommu *iommu)
+ {
+       return __iommu_calculate_agaw(iommu, MAX_AGAW_WIDTH);
+ }
+ /*
+  * calculate agaw for each iommu.
+  * "SAGAW" may be different across iommus, use a default agaw, and
+  * get a supported less agaw for iommus that don't support the default agaw.
+  */
+ int iommu_calculate_agaw(struct intel_iommu *iommu)
+ {
+       return __iommu_calculate_agaw(iommu, DEFAULT_DOMAIN_ADDRESS_WIDTH);
+ }
  /* in native case, each domain is related to only one iommu */
  static struct intel_iommu *domain_get_iommu(struct dmar_domain *domain)
  {
@@@ -809,7 -820,7 +824,7 @@@ static int iommu_alloc_root_entry(struc
  static void iommu_set_root_entry(struct intel_iommu *iommu)
  {
        void *addr;
-       u32 cmd, sts;
+       u32 sts;
        unsigned long flag;
  
        addr = iommu->root_entry;
        spin_lock_irqsave(&iommu->register_lock, flag);
        dmar_writeq(iommu->reg + DMAR_RTADDR_REG, virt_to_phys(addr));
  
-       cmd = iommu->gcmd | DMA_GCMD_SRTP;
-       writel(cmd, iommu->reg + DMAR_GCMD_REG);
+       writel(iommu->gcmd | DMA_GCMD_SRTP, iommu->reg + DMAR_GCMD_REG);
  
        /* Make sure hardware complete it */
        IOMMU_WAIT_OP(iommu, DMAR_GSTS_REG,
-               readl, (sts & DMA_GSTS_RTPS), sts);
+                     readl, (sts & DMA_GSTS_RTPS), sts);
  
        spin_unlock_irqrestore(&iommu->register_lock, flag);
  }
@@@ -834,39 -844,25 +848,25 @@@ static void iommu_flush_write_buffer(st
  
        if (!rwbf_quirk && !cap_rwbf(iommu->cap))
                return;
-       val = iommu->gcmd | DMA_GCMD_WBF;
  
        spin_lock_irqsave(&iommu->register_lock, flag);
-       writel(val, iommu->reg + DMAR_GCMD_REG);
+       writel(iommu->gcmd | DMA_GCMD_WBF, iommu->reg + DMAR_GCMD_REG);
  
        /* Make sure hardware complete it */
        IOMMU_WAIT_OP(iommu, DMAR_GSTS_REG,
-                       readl, (!(val & DMA_GSTS_WBFS)), val);
+                     readl, (!(val & DMA_GSTS_WBFS)), val);
  
        spin_unlock_irqrestore(&iommu->register_lock, flag);
  }
  
  /* return value determine if we need a write buffer flush */
- static int __iommu_flush_context(struct intel_iommu *iommu,
-       u16 did, u16 source_id, u8 function_mask, u64 type,
-       int non_present_entry_flush)
+ static void __iommu_flush_context(struct intel_iommu *iommu,
+                                 u16 did, u16 source_id, u8 function_mask,
+                                 u64 type)
  {
        u64 val = 0;
        unsigned long flag;
  
-       /*
-        * In the non-present entry flush case, if hardware doesn't cache
-        * non-present entry we do nothing and if hardware cache non-present
-        * entry, we flush entries of domain 0 (the domain id is used to cache
-        * any non-present entries)
-        */
-       if (non_present_entry_flush) {
-               if (!cap_caching_mode(iommu->cap))
-                       return 1;
-               else
-                       did = 0;
-       }
        switch (type) {
        case DMA_CCMD_GLOBAL_INVL:
                val = DMA_CCMD_GLOBAL_INVL;
                dmar_readq, (!(val & DMA_CCMD_ICC)), val);
  
        spin_unlock_irqrestore(&iommu->register_lock, flag);
-       /* flush context entry will implicitly flush write buffer */
-       return 0;
  }
  
  /* return value determine if we need a write buffer flush */
- static int __iommu_flush_iotlb(struct intel_iommu *iommu, u16 did,
-       u64 addr, unsigned int size_order, u64 type,
-       int non_present_entry_flush)
+ static void __iommu_flush_iotlb(struct intel_iommu *iommu, u16 did,
+                               u64 addr, unsigned int size_order, u64 type)
  {
        int tlb_offset = ecap_iotlb_offset(iommu->ecap);
        u64 val = 0, val_iva = 0;
        unsigned long flag;
  
-       /*
-        * In the non-present entry flush case, if hardware doesn't cache
-        * non-present entry we do nothing and if hardware cache non-present
-        * entry, we flush entries of domain 0 (the domain id is used to cache
-        * any non-present entries)
-        */
-       if (non_present_entry_flush) {
-               if (!cap_caching_mode(iommu->cap))
-                       return 1;
-               else
-                       did = 0;
-       }
        switch (type) {
        case DMA_TLB_GLOBAL_FLUSH:
                /* global flush doesn't need set IVA_REG */
                pr_debug("IOMMU: tlb flush request %Lx, actual %Lx\n",
                        (unsigned long long)DMA_TLB_IIRG(type),
                        (unsigned long long)DMA_TLB_IAIG(val));
-       /* flush iotlb entry will implicitly flush write buffer */
-       return 0;
  }
  
- static int iommu_flush_iotlb_psi(struct intel_iommu *iommu, u16 did,
-       u64 addr, unsigned int pages, int non_present_entry_flush)
+ static struct device_domain_info *iommu_support_dev_iotlb(
+       struct dmar_domain *domain, int segment, u8 bus, u8 devfn)
+ {
+       int found = 0;
+       unsigned long flags;
+       struct device_domain_info *info;
+       struct intel_iommu *iommu = device_to_iommu(segment, bus, devfn);
+       if (!ecap_dev_iotlb_support(iommu->ecap))
+               return NULL;
+       if (!iommu->qi)
+               return NULL;
+       spin_lock_irqsave(&device_domain_lock, flags);
+       list_for_each_entry(info, &domain->devices, link)
+               if (info->bus == bus && info->devfn == devfn) {
+                       found = 1;
+                       break;
+               }
+       spin_unlock_irqrestore(&device_domain_lock, flags);
+       if (!found || !info->dev)
+               return NULL;
+       if (!pci_find_ext_capability(info->dev, PCI_EXT_CAP_ID_ATS))
+               return NULL;
+       if (!dmar_find_matched_atsr_unit(info->dev))
+               return NULL;
+       info->iommu = iommu;
+       return info;
+ }
+ static void iommu_enable_dev_iotlb(struct device_domain_info *info)
  {
-       unsigned int mask;
+       if (!info)
+               return;
+       pci_enable_ats(info->dev, VTD_PAGE_SHIFT);
+ }
+ static void iommu_disable_dev_iotlb(struct device_domain_info *info)
+ {
+       if (!info->dev || !pci_ats_enabled(info->dev))
+               return;
+       pci_disable_ats(info->dev);
+ }
+ static void iommu_flush_dev_iotlb(struct dmar_domain *domain,
+                                 u64 addr, unsigned mask)
+ {
+       u16 sid, qdep;
+       unsigned long flags;
+       struct device_domain_info *info;
+       spin_lock_irqsave(&device_domain_lock, flags);
+       list_for_each_entry(info, &domain->devices, link) {
+               if (!info->dev || !pci_ats_enabled(info->dev))
+                       continue;
+               sid = info->bus << 8 | info->devfn;
+               qdep = pci_ats_queue_depth(info->dev);
+               qi_flush_dev_iotlb(info->iommu, sid, qdep, addr, mask);
+       }
+       spin_unlock_irqrestore(&device_domain_lock, flags);
+ }
+ static void iommu_flush_iotlb_psi(struct intel_iommu *iommu, u16 did,
+                                 u64 addr, unsigned int pages)
+ {
+       unsigned int mask = ilog2(__roundup_pow_of_two(pages));
  
        BUG_ON(addr & (~VTD_PAGE_MASK));
        BUG_ON(pages == 0);
  
-       /* Fallback to domain selective flush if no PSI support */
-       if (!cap_pgsel_inv(iommu->cap))
-               return iommu->flush.flush_iotlb(iommu, did, 0, 0,
-                                               DMA_TLB_DSI_FLUSH,
-                                               non_present_entry_flush);
        /*
+        * Fallback to domain selective flush if no PSI support or the size is
+        * too big.
         * PSI requires page size to be 2 ^ x, and the base address is naturally
         * aligned to the size
         */
-       mask = ilog2(__roundup_pow_of_two(pages));
-       /* Fallback to domain selective flush if size is too big */
-       if (mask > cap_max_amask_val(iommu->cap))
-               return iommu->flush.flush_iotlb(iommu, did, 0, 0,
-                       DMA_TLB_DSI_FLUSH, non_present_entry_flush);
-       return iommu->flush.flush_iotlb(iommu, did, addr, mask,
-                                       DMA_TLB_PSI_FLUSH,
-                                       non_present_entry_flush);
+       if (!cap_pgsel_inv(iommu->cap) || mask > cap_max_amask_val(iommu->cap))
+               iommu->flush.flush_iotlb(iommu, did, 0, 0,
+                                               DMA_TLB_DSI_FLUSH);
+       else
+               iommu->flush.flush_iotlb(iommu, did, addr, mask,
+                                               DMA_TLB_PSI_FLUSH);
+       if (did)
+               iommu_flush_dev_iotlb(iommu->domains[did], addr, mask);
  }
  
  static void iommu_disable_protect_mem_regions(struct intel_iommu *iommu)
@@@ -1021,13 -1064,13 +1068,13 @@@ static int iommu_enable_translation(str
        unsigned long flags;
  
        spin_lock_irqsave(&iommu->register_lock, flags);
-       writel(iommu->gcmd|DMA_GCMD_TE, iommu->reg + DMAR_GCMD_REG);
+       iommu->gcmd |= DMA_GCMD_TE;
+       writel(iommu->gcmd, iommu->reg + DMAR_GCMD_REG);
  
        /* Make sure hardware complete it */
        IOMMU_WAIT_OP(iommu, DMAR_GSTS_REG,
-               readl, (sts & DMA_GSTS_TES), sts);
+                     readl, (sts & DMA_GSTS_TES), sts);
  
-       iommu->gcmd |= DMA_GCMD_TE;
        spin_unlock_irqrestore(&iommu->register_lock, flags);
        return 0;
  }
@@@ -1043,7 -1086,7 +1090,7 @@@ static int iommu_disable_translation(st
  
        /* Make sure hardware complete it */
        IOMMU_WAIT_OP(iommu, DMAR_GSTS_REG,
-               readl, (!(sts & DMA_GSTS_TES)), sts);
+                     readl, (!(sts & DMA_GSTS_TES)), sts);
  
        spin_unlock_irqrestore(&iommu->register_lock, flag);
        return 0;
@@@ -1220,7 -1263,7 +1267,7 @@@ static void dmar_init_reserved_ranges(v
                        if (!r->flags || !(r->flags & IORESOURCE_MEM))
                                continue;
                        addr = r->start;
 -                      addr &= PAGE_MASK;
 +                      addr &= PHYSICAL_PAGE_MASK;
                        size = r->end - addr;
                        size = PAGE_ALIGN(size);
                        iova = reserve_iova(&reserved_iova_list, IOVA_PFN(addr),
@@@ -1325,8 -1368,8 +1372,8 @@@ static void domain_exit(struct dmar_dom
        free_domain_mem(domain);
  }
  
- static int domain_context_mapping_one(struct dmar_domain *domain,
-                                     int segment, u8 bus, u8 devfn)
+ static int domain_context_mapping_one(struct dmar_domain *domain, int segment,
+                                u8 bus, u8 devfn, int translation)
  {
        struct context_entry *context;
        unsigned long flags;
        unsigned long ndomains;
        int id;
        int agaw;
+       struct device_domain_info *info = NULL;
  
        pr_debug("Set context mapping for %02x:%02x.%d\n",
                bus, PCI_SLOT(devfn), PCI_FUNC(devfn));
        BUG_ON(!domain->pgd);
+       BUG_ON(translation != CONTEXT_TT_PASS_THROUGH &&
+              translation != CONTEXT_TT_MULTI_LEVEL);
  
        iommu = device_to_iommu(segment, bus, devfn);
        if (!iommu)
        }
  
        context_set_domain_id(context, id);
-       context_set_address_width(context, iommu->agaw);
-       context_set_address_root(context, virt_to_phys(pgd));
-       context_set_translation_type(context, CONTEXT_TT_MULTI_LEVEL);
+       if (translation != CONTEXT_TT_PASS_THROUGH) {
+               info = iommu_support_dev_iotlb(domain, segment, bus, devfn);
+               translation = info ? CONTEXT_TT_DEV_IOTLB :
+                                    CONTEXT_TT_MULTI_LEVEL;
+       }
+       /*
+        * In pass through mode, AW must be programmed to indicate the largest
+        * AGAW value supported by hardware. And ASR is ignored by hardware.
+        */
+       if (unlikely(translation == CONTEXT_TT_PASS_THROUGH))
+               context_set_address_width(context, iommu->msagaw);
+       else {
+               context_set_address_root(context, virt_to_phys(pgd));
+               context_set_address_width(context, iommu->agaw);
+       }
+       context_set_translation_type(context, translation);
        context_set_fault_enable(context);
        context_set_present(context);
        domain_flush_cache(domain, context, sizeof(*context));
  
-       /* it's a non-present to present mapping */
-       if (iommu->flush.flush_context(iommu, domain->id,
-               (((u16)bus) << 8) | devfn, DMA_CCMD_MASK_NOBIT,
-               DMA_CCMD_DEVICE_INVL, 1))
+       /*
+        * It's a non-present to present mapping. If hardware doesn't cache
+        * non-present entry we only need to flush the write-buffer. If the
+        * _does_ cache non-present entries, then it does so in the special
+        * domain #0, which we have to flush:
+        */
+       if (cap_caching_mode(iommu->cap)) {
+               iommu->flush.flush_context(iommu, 0,
+                                          (((u16)bus) << 8) | devfn,
+                                          DMA_CCMD_MASK_NOBIT,
+                                          DMA_CCMD_DEVICE_INVL);
+               iommu->flush.flush_iotlb(iommu, 0, 0, 0, DMA_TLB_DSI_FLUSH);
+       } else {
                iommu_flush_write_buffer(iommu);
-       else
-               iommu->flush.flush_iotlb(iommu, 0, 0, 0, DMA_TLB_DSI_FLUSH, 0);
+       }
+       iommu_enable_dev_iotlb(info);
        spin_unlock_irqrestore(&iommu->lock, flags);
  
        spin_lock_irqsave(&domain->iommu_lock, flags);
  }
  
  static int
- domain_context_mapping(struct dmar_domain *domain, struct pci_dev *pdev)
+ domain_context_mapping(struct dmar_domain *domain, struct pci_dev *pdev,
+                       int translation)
  {
        int ret;
        struct pci_dev *tmp, *parent;
  
        ret = domain_context_mapping_one(domain, pci_domain_nr(pdev->bus),
-                                        pdev->bus->number, pdev->devfn);
+                                        pdev->bus->number, pdev->devfn,
+                                        translation);
        if (ret)
                return ret;
  
                ret = domain_context_mapping_one(domain,
                                                 pci_domain_nr(parent->bus),
                                                 parent->bus->number,
-                                                parent->devfn);
+                                                parent->devfn, translation);
                if (ret)
                        return ret;
                parent = parent->bus->self;
        if (tmp->is_pcie) /* this is a PCIE-to-PCI bridge */
                return domain_context_mapping_one(domain,
                                        pci_domain_nr(tmp->subordinate),
-                                       tmp->subordinate->number, 0);
+                                       tmp->subordinate->number, 0,
+                                       translation);
        else /* this is a legacy PCI bridge */
                return domain_context_mapping_one(domain,
                                                  pci_domain_nr(tmp->bus),
                                                  tmp->bus->number,
-                                                 tmp->devfn);
+                                                 tmp->devfn,
+                                                 translation);
  }
  
  static int domain_context_mapped(struct pci_dev *pdev)
@@@ -1540,9 -1614,8 +1618,8 @@@ static void iommu_detach_dev(struct int
  
        clear_context_table(iommu, bus, devfn);
        iommu->flush.flush_context(iommu, 0, 0, 0,
-                                          DMA_CCMD_GLOBAL_INVL, 0);
-       iommu->flush.flush_iotlb(iommu, 0, 0, 0,
-                                        DMA_TLB_GLOBAL_FLUSH, 0);
+                                          DMA_CCMD_GLOBAL_INVL);
+       iommu->flush.flush_iotlb(iommu, 0, 0, 0, DMA_TLB_GLOBAL_FLUSH);
  }
  
  static void domain_remove_dev_info(struct dmar_domain *domain)
                        info->dev->dev.archdata.iommu = NULL;
                spin_unlock_irqrestore(&device_domain_lock, flags);
  
+               iommu_disable_dev_iotlb(info);
                iommu = device_to_iommu(info->segment, info->bus, info->devfn);
                iommu_detach_dev(iommu, info->bus, info->devfn);
                free_devinfo_mem(info);
@@@ -1756,7 -1830,7 +1834,7 @@@ static int iommu_prepare_identity_map(s
                goto error;
  
        /* context entry init */
-       ret = domain_context_mapping(domain, pdev);
+       ret = domain_context_mapping(domain, pdev, CONTEXT_TT_MULTI_LEVEL);
        if (!ret)
                return 0;
  error:
@@@ -1857,6 -1931,23 +1935,23 @@@ static inline void iommu_prepare_isa(vo
  }
  #endif /* !CONFIG_DMAR_FLPY_WA */
  
+ /* Initialize each context entry as pass through.*/
+ static int __init init_context_pass_through(void)
+ {
+       struct pci_dev *pdev = NULL;
+       struct dmar_domain *domain;
+       int ret;
+       for_each_pci_dev(pdev) {
+               domain = get_domain_for_dev(pdev, DEFAULT_DOMAIN_ADDRESS_WIDTH);
+               ret = domain_context_mapping(domain, pdev,
+                                            CONTEXT_TT_PASS_THROUGH);
+               if (ret)
+                       return ret;
+       }
+       return 0;
+ }
  static int __init init_dmars(void)
  {
        struct dmar_drhd_unit *drhd;
        struct pci_dev *pdev;
        struct intel_iommu *iommu;
        int i, ret;
+       int pass_through = 1;
  
        /*
         * for each drhd
                        printk(KERN_ERR "IOMMU: allocate root entry failed\n");
                        goto error;
                }
+               if (!ecap_pass_through(iommu->ecap))
+                       pass_through = 0;
        }
+       if (iommu_pass_through)
+               if (!pass_through) {
+                       printk(KERN_INFO
+                              "Pass Through is not supported by hardware.\n");
+                       iommu_pass_through = 0;
+               }
  
        /*
         * Start from the sane iommu hardware state.
                }
        }
  
 -#ifdef CONFIG_INTR_REMAP
 -      if (!intr_remapping_enabled) {
 -              ret = enable_intr_remapping(0);
 -              if (ret)
 -                      printk(KERN_ERR
 -                             "IOMMU: enable interrupt remapping failed\n");
 -      }
 -#endif
        /*
-        * For each rmrr
-        *   for each dev attached to rmrr
-        *   do
-        *     locate drhd for dev, alloc domain for dev
-        *     allocate free domain
-        *     allocate page table entries for rmrr
-        *     if context not allocated for bus
-        *           allocate and init context
-        *           set present in root table for this bus
-        *     init context with domain, translation etc
-        *    endfor
-        * endfor
+        * If pass through is set and enabled, context entries of all pci
+        * devices are intialized by pass through translation type.
         */
-       for_each_rmrr_units(rmrr) {
-               for (i = 0; i < rmrr->devices_cnt; i++) {
-                       pdev = rmrr->devices[i];
-                       /* some BIOS lists non-exist devices in DMAR table */
-                       if (!pdev)
-                               continue;
-                       ret = iommu_prepare_rmrr_dev(rmrr, pdev);
-                       if (ret)
-                               printk(KERN_ERR
-                                "IOMMU: mapping reserved region failed\n");
+       if (iommu_pass_through) {
+               ret = init_context_pass_through();
+               if (ret) {
+                       printk(KERN_ERR "IOMMU: Pass through init failed.\n");
+                       iommu_pass_through = 0;
                }
        }
  
-       iommu_prepare_gfx_mapping();
+       /*
+        * If pass through is not set or not enabled, setup context entries for
+        * identity mappings for rmrr, gfx, and isa.
+        */
+       if (!iommu_pass_through) {
+               /*
+                * For each rmrr
+                *   for each dev attached to rmrr
+                *   do
+                *     locate drhd for dev, alloc domain for dev
+                *     allocate free domain
+                *     allocate page table entries for rmrr
+                *     if context not allocated for bus
+                *           allocate and init context
+                *           set present in root table for this bus
+                *     init context with domain, translation etc
+                *    endfor
+                * endfor
+                */
+               for_each_rmrr_units(rmrr) {
+                       for (i = 0; i < rmrr->devices_cnt; i++) {
+                               pdev = rmrr->devices[i];
+                               /*
+                                * some BIOS lists non-exist devices in DMAR
+                                * table.
+                                */
+                               if (!pdev)
+                                       continue;
+                               ret = iommu_prepare_rmrr_dev(rmrr, pdev);
+                               if (ret)
+                                       printk(KERN_ERR
+                                "IOMMU: mapping reserved region failed\n");
+                       }
+               }
+               iommu_prepare_gfx_mapping();
  
-       iommu_prepare_isa();
+               iommu_prepare_isa();
+       }
  
        /*
         * for each drhd
  
                iommu_set_root_entry(iommu);
  
-               iommu->flush.flush_context(iommu, 0, 0, 0, DMA_CCMD_GLOBAL_INVL,
-                                          0);
-               iommu->flush.flush_iotlb(iommu, 0, 0, 0, DMA_TLB_GLOBAL_FLUSH,
-                                        0);
+               iommu->flush.flush_context(iommu, 0, 0, 0, DMA_CCMD_GLOBAL_INVL);
+               iommu->flush.flush_iotlb(iommu, 0, 0, 0, DMA_TLB_GLOBAL_FLUSH);
                iommu_disable_protect_mem_regions(iommu);
  
                ret = iommu_enable_translation(iommu);
@@@ -2112,7 -2239,8 +2235,8 @@@ get_valid_domain_for_dev(struct pci_de
  
        /* make sure context mapping is ok */
        if (unlikely(!domain_context_mapped(pdev))) {
-               ret = domain_context_mapping(domain, pdev);
+               ret = domain_context_mapping(domain, pdev,
+                                            CONTEXT_TT_MULTI_LEVEL);
                if (ret) {
                        printk(KERN_ERR
                                "Domain context map for %s failed",
@@@ -2168,15 -2296,15 +2292,16 @@@ static dma_addr_t __intel_map_single(st
         * is not a big problem
         */
        ret = domain_page_mapping(domain, start_paddr,
 -              ((u64)paddr) & PAGE_MASK, size, prot);
 +                                ((u64)paddr) & PHYSICAL_PAGE_MASK,
 +                                size, prot);
        if (ret)
                goto error;
  
-       /* it's a non-present to present mapping */
-       ret = iommu_flush_iotlb_psi(iommu, domain->id,
-                       start_paddr, size >> VTD_PAGE_SHIFT, 1);
-       if (ret)
+       /* it's a non-present to present mapping. Only flush if caching mode */
+       if (cap_caching_mode(iommu->cap))
+               iommu_flush_iotlb_psi(iommu, 0, start_paddr,
+                                     size >> VTD_PAGE_SHIFT);
+       else
                iommu_flush_write_buffer(iommu);
  
        return start_paddr + ((u64)paddr & (~PAGE_MASK));
@@@ -2210,15 -2338,22 +2335,22 @@@ static void flush_unmaps(void
                if (!iommu)
                        continue;
  
-               if (deferred_flush[i].next) {
-                       iommu->flush.flush_iotlb(iommu, 0, 0, 0,
-                                                DMA_TLB_GLOBAL_FLUSH, 0);
-                       for (j = 0; j < deferred_flush[i].next; j++) {
-                               __free_iova(&deferred_flush[i].domain[j]->iovad,
-                                               deferred_flush[i].iova[j]);
-                       }
-                       deferred_flush[i].next = 0;
+               if (!deferred_flush[i].next)
+                       continue;
+               iommu->flush.flush_iotlb(iommu, 0, 0, 0,
+                                        DMA_TLB_GLOBAL_FLUSH);
+               for (j = 0; j < deferred_flush[i].next; j++) {
+                       unsigned long mask;
+                       struct iova *iova = deferred_flush[i].iova[j];
+                       mask = (iova->pfn_hi - iova->pfn_lo + 1) << PAGE_SHIFT;
+                       mask = ilog2(mask >> VTD_PAGE_SHIFT);
+                       iommu_flush_dev_iotlb(deferred_flush[i].domain[j],
+                                       iova->pfn_lo << PAGE_SHIFT, mask);
+                       __free_iova(&deferred_flush[i].domain[j]->iovad, iova);
                }
+               deferred_flush[i].next = 0;
        }
  
        list_size = 0;
@@@ -2291,9 -2426,8 +2423,8 @@@ static void intel_unmap_page(struct dev
        /* free page tables */
        dma_pte_free_pagetable(domain, start_addr, start_addr + size);
        if (intel_iommu_strict) {
-               if (iommu_flush_iotlb_psi(iommu,
-                       domain->id, start_addr, size >> VTD_PAGE_SHIFT, 0))
-                       iommu_flush_write_buffer(iommu);
+               iommu_flush_iotlb_psi(iommu, domain->id, start_addr,
+                                     size >> VTD_PAGE_SHIFT);
                /* free iova */
                __free_iova(&domain->iovad, iova);
        } else {
@@@ -2384,9 -2518,8 +2515,8 @@@ static void intel_unmap_sg(struct devic
        /* free page tables */
        dma_pte_free_pagetable(domain, start_addr, start_addr + size);
  
-       if (iommu_flush_iotlb_psi(iommu, domain->id, start_addr,
-                       size >> VTD_PAGE_SHIFT, 0))
-               iommu_flush_write_buffer(iommu);
+       iommu_flush_iotlb_psi(iommu, domain->id, start_addr,
+                             size >> VTD_PAGE_SHIFT);
  
        /* free iova */
        __free_iova(&domain->iovad, iova);
@@@ -2459,8 -2592,8 +2589,8 @@@ static int intel_map_sg(struct device *
                addr = page_to_phys(sg_page(sg)) + sg->offset;
                size = aligned_size((u64)addr, sg->length);
                ret = domain_page_mapping(domain, start_addr + offset,
 -                      ((u64)addr) & PAGE_MASK,
 -                      size, prot);
 +                                        ((u64)addr) & PHYSICAL_PAGE_MASK,
 +                                        size, prot);
                if (ret) {
                        /*  clear the page */
                        dma_pte_clear_range(domain, start_addr,
                offset += size;
        }
  
-       /* it's a non-present to present mapping */
-       if (iommu_flush_iotlb_psi(iommu, domain->id,
-                       start_addr, offset >> VTD_PAGE_SHIFT, 1))
+       /* it's a non-present to present mapping. Only flush if caching mode */
+       if (cap_caching_mode(iommu->cap))
+               iommu_flush_iotlb_psi(iommu, 0, start_addr,
+                                     offset >> VTD_PAGE_SHIFT);
+       else
                iommu_flush_write_buffer(iommu);
        return nelems;
  }
  
@@@ -2640,9 -2776,9 +2773,9 @@@ static int init_iommu_hw(void
                iommu_set_root_entry(iommu);
  
                iommu->flush.flush_context(iommu, 0, 0, 0,
-                                               DMA_CCMD_GLOBAL_INVL, 0);
+                                          DMA_CCMD_GLOBAL_INVL);
                iommu->flush.flush_iotlb(iommu, 0, 0, 0,
-                                               DMA_TLB_GLOBAL_FLUSH, 0);
+                                        DMA_TLB_GLOBAL_FLUSH);
                iommu_disable_protect_mem_regions(iommu);
                iommu_enable_translation(iommu);
        }
@@@ -2657,9 -2793,9 +2790,9 @@@ static void iommu_flush_all(void
  
        for_each_active_iommu(iommu, drhd) {
                iommu->flush.flush_context(iommu, 0, 0, 0,
-                                               DMA_CCMD_GLOBAL_INVL, 0);
+                                          DMA_CCMD_GLOBAL_INVL);
                iommu->flush.flush_iotlb(iommu, 0, 0, 0,
-                                               DMA_TLB_GLOBAL_FLUSH, 0);
+                                        DMA_TLB_GLOBAL_FLUSH);
        }
  }
  
@@@ -2782,7 -2918,7 +2915,7 @@@ int __init intel_iommu_init(void
         * Check the need for DMA-remapping initialization now.
         * Above initialization will also be used by Interrupt-remapping.
         */
-       if (no_iommu || swiotlb || dmar_disabled)
+       if (no_iommu || (swiotlb && !iommu_pass_through) || dmar_disabled)
                return -ENODEV;
  
        iommu_init_mempool();
  
        init_timer(&unmap_timer);
        force_iommu = 1;
-       dma_ops = &intel_dma_ops;
+       if (!iommu_pass_through) {
+               printk(KERN_INFO
+                      "Multi-level page-table translation for DMAR.\n");
+               dma_ops = &intel_dma_ops;
+       } else
+               printk(KERN_INFO
+                      "DMAR: Pass through translation for DMAR.\n");
        init_iommu_sysfs();
  
        register_iommu(&intel_iommu_ops);
@@@ -2888,6 -3032,7 +3029,7 @@@ static void vm_domain_remove_one_dev_in
                                info->dev->dev.archdata.iommu = NULL;
                        spin_unlock_irqrestore(&device_domain_lock, flags);
  
+                       iommu_disable_dev_iotlb(info);
                        iommu_detach_dev(iommu, info->bus, info->devfn);
                        iommu_detach_dependent_devices(iommu, pdev);
                        free_devinfo_mem(info);
@@@ -2938,6 -3083,7 +3080,7 @@@ static void vm_domain_remove_all_dev_in
  
                spin_unlock_irqrestore(&device_domain_lock, flags1);
  
+               iommu_disable_dev_iotlb(info);
                iommu = device_to_iommu(info->segment, info->bus, info->devfn);
                iommu_detach_dev(iommu, info->bus, info->devfn);
                iommu_detach_dependent_devices(iommu, info->dev);
@@@ -3142,11 -3288,11 +3285,11 @@@ static int intel_iommu_attach_device(st
                return -EFAULT;
        }
  
-       ret = domain_context_mapping(dmar_domain, pdev);
+       ret = vm_domain_add_dev_info(dmar_domain, pdev);
        if (ret)
                return ret;
  
-       ret = vm_domain_add_dev_info(dmar_domain, pdev);
+       ret = domain_context_mapping(dmar_domain, pdev, CONTEXT_TT_MULTI_LEVEL);
        return ret;
  }
  
@@@ -15,14 -15,6 +15,14 @@@ static struct ioapic_scope ir_ioapic[MA
  static int ir_ioapic_num;
  int intr_remapping_enabled;
  
 +static int disable_intremap;
 +static __init int setup_nointremap(char *str)
 +{
 +      disable_intremap = 1;
 +      return 0;
 +}
 +early_param("nointremap", setup_nointremap);
 +
  struct irq_2_iommu {
        struct intel_iommu *iommu;
        u16 irte_index;
  };
  
  #ifdef CONFIG_GENERIC_HARDIRQS
 -static struct irq_2_iommu *get_one_free_irq_2_iommu(int cpu)
 +static struct irq_2_iommu *get_one_free_irq_2_iommu(int node)
  {
        struct irq_2_iommu *iommu;
 -      int node;
 -
 -      node = cpu_to_node(cpu);
  
        iommu = kzalloc_node(sizeof(*iommu), GFP_ATOMIC, node);
 -      printk(KERN_DEBUG "alloc irq_2_iommu on cpu %d node %d\n", cpu, node);
 +      printk(KERN_DEBUG "alloc irq_2_iommu on node %d\n", node);
  
        return iommu;
  }
@@@ -53,7 -48,7 +53,7 @@@ static struct irq_2_iommu *irq_2_iommu(
        return desc->irq_2_iommu;
  }
  
 -static struct irq_2_iommu *irq_2_iommu_alloc_cpu(unsigned int irq, int cpu)
 +static struct irq_2_iommu *irq_2_iommu_alloc_node(unsigned int irq, int node)
  {
        struct irq_desc *desc;
        struct irq_2_iommu *irq_iommu;
@@@ -61,7 -56,7 +61,7 @@@
        /*
         * alloc irq desc if not allocated already.
         */
 -      desc = irq_to_desc_alloc_cpu(irq, cpu);
 +      desc = irq_to_desc_alloc_node(irq, node);
        if (!desc) {
                printk(KERN_INFO "can not get irq_desc for %d\n", irq);
                return NULL;
        irq_iommu = desc->irq_2_iommu;
  
        if (!irq_iommu)
 -              desc->irq_2_iommu = get_one_free_irq_2_iommu(cpu);
 +              desc->irq_2_iommu = get_one_free_irq_2_iommu(node);
  
        return desc->irq_2_iommu;
  }
  
  static struct irq_2_iommu *irq_2_iommu_alloc(unsigned int irq)
  {
 -      return irq_2_iommu_alloc_cpu(irq, boot_cpu_id);
 +      return irq_2_iommu_alloc_node(irq, cpu_to_node(boot_cpu_id));
  }
  
  #else /* !CONFIG_SPARSE_IRQ */
@@@ -409,7 -404,7 +409,7 @@@ int free_irte(int irq
  static void iommu_set_intr_remapping(struct intel_iommu *iommu, int mode)
  {
        u64 addr;
-       u32 cmd, sts;
+       u32 sts;
        unsigned long flags;
  
        addr = virt_to_phys((void *)iommu->ir_table->base);
                    (addr) | IR_X2APIC_MODE(mode) | INTR_REMAP_TABLE_REG_SIZE);
  
        /* Set interrupt-remapping table pointer */
-       cmd = iommu->gcmd | DMA_GCMD_SIRTP;
        iommu->gcmd |= DMA_GCMD_SIRTP;
-       writel(cmd, iommu->reg + DMAR_GCMD_REG);
+       writel(iommu->gcmd, iommu->reg + DMAR_GCMD_REG);
  
        IOMMU_WAIT_OP(iommu, DMAR_GSTS_REG,
                      readl, (sts & DMA_GSTS_IRTPS), sts);
        spin_unlock_irqrestore(&iommu->register_lock, flags);
  
 -      if (mode == 0) {
 -              spin_lock_irqsave(&iommu->register_lock, flags);
 -
 -              /* enable comaptiblity format interrupt pass through */
 -              iommu->gcmd |= DMA_GCMD_CFI;
 -              writel(iommu->gcmd, iommu->reg + DMAR_GCMD_REG);
 -
 -              IOMMU_WAIT_OP(iommu, DMAR_GSTS_REG,
 -                            readl, (sts & DMA_GSTS_CFIS), sts);
 -
 -              spin_unlock_irqrestore(&iommu->register_lock, flags);
 -      }
 -
        /*
         * global invalidation of interrupt entry cache before enabling
         * interrupt-remapping.
        spin_lock_irqsave(&iommu->register_lock, flags);
  
        /* Enable interrupt-remapping */
-       cmd = iommu->gcmd | DMA_GCMD_IRE;
        iommu->gcmd |= DMA_GCMD_IRE;
-       writel(cmd, iommu->reg + DMAR_GCMD_REG);
+       writel(iommu->gcmd, iommu->reg + DMAR_GCMD_REG);
  
        IOMMU_WAIT_OP(iommu, DMAR_GSTS_REG,
                      readl, (sts & DMA_GSTS_IRES), sts);
@@@ -507,23 -513,6 +505,23 @@@ end
        spin_unlock_irqrestore(&iommu->register_lock, flags);
  }
  
 +int __init intr_remapping_supported(void)
 +{
 +      struct dmar_drhd_unit *drhd;
 +
 +      if (disable_intremap)
 +              return 0;
 +
 +      for_each_drhd_unit(drhd) {
 +              struct intel_iommu *iommu = drhd->iommu;
 +
 +              if (!ecap_ir_support(iommu->ecap))
 +                      return 0;
 +      }
 +
 +      return 1;
 +}
 +
  int __init enable_intr_remapping(int eim)
  {
        struct dmar_drhd_unit *drhd;
diff --combined drivers/pci/iov.c
@@@ -5,6 -5,7 +5,7 @@@
   *
   * PCI Express I/O Virtualization (IOV) support.
   *   Single Root IOV 1.0
+  *   Address Translation Service 1.0
   */
  
  #include <linux/pci.h>
@@@ -110,7 -111,7 +111,7 @@@ static int virtfn_add(struct pci_dev *d
        }
  
        if (reset)
 -              pci_execute_reset_function(virtfn);
 +              __pci_reset_function(virtfn);
  
        pci_device_add(virtfn, virtfn->bus);
        mutex_unlock(&iov->dev->sriov->lock);
@@@ -164,7 -165,7 +165,7 @@@ static void virtfn_remove(struct pci_de
  
        if (reset) {
                device_release_driver(&virtfn->dev);
 -              pci_execute_reset_function(virtfn);
 +              __pci_reset_function(virtfn);
        }
  
        sprintf(buf, "virtfn%u", id);
@@@ -487,15 -488,13 +488,15 @@@ found
        iov->self = dev;
        pci_read_config_dword(dev, pos + PCI_SRIOV_CAP, &iov->cap);
        pci_read_config_byte(dev, pos + PCI_SRIOV_FUNC_LINK, &iov->link);
 +      if (dev->pcie_type == PCI_EXP_TYPE_RC_END)
 +              iov->link = PCI_DEVFN(PCI_SLOT(dev->devfn), iov->link);
  
        if (pdev)
                iov->dev = pci_dev_get(pdev);
-       else {
+       else
                iov->dev = dev;
-               mutex_init(&iov->lock);
-       }
+       mutex_init(&iov->lock);
  
        dev->sriov = iov;
        dev->is_physfn = 1;
@@@ -515,11 -514,11 +516,11 @@@ static void sriov_release(struct pci_de
  {
        BUG_ON(dev->sriov->nr_virtfn);
  
-       if (dev == dev->sriov->dev)
-               mutex_destroy(&dev->sriov->lock);
-       else
+       if (dev != dev->sriov->dev)
                pci_dev_put(dev->sriov->dev);
  
+       mutex_destroy(&dev->sriov->lock);
        kfree(dev->sriov);
        dev->sriov = NULL;
  }
@@@ -681,3 -680,145 +682,145 @@@ irqreturn_t pci_sriov_migration(struct 
        return sriov_migration(dev) ? IRQ_HANDLED : IRQ_NONE;
  }
  EXPORT_SYMBOL_GPL(pci_sriov_migration);
+ static int ats_alloc_one(struct pci_dev *dev, int ps)
+ {
+       int pos;
+       u16 cap;
+       struct pci_ats *ats;
+       pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ATS);
+       if (!pos)
+               return -ENODEV;
+       ats = kzalloc(sizeof(*ats), GFP_KERNEL);
+       if (!ats)
+               return -ENOMEM;
+       ats->pos = pos;
+       ats->stu = ps;
+       pci_read_config_word(dev, pos + PCI_ATS_CAP, &cap);
+       ats->qdep = PCI_ATS_CAP_QDEP(cap) ? PCI_ATS_CAP_QDEP(cap) :
+                                           PCI_ATS_MAX_QDEP;
+       dev->ats = ats;
+       return 0;
+ }
+ static void ats_free_one(struct pci_dev *dev)
+ {
+       kfree(dev->ats);
+       dev->ats = NULL;
+ }
+ /**
+  * pci_enable_ats - enable the ATS capability
+  * @dev: the PCI device
+  * @ps: the IOMMU page shift
+  *
+  * Returns 0 on success, or negative on failure.
+  */
+ int pci_enable_ats(struct pci_dev *dev, int ps)
+ {
+       int rc;
+       u16 ctrl;
+       BUG_ON(dev->ats && dev->ats->is_enabled);
+       if (ps < PCI_ATS_MIN_STU)
+               return -EINVAL;
+       if (dev->is_physfn || dev->is_virtfn) {
+               struct pci_dev *pdev = dev->is_physfn ? dev : dev->physfn;
+               mutex_lock(&pdev->sriov->lock);
+               if (pdev->ats)
+                       rc = pdev->ats->stu == ps ? 0 : -EINVAL;
+               else
+                       rc = ats_alloc_one(pdev, ps);
+               if (!rc)
+                       pdev->ats->ref_cnt++;
+               mutex_unlock(&pdev->sriov->lock);
+               if (rc)
+                       return rc;
+       }
+       if (!dev->is_physfn) {
+               rc = ats_alloc_one(dev, ps);
+               if (rc)
+                       return rc;
+       }
+       ctrl = PCI_ATS_CTRL_ENABLE;
+       if (!dev->is_virtfn)
+               ctrl |= PCI_ATS_CTRL_STU(ps - PCI_ATS_MIN_STU);
+       pci_write_config_word(dev, dev->ats->pos + PCI_ATS_CTRL, ctrl);
+       dev->ats->is_enabled = 1;
+       return 0;
+ }
+ /**
+  * pci_disable_ats - disable the ATS capability
+  * @dev: the PCI device
+  */
+ void pci_disable_ats(struct pci_dev *dev)
+ {
+       u16 ctrl;
+       BUG_ON(!dev->ats || !dev->ats->is_enabled);
+       pci_read_config_word(dev, dev->ats->pos + PCI_ATS_CTRL, &ctrl);
+       ctrl &= ~PCI_ATS_CTRL_ENABLE;
+       pci_write_config_word(dev, dev->ats->pos + PCI_ATS_CTRL, ctrl);
+       dev->ats->is_enabled = 0;
+       if (dev->is_physfn || dev->is_virtfn) {
+               struct pci_dev *pdev = dev->is_physfn ? dev : dev->physfn;
+               mutex_lock(&pdev->sriov->lock);
+               pdev->ats->ref_cnt--;
+               if (!pdev->ats->ref_cnt)
+                       ats_free_one(pdev);
+               mutex_unlock(&pdev->sriov->lock);
+       }
+       if (!dev->is_physfn)
+               ats_free_one(dev);
+ }
+ /**
+  * pci_ats_queue_depth - query the ATS Invalidate Queue Depth
+  * @dev: the PCI device
+  *
+  * Returns the queue depth on success, or negative on failure.
+  *
+  * The ATS spec uses 0 in the Invalidate Queue Depth field to
+  * indicate that the function can accept 32 Invalidate Request.
+  * But here we use the `real' values (i.e. 1~32) for the Queue
+  * Depth; and 0 indicates the function shares the Queue with
+  * other functions (doesn't exclusively own a Queue).
+  */
+ int pci_ats_queue_depth(struct pci_dev *dev)
+ {
+       int pos;
+       u16 cap;
+       if (dev->is_virtfn)
+               return 0;
+       if (dev->ats)
+               return dev->ats->qdep;
+       pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ATS);
+       if (!pos)
+               return -ENODEV;
+       pci_read_config_word(dev, pos + PCI_ATS_CAP, &cap);
+       return PCI_ATS_CAP_QDEP(cap) ? PCI_ATS_CAP_QDEP(cap) :
+                                      PCI_ATS_MAX_QDEP;
+ }
diff --combined include/linux/dmar.h
@@@ -108,7 -108,6 +108,7 @@@ struct irte 
  };
  #ifdef CONFIG_INTR_REMAP
  extern int intr_remapping_enabled;
 +extern int intr_remapping_supported(void);
  extern int enable_intr_remapping(int);
  extern void disable_intr_remapping(void);
  extern int reenable_intr_remapping(int);
@@@ -158,8 -157,6 +158,8 @@@ static inline struct intel_iommu *map_i
  }
  #define irq_remapped(irq)             (0)
  #define enable_intr_remapping(mode)   (-1)
 +#define disable_intr_remapping()      (0)
 +#define reenable_intr_remapping(mode) (0)
  #define intr_remapping_enabled                (0)
  #endif
  
@@@ -188,6 -185,15 +188,15 @@@ struct dmar_rmrr_unit 
  
  #define for_each_rmrr_units(rmrr) \
        list_for_each_entry(rmrr, &dmar_rmrr_units, list)
+ struct dmar_atsr_unit {
+       struct list_head list;          /* list of ATSR units */
+       struct acpi_dmar_header *hdr;   /* ACPI header */
+       struct pci_dev **devices;       /* target devices */
+       int devices_cnt;                /* target device count */
+       u8 include_all:1;               /* include all ports */
+ };
  /* Intel DMAR  initialization functions */
  extern int intel_iommu_init(void);
  #else
diff --combined include/linux/pci.h
@@@ -124,14 -124,6 +124,14 @@@ typedef int __bitwise pci_power_t
  #define PCI_UNKNOWN   ((pci_power_t __force) 5)
  #define PCI_POWER_ERROR       ((pci_power_t __force) -1)
  
 +/* Remember to update this when the list above changes! */
 +extern const char *pci_power_names[];
 +
 +static inline const char *pci_power_name(pci_power_t state)
 +{
 +      return pci_power_names[1 + (int) state];
 +}
 +
  #define PCI_PM_D2_DELAY       200
  #define PCI_PM_D3_WAIT        10
  #define PCI_PM_BUS_WAIT       50
@@@ -196,6 -188,7 +196,7 @@@ struct pci_cap_saved_state 
  struct pcie_link_state;
  struct pci_vpd;
  struct pci_sriov;
+ struct pci_ats;
  
  /*
   * The pci_dev structure is used to describe PCI devices.
@@@ -293,6 -286,7 +294,7 @@@ struct pci_dev 
                struct pci_sriov *sriov;        /* SR-IOV capability related */
                struct pci_dev *physfn; /* the PF this VF is associated with */
        };
+       struct pci_ats  *ats;   /* Address Translation Service */
  #endif
  };
  
@@@ -607,6 -601,8 +609,6 @@@ extern void pci_sort_breadthfirst(void)
  struct pci_dev __deprecated *pci_find_device(unsigned int vendor,
                                             unsigned int device,
                                             struct pci_dev *from);
 -struct pci_dev __deprecated *pci_find_slot(unsigned int bus,
 -                                         unsigned int devfn);
  #endif /* CONFIG_PCI_LEGACY */
  
  enum pci_lost_interrupt_reason {
@@@ -645,7 -641,6 +647,7 @@@ int pci_bus_write_config_word(struct pc
                              int where, u16 val);
  int pci_bus_write_config_dword(struct pci_bus *bus, unsigned int devfn,
                               int where, u32 val);
 +struct pci_ops *pci_bus_set_ops(struct pci_bus *bus, struct pci_ops *ops);
  
  static inline int pci_read_config_byte(struct pci_dev *dev, int where, u8 *val)
  {
@@@ -710,8 -705,8 +712,8 @@@ int pcix_get_mmrbc(struct pci_dev *dev)
  int pcix_set_mmrbc(struct pci_dev *dev, int mmrbc);
  int pcie_get_readrq(struct pci_dev *dev);
  int pcie_set_readrq(struct pci_dev *dev, int rq);
 +int __pci_reset_function(struct pci_dev *dev);
  int pci_reset_function(struct pci_dev *dev);
 -int pci_execute_reset_function(struct pci_dev *dev);
  void pci_update_resource(struct pci_dev *dev, int resno);
  int __must_check pci_assign_resource(struct pci_dev *dev, int i);
  int pci_select_bars(struct pci_dev *dev, unsigned long flags);
@@@ -731,7 -726,7 +733,7 @@@ int pci_set_power_state(struct pci_dev 
  pci_power_t pci_choose_state(struct pci_dev *dev, pm_message_t state);
  bool pci_pme_capable(struct pci_dev *dev, pci_power_t state);
  void pci_pme_active(struct pci_dev *dev, bool enable);
 -int pci_enable_wake(struct pci_dev *dev, pci_power_t state, int enable);
 +int pci_enable_wake(struct pci_dev *dev, pci_power_t state, bool enable);
  int pci_wake_from_d3(struct pci_dev *dev, bool enable);
  pci_power_t pci_target_state(struct pci_dev *dev);
  int pci_prepare_to_sleep(struct pci_dev *dev);
@@@ -797,7 -792,7 +799,7 @@@ const struct pci_device_id *pci_match_i
  int pci_scan_bridge(struct pci_bus *bus, struct pci_dev *dev, int max,
                    int pass);
  
 -void pci_walk_bus(struct pci_bus *top, void (*cb)(struct pci_dev *, void *),
 +void pci_walk_bus(struct pci_bus *top, int (*cb)(struct pci_dev *, void *),
                  void *userdata);
  int pci_cfg_space_size_ext(struct pci_dev *dev);
  int pci_cfg_space_size(struct pci_dev *dev);
@@@ -887,17 -882,6 +889,17 @@@ static inline int pcie_aspm_enabled(voi
  extern int pcie_aspm_enabled(void);
  #endif
  
 +#ifndef CONFIG_PCIE_ECRC
 +static inline void pcie_set_ecrc_checking(struct pci_dev *dev)
 +{
 +      return;
 +}
 +static inline void pcie_ecrc_get_policy(char *str) {};
 +#else
 +extern void pcie_set_ecrc_checking(struct pci_dev *dev);
 +extern void pcie_ecrc_get_policy(char *str);
 +#endif
 +
  #define pci_enable_msi(pdev)  pci_enable_msi_block(pdev, 1)
  
  #ifdef CONFIG_HT_IRQ
@@@ -954,6 -938,12 +956,6 @@@ static inline struct pci_dev *pci_find_
        return NULL;
  }
  
 -static inline struct pci_dev *pci_find_slot(unsigned int bus,
 -                                          unsigned int devfn)
 -{
 -      return NULL;
 -}
 -
  static inline struct pci_dev *pci_get_device(unsigned int vendor,
                                             unsigned int device,
                                             struct pci_dev *from)
@@@ -1109,10 -1099,6 +1111,10 @@@ static inline struct pci_dev *pci_get_b
  
  #include <asm/pci.h>
  
 +#ifndef PCIBIOS_MAX_MEM_32
 +#define PCIBIOS_MAX_MEM_32 (-1)
 +#endif
 +
  /* these helpers provide future and backwards compatibility
   * for accessing popular PCI BAR info */
  #define pci_resource_start(dev, bar)  ((dev)->resource[(bar)].start)
@@@ -1269,10 -1255,5 +1271,10 @@@ static inline irqreturn_t pci_sriov_mig
  }
  #endif
  
 +#if defined(CONFIG_HOTPLUG_PCI) || defined(CONFIG_HOTPLUG_PCI_MODULE)
 +extern void pci_hp_create_module_link(struct pci_slot *pci_slot);
 +extern void pci_hp_remove_module_link(struct pci_slot *pci_slot);
 +#endif
 +
  #endif /* __KERNEL__ */
  #endif /* LINUX_PCI_H */
diff --combined include/linux/pci_regs.h
  #define PCI_MSI_ADDRESS_LO    4       /* Lower 32 bits */
  #define PCI_MSI_ADDRESS_HI    8       /* Upper 32 bits (if PCI_MSI_FLAGS_64BIT set) */
  #define PCI_MSI_DATA_32               8       /* 16 bits of data for 32-bit devices */
 +#define PCI_MSI_MASK_32               12      /* Mask bits register for 32-bit devices */
  #define PCI_MSI_DATA_64               12      /* 16 bits of data for 64-bit devices */
 -#define PCI_MSI_MASK_BIT      16      /* Mask bits register */
 +#define PCI_MSI_MASK_64               16      /* Mask bits register for 64-bit devices */
  
  /* MSI-X registers (these are at offset PCI_MSIX_FLAGS) */
  #define PCI_MSIX_FLAGS                2
  #define  PCI_MSIX_FLAGS_ENABLE        (1 << 15)
  #define  PCI_MSIX_FLAGS_MASKALL       (1 << 14)
  #define PCI_MSIX_FLAGS_BIRMASK        (7 << 0)
 -#define PCI_MSIX_FLAGS_BITMASK        (1 << 0)
  
  /* CompactPCI Hotswap Register */
  
  #define  PCI_EXP_TYPE_DOWNSTREAM 0x6  /* Downstream Port */
  #define  PCI_EXP_TYPE_PCI_BRIDGE 0x7  /* PCI/PCI-X Bridge */
  #define  PCI_EXP_TYPE_RC_END  0x9     /* Root Complex Integrated Endpoint */
 +#define  PCI_EXP_TYPE_RC_EC   0x10    /* Root Complex Event Collector */
  #define PCI_EXP_FLAGS_SLOT    0x0100  /* Slot implemented */
  #define PCI_EXP_FLAGS_IRQ     0x3e00  /* Interrupt message number */
  #define PCI_EXP_DEVCAP                4       /* Device capabilities */
  #define PCI_EXT_CAP_ID_DSN    3
  #define PCI_EXT_CAP_ID_PWR    4
  #define PCI_EXT_CAP_ID_ARI    14
+ #define PCI_EXT_CAP_ID_ATS    15
  #define PCI_EXT_CAP_ID_SRIOV  16
  
  /* Advanced Error Reporting */
  #define  PCI_ARI_CTRL_ACS     0x0002  /* ACS Function Groups Enable */
  #define  PCI_ARI_CTRL_FG(x)   (((x) >> 4) & 7) /* Function Group */
  
+ /* Address Translation Service */
+ #define PCI_ATS_CAP           0x04    /* ATS Capability Register */
+ #define  PCI_ATS_CAP_QDEP(x)  ((x) & 0x1f)    /* Invalidate Queue Depth */
+ #define  PCI_ATS_MAX_QDEP     32      /* Max Invalidate Queue Depth */
+ #define PCI_ATS_CTRL          0x06    /* ATS Control Register */
+ #define  PCI_ATS_CTRL_ENABLE  0x8000  /* ATS Enable */
+ #define  PCI_ATS_CTRL_STU(x)  ((x) & 0x1f)    /* Smallest Translation Unit */
+ #define  PCI_ATS_MIN_STU      12      /* shift of minimum STU block */
  /* Single Root I/O Virtualization */
  #define PCI_SRIOV_CAP         0x04    /* SR-IOV Capabilities */
  #define  PCI_SRIOV_CAP_VFM    0x01    /* VF Migration Capable */