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