GNU Linux-libre 4.14.266-gnu1
[releases.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 /*
22  * pci_xen_swiotlb_detect - set xen_swiotlb to 1 if necessary
23  *
24  * This returns non-zero if we are forced to use xen_swiotlb (by the boot
25  * option).
26  */
27 int __init pci_xen_swiotlb_detect(void)
28 {
29
30         if (!xen_pv_domain())
31                 return 0;
32
33         /* If running as PV guest, either iommu=soft, or swiotlb=force will
34          * activate this IOMMU. If running as PV privileged, activate it
35          * irregardless.
36          */
37         if (xen_initial_domain() || swiotlb || swiotlb_force == SWIOTLB_FORCE)
38                 xen_swiotlb = 1;
39
40         /* If we are running under Xen, we MUST disable the native SWIOTLB.
41          * Don't worry about swiotlb_force flag activating the native, as
42          * the 'swiotlb' flag is the only one turning it on. */
43         swiotlb = 0;
44
45 #ifdef CONFIG_X86_64
46         /* pci_swiotlb_detect_4gb turns on native SWIOTLB if no_iommu == 0
47          * (so no iommu=X command line over-writes).
48          * Considering that PV guests do not want the *native SWIOTLB* but
49          * only Xen SWIOTLB it is not useful to us so set no_iommu=1 here.
50          */
51         if (max_pfn > MAX_DMA32_PFN)
52                 no_iommu = 1;
53 #endif
54         return xen_swiotlb;
55 }
56
57 void __init pci_xen_swiotlb_init(void)
58 {
59         if (xen_swiotlb) {
60                 xen_swiotlb_init(1, true /* early */);
61                 dma_ops = &xen_swiotlb_dma_ops;
62
63 #ifdef CONFIG_PCI
64                 /* Make sure ACS will be enabled */
65                 pci_request_acs();
66 #endif
67         }
68 }
69
70 int pci_xen_swiotlb_init_late(void)
71 {
72         int rc;
73
74         if (xen_swiotlb)
75                 return 0;
76
77         rc = xen_swiotlb_init(1, false /* late */);
78         if (rc)
79                 return rc;
80
81         dma_ops = &xen_swiotlb_dma_ops;
82 #ifdef CONFIG_PCI
83         /* Make sure ACS will be enabled */
84         pci_request_acs();
85 #endif
86
87         return 0;
88 }
89 EXPORT_SYMBOL_GPL(pci_xen_swiotlb_init_late);
90
91 IOMMU_INIT_FINISH(pci_xen_swiotlb_detect,
92                   NULL,
93                   pci_xen_swiotlb_init,
94                   NULL);