2018-08-28 10:40:15 +03:00
// SPDX-License-Identifier: GPL-2.0
2010-02-09 22:30:55 +03:00
/* Glue code to lib/swiotlb-xen.c */
2020-09-22 16:31:03 +03:00
# include <linux/dma-map-ops.h>
2010-08-19 21:34:58 +04:00
# include <linux/pci.h>
2010-02-09 22:30:55 +03:00
# include <xen/swiotlb-xen.h>
# include <asm/xen/hypervisor.h>
# include <xen/xen.h>
2010-08-26 21:58:01 +04:00
# include <asm/iommu_table.h>
2010-02-09 22:30:55 +03:00
2012-09-23 04:01:16 +04:00
2012-08-21 22:49:34 +04:00
# include <asm/xen/swiotlb-xen.h>
2012-07-28 04:16:00 +04:00
# ifdef CONFIG_X86_64
# include <asm/iommu.h>
# include <asm/dma.h>
# endif
2012-08-23 22:36:15 +04:00
# include <linux/export.h>
2012-09-23 04:01:16 +04:00
2021-09-17 13:49:04 +03:00
static int xen_swiotlb __read_mostly ;
2010-02-09 22:30:55 +03:00
/*
* pci_xen_swiotlb_detect - set xen_swiotlb to 1 if necessary
*
* This returns non - zero if we are forced to use xen_swiotlb ( by the boot
* option ) .
*/
int __init pci_xen_swiotlb_detect ( void )
{
2012-07-28 04:10:58 +04:00
if ( ! xen_pv_domain ( ) )
return 0 ;
2010-02-09 22:30:55 +03:00
/* If running as PV guest, either iommu=soft, or swiotlb=force will
* activate this IOMMU . If running as PV privileged , activate it
2011-05-10 12:16:21 +04:00
* irregardless .
2010-02-09 22:30:55 +03:00
*/
2016-12-16 16:28:41 +03:00
if ( xen_initial_domain ( ) | | swiotlb | | swiotlb_force = = SWIOTLB_FORCE )
2010-02-09 22:30:55 +03:00
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 . */
2012-07-28 04:10:58 +04:00
swiotlb = 0 ;
2010-02-09 22:30:55 +03:00
2012-07-28 04:16:00 +04:00
# 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
2010-02-09 22:30:55 +03:00
return xen_swiotlb ;
}
2021-09-17 13:49:04 +03:00
static void __init pci_xen_swiotlb_init ( void )
2010-02-09 22:30:55 +03:00
{
if ( xen_swiotlb ) {
2021-03-01 10:44:32 +03:00
xen_swiotlb_init_early ( ) ;
2010-02-09 22:30:55 +03:00
dma_ops = & xen_swiotlb_dma_ops ;
2010-08-19 21:34:58 +04:00
2013-11-04 22:11:54 +04:00
# ifdef CONFIG_PCI
2010-08-19 21:34:58 +04:00
/* Make sure ACS will be enabled */
pci_request_acs ( ) ;
2013-11-04 22:11:54 +04:00
# endif
2010-02-09 22:30:55 +03:00
}
}
2012-08-23 22:36:15 +04:00
int pci_xen_swiotlb_init_late ( void )
{
int rc ;
if ( xen_swiotlb )
return 0 ;
2021-03-01 10:44:32 +03:00
rc = xen_swiotlb_init ( ) ;
2012-08-23 22:36:15 +04:00
if ( rc )
return rc ;
dma_ops = & xen_swiotlb_dma_ops ;
2013-11-04 22:11:54 +04:00
# ifdef CONFIG_PCI
2012-08-23 22:36:15 +04:00
/* Make sure ACS will be enabled */
pci_request_acs ( ) ;
2013-11-04 22:11:54 +04:00
# endif
2012-08-23 22:36:15 +04:00
return 0 ;
}
EXPORT_SYMBOL_GPL ( pci_xen_swiotlb_init_late ) ;
2010-08-26 21:58:01 +04:00
IOMMU_INIT_FINISH ( pci_xen_swiotlb_detect ,
2012-08-13 19:00:08 +04:00
NULL ,
2010-08-26 21:58:01 +04:00
pci_xen_swiotlb_init ,
2012-08-13 19:00:08 +04:00
NULL ) ;