LCOV - code coverage report
Current view: top level - arch/x86/kernel - pci-dma.c (source / functions) Hit Total Coverage
Test: combined.info Lines: 13 68 19.1 %
Date: 2022-04-01 14:35:51 Functions: 2 5 40.0 %
Branches: 9 60 15.0 %

           Branch data     Line data    Source code
       1                 :            : // SPDX-License-Identifier: GPL-2.0
       2                 :            : #include <linux/dma-direct.h>
       3                 :            : #include <linux/dma-debug.h>
       4                 :            : #include <linux/iommu.h>
       5                 :            : #include <linux/dmar.h>
       6                 :            : #include <linux/export.h>
       7                 :            : #include <linux/memblock.h>
       8                 :            : #include <linux/gfp.h>
       9                 :            : #include <linux/pci.h>
      10                 :            : 
      11                 :            : #include <asm/proto.h>
      12                 :            : #include <asm/dma.h>
      13                 :            : #include <asm/iommu.h>
      14                 :            : #include <asm/gart.h>
      15                 :            : #include <asm/x86_init.h>
      16                 :            : #include <asm/iommu_table.h>
      17                 :            : 
      18                 :            : static bool disable_dac_quirk __read_mostly;
      19                 :            : 
      20                 :            : const struct dma_map_ops *dma_ops;
      21                 :            : EXPORT_SYMBOL(dma_ops);
      22                 :            : 
      23                 :            : #ifdef CONFIG_IOMMU_DEBUG
      24                 :            : int panic_on_overflow __read_mostly = 1;
      25                 :            : int force_iommu __read_mostly = 1;
      26                 :            : #else
      27                 :            : int panic_on_overflow __read_mostly = 0;
      28                 :            : int force_iommu __read_mostly = 0;
      29                 :            : #endif
      30                 :            : 
      31                 :            : int iommu_merge __read_mostly = 0;
      32                 :            : 
      33                 :            : int no_iommu __read_mostly;
      34                 :            : /* Set this to 1 if there is a HW IOMMU in the system */
      35                 :            : int iommu_detected __read_mostly = 0;
      36                 :            : 
      37                 :            : extern struct iommu_table_entry __iommu_table[], __iommu_table_end[];
      38                 :            : 
      39                 :         21 : void __init pci_iommu_alloc(void)
      40                 :            : {
      41                 :         21 :         struct iommu_table_entry *p;
      42                 :            : 
      43                 :         21 :         sort_iommu_table(__iommu_table, __iommu_table_end);
      44                 :         21 :         check_iommu_entries(__iommu_table, __iommu_table_end);
      45                 :            : 
      46         [ +  + ]:        126 :         for (p = __iommu_table; p < __iommu_table_end; p++) {
      47   [ +  -  +  -  :         84 :                 if (p && p->detect && p->detect() > 0) {
                   -  + ]
      48                 :          0 :                         p->flags |= IOMMU_DETECTED;
      49         [ #  # ]:          0 :                         if (p->early_init)
      50                 :          0 :                                 p->early_init();
      51         [ #  # ]:          0 :                         if (p->flags & IOMMU_FINISH_IF_DETECTED)
      52                 :            :                                 break;
      53                 :            :                 }
      54                 :            :         }
      55                 :         21 : }
      56                 :            : 
      57                 :            : /*
      58                 :            :  * See <Documentation/x86/x86_64/boot-options.rst> for the iommu kernel
      59                 :            :  * parameter documentation.
      60                 :            :  */
      61                 :          0 : static __init int iommu_setup(char *p)
      62                 :            : {
      63                 :          0 :         iommu_merge = 1;
      64                 :            : 
      65         [ #  # ]:          0 :         if (!p)
      66                 :            :                 return -EINVAL;
      67                 :            : 
      68         [ #  # ]:          0 :         while (*p) {
      69         [ #  # ]:          0 :                 if (!strncmp(p, "off", 3))
      70                 :          0 :                         no_iommu = 1;
      71                 :            :                 /* gart_parse_options has more force support */
      72         [ #  # ]:          0 :                 if (!strncmp(p, "force", 5))
      73                 :          0 :                         force_iommu = 1;
      74         [ #  # ]:          0 :                 if (!strncmp(p, "noforce", 7)) {
      75                 :          0 :                         iommu_merge = 0;
      76                 :          0 :                         force_iommu = 0;
      77                 :            :                 }
      78                 :            : 
      79         [ #  # ]:          0 :                 if (!strncmp(p, "biomerge", 8)) {
      80                 :          0 :                         iommu_merge = 1;
      81                 :          0 :                         force_iommu = 1;
      82                 :            :                 }
      83         [ #  # ]:          0 :                 if (!strncmp(p, "panic", 5))
      84                 :          0 :                         panic_on_overflow = 1;
      85         [ #  # ]:          0 :                 if (!strncmp(p, "nopanic", 7))
      86                 :          0 :                         panic_on_overflow = 0;
      87         [ #  # ]:          0 :                 if (!strncmp(p, "merge", 5)) {
      88                 :          0 :                         iommu_merge = 1;
      89                 :          0 :                         force_iommu = 1;
      90                 :            :                 }
      91         [ #  # ]:          0 :                 if (!strncmp(p, "nomerge", 7))
      92                 :          0 :                         iommu_merge = 0;
      93         [ #  # ]:          0 :                 if (!strncmp(p, "forcesac", 8))
      94                 :          0 :                         pr_warn("forcesac option ignored.\n");
      95         [ #  # ]:          0 :                 if (!strncmp(p, "allowdac", 8))
      96                 :          0 :                         pr_warn("allowdac option ignored.\n");
      97         [ #  # ]:          0 :                 if (!strncmp(p, "nodac", 5))
      98                 :          0 :                         pr_warn("nodac option ignored.\n");
      99         [ #  # ]:          0 :                 if (!strncmp(p, "usedac", 6)) {
     100                 :          0 :                         disable_dac_quirk = true;
     101                 :          0 :                         return 1;
     102                 :            :                 }
     103                 :            : #ifdef CONFIG_SWIOTLB
     104         [ #  # ]:          0 :                 if (!strncmp(p, "soft", 4))
     105                 :          0 :                         swiotlb = 1;
     106                 :            : #endif
     107         [ #  # ]:          0 :                 if (!strncmp(p, "pt", 2))
     108                 :          0 :                         iommu_set_default_passthrough(true);
     109         [ #  # ]:          0 :                 if (!strncmp(p, "nopt", 4))
     110                 :          0 :                         iommu_set_default_translated(true);
     111                 :            : 
     112         [ #  # ]:          0 :                 gart_parse_options(p);
     113                 :            : 
     114                 :          0 :                 p += strcspn(p, ",");
     115         [ #  # ]:          0 :                 if (*p == ',')
     116                 :          0 :                         ++p;
     117                 :            :         }
     118                 :            :         return 0;
     119                 :            : }
     120                 :            : early_param("iommu", iommu_setup);
     121                 :            : 
     122                 :         21 : static int __init pci_iommu_init(void)
     123                 :            : {
     124                 :         21 :         struct iommu_table_entry *p;
     125                 :            : 
     126                 :         21 :         x86_init.iommu.iommu_init();
     127                 :            : 
     128         [ +  + ]:        126 :         for (p = __iommu_table; p < __iommu_table_end; p++) {
     129   [ +  -  -  +  :         84 :                 if (p && (p->flags & IOMMU_DETECTED) && p->late_init)
                   -  - ]
     130                 :          0 :                         p->late_init();
     131                 :            :         }
     132                 :            : 
     133                 :         21 :         return 0;
     134                 :            : }
     135                 :            : /* Must execute after PCI subsystem */
     136                 :            : rootfs_initcall(pci_iommu_init);
     137                 :            : 
     138                 :            : #ifdef CONFIG_PCI
     139                 :            : /* Many VIA bridges seem to corrupt data for DAC. Disable it here */
     140                 :            : 
     141                 :          0 : static int via_no_dac_cb(struct pci_dev *pdev, void *data)
     142                 :            : {
     143                 :          0 :         pdev->dev.bus_dma_limit = DMA_BIT_MASK(32);
     144                 :          0 :         return 0;
     145                 :            : }
     146                 :            : 
     147                 :          0 : static void via_no_dac(struct pci_dev *dev)
     148                 :            : {
     149         [ #  # ]:          0 :         if (!disable_dac_quirk) {
     150                 :          0 :                 dev_info(&dev->dev, "disabling DAC on VIA PCI bridge\n");
     151                 :          0 :                 pci_walk_bus(dev->subordinate, via_no_dac_cb, NULL);
     152                 :            :         }
     153                 :          0 : }
     154                 :            : DECLARE_PCI_FIXUP_CLASS_FINAL(PCI_VENDOR_ID_VIA, PCI_ANY_ID,
     155                 :            :                                 PCI_CLASS_BRIDGE_PCI, 8, via_no_dac);
     156                 :            : #endif

Generated by: LCOV version 1.14