]> git.openfabrics.org - ~shefty/rdma-dev.git/blob - arch/x86/xen/pci-swiotlb-xen.c
Merge branch 'stable/late-swiotlb.v3.3' into stable/for-linus-3.7
[~shefty/rdma-dev.git] / arch / x86 / xen / pci-swiotlb-xen.c
1 /* Glue code to lib/swiotlb-xen.c */
2
3 #include <linux/dma-mapping.h>
4 #include <linux/pci.h>
5 #include <xen/swiotlb-xen.h>
6
7 #include <asm/xen/hypervisor.h>
8 #include <xen/xen.h>
9 #include <asm/iommu_table.h>
10
11
12 #include <asm/xen/swiotlb-xen.h>
13 #ifdef CONFIG_X86_64
14 #include <asm/iommu.h>
15 #include <asm/dma.h>
16 #endif
17 #include <linux/export.h>
18
19 int xen_swiotlb __read_mostly;
20
21 static struct dma_map_ops xen_swiotlb_dma_ops = {
22         .mapping_error = xen_swiotlb_dma_mapping_error,
23         .alloc = xen_swiotlb_alloc_coherent,
24         .free = xen_swiotlb_free_coherent,
25         .sync_single_for_cpu = xen_swiotlb_sync_single_for_cpu,
26         .sync_single_for_device = xen_swiotlb_sync_single_for_device,
27         .sync_sg_for_cpu = xen_swiotlb_sync_sg_for_cpu,
28         .sync_sg_for_device = xen_swiotlb_sync_sg_for_device,
29         .map_sg = xen_swiotlb_map_sg_attrs,
30         .unmap_sg = xen_swiotlb_unmap_sg_attrs,
31         .map_page = xen_swiotlb_map_page,
32         .unmap_page = xen_swiotlb_unmap_page,
33         .dma_supported = xen_swiotlb_dma_supported,
34 };
35
36 /*
37  * pci_xen_swiotlb_detect - set xen_swiotlb to 1 if necessary
38  *
39  * This returns non-zero if we are forced to use xen_swiotlb (by the boot
40  * option).
41  */
42 int __init pci_xen_swiotlb_detect(void)
43 {
44
45         if (!xen_pv_domain())
46                 return 0;
47
48         /* If running as PV guest, either iommu=soft, or swiotlb=force will
49          * activate this IOMMU. If running as PV privileged, activate it
50          * irregardless.
51          */
52         if ((xen_initial_domain() || swiotlb || swiotlb_force))
53                 xen_swiotlb = 1;
54
55         /* If we are running under Xen, we MUST disable the native SWIOTLB.
56          * Don't worry about swiotlb_force flag activating the native, as
57          * the 'swiotlb' flag is the only one turning it on. */
58         swiotlb = 0;
59
60 #ifdef CONFIG_X86_64
61         /* pci_swiotlb_detect_4gb turns on native SWIOTLB if no_iommu == 0
62          * (so no iommu=X command line over-writes).
63          * Considering that PV guests do not want the *native SWIOTLB* but
64          * only Xen SWIOTLB it is not useful to us so set no_iommu=1 here.
65          */
66         if (max_pfn > MAX_DMA32_PFN)
67                 no_iommu = 1;
68 #endif
69         return xen_swiotlb;
70 }
71
72 void __init pci_xen_swiotlb_init(void)
73 {
74         if (xen_swiotlb) {
75                 xen_swiotlb_init(1, true /* early */);
76                 dma_ops = &xen_swiotlb_dma_ops;
77
78                 /* Make sure ACS will be enabled */
79                 pci_request_acs();
80         }
81 }
82
83 int pci_xen_swiotlb_init_late(void)
84 {
85         int rc;
86
87         if (xen_swiotlb)
88                 return 0;
89
90         rc = xen_swiotlb_init(1, false /* late */);
91         if (rc)
92                 return rc;
93
94         dma_ops = &xen_swiotlb_dma_ops;
95         /* Make sure ACS will be enabled */
96         pci_request_acs();
97
98         return 0;
99 }
100 EXPORT_SYMBOL_GPL(pci_xen_swiotlb_init_late);
101
102 IOMMU_INIT_FINISH(pci_xen_swiotlb_detect,
103                   NULL,
104                   pci_xen_swiotlb_init,
105                   NULL);