2010-02-09 22:30:55 +03:00
/* Glue code to lib/swiotlb-xen.c */
# include <linux/dma-mapping.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
2010-02-09 22:30:55 +03:00
int xen_swiotlb __read_mostly ;
static struct dma_map_ops xen_swiotlb_dma_ops = {
. mapping_error = xen_swiotlb_dma_mapping_error ,
2012-03-27 16:28:18 +04:00
. alloc = xen_swiotlb_alloc_coherent ,
. free = xen_swiotlb_free_coherent ,
2010-02-09 22:30:55 +03:00
. sync_single_for_cpu = xen_swiotlb_sync_single_for_cpu ,
. sync_single_for_device = xen_swiotlb_sync_single_for_device ,
. sync_sg_for_cpu = xen_swiotlb_sync_sg_for_cpu ,
. sync_sg_for_device = xen_swiotlb_sync_sg_for_device ,
. map_sg = xen_swiotlb_map_sg_attrs ,
. unmap_sg = xen_swiotlb_unmap_sg_attrs ,
. map_page = xen_swiotlb_map_page ,
. unmap_page = xen_swiotlb_unmap_page ,
. dma_supported = xen_swiotlb_dma_supported ,
} ;
/*
* 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
*/
2012-07-28 04:10:58 +04:00
if ( ( xen_initial_domain ( ) | | swiotlb | | 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 ;
}
void __init pci_xen_swiotlb_init ( void )
{
if ( xen_swiotlb ) {
2012-08-23 22:36:15 +04:00
xen_swiotlb_init ( 1 , true /* early */ ) ;
2010-02-09 22:30:55 +03:00
dma_ops = & xen_swiotlb_dma_ops ;
2010-08-19 21:34:58 +04:00
/* Make sure ACS will be enabled */
pci_request_acs ( ) ;
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 ;
rc = xen_swiotlb_init ( 1 , false /* late */ ) ;
if ( rc )
return rc ;
dma_ops = & xen_swiotlb_dma_ops ;
/* Make sure ACS will be enabled */
pci_request_acs ( ) ;
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 ) ;