Linux Audio

Check our new training course

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