]> git.kernelconcepts.de Git - karo-tx-linux.git/blob - arch/x86/xen/pci-swiotlb-xen.c
42b08f8fc2cae906d5c5101bcd8f6c59e51d4568
[karo-tx-linux.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 const struct dma_map_ops xen_swiotlb_dma_ops = {
22         .alloc = xen_swiotlb_alloc_coherent,
23         .free = xen_swiotlb_free_coherent,
24         .sync_single_for_cpu = xen_swiotlb_sync_single_for_cpu,
25         .sync_single_for_device = xen_swiotlb_sync_single_for_device,
26         .sync_sg_for_cpu = xen_swiotlb_sync_sg_for_cpu,
27         .sync_sg_for_device = xen_swiotlb_sync_sg_for_device,
28         .map_sg = xen_swiotlb_map_sg_attrs,
29         .unmap_sg = xen_swiotlb_unmap_sg_attrs,
30         .map_page = xen_swiotlb_map_page,
31         .unmap_page = xen_swiotlb_unmap_page,
32         .dma_supported = xen_swiotlb_dma_supported,
33 };
34
35 /*
36  * pci_xen_swiotlb_detect - set xen_swiotlb to 1 if necessary
37  *
38  * This returns non-zero if we are forced to use xen_swiotlb (by the boot
39  * option).
40  */
41 int __init pci_xen_swiotlb_detect(void)
42 {
43
44         if (!xen_pv_domain())
45                 return 0;
46
47         /* If running as PV guest, either iommu=soft, or swiotlb=force will
48          * activate this IOMMU. If running as PV privileged, activate it
49          * irregardless.
50          */
51         if (xen_initial_domain() || swiotlb || swiotlb_force == SWIOTLB_FORCE)
52                 xen_swiotlb = 1;
53
54         /* If we are running under Xen, we MUST disable the native SWIOTLB.
55          * Don't worry about swiotlb_force flag activating the native, as
56          * the 'swiotlb' flag is the only one turning it on. */
57         swiotlb = 0;
58
59 #ifdef CONFIG_X86_64
60         /* pci_swiotlb_detect_4gb turns on native SWIOTLB if no_iommu == 0
61          * (so no iommu=X command line over-writes).
62          * Considering that PV guests do not want the *native SWIOTLB* but
63          * only Xen SWIOTLB it is not useful to us so set no_iommu=1 here.
64          */
65         if (max_pfn > MAX_DMA32_PFN)
66                 no_iommu = 1;
67 #endif
68         return xen_swiotlb;
69 }
70
71 void __init pci_xen_swiotlb_init(void)
72 {
73         if (xen_swiotlb) {
74                 xen_swiotlb_init(1, true /* early */);
75                 dma_ops = &xen_swiotlb_dma_ops;
76
77 #ifdef CONFIG_PCI
78                 /* Make sure ACS will be enabled */
79                 pci_request_acs();
80 #endif
81         }
82 }
83
84 int pci_xen_swiotlb_init_late(void)
85 {
86         int rc;
87
88         if (xen_swiotlb)
89                 return 0;
90
91         rc = xen_swiotlb_init(1, false /* late */);
92         if (rc)
93                 return rc;
94
95         dma_ops = &xen_swiotlb_dma_ops;
96 #ifdef CONFIG_PCI
97         /* Make sure ACS will be enabled */
98         pci_request_acs();
99 #endif
100
101         return 0;
102 }
103 EXPORT_SYMBOL_GPL(pci_xen_swiotlb_init_late);
104
105 IOMMU_INIT_FINISH(pci_xen_swiotlb_detect,
106                   NULL,
107                   pci_xen_swiotlb_init,
108                   NULL);