Skip to content

Commit

Permalink
Merge branches 'iommu/fixes', 'arm/mediatek', 'arm/smmu', 'arm/exynos…
Browse files Browse the repository at this point in the history
…', 'unisoc', 'x86/vt-d', 'x86/amd' and 'core' into next
  • Loading branch information
joergroedel committed Apr 16, 2021
9 parents d434405 + 3431c3f + ac304c0 + fe99782 + d0272ea + a56af06 + 38c527a + 304c73b + 84b6269 commit 49d1152
Show file tree
Hide file tree
Showing 53 changed files with 2,073 additions and 2,141 deletions.
15 changes: 8 additions & 7 deletions Documentation/admin-guide/kernel-parameters.txt
Original file line number Diff line number Diff line change
Expand Up @@ -1869,13 +1869,6 @@
bypassed by not enabling DMAR with this option. In
this case, gfx device will use physical address for
DMA.
forcedac [X86-64]
With this option iommu will not optimize to look
for io virtual address below 32-bit forcing dual
address cycle on pci bus for cards supporting greater
than 32-bit addressing. The default is to look
for translation below 32-bit and if not available
then look in the higher range.
strict [Default Off]
With this option on every unmap_single operation will
result in a hardware IOTLB flush operation as opposed
Expand Down Expand Up @@ -1964,6 +1957,14 @@
nobypass [PPC/POWERNV]
Disable IOMMU bypass, using IOMMU for PCI devices.

iommu.forcedac= [ARM64, X86] Control IOVA allocation for PCI devices.
Format: { "0" | "1" }
0 - Try to allocate a 32-bit DMA address first, before
falling back to the full range if needed.
1 - Allocate directly from the full usable range,
forcing Dual Address Cycle for PCI cards supporting
greater than 32-bit addressing.

iommu.strict= [ARM64] Configure TLB invalidation behaviour
Format: { "0" | "1" }
0 - Lazy mode.
Expand Down
1 change: 1 addition & 0 deletions Documentation/devicetree/bindings/iommu/arm,smmu.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ properties:
items:
- enum:
- qcom,sc7180-smmu-500
- qcom,sc7280-smmu-500
- qcom,sc8180x-smmu-500
- qcom,sdm845-smmu-500
- qcom,sm8150-smmu-500
Expand Down
57 changes: 57 additions & 0 deletions Documentation/devicetree/bindings/iommu/sprd,iommu.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
# Copyright 2020 Unisoc Inc.
%YAML 1.2
---
$id: http://devicetree.org/schemas/iommu/sprd,iommu.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#

title: Unisoc IOMMU and Multi-media MMU

maintainers:
- Chunyan Zhang <[email protected]>

properties:
compatible:
enum:
- sprd,iommu-v1

"#iommu-cells":
const: 0
description:
Unisoc IOMMUs are all single-master IOMMU devices, therefore no
additional information needs to associate with its master device.
Please refer to the generic bindings document for more details,
Documentation/devicetree/bindings/iommu/iommu.txt

reg:
maxItems: 1

clocks:
description:
Reference to a gate clock phandle, since access to some of IOMMUs are
controlled by gate clock, but this is not required.

required:
- compatible
- reg
- "#iommu-cells"

additionalProperties: false

examples:
- |
iommu_disp: iommu@63000800 {
compatible = "sprd,iommu-v1";
reg = <0x63000800 0x80>;
#iommu-cells = <0>;
};
- |
iommu_jpg: iommu@62300300 {
compatible = "sprd,iommu-v1";
reg = <0x62300300 0x80>;
#iommu-cells = <0>;
clocks = <&mm_gate 1>;
};
...
12 changes: 3 additions & 9 deletions arch/powerpc/include/asm/fsl_pamu_stash.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,21 +7,15 @@
#ifndef __FSL_PAMU_STASH_H
#define __FSL_PAMU_STASH_H

struct iommu_domain;

/* cache stash targets */
enum pamu_stash_target {
PAMU_ATTR_CACHE_L1 = 1,
PAMU_ATTR_CACHE_L2,
PAMU_ATTR_CACHE_L3,
};

/*
* This attribute allows configuring stashig specific parameters
* in the PAMU hardware.
*/

struct pamu_stash_attribute {
u32 cpu; /* cpu number */
u32 cache; /* cache to stash to: L1,L2,L3 */
};
int fsl_pamu_configure_l1_stash(struct iommu_domain *domain, u32 cpu);

#endif /* __FSL_PAMU_STASH_H */
1 change: 1 addition & 0 deletions arch/x86/events/amd/iommu.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
#include <linux/init.h>
#include <linux/cpumask.h>
#include <linux/slab.h>
#include <linux/amd-iommu.h>

#include "../perf_event.h"
#include "iommu.h"
Expand Down
19 changes: 0 additions & 19 deletions arch/x86/events/amd/iommu.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,23 +21,4 @@
#define PC_MAX_SPEC_BNKS 64
#define PC_MAX_SPEC_CNTRS 16

struct amd_iommu;

/* amd_iommu_init.c external support functions */
extern int amd_iommu_get_num_iommus(void);

extern bool amd_iommu_pc_supported(void);

extern u8 amd_iommu_pc_get_max_banks(unsigned int idx);

extern u8 amd_iommu_pc_get_max_counters(unsigned int idx);

extern int amd_iommu_pc_set_reg(struct amd_iommu *iommu, u8 bank, u8 cntr,
u8 fxn, u64 *value);

extern int amd_iommu_pc_get_reg(struct amd_iommu *iommu, u8 bank, u8 cntr,
u8 fxn, u64 *value);

extern struct amd_iommu *get_amd_iommu(int idx);

#endif /*_PERF_EVENT_AMD_IOMMU_H_*/
13 changes: 7 additions & 6 deletions drivers/acpi/arm64/iort.c
Original file line number Diff line number Diff line change
Expand Up @@ -968,15 +968,16 @@ static int iort_pci_iommu_init(struct pci_dev *pdev, u16 alias, void *data)
static void iort_named_component_init(struct device *dev,
struct acpi_iort_node *node)
{
struct property_entry props[2] = {};
struct acpi_iort_named_component *nc;
struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev);

if (!fwspec)
return;

nc = (struct acpi_iort_named_component *)node->node_data;
fwspec->num_pasid_bits = FIELD_GET(ACPI_IORT_NC_PASID_BITS,
nc->node_flags);
props[0] = PROPERTY_ENTRY_U32("pasid-num-bits",
FIELD_GET(ACPI_IORT_NC_PASID_BITS,
nc->node_flags));

if (device_add_properties(dev, props))
dev_warn(dev, "Could not add device properties\n");
}

static int iort_nc_iommu_map(struct device *dev, struct acpi_iort_node *node)
Expand Down
4 changes: 0 additions & 4 deletions drivers/gpu/drm/amd/amdkfd/kfd_iommu.c
Original file line number Diff line number Diff line change
Expand Up @@ -329,10 +329,6 @@ int kfd_iommu_resume(struct kfd_dev *kfd)
return 0;
}

extern bool amd_iommu_pc_supported(void);
extern u8 amd_iommu_pc_get_max_banks(u16 devid);
extern u8 amd_iommu_pc_get_max_counters(u16 devid);

/** kfd_iommu_add_perf_counters - Add IOMMU performance counters to topology
*/
int kfd_iommu_add_perf_counters(struct kfd_topology_device *kdev)
Expand Down
5 changes: 1 addition & 4 deletions drivers/gpu/drm/msm/adreno/adreno_gpu.c
Original file line number Diff line number Diff line change
Expand Up @@ -188,10 +188,7 @@ int adreno_zap_shader_load(struct msm_gpu *gpu, u32 pasid)

void adreno_set_llc_attributes(struct iommu_domain *iommu)
{
struct io_pgtable_domain_attr pgtbl_cfg;

pgtbl_cfg.quirks = IO_PGTABLE_QUIRK_ARM_OUTER_WBWA;
iommu_domain_set_attr(iommu, DOMAIN_ATTR_IO_PGTABLE_CFG, &pgtbl_cfg);
iommu_set_pgtable_quirks(iommu, IO_PGTABLE_QUIRK_ARM_OUTER_WBWA);
}

struct msm_gem_address_space *
Expand Down
16 changes: 14 additions & 2 deletions drivers/iommu/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -349,7 +349,7 @@ config S390_AP_IOMMU
is not implemented as it is not necessary for VFIO.

config MTK_IOMMU
bool "MTK IOMMU Support"
tristate "MediaTek IOMMU Support"
depends on ARCH_MEDIATEK || COMPILE_TEST
select ARM_DMA_USE_IOMMU
select IOMMU_API
Expand All @@ -364,7 +364,7 @@ config MTK_IOMMU
If unsure, say N here.

config MTK_IOMMU_V1
bool "MTK IOMMU Version 1 (M4U gen1) Support"
tristate "MediaTek IOMMU Version 1 (M4U gen1) Support"
depends on ARM
depends on ARCH_MEDIATEK || COMPILE_TEST
select ARM_DMA_USE_IOMMU
Expand Down Expand Up @@ -408,4 +408,16 @@ config VIRTIO_IOMMU

Say Y here if you intend to run this kernel as a guest.

config SPRD_IOMMU
tristate "Unisoc IOMMU Support"
depends on ARCH_SPRD || COMPILE_TEST
select IOMMU_API
help
Support for IOMMU on Unisoc's SoCs, this IOMMU can be used by
Unisoc's multimedia devices, such as display, Image codec(jpeg)
and a few signal processors, including VSP(video), GSP(graphic),
ISP(image), and CPP(camera pixel processor), etc.

Say Y here if you want to use the multimedia devices listed above.

endif # IOMMU_SUPPORT
3 changes: 2 additions & 1 deletion drivers/iommu/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,5 @@ obj-$(CONFIG_FSL_PAMU) += fsl_pamu.o fsl_pamu_domain.o
obj-$(CONFIG_S390_IOMMU) += s390-iommu.o
obj-$(CONFIG_HYPERV_IOMMU) += hyperv-iommu.o
obj-$(CONFIG_VIRTIO_IOMMU) += virtio-iommu.o
obj-$(CONFIG_IOMMU_SVA_LIB) += iommu-sva-lib.o
obj-$(CONFIG_IOMMU_SVA_LIB) += iommu-sva-lib.o io-pgfault.o
obj-$(CONFIG_SPRD_IOMMU) += sprd-iommu.o
2 changes: 0 additions & 2 deletions drivers/iommu/amd/amd_iommu.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@

#include "amd_iommu_types.h"

extern int amd_iommu_get_num_iommus(void);
extern int amd_iommu_init_dma_ops(void);
extern int amd_iommu_init_passthrough(void);
extern irqreturn_t amd_iommu_int_thread(int irq, void *data);
Expand Down Expand Up @@ -65,7 +64,6 @@ extern int amd_iommu_flush_tlb(struct iommu_domain *dom, u32 pasid);
extern int amd_iommu_domain_set_gcr3(struct iommu_domain *dom, u32 pasid,
unsigned long cr3);
extern int amd_iommu_domain_clear_gcr3(struct iommu_domain *dom, u32 pasid);
extern struct iommu_domain *amd_iommu_get_v2_domain(struct pci_dev *pdev);

#ifdef CONFIG_IRQ_REMAP
extern int amd_iommu_create_irq_domain(struct amd_iommu *iommu);
Expand Down
1 change: 0 additions & 1 deletion drivers/iommu/amd/amd_iommu_types.h
Original file line number Diff line number Diff line change
Expand Up @@ -693,7 +693,6 @@ struct iommu_dev_data {
} ats; /* ATS state */
bool pri_tlp; /* PASID TLB required for
PPR completions */
u32 errata; /* Bitmap for errata to apply */
bool use_vapic; /* Enable device to use vapic mode */
bool defer_attach;

Expand Down
56 changes: 3 additions & 53 deletions drivers/iommu/amd/init.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
#include <linux/acpi.h>
#include <linux/list.h>
#include <linux/bitmap.h>
#include <linux/delay.h>
#include <linux/slab.h>
#include <linux/syscore_ops.h>
#include <linux/interrupt.h>
Expand Down Expand Up @@ -208,7 +207,6 @@ u16 *amd_iommu_alias_table;
* for a specific device. It is also indexed by the PCI device id.
*/
struct amd_iommu **amd_iommu_rlookup_table;
EXPORT_SYMBOL(amd_iommu_rlookup_table);

/*
* This table is used to find the irq remapping table for a given device id
Expand Down Expand Up @@ -257,8 +255,6 @@ static enum iommu_init_state init_state = IOMMU_START_STATE;
static int amd_iommu_enable_interrupts(void);
static int __init iommu_go_to_state(enum iommu_init_state state);
static void init_device_table_dma(void);
static int iommu_pc_get_set_reg(struct amd_iommu *iommu, u8 bank, u8 cntr,
u8 fxn, u64 *value, bool is_write);

static bool amd_iommu_pre_enabled = true;

Expand All @@ -268,7 +264,6 @@ bool translation_pre_enabled(struct amd_iommu *iommu)
{
return (iommu->flags & AMD_IOMMU_FLAG_TRANS_PRE_ENABLED);
}
EXPORT_SYMBOL(translation_pre_enabled);

static void clear_translation_pre_enabled(struct amd_iommu *iommu)
{
Expand Down Expand Up @@ -1717,65 +1712,23 @@ static int __init init_iommu_all(struct acpi_table_header *table)
return 0;
}

static void __init init_iommu_perf_ctr(struct amd_iommu *iommu)
static void init_iommu_perf_ctr(struct amd_iommu *iommu)
{
int retry;
u64 val;
struct pci_dev *pdev = iommu->dev;
u64 val = 0xabcd, val2 = 0, save_reg, save_src;

if (!iommu_feature(iommu, FEATURE_PC))
return;

amd_iommu_pc_present = true;

/* save the value to restore, if writable */
if (iommu_pc_get_set_reg(iommu, 0, 0, 0, &save_reg, false) ||
iommu_pc_get_set_reg(iommu, 0, 0, 8, &save_src, false))
goto pc_false;

/*
* Disable power gating by programing the performance counter
* source to 20 (i.e. counts the reads and writes from/to IOMMU
* Reserved Register [MMIO Offset 1FF8h] that are ignored.),
* which never get incremented during this init phase.
* (Note: The event is also deprecated.)
*/
val = 20;
if (iommu_pc_get_set_reg(iommu, 0, 0, 8, &val, true))
goto pc_false;

/* Check if the performance counters can be written to */
val = 0xabcd;
for (retry = 5; retry; retry--) {
if (iommu_pc_get_set_reg(iommu, 0, 0, 0, &val, true) ||
iommu_pc_get_set_reg(iommu, 0, 0, 0, &val2, false) ||
val2)
break;

/* Wait about 20 msec for power gating to disable and retry. */
msleep(20);
}

/* restore */
if (iommu_pc_get_set_reg(iommu, 0, 0, 0, &save_reg, true) ||
iommu_pc_get_set_reg(iommu, 0, 0, 8, &save_src, true))
goto pc_false;

if (val != val2)
goto pc_false;

pci_info(pdev, "IOMMU performance counters supported\n");

val = readl(iommu->mmio_base + MMIO_CNTR_CONF_OFFSET);
iommu->max_banks = (u8) ((val >> 12) & 0x3f);
iommu->max_counters = (u8) ((val >> 7) & 0xf);

return;

pc_false:
pci_err(pdev, "Unable to read/write to IOMMU perf counter.\n");
amd_iommu_pc_present = false;
return;
}

static ssize_t amd_iommu_show_cap(struct device *dev,
Expand Down Expand Up @@ -1837,7 +1790,7 @@ static void __init late_iommu_features_init(struct amd_iommu *iommu)
* IVHD and MMIO conflict.
*/
if (features != iommu->features)
pr_warn(FW_WARN "EFR mismatch. Use IVHD EFR (%#llx : %#llx\n).",
pr_warn(FW_WARN "EFR mismatch. Use IVHD EFR (%#llx : %#llx).\n",
features, iommu->features);
}

Expand Down Expand Up @@ -3277,7 +3230,6 @@ struct amd_iommu *get_amd_iommu(unsigned int idx)
return iommu;
return NULL;
}
EXPORT_SYMBOL(get_amd_iommu);

/****************************************************************************
*
Expand Down Expand Up @@ -3359,7 +3311,6 @@ int amd_iommu_pc_get_reg(struct amd_iommu *iommu, u8 bank, u8 cntr, u8 fxn, u64

return iommu_pc_get_set_reg(iommu, bank, cntr, fxn, value, false);
}
EXPORT_SYMBOL(amd_iommu_pc_get_reg);

int amd_iommu_pc_set_reg(struct amd_iommu *iommu, u8 bank, u8 cntr, u8 fxn, u64 *value)
{
Expand All @@ -3368,4 +3319,3 @@ int amd_iommu_pc_set_reg(struct amd_iommu *iommu, u8 bank, u8 cntr, u8 fxn, u64

return iommu_pc_get_set_reg(iommu, bank, cntr, fxn, value, true);
}
EXPORT_SYMBOL(amd_iommu_pc_set_reg);
Loading

0 comments on commit 49d1152

Please sign in to comment.