Skip to content

Commit bb97be2

Browse files
committed
Merge tag 'iommu-updates-v5.1' of git://git.kernel.org/pub/scm/linux/kernel/git/joro/iommu
Pull IOMMU updates from Joerg Roedel: - A big cleanup and optimization patch-set for the Tegra GART driver - Documentation updates and fixes for the IOMMU-API - Support for page request in Intel VT-d scalable mode - Intel VT-d dma_[un]map_resource() support - Updates to the ATS enabling code for PCI (acked by Bjorn) and Intel VT-d to align with the latest version of the ATS spec - Relaxed IRQ source checking in the Intel VT-d driver for some aliased devices, needed for future devices which send IRQ messages from more than on request-ID - IRQ remapping driver for Hyper-V - Patches to make generic IOVA and IO-Page-Table code usable outside of the IOMMU code - Various other small fixes and cleanups * tag 'iommu-updates-v5.1' of git://git.kernel.org/pub/scm/linux/kernel/git/joro/iommu: (60 commits) iommu/vt-d: Get domain ID before clear pasid entry iommu/vt-d: Fix NULL pointer reference in intel_svm_bind_mm() iommu/vt-d: Set context field after value initialized iommu/vt-d: Disable ATS support on untrusted devices iommu/mediatek: Fix semicolon code style issue MAINTAINERS: Add Hyper-V IOMMU driver into Hyper-V CORE AND DRIVERS scope iommu/hyper-v: Add Hyper-V stub IOMMU driver x86/Hyper-V: Set x2apic destination mode to physical when x2apic is available PCI/ATS: Add inline to pci_prg_resp_pasid_required() iommu/vt-d: Check identity map for hot-added devices iommu: Fix IOMMU debugfs fallout iommu: Document iommu_ops.is_attach_deferred() iommu: Document iommu_ops.iotlb_sync_map() iommu/vt-d: Enable ATS only if the device uses page aligned address. PCI/ATS: Add pci_ats_page_aligned() interface iommu/vt-d: Fix PRI/PASID dependency issue. PCI/ATS: Add pci_prg_resp_pasid_required() interface. iommu/vt-d: Allow interrupts from the entire bus for aliased devices iommu/vt-d: Add helper to set an IRTE to verify only the bus number iommu: Fix flush_tlb_all typo ...
2 parents b7a7d1c + d05e4c8 commit bb97be2

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

44 files changed

+838
-611
lines changed

Documentation/devicetree/bindings/iommu/nvidia,tegra20-gart.txt

Lines changed: 0 additions & 14 deletions
This file was deleted.
Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,37 @@
11
NVIDIA Tegra20 MC(Memory Controller)
22

33
Required properties:
4-
- compatible : "nvidia,tegra20-mc"
5-
- reg : Should contain 2 register ranges(address and length); see the
6-
example below. Note that the MC registers are interleaved with the
7-
GART registers, and hence must be represented as multiple ranges.
4+
- compatible : "nvidia,tegra20-mc-gart"
5+
- reg : Should contain 2 register ranges: physical base address and length of
6+
the controller's registers and the GART aperture respectively.
7+
- clocks: Must contain an entry for each entry in clock-names.
8+
See ../clocks/clock-bindings.txt for details.
9+
- clock-names: Must include the following entries:
10+
- mc: the module's clock input
811
- interrupts : Should contain MC General interrupt.
912
- #reset-cells : Should be 1. This cell represents memory client module ID.
1013
The assignments may be found in header file <dt-bindings/memory/tegra20-mc.h>
1114
or in the TRM documentation.
15+
- #iommu-cells: Should be 0. This cell represents the number of cells in an
16+
IOMMU specifier needed to encode an address. GART supports only a single
17+
address space that is shared by all devices, therefore no additional
18+
information needed for the address encoding.
1219

1320
Example:
1421
mc: memory-controller@7000f000 {
15-
compatible = "nvidia,tegra20-mc";
16-
reg = <0x7000f000 0x024
17-
0x7000f03c 0x3c4>;
18-
interrupts = <0 77 0x04>;
22+
compatible = "nvidia,tegra20-mc-gart";
23+
reg = <0x7000f000 0x400 /* controller registers */
24+
0x58000000 0x02000000>; /* GART aperture */
25+
clocks = <&tegra_car TEGRA20_CLK_MC>;
26+
clock-names = "mc";
27+
interrupts = <GIC_SPI 77 0x04>;
1928
#reset-cells = <1>;
29+
#iommu-cells = <0>;
2030
};
2131

2232
video-codec@6001a000 {
2333
compatible = "nvidia,tegra20-vde";
2434
...
2535
resets = <&mc TEGRA20_MC_RESET_VDE>;
36+
iommus = <&mc>;
2637
};

MAINTAINERS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7170,6 +7170,7 @@ F: drivers/net/hyperv/
71707170
F: drivers/scsi/storvsc_drv.c
71717171
F: drivers/uio/uio_hv_generic.c
71727172
F: drivers/video/fbdev/hyperv_fb.c
7173+
F: drivers/iommu/hyperv_iommu.c
71737174
F: net/vmw_vsock/hyperv_transport.c
71747175
F: include/linux/hyperv.h
71757176
F: include/uapi/linux/hyperv.h

arch/arm/boot/dts/tegra20.dtsi

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -616,17 +616,14 @@
616616
};
617617

618618
mc: memory-controller@7000f000 {
619-
compatible = "nvidia,tegra20-mc";
620-
reg = <0x7000f000 0x024
621-
0x7000f03c 0x3c4>;
619+
compatible = "nvidia,tegra20-mc-gart";
620+
reg = <0x7000f000 0x400 /* controller registers */
621+
0x58000000 0x02000000>; /* GART aperture */
622+
clocks = <&tegra_car TEGRA20_CLK_MC>;
623+
clock-names = "mc";
622624
interrupts = <GIC_SPI 77 IRQ_TYPE_LEVEL_HIGH>;
623625
#reset-cells = <1>;
624-
};
625-
626-
iommu@7000f024 {
627-
compatible = "nvidia,tegra20-gart";
628-
reg = <0x7000f024 0x00000018 /* controller registers */
629-
0x58000000 0x02000000>; /* GART aperture */
626+
#iommu-cells = <0>;
630627
};
631628

632629
memory-controller@7000f400 {

arch/x86/kernel/cpu/mshyperv.c

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -328,6 +328,18 @@ static void __init ms_hyperv_init_platform(void)
328328
# ifdef CONFIG_SMP
329329
smp_ops.smp_prepare_boot_cpu = hv_smp_prepare_boot_cpu;
330330
# endif
331+
332+
/*
333+
* Hyper-V doesn't provide irq remapping for IO-APIC. To enable x2apic,
334+
* set x2apic destination mode to physcial mode when x2apic is available
335+
* and Hyper-V IOMMU driver makes sure cpus assigned with IO-APIC irqs
336+
* have 8-bit APIC id.
337+
*/
338+
# ifdef CONFIG_X86_X2APIC
339+
if (x2apic_supported())
340+
x2apic_phys = 1;
341+
# endif
342+
331343
#endif
332344
}
333345

drivers/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ obj-y += tty/
5656
obj-y += char/
5757

5858
# iommu/ comes before gpu as gpu are using iommu controllers
59-
obj-$(CONFIG_IOMMU_SUPPORT) += iommu/
59+
obj-y += iommu/
6060

6161
# gpu/ comes after char for AGP vs DRM startup and after iommu
6262
obj-y += gpu/

drivers/iommu/Kconfig

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
# The IOVA library may also be used by non-IOMMU_API users
2+
config IOMMU_IOVA
3+
tristate
4+
15
# IOMMU_API always gets selected by whoever wants it.
26
config IOMMU_API
37
bool
@@ -81,9 +85,6 @@ config IOMMU_DEFAULT_PASSTHROUGH
8185

8286
If unsure, say N here.
8387

84-
config IOMMU_IOVA
85-
tristate
86-
8788
config OF_IOMMU
8889
def_bool y
8990
depends on OF && IOMMU_API
@@ -282,6 +283,7 @@ config ROCKCHIP_IOMMU
282283
config TEGRA_IOMMU_GART
283284
bool "Tegra GART IOMMU Support"
284285
depends on ARCH_TEGRA_2x_SOC
286+
depends on TEGRA_MC
285287
select IOMMU_API
286288
help
287289
Enables support for remapping discontiguous physical memory
@@ -435,4 +437,13 @@ config QCOM_IOMMU
435437
help
436438
Support for IOMMU on certain Qualcomm SoCs.
437439

440+
config HYPERV_IOMMU
441+
bool "Hyper-V x2APIC IRQ Handling"
442+
depends on HYPERV
443+
select IOMMU_API
444+
default HYPERV
445+
help
446+
Stub IOMMU driver to handle IRQs as to allow Hyper-V Linux
447+
guests to run with x2APIC mode enabled.
448+
438449
endif # IOMMU_SUPPORT

drivers/iommu/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,3 +32,4 @@ obj-$(CONFIG_EXYNOS_IOMMU) += exynos-iommu.o
3232
obj-$(CONFIG_FSL_PAMU) += fsl_pamu.o fsl_pamu_domain.o
3333
obj-$(CONFIG_S390_IOMMU) += s390-iommu.o
3434
obj-$(CONFIG_QCOM_IOMMU) += qcom_iommu.o
35+
obj-$(CONFIG_HYPERV_IOMMU) += hyperv-iommu.o

drivers/iommu/amd_iommu.c

Lines changed: 13 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
*/
1919

2020
#define pr_fmt(fmt) "AMD-Vi: " fmt
21+
#define dev_fmt(fmt) pr_fmt(fmt)
2122

2223
#include <linux/ratelimit.h>
2324
#include <linux/pci.h>
@@ -279,10 +280,10 @@ static u16 get_alias(struct device *dev)
279280
return pci_alias;
280281
}
281282

282-
pr_info("Using IVRS reported alias %02x:%02x.%d "
283-
"for device %s[%04x:%04x], kernel reported alias "
283+
pci_info(pdev, "Using IVRS reported alias %02x:%02x.%d "
284+
"for device [%04x:%04x], kernel reported alias "
284285
"%02x:%02x.%d\n", PCI_BUS_NUM(ivrs_alias), PCI_SLOT(ivrs_alias),
285-
PCI_FUNC(ivrs_alias), dev_name(dev), pdev->vendor, pdev->device,
286+
PCI_FUNC(ivrs_alias), pdev->vendor, pdev->device,
286287
PCI_BUS_NUM(pci_alias), PCI_SLOT(pci_alias),
287288
PCI_FUNC(pci_alias));
288289

@@ -293,9 +294,8 @@ static u16 get_alias(struct device *dev)
293294
if (pci_alias == devid &&
294295
PCI_BUS_NUM(ivrs_alias) == pdev->bus->number) {
295296
pci_add_dma_alias(pdev, ivrs_alias & 0xff);
296-
pr_info("Added PCI DMA alias %02x.%d for %s\n",
297-
PCI_SLOT(ivrs_alias), PCI_FUNC(ivrs_alias),
298-
dev_name(dev));
297+
pci_info(pdev, "Added PCI DMA alias %02x.%d\n",
298+
PCI_SLOT(ivrs_alias), PCI_FUNC(ivrs_alias));
299299
}
300300

301301
return ivrs_alias;
@@ -545,7 +545,7 @@ static void amd_iommu_report_page_fault(u16 devid, u16 domain_id,
545545
dev_data = get_dev_data(&pdev->dev);
546546

547547
if (dev_data && __ratelimit(&dev_data->rs)) {
548-
dev_err(&pdev->dev, "Event logged [IO_PAGE_FAULT domain=0x%04x address=0x%llx flags=0x%04x]\n",
548+
pci_err(pdev, "Event logged [IO_PAGE_FAULT domain=0x%04x address=0x%llx flags=0x%04x]\n",
549549
domain_id, address, flags);
550550
} else if (printk_ratelimit()) {
551551
pr_err("Event logged [IO_PAGE_FAULT device=%02x:%02x.%x domain=0x%04x address=0x%llx flags=0x%04x]\n",
@@ -2258,8 +2258,7 @@ static int amd_iommu_add_device(struct device *dev)
22582258
ret = iommu_init_device(dev);
22592259
if (ret) {
22602260
if (ret != -ENOTSUPP)
2261-
pr_err("Failed to initialize device %s - trying to proceed anyway\n",
2262-
dev_name(dev));
2261+
dev_err(dev, "Failed to initialize - trying to proceed anyway\n");
22632262

22642263
iommu_ignore_device(dev);
22652264
dev->dma_ops = NULL;
@@ -2569,6 +2568,7 @@ static int map_sg(struct device *dev, struct scatterlist *sglist,
25692568
struct scatterlist *s;
25702569
unsigned long address;
25712570
u64 dma_mask;
2571+
int ret;
25722572

25732573
domain = get_domain(dev);
25742574
if (IS_ERR(domain))
@@ -2591,7 +2591,6 @@ static int map_sg(struct device *dev, struct scatterlist *sglist,
25912591

25922592
for (j = 0; j < pages; ++j) {
25932593
unsigned long bus_addr, phys_addr;
2594-
int ret;
25952594

25962595
bus_addr = address + s->dma_address + (j << PAGE_SHIFT);
25972596
phys_addr = (sg_phys(s) & PAGE_MASK) + (j << PAGE_SHIFT);
@@ -2612,8 +2611,8 @@ static int map_sg(struct device *dev, struct scatterlist *sglist,
26122611
return nelems;
26132612

26142613
out_unmap:
2615-
pr_err("%s: IOMMU mapping error in map_sg (io-pages: %d)\n",
2616-
dev_name(dev), npages);
2614+
dev_err(dev, "IOMMU mapping error in map_sg (io-pages: %d reason: %d)\n",
2615+
npages, ret);
26172616

26182617
for_each_sg(sglist, s, nelems, i) {
26192618
int j, pages = iommu_num_pages(sg_phys(s), s->length, PAGE_SIZE);
@@ -2807,7 +2806,7 @@ static int init_reserved_iova_ranges(void)
28072806
IOVA_PFN(r->start),
28082807
IOVA_PFN(r->end));
28092808
if (!val) {
2810-
pr_err("Reserve pci-resource range failed\n");
2809+
pci_err(pdev, "Reserve pci-resource range %pR failed\n", r);
28112810
return -ENOMEM;
28122811
}
28132812
}
@@ -3177,8 +3176,7 @@ static void amd_iommu_get_resv_regions(struct device *dev,
31773176
length, prot,
31783177
IOMMU_RESV_DIRECT);
31793178
if (!region) {
3180-
pr_err("Out of memory allocating dm-regions for %s\n",
3181-
dev_name(dev));
3179+
dev_err(dev, "Out of memory allocating dm-regions\n");
31823180
return;
31833181
}
31843182
list_add_tail(&region->list, head);

drivers/iommu/amd_iommu_init.c

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
*/
1919

2020
#define pr_fmt(fmt) "AMD-Vi: " fmt
21+
#define dev_fmt(fmt) pr_fmt(fmt)
2122

2223
#include <linux/pci.h>
2324
#include <linux/acpi.h>
@@ -1457,8 +1458,7 @@ static void amd_iommu_erratum_746_workaround(struct amd_iommu *iommu)
14571458
pci_write_config_dword(iommu->dev, 0xf0, 0x90 | (1 << 8));
14581459

14591460
pci_write_config_dword(iommu->dev, 0xf4, value | 0x4);
1460-
pr_info("Applying erratum 746 workaround for IOMMU at %s\n",
1461-
dev_name(&iommu->dev->dev));
1461+
pci_info(iommu->dev, "Applying erratum 746 workaround\n");
14621462

14631463
/* Clear the enable writing bit */
14641464
pci_write_config_dword(iommu->dev, 0xf0, 0x90);
@@ -1488,8 +1488,7 @@ static void amd_iommu_ats_write_check_workaround(struct amd_iommu *iommu)
14881488
/* Set L2_DEBUG_3[AtsIgnoreIWDis] = 1 */
14891489
iommu_write_l2(iommu, 0x47, value | BIT(0));
14901490

1491-
pr_info("Applying ATS write check workaround for IOMMU at %s\n",
1492-
dev_name(&iommu->dev->dev));
1491+
pci_info(iommu->dev, "Applying ATS write check workaround\n");
14931492
}
14941493

14951494
/*
@@ -1665,6 +1664,7 @@ static int iommu_pc_get_set_reg(struct amd_iommu *iommu, u8 bank, u8 cntr,
16651664

16661665
static void init_iommu_perf_ctr(struct amd_iommu *iommu)
16671666
{
1667+
struct pci_dev *pdev = iommu->dev;
16681668
u64 val = 0xabcd, val2 = 0;
16691669

16701670
if (!iommu_feature(iommu, FEATURE_PC))
@@ -1676,12 +1676,12 @@ static void init_iommu_perf_ctr(struct amd_iommu *iommu)
16761676
if ((iommu_pc_get_set_reg(iommu, 0, 0, 0, &val, true)) ||
16771677
(iommu_pc_get_set_reg(iommu, 0, 0, 0, &val2, false)) ||
16781678
(val != val2)) {
1679-
pr_err("Unable to write to IOMMU perf counter.\n");
1679+
pci_err(pdev, "Unable to write to IOMMU perf counter.\n");
16801680
amd_iommu_pc_present = false;
16811681
return;
16821682
}
16831683

1684-
pr_info("IOMMU performance counters supported\n");
1684+
pci_info(pdev, "IOMMU performance counters supported\n");
16851685

16861686
val = readl(iommu->mmio_base + MMIO_CNTR_CONF_OFFSET);
16871687
iommu->max_banks = (u8) ((val >> 12) & 0x3f);
@@ -1840,14 +1840,14 @@ static void print_iommu_info(void)
18401840
struct amd_iommu *iommu;
18411841

18421842
for_each_iommu(iommu) {
1843+
struct pci_dev *pdev = iommu->dev;
18431844
int i;
18441845

1845-
pr_info("Found IOMMU at %s cap 0x%hx\n",
1846-
dev_name(&iommu->dev->dev), iommu->cap_ptr);
1846+
pci_info(pdev, "Found IOMMU cap 0x%hx\n", iommu->cap_ptr);
18471847

18481848
if (iommu->cap & (1 << IOMMU_CAP_EFR)) {
1849-
pr_info("Extended features (%#llx):\n",
1850-
iommu->features);
1849+
pci_info(pdev, "Extended features (%#llx):\n",
1850+
iommu->features);
18511851
for (i = 0; i < ARRAY_SIZE(feat_str); ++i) {
18521852
if (iommu_feature(iommu, (1ULL << i)))
18531853
pr_cont(" %s", feat_str[i]);

drivers/iommu/amd_iommu_v2.c

Lines changed: 0 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -370,29 +370,6 @@ static struct pasid_state *mn_to_state(struct mmu_notifier *mn)
370370
return container_of(mn, struct pasid_state, mn);
371371
}
372372

373-
static void __mn_flush_page(struct mmu_notifier *mn,
374-
unsigned long address)
375-
{
376-
struct pasid_state *pasid_state;
377-
struct device_state *dev_state;
378-
379-
pasid_state = mn_to_state(mn);
380-
dev_state = pasid_state->device_state;
381-
382-
amd_iommu_flush_page(dev_state->domain, pasid_state->pasid, address);
383-
}
384-
385-
static int mn_clear_flush_young(struct mmu_notifier *mn,
386-
struct mm_struct *mm,
387-
unsigned long start,
388-
unsigned long end)
389-
{
390-
for (; start < end; start += PAGE_SIZE)
391-
__mn_flush_page(mn, start);
392-
393-
return 0;
394-
}
395-
396373
static void mn_invalidate_range(struct mmu_notifier *mn,
397374
struct mm_struct *mm,
398375
unsigned long start, unsigned long end)
@@ -430,7 +407,6 @@ static void mn_release(struct mmu_notifier *mn, struct mm_struct *mm)
430407

431408
static const struct mmu_notifier_ops iommu_mn = {
432409
.release = mn_release,
433-
.clear_flush_young = mn_clear_flush_young,
434410
.invalidate_range = mn_invalidate_range,
435411
};
436412

drivers/iommu/arm-smmu-v3.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#include <linux/dma-iommu.h>
1919
#include <linux/err.h>
2020
#include <linux/interrupt.h>
21+
#include <linux/io-pgtable.h>
2122
#include <linux/iommu.h>
2223
#include <linux/iopoll.h>
2324
#include <linux/init.h>
@@ -32,8 +33,6 @@
3233

3334
#include <linux/amba/bus.h>
3435

35-
#include "io-pgtable.h"
36-
3736
/* MMIO registers */
3837
#define ARM_SMMU_IDR0 0x0
3938
#define IDR0_ST_LVL GENMASK(28, 27)

0 commit comments

Comments
 (0)