linux/arch/x86/xen/pci-swiotlb-xen.c
<<
>>
Prefs
   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
  21static 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 */
  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
  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
  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}
  91EXPORT_SYMBOL_GPL(pci_xen_swiotlb_init_late);
  92
  93IOMMU_INIT_FINISH(pci_xen_swiotlb_detect,
  94                  NULL,
  95                  pci_xen_swiotlb_init,
  96                  NULL);
  97