1 // SPDX-License-Identifier: GPL-2.0 2 3 /* Glue code to lib/swiotlb-xen.c */ 4 5 #include <linux/dma-map-ops.h> 6 #include <linux/pci.h> 7 #include <xen/swiotlb-xen.h> 8 9 #include <asm/xen/hypervisor.h> 10 #include <xen/xen.h> 11 #include <asm/iommu_table.h> 12 13 14 #include <asm/xen/swiotlb-xen.h> 15 #ifdef CONFIG_X86_64 16 #include <asm/iommu.h> 17 #include <asm/dma.h> 18 #endif 19 #include <linux/export.h> 20 21 static int xen_swiotlb __read_mostly; 22 23 /* 24 * pci_xen_swiotlb_detect - set xen_swiotlb to 1 if necessary 25 * 26 * This returns non-zero if we are forced to use xen_swiotlb (by the boot 27 * option). 28 */ pci_xen_swiotlb_detect(void)29int __init pci_xen_swiotlb_detect(void) 30 { 31 32 if (!xen_pv_domain()) 33 return 0; 34 35 /* If running as PV guest, either iommu=soft, or swiotlb=force will 36 * activate this IOMMU. If running as PV privileged, activate it 37 * irregardless. 38 */ 39 if (xen_initial_domain() || swiotlb || swiotlb_force == SWIOTLB_FORCE) 40 xen_swiotlb = 1; 41 42 /* If we are running under Xen, we MUST disable the native SWIOTLB. 43 * Don't worry about swiotlb_force flag activating the native, as 44 * the 'swiotlb' flag is the only one turning it on. */ 45 swiotlb = 0; 46 47 #ifdef CONFIG_X86_64 48 /* pci_swiotlb_detect_4gb turns on native SWIOTLB if no_iommu == 0 49 * (so no iommu=X command line over-writes). 50 * Considering that PV guests do not want the *native SWIOTLB* but 51 * only Xen SWIOTLB it is not useful to us so set no_iommu=1 here. 52 */ 53 if (max_pfn > MAX_DMA32_PFN) 54 no_iommu = 1; 55 #endif 56 return xen_swiotlb; 57 } 58 pci_xen_swiotlb_init(void)59static void __init pci_xen_swiotlb_init(void) 60 { 61 if (xen_swiotlb) { 62 xen_swiotlb_init_early(); 63 dma_ops = &xen_swiotlb_dma_ops; 64 65 #ifdef CONFIG_PCI 66 /* Make sure ACS will be enabled */ 67 pci_request_acs(); 68 #endif 69 } 70 } 71 pci_xen_swiotlb_init_late(void)72int pci_xen_swiotlb_init_late(void) 73 { 74 int rc; 75 76 if (xen_swiotlb) 77 return 0; 78 79 rc = xen_swiotlb_init(); 80 if (rc) 81 return rc; 82 83 dma_ops = &xen_swiotlb_dma_ops; 84 #ifdef CONFIG_PCI 85 /* Make sure ACS will be enabled */ 86 pci_request_acs(); 87 #endif 88 89 return 0; 90 } 91 EXPORT_SYMBOL_GPL(pci_xen_swiotlb_init_late); 92 93 IOMMU_INIT_FINISH(pci_xen_swiotlb_detect, 94 NULL, 95 pci_xen_swiotlb_init, 96 NULL); 97