projects/linux·commit 1d239c1e

Merge tag 'iommu-updates-v5.20-or-v6.0' of git://git.kernel.org/pub/scm/linux/kernel/git/joro/iommu

1d239c1e · Linus Torvalds <[email protected]> · 2022-08-06 10:42:38 -07:00

Pull iommu updates from Joerg Roedel:

 - The most intrusive patch is small and changes the default allocation
   policy for DMA addresses.

   Before the change the allocator tried its best to find an address in
   the first 4GB. But that lead to performance problems when that space
   gets exhaused, and since most devices are capable of 64-bit DMA these
   days, we changed it to search in the full DMA-mask range from the
   beginning.

   This change has the potential to uncover bugs elsewhere, in the
   kernel or the hardware. There is a Kconfig option and a command line
   option to restore the old behavior, but none of them is enabled by
   default.

 - Add Robin Murphy as reviewer of IOMMU code and maintainer for the
   dma-iommu and iova code

 - Chaning IOVA magazine size from 1032 to 1024 bytes to save memory

 - Some core code cleanups and dead-code removal

 - Support for ACPI IORT RMR node

 - Support for multiple PCI domains in the AMD-Vi driver

 - ARM SMMU changes from Will Deacon:
      - Add even more Qualcomm device-tree compatible strings
      - Support dumping of IMP DEF Qualcomm registers on TLB sync
        timeout
      - Fix reference count leak on device tree node in Qualcomm driver

 - Intel VT-d driver updates from Lu Baolu:
      - Make intel-iommu.h private
      - Optimize the use of two locks
      - Extend the driver to support large-scale platforms
      - Cleanup some dead code

 - MediaTek IOMMU refactoring and support for TTBR up to 35bit

 - Basic support for Exynos SysMMU v7

 - VirtIO IOMMU driver gets a map/unmap_pages() implementation

 - Other smaller cleanups and fixes

* tag 'iommu-updates-v5.20-or-v6.0' of git://git.kernel.org/pub/scm/linux/kernel/git/joro/iommu: (116 commits)
  iommu/amd: Fix compile warning in init code
  iommu/amd: Add support for AVIC when SNP is enabled
  iommu/amd: Simplify and Consolidate Virtual APIC (AVIC) Enablement
  ACPI/IORT: Fix build error implicit-function-declaration
  drivers: iommu: fix clang -wformat warning
  iommu/arm-smmu: qcom_iommu: Add of_node_put() when breaking out of loop
  iommu/arm-smmu-qcom: Add SM6375 SMMU compatible
  dt-bindings: arm-smmu: Add compatible for Qualcomm SM6375
  MAINTAINERS: Add Robin Murphy as IOMMU SUBSYTEM reviewer
  iommu/amd: Do not support IOMMUv2 APIs when SNP is enabled
  iommu/amd: Do not support IOMMU_DOMAIN_IDENTITY after SNP is enabled
  iommu/amd: Set translation valid bit only when IO page tables are in use
  iommu/amd: Introduce function to check and enable SNP
  iommu/amd: Globally detect SNP support
  iommu/amd: Process all IVHDs before enabling IOMMU features
  iommu/amd: Introduce global variable for storing common EFR and EFR2
  iommu/amd: Introduce Support for Extended Feature 2 Register
  iommu/amd: Change macro for IOMMU control register bit shift to decimal value
  iommu/exynos: Enable default VM instance on SysMMU v7
  iommu/exynos: Add SysMMU v7 register set
  ...
Commit
1d239c1eb873c7d6c6cbc80d68330c939fd86136
Parents
75b9fcb5 · c10100a4

Merge commit. Changes below are compared with the first parent: 75b9fcb5.

Changes

59 files changed · +2521 −1484

FileStatusAddDelContent
Documentation/admin-guide/kernel-parameters.txtmodified+25−9View file
Documentation/devicetree/bindings/iommu/arm,smmu.yamlmodified+1−0View file
Documentation/devicetree/bindings/iommu/mediatek,iommu.yamlmodified+17−0View file
MAINTAINERSmodified+12−2View file
arch/x86/kernel/tboot.cmodified+0−15View file
arch/x86/kvm/x86.cmodified+0−1View file
drivers/acpi/arm64/iort.cmodified+340−20View file
drivers/char/agp/intel-gtt.cmodified+7−10View file
drivers/gpu/drm/i915/display/intel_display.cmodified+0−1View file
drivers/gpu/drm/i915/gem/i915_gem_execbuffer.cmodified+0−1View file
drivers/iommu/Kconfigmodified+36−0View file
drivers/iommu/amd/amd_iommu.hmodified+16−2View file
drivers/iommu/amd/amd_iommu_types.hmodified+128−58View file
drivers/iommu/amd/init.cmodified+607−335View file
drivers/iommu/amd/io_pgtable.cmodified+2−4View file
drivers/iommu/amd/iommu.cmodified+349−236View file
drivers/iommu/amd/iommu_v2.cmodified+29−38View file
drivers/iommu/amd/quirks.cmodified+2−2View file
drivers/iommu/apple-dart.cmodified+0−4View file
drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.cmodified+76−68View file
drivers/iommu/arm/arm-smmu/Makefilemodified+1−0View file
drivers/iommu/arm/arm-smmu/arm-smmu-qcom-debug.cadded+142−0View file
drivers/iommu/arm/arm-smmu/arm-smmu-qcom.cmodified+28−6View file
drivers/iommu/arm/arm-smmu/arm-smmu-qcom.hadded+28−0View file
drivers/iommu/arm/arm-smmu/arm-smmu.cmodified+58−15View file
drivers/iommu/arm/arm-smmu/arm-smmu.hmodified+1−0View file
drivers/iommu/arm/arm-smmu/qcom_iommu.cmodified+5−13View file
drivers/iommu/dma-iommu.cmodified+15−6View file
drivers/iommu/exynos-iommu.cmodified+136−46View file
drivers/iommu/fsl_pamu_domain.cmodified+0−5View file
drivers/iommu/intel/cap_audit.cmodified+1−1View file
drivers/iommu/intel/debugfs.cmodified+34−17View file
drivers/iommu/intel/dmar.cmodified+10−29View file
drivers/iommu/intel/iommu.cmodified+152−295View file
include/linux/intel-iommu.h → drivers/iommu/intel/iommu.hrenamed+21−14View file
drivers/iommu/intel/irq_remapping.cmodified+1−1View file
drivers/iommu/intel/pasid.cmodified+57−50View file
drivers/iommu/intel/pasid.hmodified+1−0View file
drivers/iommu/intel/perf.cmodified+1−1View file
drivers/iommu/intel/svm.cmodified+4−7View file
drivers/iommu/intel/trace.cmodified+1−1View file
include/trace/events/intel_iommu.h → drivers/iommu/intel/trace.hrenamed+6−1View file
drivers/iommu/io-pgtable-arm-v7s.cmodified+56−19View file
drivers/iommu/iommu.cmodified+19−36View file
drivers/iommu/iova.cmodified+6−1View file
drivers/iommu/msm_iommu.cmodified+1−6View file
drivers/iommu/mtk_iommu.cmodified+37−34View file
drivers/iommu/mtk_iommu_v1.cmodified+0−5View file
drivers/iommu/sprd-iommu.cmodified+0−11View file
drivers/iommu/sun50i-iommu.cmodified+0−3View file
drivers/iommu/tegra-gart.cmodified+0−5View file
drivers/iommu/tegra-smmu.cmodified+0−3View file
drivers/iommu/virtio-iommu.cmodified+15−16View file
include/linux/acpi_iort.hmodified+11−3View file
include/linux/amd-iommu.hmodified+4−0View file
include/linux/dmar.hmodified+1−5View file
include/linux/io-pgtable.hmodified+10−5View file
include/linux/iommu.hmodified+11−16View file
include/linux/tboot.hmodified+0−2View file

Only the first 600 diff lines are shown. Download the complete patch.

Documentation/admin-guide/kernel-parameters.txt

View file
diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt
index 43c31e9..22d7b51 100644
--- a/Documentation/admin-guide/kernel-parameters.txt
+++ b/Documentation/admin-guide/kernel-parameters.txt
@@ -2274,23 +2274,39 @@
ivrs_ioapic [HW,X86-64]
Provide an override to the IOAPIC-ID<->DEVICE-ID
- mapping provided in the IVRS ACPI table. For
- example, to map IOAPIC-ID decimal 10 to
- PCI device 00:14.0 write the parameter as:
+ mapping provided in the IVRS ACPI table.
+ By default, PCI segment is 0, and can be omitted.
+ For example:
+ * To map IOAPIC-ID decimal 10 to PCI device 00:14.0
+ write the parameter as:
ivrs_ioapic[10]=00:14.0
+ * To map IOAPIC-ID decimal 10 to PCI segment 0x1 and
+ PCI device 00:14.0 write the parameter as:
+ ivrs_ioapic[10]=0001:00:14.0
ivrs_hpet [HW,X86-64]
Provide an override to the HPET-ID<->DEVICE-ID
- mapping provided in the IVRS ACPI table. For
- example, to map HPET-ID decimal 0 to
- PCI device 00:14.0 write the parameter as:
+ mapping provided in the IVRS ACPI table.
+ By default, PCI segment is 0, and can be omitted.
+ For example:
+ * To map HPET-ID decimal 0 to PCI device 00:14.0
+ write the parameter as:
ivrs_hpet[0]=00:14.0
+ * To map HPET-ID decimal 10 to PCI segment 0x1 and
+ PCI device 00:14.0 write the parameter as:
+ ivrs_ioapic[10]=0001:00:14.0
ivrs_acpihid [HW,X86-64]
Provide an override to the ACPI-HID:UID<->DEVICE-ID
- mapping provided in the IVRS ACPI table. For
- example, to map UART-HID:UID AMD0020:0 to
- PCI device 00:14.5 write the parameter as:
+ mapping provided in the IVRS ACPI table.
+
+ For example, to map UART-HID:UID AMD0020:0 to
+ PCI segment 0x1 and PCI device ID 00:14.5,
+ write the parameter as:
+ ivrs_acpihid[0001:00:14.5]=AMD0020:0
+
+ By default, PCI segment is 0, and can be omitted.
+ For example, PCI device 00:14.5 write the parameter as:
ivrs_acpihid[00:14.5]=AMD0020:0
js= [HW,JOY] Analog joystick

Documentation/devicetree/bindings/iommu/arm,smmu.yaml

View file
diff --git a/Documentation/devicetree/bindings/iommu/arm,smmu.yaml b/Documentation/devicetree/bindings/iommu/arm,smmu.yaml
index 76fc2c0..9066e6d 100644
--- a/Documentation/devicetree/bindings/iommu/arm,smmu.yaml
+++ b/Documentation/devicetree/bindings/iommu/arm,smmu.yaml
@@ -42,6 +42,7 @@ properties:
- qcom,sdx55-smmu-500
- qcom,sdx65-smmu-500
- qcom,sm6350-smmu-500
+ - qcom,sm6375-smmu-500
- qcom,sm8150-smmu-500
- qcom,sm8250-smmu-500
- qcom,sm8350-smmu-500

Documentation/devicetree/bindings/iommu/mediatek,iommu.yaml

View file
diff --git a/Documentation/devicetree/bindings/iommu/mediatek,iommu.yaml b/Documentation/devicetree/bindings/iommu/mediatek,iommu.yaml
index 2ae3bba..fee0241 100644
--- a/Documentation/devicetree/bindings/iommu/mediatek,iommu.yaml
+++ b/Documentation/devicetree/bindings/iommu/mediatek,iommu.yaml
@@ -101,6 +101,10 @@ properties:
items:
- const: bclk
+ mediatek,infracfg:
+ $ref: /schemas/types.yaml#/definitions/phandle
+ description: The phandle to the mediatek infracfg syscon
+
mediatek,larbs:
$ref: /schemas/types.yaml#/definitions/phandle-array
minItems: 1
@@ -167,6 +171,18 @@ allOf:
required:
- power-domains
+ - if:
+ properties:
+ compatible:
+ contains:
+ enum:
+ - mediatek,mt2712-m4u
+ - mediatek,mt8173-m4u
+
+ then:
+ required:
+ - mediatek,infracfg
+
- if: # The IOMMUs don't have larbs.
not:
properties:
@@ -191,6 +207,7 @@ examples:
interrupts = <GIC_SPI 139 IRQ_TYPE_LEVEL_LOW>;
clocks = <&infracfg CLK_INFRA_M4U>;
clock-names = "bclk";
+ mediatek,infracfg = <&infracfg>;
mediatek,larbs = <&larb0>, <&larb1>, <&larb2>,
<&larb3>, <&larb4>, <&larb5>;
#iommu-cells = <1>;

MAINTAINERS

View file
diff --git a/MAINTAINERS b/MAINTAINERS
index 89e42cf..c8375b6 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -10233,7 +10233,6 @@ L: [email protected]
S: Supported
T: git git://git.kernel.org/pub/scm/linux/kernel/git/joro/iommu.git
F: drivers/iommu/intel/
-F: include/linux/intel-iommu.h
F: include/linux/intel-svm.h
INTEL IOP-ADMA DMA DRIVER
@@ -10605,9 +10604,20 @@ T: git git://git.kernel.org/pub/scm/fs/xfs/xfs-linux.git
F: fs/iomap/
F: include/linux/iomap.h
-IOMMU DRIVERS
+IOMMU DMA-API LAYER
+M: Robin Murphy <[email protected]>
+S: Maintained
+T: git git://git.kernel.org/pub/scm/linux/kernel/git/joro/iommu.git
+F: drivers/iommu/dma-iommu.c
+F: drivers/iommu/iova.c
+F: include/linux/dma-iommu.h
+F: include/linux/iova.h
+
+IOMMU SUBSYSTEM
M: Joerg Roedel <[email protected]>
M: Will Deacon <[email protected]>
+R: Robin Murphy <[email protected]>
S: Maintained
T: git git://git.kernel.org/pub/scm/linux/kernel/git/joro/iommu.git

arch/x86/kernel/tboot.c

View file
diff --git a/arch/x86/kernel/tboot.c b/arch/x86/kernel/tboot.c
index 0c1154a..3bacd93 100644
--- a/arch/x86/kernel/tboot.c
+++ b/arch/x86/kernel/tboot.c
@@ -6,7 +6,6 @@
* Copyright (c) 2006-2009, Intel Corporation
*/
-#include <linux/intel-iommu.h>
#include <linux/init_task.h>
#include <linux/spinlock.h>
#include <linux/export.h>
@@ -516,17 +515,3 @@ struct acpi_table_header *tboot_get_dmar_table(struct acpi_table_header *dmar_tb
return dmar_tbl;
}
-
-int tboot_force_iommu(void)
-{
- if (!tboot_enabled())
- return 0;
-
- if (no_iommu || dmar_disabled)
- pr_warn("Forcing Intel-IOMMU to enabled\n");
-
- dmar_disabled = 0;
- no_iommu = 0;
-
- return 1;
-}

arch/x86/kvm/x86.c

View file
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 33560bf..79a8a74 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -41,7 +41,6 @@
#include <linux/mman.h>
#include <linux/highmem.h>
#include <linux/iommu.h>
-#include <linux/intel-iommu.h>
#include <linux/cpufreq.h>
#include <linux/user-return-notifier.h>
#include <linux/srcu.h>

drivers/acpi/arm64/iort.c

View file
diff --git a/drivers/acpi/arm64/iort.c b/drivers/acpi/arm64/iort.c
index f2f8f05..ca2aed8 100644
--- a/drivers/acpi/arm64/iort.c
+++ b/drivers/acpi/arm64/iort.c
@@ -788,6 +788,294 @@ void acpi_configure_pmsi_domain(struct device *dev)
}
#ifdef CONFIG_IOMMU_API
+static void iort_rmr_free(struct device *dev,
+ struct iommu_resv_region *region)
+{
+ struct iommu_iort_rmr_data *rmr_data;
+
+ rmr_data = container_of(region, struct iommu_iort_rmr_data, rr);
+ kfree(rmr_data->sids);
+ kfree(rmr_data);
+}
+
+static struct iommu_iort_rmr_data *iort_rmr_alloc(
+ struct acpi_iort_rmr_desc *rmr_desc,
+ int prot, enum iommu_resv_type type,
+ u32 *sids, u32 num_sids)
+{
+ struct iommu_iort_rmr_data *rmr_data;
+ struct iommu_resv_region *region;
+ u32 *sids_copy;
+ u64 addr = rmr_desc->base_address, size = rmr_desc->length;
+
+ rmr_data = kmalloc(sizeof(*rmr_data), GFP_KERNEL);
+ if (!rmr_data)
+ return NULL;
+
+ /* Create a copy of SIDs array to associate with this rmr_data */
+ sids_copy = kmemdup(sids, num_sids * sizeof(*sids), GFP_KERNEL);
+ if (!sids_copy) {
+ kfree(rmr_data);
+ return NULL;
+ }
+ rmr_data->sids = sids_copy;
+ rmr_data->num_sids = num_sids;
+
+ if (!IS_ALIGNED(addr, SZ_64K) || !IS_ALIGNED(size, SZ_64K)) {
+ /* PAGE align base addr and size */
+ addr &= PAGE_MASK;
+ size = PAGE_ALIGN(size + offset_in_page(rmr_desc->base_address));
+
+ pr_err(FW_BUG "RMR descriptor[0x%llx - 0x%llx] not aligned to 64K, continue with [0x%llx - 0x%llx]\n",
+ rmr_desc->base_address,
+ rmr_desc->base_address + rmr_desc->length - 1,
+ addr, addr + size - 1);
+ }
+
+ region = &rmr_data->rr;
+ INIT_LIST_HEAD(&region->list);
+ region->start = addr;
+ region->length = size;
+ region->prot = prot;
+ region->type = type;
+ region->free = iort_rmr_free;
+
+ return rmr_data;
+}
+
+static void iort_rmr_desc_check_overlap(struct acpi_iort_rmr_desc *desc,
+ u32 count)
+{
+ int i, j;
+
+ for (i = 0; i < count; i++) {
+ u64 end, start = desc[i].base_address, length = desc[i].length;
+
+ if (!length) {
+ pr_err(FW_BUG "RMR descriptor[0x%llx] with zero length, continue anyway\n",
+ start);
+ continue;
+ }
+
+ end = start + length - 1;
+
+ /* Check for address overlap */
+ for (j = i + 1; j < count; j++) {
+ u64 e_start = desc[j].base_address;
+ u64 e_end = e_start + desc[j].length - 1;
+
+ if (start <= e_end && end >= e_start)
+ pr_err(FW_BUG "RMR descriptor[0x%llx - 0x%llx] overlaps, continue anyway\n",
+ start, end);
+ }
+ }
+}
+
+/*
+ * Please note, we will keep the already allocated RMR reserve
+ * regions in case of a memory allocation failure.
+ */
+static void iort_get_rmrs(struct acpi_iort_node *node,
+ struct acpi_iort_node *smmu,
+ u32 *sids, u32 num_sids,
+ struct list_head *head)
+{
+ struct acpi_iort_rmr *rmr = (struct acpi_iort_rmr *)node->node_data;
+ struct acpi_iort_rmr_desc *rmr_desc;
+ int i;
+
+ rmr_desc = ACPI_ADD_PTR(struct acpi_iort_rmr_desc, node,
+ rmr->rmr_offset);
+
+ iort_rmr_desc_check_overlap(rmr_desc, rmr->rmr_count);
+
+ for (i = 0; i < rmr->rmr_count; i++, rmr_desc++) {
+ struct iommu_iort_rmr_data *rmr_data;
+ enum iommu_resv_type type;
+ int prot = IOMMU_READ | IOMMU_WRITE;
+
+ if (rmr->flags & ACPI_IORT_RMR_REMAP_PERMITTED)
+ type = IOMMU_RESV_DIRECT_RELAXABLE;
+ else
+ type = IOMMU_RESV_DIRECT;
+
+ if (rmr->flags & ACPI_IORT_RMR_ACCESS_PRIVILEGE)
+ prot |= IOMMU_PRIV;
+
+ /* Attributes 0x00 - 0x03 represents device memory */
+ if (ACPI_IORT_RMR_ACCESS_ATTRIBUTES(rmr->flags) <=
+ ACPI_IORT_RMR_ATTR_DEVICE_GRE)
+ prot |= IOMMU_MMIO;
+ else if (ACPI_IORT_RMR_ACCESS_ATTRIBUTES(rmr->flags) ==
+ ACPI_IORT_RMR_ATTR_NORMAL_IWB_OWB)
+ prot |= IOMMU_CACHE;
+
+ rmr_data = iort_rmr_alloc(rmr_desc, prot, type,
+ sids, num_sids);
+ if (!rmr_data)
+ return;
+
+ list_add_tail(&rmr_data->rr.list, head);
+ }
+}
+
+static u32 *iort_rmr_alloc_sids(u32 *sids, u32 count, u32 id_start,
+ u32 new_count)
+{
+ u32 *new_sids;
+ u32 total_count = count + new_count;
+ int i;
+
+ new_sids = krealloc_array(sids, count + new_count,
+ sizeof(*new_sids), GFP_KERNEL);
+ if (!new_sids)
+ return NULL;
+
+ for (i = count; i < total_count; i++)
+ new_sids[i] = id_start++;
+
+ return new_sids;
+}
+
+static bool iort_rmr_has_dev(struct device *dev, u32 id_start,
+ u32 id_count)
+{
+ int i;
+ struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev);
+
+ /*
+ * Make sure the kernel has preserved the boot firmware PCIe
+ * configuration. This is required to ensure that the RMR PCIe
+ * StreamIDs are still valid (Refer: ARM DEN 0049E.d Section 3.1.1.5).
+ */
+ if (dev_is_pci(dev)) {
+ struct pci_dev *pdev = to_pci_dev(dev);
+ struct pci_host_bridge *host = pci_find_host_bridge(pdev->bus);
+
+ if (!host->preserve_config)
+ return false;
+ }
+
+ for (i = 0; i < fwspec->num_ids; i++) {
+ if (fwspec->ids[i] >= id_start &&
+ fwspec->ids[i] <= id_start + id_count)
+ return true;
+ }
+
+ return false;
+}
+
+static void iort_node_get_rmr_info(struct acpi_iort_node *node,
+ struct acpi_iort_node *iommu,
+ struct device *dev, struct list_head *head)
+{
+ struct acpi_iort_node *smmu = NULL;
+ struct acpi_iort_rmr *rmr;
+ struct acpi_iort_id_mapping *map;
+ u32 *sids = NULL;
+ u32 num_sids = 0;
+ int i;
+
+ if (!node->mapping_offset || !node->mapping_count) {
+ pr_err(FW_BUG "Invalid ID mapping, skipping RMR node %p\n",
+ node);
+ return;
+ }
+
+ rmr = (struct acpi_iort_rmr *)node->node_data;
+ if (!rmr->rmr_offset || !rmr->rmr_count)
+ return;
+
+ map = ACPI_ADD_PTR(struct acpi_iort_id_mapping, node,
+ node->mapping_offset);
+
+ /*
+ * Go through the ID mappings and see if we have a match for SMMU
+ * and dev(if !NULL). If found, get the sids for the Node.
+ * Please note, id_count is equal to the number of IDs in the
+ * range minus one.
+ */
+ for (i = 0; i < node->mapping_count; i++, map++) {
+ struct acpi_iort_node *parent;
+
+ if (!map->id_count)
+ continue;
+
+ parent = ACPI_ADD_PTR(struct acpi_iort_node, iort_table,
+ map->output_reference);
+ if (parent != iommu)
+ continue;
+
+ /* If dev is valid, check RMR node corresponds to the dev SID */
+ if (dev && !iort_rmr_has_dev(dev, map->output_base,
+ map->id_count))
+ continue;
+
+ /* Retrieve SIDs associated with the Node. */
+ sids = iort_rmr_alloc_sids(sids, num_sids, map->output_base,
+ map->id_count + 1);
+ if (!sids)
+ return;
+
+ num_sids += map->id_count + 1;
+ }
+
+ if (!sids)
+ return;
+
+ iort_get_rmrs(node, smmu, sids, num_sids, head);
+ kfree(sids);
+}
+
+static void iort_find_rmrs(struct acpi_iort_node *iommu, struct device *dev,
+ struct list_head *head)
+{
+ struct acpi_table_iort *iort;
+ struct acpi_iort_node *iort_node, *iort_end;
+ int i;
+
+ /* Only supports ARM DEN 0049E.d onwards */
+ if (iort_table->revision < 5)
+ return;
+
+ iort = (struct acpi_table_iort *)iort_table;
+
+ iort_node = ACPI_ADD_PTR(struct acpi_iort_node, iort,
+ iort->node_offset);
+ iort_end = ACPI_ADD_PTR(struct acpi_iort_node, iort,
+ iort_table->length);
+
+ for (i = 0; i < iort->node_count; i++) {
+ if (WARN_TAINT(iort_node >= iort_end, TAINT_FIRMWARE_WORKAROUND,
+ "IORT node pointer overflows, bad table!\n"))
+ return;
+
+ if (iort_node->type == ACPI_IORT_NODE_RMR)
+ iort_node_get_rmr_info(iort_node, iommu, dev, head);
+
+ iort_node = ACPI_ADD_PTR(struct acpi_iort_node, iort_node,
+ iort_node->length);
+ }
+}
+
+/*
+ * Populate the RMR list associated with a given IOMMU and dev(if provided).
+ * If dev is NULL, the function populates all the RMRs associated with the
+ * given IOMMU.
+ */
+static void iort_iommu_rmr_get_resv_regions(struct fwnode_handle *iommu_fwnode,
+ struct device *dev,
+ struct list_head *head)
+{
+ struct acpi_iort_node *iommu;
+
+ iommu = iort_get_iort_node(iommu_fwnode);
+ if (!iommu)
+ return;
+
+ iort_find_rmrs(iommu, dev, head);
+}
+
static struct acpi_iort_node *iort_get_msi_resv_iommu(struct device *dev)
{
struct acpi_iort_node *iommu;
@@ -806,27 +1094,22 @@ static struct acpi_iort_node *iort_get_msi_resv_iommu(struct device *dev)
return NULL;
}
-/**
- * iort_iommu_msi_get_resv_regions - Reserved region driver helper
- * @dev: Device from iommu_get_resv_regions()
- * @head: Reserved region list from iommu_get_resv_regions()
- *
- * Returns: Number of msi reserved regions on success (0 if platform
- * doesn't require the reservation or no associated msi regions),
- * appropriate error value otherwise. The ITS interrupt translation
- * spaces (ITS_base + SZ_64K, SZ_64K) associated with the device
- * are the msi reserved regions.
+/*
+ * Retrieve platform specific HW MSI reserve regions.
+ * The ITS interrupt translation spaces (ITS_base + SZ_64K, SZ_64K)
+ * associated with the device are the HW MSI reserved regions.
*/
-int iort_iommu_msi_get_resv_regions(struct device *dev, struct list_head *head)
+static void iort_iommu_msi_get_resv_regions(struct device *dev,
+ struct list_head *head)
{
struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev);
struct acpi_iort_its_group *its;
struct acpi_iort_node *iommu_node, *its_node = NULL;
- int i, resv = 0;
+ int i;
iommu_node = iort_get_msi_resv_iommu(dev);
if (!iommu_node)
- return 0;
+ return;
/*
* Current logic to reserve ITS regions relies on HW topologies
@@ -846,7 +1129,7 @@ int iort_iommu_msi_get_resv_regions(struct device *dev, struct list_head *head)
}
if (!its_node)
- return 0;
+ return;
/* Move to ITS specific data */
its = (struct acpi_iort_its_group *)its_node->node_data;
@@ -860,15 +1143,52 @@ int iort_iommu_msi_get_resv_regions(struct device *dev, struct list_head *head)
region = iommu_alloc_resv_region(base + SZ_64K, SZ_64K,
prot, IOMMU_RESV_MSI);
- if (region) {
+ if (region)
list_add_tail(&region->list, head);
- resv++;
- }
}
}
+}
+
+/**
+ * iort_iommu_get_resv_regions - Generic helper to retrieve reserved regions.
+ * @dev: Device from iommu_get_resv_regions()
+ * @head: Reserved region list from iommu_get_resv_regions()
+ */
+void iort_iommu_get_resv_regions(struct device *dev, struct list_head *head)
+{
+ struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev);
+
+ iort_iommu_msi_get_resv_regions(dev, head);
+ iort_iommu_rmr_get_resv_regions(fwspec->iommu_fwnode, dev, head);
+}
+
+/**
+ * iort_get_rmr_sids - Retrieve IORT RMR node reserved regions with
+ * associated StreamIDs information.
+ * @iommu_fwnode: fwnode associated with IOMMU
+ * @head: Resereved region list
+ */
+void iort_get_rmr_sids(struct fwnode_handle *iommu_fwnode,
+ struct list_head *head)
+{
+ iort_iommu_rmr_get_resv_regions(iommu_fwnode, NULL, head);
+}
+EXPORT_SYMBOL_GPL(iort_get_rmr_sids);
+
+/**
+ * iort_put_rmr_sids - Free memory allocated for RMR reserved regions.
+ * @iommu_fwnode: fwnode associated with IOMMU
+ * @head: Resereved region list
+ */
+void iort_put_rmr_sids(struct fwnode_handle *iommu_fwnode,
+ struct list_head *head)
+{
+ struct iommu_resv_region *entry, *next;
- return (resv == its->its_count) ? resv : -ENODEV;
+ list_for_each_entry_safe(entry, next, head, list)
+ entry->free(NULL, entry);
}
+EXPORT_SYMBOL_GPL(iort_put_rmr_sids);
static inline bool iort_iommu_driver_enabled(u8 type)
{
@@ -1034,8 +1354,8 @@ int iort_iommu_configure_id(struct device *dev, const u32 *id_in)
}
#else
-int iort_iommu_msi_get_resv_regions(struct device *dev, struct list_head *head)
-{ return 0; }
+void iort_iommu_get_resv_regions(struct device *dev, struct list_head *head)
+{ }
int iort_iommu_configure_id(struct device *dev, const u32 *input_id)
{ return -ENODEV; }
#endif

drivers/char/agp/intel-gtt.c

View file
diff --git a/drivers/char/agp/intel-gtt.c b/drivers/char/agp/intel-gtt.c
index fe7e210..bf6716f 100644
--- a/drivers/char/agp/intel-gtt.c
+++ b/drivers/char/agp/intel-gtt.c
@@ -20,7 +20,7 @@

This diff is incomplete. Download the complete patch.

drivers/gpu/drm/i915/display/intel_display.c

View file

This diff is incomplete. Download the complete patch.

drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c

View file

This diff is incomplete. Download the complete patch.

drivers/iommu/Kconfig

View file

This diff is incomplete. Download the complete patch.

drivers/iommu/amd/amd_iommu.h

View file

This diff is incomplete. Download the complete patch.

drivers/iommu/amd/amd_iommu_types.h

View file

This diff is incomplete. Download the complete patch.

drivers/iommu/amd/init.c

View file

This diff is incomplete. Download the complete patch.

drivers/iommu/amd/io_pgtable.c

View file

This diff is incomplete. Download the complete patch.

drivers/iommu/amd/iommu.c

View file

This diff is incomplete. Download the complete patch.

drivers/iommu/amd/iommu_v2.c

View file

This diff is incomplete. Download the complete patch.

drivers/iommu/amd/quirks.c

View file

This diff is incomplete. Download the complete patch.

drivers/iommu/apple-dart.c

View file

This diff is incomplete. Download the complete patch.

drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c

View file

This diff is incomplete. Download the complete patch.

drivers/iommu/arm/arm-smmu/Makefile

View file

This diff is incomplete. Download the complete patch.

drivers/iommu/arm/arm-smmu/arm-smmu-qcom-debug.c

View file

This diff is incomplete. Download the complete patch.

drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c

View file

This diff is incomplete. Download the complete patch.

drivers/iommu/arm/arm-smmu/arm-smmu-qcom.h

View file

This diff is incomplete. Download the complete patch.

drivers/iommu/arm/arm-smmu/arm-smmu.c

View file

This diff is incomplete. Download the complete patch.

drivers/iommu/arm/arm-smmu/arm-smmu.h

View file

This diff is incomplete. Download the complete patch.

drivers/iommu/arm/arm-smmu/qcom_iommu.c

View file

This diff is incomplete. Download the complete patch.

drivers/iommu/dma-iommu.c

View file

This diff is incomplete. Download the complete patch.

drivers/iommu/exynos-iommu.c

View file

This diff is incomplete. Download the complete patch.

drivers/iommu/fsl_pamu_domain.c

View file

This diff is incomplete. Download the complete patch.

drivers/iommu/intel/cap_audit.c

View file

This diff is incomplete. Download the complete patch.

drivers/iommu/intel/debugfs.c

View file

This diff is incomplete. Download the complete patch.

drivers/iommu/intel/dmar.c

View file

This diff is incomplete. Download the complete patch.

drivers/iommu/intel/iommu.c

View file

This diff is incomplete. Download the complete patch.

drivers/iommu/intel/iommu.h

View file

This diff is incomplete. Download the complete patch.

drivers/iommu/intel/irq_remapping.c

View file

This diff is incomplete. Download the complete patch.

drivers/iommu/intel/pasid.c

View file

This diff is incomplete. Download the complete patch.

drivers/iommu/intel/pasid.h

View file

This diff is incomplete. Download the complete patch.

drivers/iommu/intel/perf.c

View file

This diff is incomplete. Download the complete patch.

drivers/iommu/intel/svm.c

View file

This diff is incomplete. Download the complete patch.

drivers/iommu/intel/trace.c

View file

This diff is incomplete. Download the complete patch.

drivers/iommu/intel/trace.h

View file

This diff is incomplete. Download the complete patch.

drivers/iommu/io-pgtable-arm-v7s.c

View file

This diff is incomplete. Download the complete patch.

drivers/iommu/iommu.c

View file

This diff is incomplete. Download the complete patch.

drivers/iommu/iova.c

View file

This diff is incomplete. Download the complete patch.

drivers/iommu/msm_iommu.c

View file

This diff is incomplete. Download the complete patch.

drivers/iommu/mtk_iommu.c

View file

This diff is incomplete. Download the complete patch.

drivers/iommu/mtk_iommu_v1.c

View file

This diff is incomplete. Download the complete patch.

drivers/iommu/sprd-iommu.c

View file

This diff is incomplete. Download the complete patch.

drivers/iommu/sun50i-iommu.c

View file

This diff is incomplete. Download the complete patch.

drivers/iommu/tegra-gart.c

View file

This diff is incomplete. Download the complete patch.

drivers/iommu/tegra-smmu.c

View file

This diff is incomplete. Download the complete patch.

drivers/iommu/virtio-iommu.c

View file

This diff is incomplete. Download the complete patch.

include/linux/acpi_iort.h

View file

This diff is incomplete. Download the complete patch.

include/linux/amd-iommu.h

View file

This diff is incomplete. Download the complete patch.

include/linux/dmar.h

View file

This diff is incomplete. Download the complete patch.

include/linux/io-pgtable.h

View file

This diff is incomplete. Download the complete patch.

include/linux/iommu.h

View file

This diff is incomplete. Download the complete patch.

include/linux/tboot.h

View file

This diff is incomplete. Download the complete patch.