]> Pileus Git - ~andy/linux/blobdiff - arch/x86/xen/pci-swiotlb-xen.c
Merge branch 'stable/late-swiotlb.v3.3' into stable/for-linus-3.7
[~andy/linux] / arch / x86 / xen / pci-swiotlb-xen.c
index 1ab45941502d6ca71238ca2f33897dd3e75b496e..969570491c3964d0023dc82a231ff683ee88f735 100644 (file)
@@ -8,7 +8,14 @@
 #include <xen/xen.h>
 #include <asm/iommu_table.h>
 
+
 #include <asm/xen/swiotlb-xen.h>
+#ifdef CONFIG_X86_64
+#include <asm/iommu.h>
+#include <asm/dma.h>
+#endif
+#include <linux/export.h>
+
 int xen_swiotlb __read_mostly;
 
 static struct dma_map_ops xen_swiotlb_dma_ops = {
@@ -35,33 +42,63 @@ static struct dma_map_ops xen_swiotlb_dma_ops = {
 int __init pci_xen_swiotlb_detect(void)
 {
 
+       if (!xen_pv_domain())
+               return 0;
+
        /* If running as PV guest, either iommu=soft, or swiotlb=force will
         * activate this IOMMU. If running as PV privileged, activate it
         * irregardless.
         */
-       if ((xen_initial_domain() || swiotlb || swiotlb_force) &&
-           (xen_pv_domain()))
+       if ((xen_initial_domain() || swiotlb || swiotlb_force))
                xen_swiotlb = 1;
 
        /* If we are running under Xen, we MUST disable the native SWIOTLB.
         * Don't worry about swiotlb_force flag activating the native, as
         * the 'swiotlb' flag is the only one turning it on. */
-       if (xen_pv_domain())
-               swiotlb = 0;
+       swiotlb = 0;
 
+#ifdef CONFIG_X86_64
+       /* pci_swiotlb_detect_4gb turns on native SWIOTLB if no_iommu == 0
+        * (so no iommu=X command line over-writes).
+        * Considering that PV guests do not want the *native SWIOTLB* but
+        * only Xen SWIOTLB it is not useful to us so set no_iommu=1 here.
+        */
+       if (max_pfn > MAX_DMA32_PFN)
+               no_iommu = 1;
+#endif
        return xen_swiotlb;
 }
 
 void __init pci_xen_swiotlb_init(void)
 {
        if (xen_swiotlb) {
-               xen_swiotlb_init(1);
+               xen_swiotlb_init(1, true /* early */);
                dma_ops = &xen_swiotlb_dma_ops;
 
                /* Make sure ACS will be enabled */
                pci_request_acs();
        }
 }
+
+int pci_xen_swiotlb_init_late(void)
+{
+       int rc;
+
+       if (xen_swiotlb)
+               return 0;
+
+       rc = xen_swiotlb_init(1, false /* late */);
+       if (rc)
+               return rc;
+
+       dma_ops = &xen_swiotlb_dma_ops;
+       /* Make sure ACS will be enabled */
+       pci_request_acs();
+
+       return 0;
+}
+EXPORT_SYMBOL_GPL(pci_xen_swiotlb_init_late);
+
 IOMMU_INIT_FINISH(pci_xen_swiotlb_detect,
                  NULL,
                  pci_xen_swiotlb_init,