Skip to content

Commit

Permalink
Merge branches 'arm/smmu', 'mediatek', 's390', 'ti/omap', 'riscv' and…
Browse files Browse the repository at this point in the history
… 'core' into next
  • Loading branch information
joergroedel committed Nov 15, 2024
7 parents 2d5404c + 9af48bb + 3ab21ad + ecda483 + 95b6235 + 488ffbf + fcdb982 commit ae3325f
Show file tree
Hide file tree
Showing 34 changed files with 3,333 additions and 470 deletions.
5 changes: 5 additions & 0 deletions Documentation/devicetree/bindings/iommu/arm,smmu.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,12 @@ properties:
items:
- enum:
- qcom,qcm2290-smmu-500
- qcom,qcs615-smmu-500
- qcom,qcs8300-smmu-500
- qcom,qdu1000-smmu-500
- qcom,sa8255p-smmu-500
- qcom,sa8775p-smmu-500
- qcom,sar2130p-smmu-500
- qcom,sc7180-smmu-500
- qcom,sc7280-smmu-500
- qcom,sc8180x-smmu-500
Expand Down Expand Up @@ -88,6 +90,7 @@ properties:
- qcom,qcm2290-smmu-500
- qcom,sa8255p-smmu-500
- qcom,sa8775p-smmu-500
- qcom,sar2130p-smmu-500
- qcom,sc7280-smmu-500
- qcom,sc8180x-smmu-500
- qcom,sc8280xp-smmu-500
Expand Down Expand Up @@ -524,6 +527,7 @@ allOf:
compatible:
items:
- enum:
- qcom,sar2130p-smmu-500
- qcom,sm8550-smmu-500
- qcom,sm8650-smmu-500
- qcom,x1e80100-smmu-500
Expand Down Expand Up @@ -555,6 +559,7 @@ allOf:
- cavium,smmu-v2
- marvell,ap806-smmu-500
- nvidia,smmu-500
- qcom,qcs615-smmu-500
- qcom,qcs8300-smmu-500
- qcom,qdu1000-smmu-500
- qcom,sa8255p-smmu-500
Expand Down
147 changes: 147 additions & 0 deletions Documentation/devicetree/bindings/iommu/riscv,iommu.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/iommu/riscv,iommu.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#

title: RISC-V IOMMU Architecture Implementation

maintainers:
- Tomasz Jeznach <[email protected]>

description: |
The RISC-V IOMMU provides memory address translation and isolation for
input and output devices, supporting per-device translation context,
shared process address spaces including the ATS and PRI components of
the PCIe specification, two stage address translation and MSI remapping.
It supports identical translation table format to the RISC-V address
translation tables with page level access and protection attributes.
Hardware uses in-memory command and fault reporting queues with wired
interrupt or MSI notifications.
Visit https://github.com/riscv-non-isa/riscv-iommu for more details.
For information on assigning RISC-V IOMMU to its peripheral devices,
see generic IOMMU bindings.
properties:
# For PCIe IOMMU hardware compatible property should contain the vendor
# and device ID according to the PCI Bus Binding specification.
# Since PCI provides built-in identification methods, compatible is not
# actually required. For non-PCIe hardware implementations 'riscv,iommu'
# should be specified along with 'reg' property providing MMIO location.
compatible:
oneOf:
- items:
- enum:
- qemu,riscv-iommu
- const: riscv,iommu
- items:
- enum:
- pci1efd,edf1
- const: riscv,pci-iommu

reg:
maxItems: 1
description:
For non-PCI devices this represents base address and size of for the
IOMMU memory mapped registers interface.
For PCI IOMMU hardware implementation this should represent an address
of the IOMMU, as defined in the PCI Bus Binding reference.

'#iommu-cells':
const: 1
description:
The single cell describes the requester id emitted by a master to the
IOMMU.

interrupts:
minItems: 1
maxItems: 4
description:
Wired interrupt vectors available for RISC-V IOMMU to notify the
RISC-V HARTS. The cause to interrupt vector is software defined
using IVEC IOMMU register.

msi-parent: true

power-domains:
maxItems: 1

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

additionalProperties: false

examples:
- |+
/* Example 1 (IOMMU device with wired interrupts) */
#include <dt-bindings/interrupt-controller/irq.h>
iommu1: iommu@1bccd000 {
compatible = "qemu,riscv-iommu", "riscv,iommu";
reg = <0x1bccd000 0x1000>;
interrupt-parent = <&aplic_smode>;
interrupts = <32 IRQ_TYPE_LEVEL_HIGH>,
<33 IRQ_TYPE_LEVEL_HIGH>,
<34 IRQ_TYPE_LEVEL_HIGH>,
<35 IRQ_TYPE_LEVEL_HIGH>;
#iommu-cells = <1>;
};
/* Device with two IOMMU device IDs, 0 and 7 */
master1 {
iommus = <&iommu1 0>, <&iommu1 7>;
};
- |+
/* Example 2 (IOMMU device with shared wired interrupt) */
#include <dt-bindings/interrupt-controller/irq.h>
iommu2: iommu@1bccd000 {
compatible = "qemu,riscv-iommu", "riscv,iommu";
reg = <0x1bccd000 0x1000>;
interrupt-parent = <&aplic_smode>;
interrupts = <32 IRQ_TYPE_LEVEL_HIGH>;
#iommu-cells = <1>;
};
- |+
/* Example 3 (IOMMU device with MSIs) */
iommu3: iommu@1bcdd000 {
compatible = "qemu,riscv-iommu", "riscv,iommu";
reg = <0x1bccd000 0x1000>;
msi-parent = <&imsics_smode>;
#iommu-cells = <1>;
};
- |+
/* Example 4 (IOMMU PCIe device with MSIs) */
bus {
#address-cells = <2>;
#size-cells = <2>;
pcie@30000000 {
device_type = "pci";
#address-cells = <3>;
#size-cells = <2>;
reg = <0x0 0x30000000 0x0 0x1000000>;
ranges = <0x02000000 0x0 0x41000000 0x0 0x41000000 0x0 0x0f000000>;
/*
* The IOMMU manages all functions in this PCI domain except
* itself. Omit BDF 00:01.0.
*/
iommu-map = <0x0 &iommu0 0x0 0x8>,
<0x9 &iommu0 0x9 0xfff7>;
/* The IOMMU programming interface uses slot 00:01.0 */
iommu0: iommu@1,0 {
compatible = "pci1efd,edf1", "riscv,pci-iommu";
reg = <0x800 0 0 0 0>;
#iommu-cells = <1>;
};
};
};
9 changes: 9 additions & 0 deletions MAINTAINERS
Original file line number Diff line number Diff line change
Expand Up @@ -19810,6 +19810,15 @@ F: arch/riscv/
N: riscv
K: riscv

RISC-V IOMMU
M: Tomasz Jeznach <[email protected]>
L: [email protected]
L: [email protected]
S: Maintained
T: git git://git.kernel.org/pub/scm/linux/kernel/git/iommu/linux.git
F: Documentation/devicetree/bindings/iommu/riscv,iommu.yaml
F: drivers/iommu/riscv/

RISC-V MICROCHIP FPGA SUPPORT
M: Conor Dooley <[email protected]>
M: Daire McNamara <[email protected]>
Expand Down
4 changes: 2 additions & 2 deletions arch/s390/include/asm/pci.h
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,6 @@ struct zpci_bar_struct {
u8 size; /* order 2 exponent */
};

struct s390_domain;
struct kvm_zdev;

#define ZPCI_FUNCTIONS_PER_BUS 256
Expand Down Expand Up @@ -181,9 +180,10 @@ struct zpci_dev {
struct dentry *debugfs_dev;

/* IOMMU and passthrough */
struct s390_domain *s390_domain; /* s390 IOMMU domain data */
struct iommu_domain *s390_domain; /* attached IOMMU domain */
struct kvm_zdev *kzdev;
struct mutex kzdev_lock;
spinlock_t dom_lock; /* protect s390_domain change */
};

static inline bool zdev_enabled(struct zpci_dev *zdev)
Expand Down
3 changes: 3 additions & 0 deletions arch/s390/pci/pci.c
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,7 @@ int zpci_fmb_enable_device(struct zpci_dev *zdev)
u64 req = ZPCI_CREATE_REQ(zdev->fh, 0, ZPCI_MOD_FC_SET_MEASURE);
struct zpci_iommu_ctrs *ctrs;
struct zpci_fib fib = {0};
unsigned long flags;
u8 cc, status;

if (zdev->fmb || sizeof(*zdev->fmb) < zdev->fmb_length)
Expand All @@ -171,6 +172,7 @@ int zpci_fmb_enable_device(struct zpci_dev *zdev)
WARN_ON((u64) zdev->fmb & 0xf);

/* reset software counters */
spin_lock_irqsave(&zdev->dom_lock, flags);
ctrs = zpci_get_iommu_ctrs(zdev);
if (ctrs) {
atomic64_set(&ctrs->mapped_pages, 0);
Expand All @@ -179,6 +181,7 @@ int zpci_fmb_enable_device(struct zpci_dev *zdev)
atomic64_set(&ctrs->sync_map_rpcits, 0);
atomic64_set(&ctrs->sync_rpcits, 0);
}
spin_unlock_irqrestore(&zdev->dom_lock, flags);


fib.fmb_addr = virt_to_phys(zdev->fmb);
Expand Down
10 changes: 8 additions & 2 deletions arch/s390/pci/pci_debug.c
Original file line number Diff line number Diff line change
Expand Up @@ -71,17 +71,23 @@ static void pci_fmb_show(struct seq_file *m, char *name[], int length,

static void pci_sw_counter_show(struct seq_file *m)
{
struct zpci_iommu_ctrs *ctrs = zpci_get_iommu_ctrs(m->private);
struct zpci_dev *zdev = m->private;
struct zpci_iommu_ctrs *ctrs;
atomic64_t *counter;
unsigned long flags;
int i;

spin_lock_irqsave(&zdev->dom_lock, flags);
ctrs = zpci_get_iommu_ctrs(m->private);
if (!ctrs)
return;
goto unlock;

counter = &ctrs->mapped_pages;
for (i = 0; i < ARRAY_SIZE(pci_sw_names); i++, counter++)
seq_printf(m, "%26s:\t%llu\n", pci_sw_names[i],
atomic64_read(counter));
unlock:
spin_unlock_irqrestore(&zdev->dom_lock, flags);
}

static int pci_perf_show(struct seq_file *m, void *v)
Expand Down
4 changes: 2 additions & 2 deletions drivers/gpu/drm/nouveau/nvkm/engine/device/tegra.c
Original file line number Diff line number Diff line change
Expand Up @@ -120,8 +120,8 @@ nvkm_device_tegra_probe_iommu(struct nvkm_device_tegra *tdev)
mutex_init(&tdev->iommu.mutex);

if (device_iommu_mapped(dev)) {
tdev->iommu.domain = iommu_domain_alloc(&platform_bus_type);
if (!tdev->iommu.domain)
tdev->iommu.domain = iommu_paging_domain_alloc(dev);
if (IS_ERR(tdev->iommu.domain))
goto error;

/*
Expand Down
1 change: 1 addition & 0 deletions drivers/iommu/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,7 @@ config MSM_IOMMU
source "drivers/iommu/amd/Kconfig"
source "drivers/iommu/intel/Kconfig"
source "drivers/iommu/iommufd/Kconfig"
source "drivers/iommu/riscv/Kconfig"

config IRQ_REMAP
bool "Support for Interrupt Remapping"
Expand Down
2 changes: 1 addition & 1 deletion drivers/iommu/Makefile
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# SPDX-License-Identifier: GPL-2.0
obj-y += amd/ intel/ arm/ iommufd/
obj-y += amd/ intel/ arm/ iommufd/ riscv/
obj-$(CONFIG_IOMMU_API) += iommu.o
obj-$(CONFIG_IOMMU_API) += iommu-traces.o
obj-$(CONFIG_IOMMU_API) += iommu-sysfs.o
Expand Down
8 changes: 7 additions & 1 deletion drivers/iommu/amd/amd_iommu.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ extern int amd_iommu_gpt_level;
extern unsigned long amd_iommu_pgsize_bitmap;

/* Protection domain ops */
void amd_iommu_init_identity_domain(void);
struct protection_domain *protection_domain_alloc(unsigned int type, int nid);
void protection_domain_free(struct protection_domain *domain);
struct iommu_domain *amd_iommu_domain_alloc_sva(struct device *dev,
Expand Down Expand Up @@ -118,9 +119,14 @@ static inline bool check_feature2(u64 mask)
return (amd_iommu_efr2 & mask);
}

static inline bool amd_iommu_v2_pgtbl_supported(void)
{
return (check_feature(FEATURE_GIOSUP) && check_feature(FEATURE_GT));
}

static inline bool amd_iommu_gt_ppr_supported(void)
{
return (check_feature(FEATURE_GT) &&
return (amd_iommu_v2_pgtbl_supported() &&
check_feature(FEATURE_PPR) &&
check_feature(FEATURE_EPHSUP));
}
Expand Down
18 changes: 10 additions & 8 deletions drivers/iommu/amd/init.c
Original file line number Diff line number Diff line change
Expand Up @@ -2070,14 +2070,6 @@ static int __init iommu_init_pci(struct amd_iommu *iommu)

init_iommu_perf_ctr(iommu);

if (amd_iommu_pgtable == AMD_IOMMU_V2) {
if (!check_feature(FEATURE_GIOSUP) ||
!check_feature(FEATURE_GT)) {
pr_warn("Cannot enable v2 page table for DMA-API. Fallback to v1.\n");
amd_iommu_pgtable = AMD_IOMMU_V1;
}
}

if (is_rd890_iommu(iommu->dev)) {
int i, j;

Expand Down Expand Up @@ -2172,6 +2164,9 @@ static int __init amd_iommu_init_pci(void)
struct amd_iommu_pci_seg *pci_seg;
int ret;

/* Init global identity domain before registering IOMMU */
amd_iommu_init_identity_domain();

for_each_iommu(iommu) {
ret = iommu_init_pci(iommu);
if (ret) {
Expand Down Expand Up @@ -3091,6 +3086,13 @@ static int __init early_amd_iommu_init(void)
FIELD_GET(FEATURE_GATS, amd_iommu_efr) == GUEST_PGTABLE_5_LEVEL)
amd_iommu_gpt_level = PAGE_MODE_5_LEVEL;

if (amd_iommu_pgtable == AMD_IOMMU_V2) {
if (!amd_iommu_v2_pgtbl_supported()) {
pr_warn("Cannot enable v2 page table for DMA-API. Fallback to v1.\n");
amd_iommu_pgtable = AMD_IOMMU_V1;
}
}

/* Disable any previously enabled IOMMUs */
if (!is_kdump_kernel() || amd_iommu_disabled)
disable_iommus();
Expand Down
Loading

0 comments on commit ae3325f

Please sign in to comment.