Skip to content

Commit

Permalink
Merge tag 'iommu-updates-v5.14' of git://git.kernel.org/pub/scm/linux…
Browse files Browse the repository at this point in the history
…/kernel/git/joro/iommu

Pull iommu updates from Joerg Roedel:

 - SMMU Updates from Will Deacon:

     - SMMUv3:
        - Support stalling faults for platform devices
        - Decrease defaults sizes for the event and PRI queues
     - SMMUv2:
        - Support for a new '->probe_finalize' hook, needed by Nvidia
        - Even more Qualcomm compatible strings
        - Avoid Adreno TTBR1 quirk for DB820C platform

 - Intel VT-d updates from Lu Baolu:

     - Convert Intel IOMMU to use sva_lib helpers in iommu core
     - ftrace and debugfs supports for page fault handling
     - Support asynchronous nested capabilities
     - Various misc cleanups

 - Support for new VIOT ACPI table to make the VirtIO IOMMU
   available on x86

 - Add the amd_iommu=force_enable command line option to enable
   the IOMMU on platforms where they are known to cause problems

 - Support for version 2 of the Rockchip IOMMU

 - Various smaller fixes, cleanups and refactorings

* tag 'iommu-updates-v5.14' of git://git.kernel.org/pub/scm/linux/kernel/git/joro/iommu: (66 commits)
  iommu/virtio: Enable x86 support
  iommu/dma: Pass address limit rather than size to iommu_setup_dma_ops()
  ACPI: Add driver for the VIOT table
  ACPI: Move IOMMU setup code out of IORT
  ACPI: arm64: Move DMA setup operations out of IORT
  iommu/vt-d: Fix dereference of pointer info before it is null checked
  iommu: Update "iommu.strict" documentation
  iommu/arm-smmu: Check smmu->impl pointer before dereferencing
  iommu/arm-smmu-v3: Remove unnecessary oom message
  iommu/arm-smmu: Fix arm_smmu_device refcount leak in address translation
  iommu/arm-smmu: Fix arm_smmu_device refcount leak when arm_smmu_rpm_get fails
  iommu/vt-d: Fix linker error on 32-bit
  iommu/vt-d: No need to typecast
  iommu/vt-d: Define counter explicitly as unsigned int
  iommu/vt-d: Remove unnecessary braces
  iommu/vt-d: Removed unused iommu_count in dmar domain
  iommu/vt-d: Use bitfields for DMAR capabilities
  iommu/vt-d: Use DEVICE_ATTR_RO macro
  iommu/vt-d: Fix out-bounds-warning in intel/svm.c
  iommu/vt-d: Add PRQ handling latency sampling
  ...
  • Loading branch information
torvalds committed Jul 2, 2021
2 parents 35e4353 + 2b9d8e3 commit cd3eb7e
Show file tree
Hide file tree
Showing 56 changed files with 2,172 additions and 781 deletions.
9 changes: 8 additions & 1 deletion Documentation/admin-guide/kernel-parameters.txt
Original file line number Diff line number Diff line change
Expand Up @@ -301,6 +301,9 @@
allowed anymore to lift isolation
requirements as needed. This option
does not override iommu=pt
force_enable - Force enable the IOMMU on platforms known
to be buggy with IOMMU enabled. Use this
option with care.

amd_iommu_dump= [HW,X86-64]
Enable AMD IOMMU driver option to dump the ACPI table
Expand Down Expand Up @@ -2031,7 +2034,7 @@
forcing Dual Address Cycle for PCI cards supporting
greater than 32-bit addressing.

iommu.strict= [ARM64] Configure TLB invalidation behaviour
iommu.strict= [ARM64, X86] Configure TLB invalidation behaviour
Format: { "0" | "1" }
0 - Lazy mode.
Request that DMA unmap operations use deferred
Expand All @@ -2042,6 +2045,10 @@
1 - Strict mode (default).
DMA unmap operations invalidate IOMMU hardware TLBs
synchronously.
Note: on x86, the default behaviour depends on the
equivalent driver-specific parameters, but a strict
mode explicitly specified by either method takes
precedence.

iommu.passthrough=
[ARM64, X86] Configure DMA to bypass the IOMMU by default.
Expand Down
18 changes: 18 additions & 0 deletions Documentation/devicetree/bindings/iommu/iommu.txt
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,24 @@ Optional properties:
tagging DMA transactions with an address space identifier. By default,
this is 0, which means that the device only has one address space.

- dma-can-stall: When present, the master can wait for a transaction to
complete for an indefinite amount of time. Upon translation fault some
IOMMUs, instead of aborting the translation immediately, may first
notify the driver and keep the transaction in flight. This allows the OS
to inspect the fault and, for example, make physical pages resident
before updating the mappings and completing the transaction. Such IOMMU
accepts a limited number of simultaneous stalled transactions before
having to either put back-pressure on the master, or abort new faulting
transactions.

Firmware has to opt-in stalling, because most buses and masters don't
support it. In particular it isn't compatible with PCI, where
transactions have to complete before a time limit. More generally it
won't work in systems and masters that haven't been designed for
stalling. For example the OS, in order to handle a stalled transaction,
may attempt to retrieve pages from secondary storage in a stalled
domain, leading to a deadlock.


Notes:
======
Expand Down
38 changes: 0 additions & 38 deletions Documentation/devicetree/bindings/iommu/rockchip,iommu.txt

This file was deleted.

85 changes: 85 additions & 0 deletions Documentation/devicetree/bindings/iommu/rockchip,iommu.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
# SPDX-License-Identifier: GPL-2.0-only
%YAML 1.2
---
$id: http://devicetree.org/schemas/iommu/rockchip,iommu.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#

title: Rockchip IOMMU

maintainers:
- Heiko Stuebner <[email protected]>

description: |+
A Rockchip DRM iommu translates io virtual addresses to physical addresses for
its master device. Each slave device is bound to a single master device and
shares its clocks, power domain and irq.
For information on assigning IOMMU controller to its peripheral devices,
see generic IOMMU bindings.
properties:
compatible:
enum:
- rockchip,iommu
- rockchip,rk3568-iommu

reg:
items:
- description: configuration registers for MMU instance 0
- description: configuration registers for MMU instance 1
minItems: 1
maxItems: 2

interrupts:
items:
- description: interruption for MMU instance 0
- description: interruption for MMU instance 1
minItems: 1
maxItems: 2

clocks:
items:
- description: Core clock
- description: Interface clock

clock-names:
items:
- const: aclk
- const: iface

"#iommu-cells":
const: 0

power-domains:
maxItems: 1

rockchip,disable-mmu-reset:
$ref: /schemas/types.yaml#/definitions/flag
description: |
Do not use the mmu reset operation.
Some mmu instances may produce unexpected results
when the reset operation is used.
required:
- compatible
- reg
- interrupts
- clocks
- clock-names
- "#iommu-cells"

additionalProperties: false

examples:
- |
#include <dt-bindings/clock/rk3399-cru.h>
#include <dt-bindings/interrupt-controller/arm-gic.h>
vopl_mmu: iommu@ff940300 {
compatible = "rockchip,iommu";
reg = <0xff940300 0x100>;
interrupts = <GIC_SPI 16 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&cru ACLK_VOP1>, <&cru HCLK_VOP1>;
clock-names = "aclk", "iface";
#iommu-cells = <0>;
};
8 changes: 8 additions & 0 deletions MAINTAINERS
Original file line number Diff line number Diff line change
Expand Up @@ -431,6 +431,14 @@ W: https://01.org/linux-acpi
B: https://bugzilla.kernel.org
F: drivers/acpi/acpi_video.c

ACPI VIOT DRIVER
M: Jean-Philippe Brucker <[email protected]>
L: [email protected]
L: [email protected]
S: Maintained
F: drivers/acpi/viot.c
F: include/linux/acpi_viot.h

ACPI WMI DRIVER
L: [email protected]
S: Orphan
Expand Down
2 changes: 1 addition & 1 deletion arch/arm64/boot/dts/qcom/msm8996.dtsi
Original file line number Diff line number Diff line change
Expand Up @@ -1136,7 +1136,7 @@
};

adreno_smmu: iommu@b40000 {
compatible = "qcom,msm8996-smmu-v2", "qcom,smmu-v2";
compatible = "qcom,msm8996-smmu-v2", "qcom,adreno-smmu", "qcom,smmu-v2";
reg = <0x00b40000 0x10000>;

#global-interrupts = <1>;
Expand Down
2 changes: 1 addition & 1 deletion arch/arm64/mm/dma-mapping.c
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ void arch_setup_dma_ops(struct device *dev, u64 dma_base, u64 size,

dev->dma_coherent = coherent;
if (iommu)
iommu_setup_dma_ops(dev, dma_base, size);
iommu_setup_dma_ops(dev, dma_base, dma_base + size - 1);

#ifdef CONFIG_XEN
if (xen_swiotlb_detect())
Expand Down
3 changes: 3 additions & 0 deletions drivers/acpi/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -526,6 +526,9 @@ endif

source "drivers/acpi/pmic/Kconfig"

config ACPI_VIOT
bool

endif # ACPI

config X86_PM_TIMER
Expand Down
2 changes: 2 additions & 0 deletions drivers/acpi/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -124,3 +124,5 @@ video-objs += acpi_video.o video_detect.o
obj-y += dptf/

obj-$(CONFIG_ARM64) += arm64/

obj-$(CONFIG_ACPI_VIOT) += viot.o
1 change: 1 addition & 0 deletions drivers/acpi/arm64/Makefile
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# SPDX-License-Identifier: GPL-2.0-only
obj-$(CONFIG_ACPI_IORT) += iort.o
obj-$(CONFIG_ACPI_GTDT) += gtdt.o
obj-y += dma.o
50 changes: 50 additions & 0 deletions drivers/acpi/arm64/dma.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
// SPDX-License-Identifier: GPL-2.0-only
#include <linux/acpi.h>
#include <linux/acpi_iort.h>
#include <linux/device.h>
#include <linux/dma-direct.h>

void acpi_arch_dma_setup(struct device *dev, u64 *dma_addr, u64 *dma_size)
{
int ret;
u64 end, mask;
u64 dmaaddr = 0, size = 0, offset = 0;

/*
* If @dev is expected to be DMA-capable then the bus code that created
* it should have initialised its dma_mask pointer by this point. For
* now, we'll continue the legacy behaviour of coercing it to the
* coherent mask if not, but we'll no longer do so quietly.
*/
if (!dev->dma_mask) {
dev_warn(dev, "DMA mask not set\n");
dev->dma_mask = &dev->coherent_dma_mask;
}

if (dev->coherent_dma_mask)
size = max(dev->coherent_dma_mask, dev->coherent_dma_mask + 1);
else
size = 1ULL << 32;

ret = acpi_dma_get_range(dev, &dmaaddr, &offset, &size);
if (ret == -ENODEV)
ret = iort_dma_get_ranges(dev, &size);
if (!ret) {
/*
* Limit coherent and dma mask based on size retrieved from
* firmware.
*/
end = dmaaddr + size - 1;
mask = DMA_BIT_MASK(ilog2(end) + 1);
dev->bus_dma_limit = end;
dev->coherent_dma_mask = min(dev->coherent_dma_mask, mask);
*dev->dma_mask = min(*dev->dma_mask, mask);
}

*dma_addr = dmaaddr;
*dma_size = size;

ret = dma_direct_set_offset(dev, dmaaddr + offset, dmaaddr, size);

dev_dbg(dev, "dma_offset(%#08llx)%s\n", offset, ret ? " failed!" : "");
}
Loading

0 comments on commit cd3eb7e

Please sign in to comment.