Skip to content

Commit

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

Pull iommu updates from Joerg Roedel:
 "Core iommufd dependencies from Jason:
   - Change the iommufd fault handle into an always present hwpt handle
     in the domain
   - Give iommufd its own SW_MSI implementation along with some IRQ
     layer rework
   - Improvements to the handle attach API

  Core fixes for probe-issues from Robin

  Intel VT-d changes:
   - Checking for SVA support in domain allocation and attach paths
   - Move PCI ATS and PRI configuration into probe paths
   - Fix a pentential hang on reboot -f
   - Miscellaneous cleanups

  AMD-Vi changes:
   - Support for up to 2k IRQs per PCI device function
   - Set of smaller fixes

  ARM-SMMU changes:
   - SMMUv2 devicetree binding updates for Qualcomm implementations
     (QCS8300 GPU and MSM8937)
   - Clean up SMMUv2 runtime PM implementation to help with wider rework
     of pm_runtime_put_autosuspend()

  Rockchip driver changes:
   - Driver adjustments for recent DT probing changes

  S390 IOMMU changes:
   - Support for IOMMU passthrough

  Apple Dart changes:
   - Driver adjustments to meet ISP device requirements
   - Null-ptr deref fix
   - Disable subpage protection for DART 1"

* tag 'iommu-updates-v6.15' of git://git.kernel.org/pub/scm/linux/kernel/git/iommu/linux: (54 commits)
  iommu/vt-d: Fix possible circular locking dependency
  iommu/vt-d: Don't clobber posted vCPU IRTE when host IRQ affinity changes
  iommu/vt-d: Put IRTE back into posted MSI mode if vCPU posting is disabled
  iommu: apple-dart: fix potential null pointer deref
  iommu/rockchip: Retire global dma_dev workaround
  iommu/rockchip: Register in a sensible order
  iommu/rockchip: Allocate per-device data sensibly
  iommu/mediatek-v1: Support COMPILE_TEST
  iommu/amd: Enable support for up to 2K interrupts per function
  iommu/amd: Rename DTE_INTTABLEN* and MAX_IRQS_PER_TABLE macro
  iommu/amd: Replace slab cache allocator with page allocator
  iommu/amd: Introduce generic function to set multibit feature value
  iommu: Don't warn prematurely about dodgy probes
  iommu/arm-smmu: Set rpm auto_suspend once during probe
  dt-bindings: arm-smmu: Document QCS8300 GPU SMMU
  iommu: Get DT/ACPI parsing into the proper probe path
  iommu: Keep dev->iommu state consistent
  iommu: Resolve ops in iommu_init_device()
  iommu: Handle race with default domain setup
  iommu: Unexport iommu_fwspec_free()
  ...
  • Loading branch information
Linus Torvalds committed Mar 27, 2025
2 parents 2e3fcbc + 22df63a commit 336b4da
Show file tree
Hide file tree
Showing 55 changed files with 1,091 additions and 860 deletions.
3 changes: 2 additions & 1 deletion Documentation/devicetree/bindings/iommu/arm,smmu.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ properties:
- enum:
- qcom,qcm2290-smmu-500
- qcom,qcs615-smmu-500
- qcom,qcs8300-smmu-500
- qcom,sa8255p-smmu-500
- qcom,sa8775p-smmu-500
- qcom,sar2130p-smmu-500
Expand Down Expand Up @@ -397,6 +398,7 @@ allOf:
compatible:
contains:
enum:
- qcom,qcs8300-smmu-500
- qcom,sa8775p-smmu-500
- qcom,sc7280-smmu-500
- qcom,sc8280xp-smmu-500
Expand Down Expand Up @@ -581,7 +583,6 @@ allOf:
- cavium,smmu-v2
- marvell,ap806-smmu-500
- nvidia,smmu-500
- qcom,qcs8300-smmu-500
- qcom,qdu1000-smmu-500
- qcom,sa8255p-smmu-500
- qcom,sc7180-smmu-500
Expand Down
1 change: 1 addition & 0 deletions Documentation/devicetree/bindings/iommu/qcom,iommu.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ properties:
- enum:
- qcom,msm8916-iommu
- qcom,msm8917-iommu
- qcom,msm8937-iommu
- qcom,msm8953-iommu
- const: qcom,msm-iommu-v1
- items:
Expand Down
4 changes: 3 additions & 1 deletion arch/s390/include/asm/pci.h
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ struct zpci_dev {
u8 util_str_avail : 1;
u8 irqs_registered : 1;
u8 tid_avail : 1;
u8 reserved : 1;
u8 rtr_avail : 1; /* Relaxed translation allowed */
unsigned int devfn; /* DEVFN part of the RID*/

u8 pfip[CLP_PFIP_NR_SEGMENTS]; /* pci function internal path */
Expand Down Expand Up @@ -217,6 +217,7 @@ extern struct airq_iv *zpci_aif_sbv;
struct zpci_dev *zpci_create_device(u32 fid, u32 fh, enum zpci_state state);
int zpci_add_device(struct zpci_dev *zdev);
int zpci_enable_device(struct zpci_dev *);
int zpci_reenable_device(struct zpci_dev *zdev);
int zpci_disable_device(struct zpci_dev *);
int zpci_scan_configured_device(struct zpci_dev *zdev, u32 fh);
int zpci_deconfigure_device(struct zpci_dev *zdev);
Expand Down Expand Up @@ -245,6 +246,7 @@ void update_uid_checking(bool new);
/* IOMMU Interface */
int zpci_init_iommu(struct zpci_dev *zdev);
void zpci_destroy_iommu(struct zpci_dev *zdev);
int zpci_iommu_register_ioat(struct zpci_dev *zdev, u8 *status);

#ifdef CONFIG_PCI
static inline bool zpci_use_mio(struct zpci_dev *zdev)
Expand Down
4 changes: 3 additions & 1 deletion arch/s390/include/asm/pci_clp.h
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,9 @@ struct clp_rsp_query_pci_grp {
u16 : 4;
u16 noi : 12; /* number of interrupts */
u8 version;
u8 : 6;
u8 : 2;
u8 rtr : 1; /* Relaxed translation requirement */
u8 : 3;
u8 frame : 1;
u8 refresh : 1; /* TLB refresh mode */
u16 : 3;
Expand Down
17 changes: 2 additions & 15 deletions arch/s390/kvm/pci.c
Original file line number Diff line number Diff line change
Expand Up @@ -433,7 +433,6 @@ static void kvm_s390_pci_dev_release(struct zpci_dev *zdev)
static int kvm_s390_pci_register_kvm(void *opaque, struct kvm *kvm)
{
struct zpci_dev *zdev = opaque;
u8 status;
int rc;

if (!zdev)
Expand Down Expand Up @@ -480,13 +479,7 @@ static int kvm_s390_pci_register_kvm(void *opaque, struct kvm *kvm)
*/
zdev->gisa = (u32)virt_to_phys(&kvm->arch.sie_page2->gisa);

rc = zpci_enable_device(zdev);
if (rc)
goto clear_gisa;

/* Re-register the IOMMU that was already created */
rc = zpci_register_ioat(zdev, 0, zdev->start_dma, zdev->end_dma,
virt_to_phys(zdev->dma_table), &status);
rc = zpci_reenable_device(zdev);
if (rc)
goto clear_gisa;

Expand Down Expand Up @@ -516,7 +509,6 @@ static void kvm_s390_pci_unregister_kvm(void *opaque)
{
struct zpci_dev *zdev = opaque;
struct kvm *kvm;
u8 status;

if (!zdev)
return;
Expand Down Expand Up @@ -550,12 +542,7 @@ static void kvm_s390_pci_unregister_kvm(void *opaque)
goto out;
}

if (zpci_enable_device(zdev))
goto out;

/* Re-register the IOMMU that was already created */
zpci_register_ioat(zdev, 0, zdev->start_dma, zdev->end_dma,
virt_to_phys(zdev->dma_table), &status);
zpci_reenable_device(zdev);

out:
spin_lock(&kvm->arch.kzdev_list_lock);
Expand Down
35 changes: 20 additions & 15 deletions arch/s390/pci/pci.c
Original file line number Diff line number Diff line change
Expand Up @@ -124,14 +124,13 @@ int zpci_register_ioat(struct zpci_dev *zdev, u8 dmaas,
struct zpci_fib fib = {0};
u8 cc;

WARN_ON_ONCE(iota & 0x3fff);
fib.pba = base;
/* Work around off by one in ISM virt device */
if (zdev->pft == PCI_FUNC_TYPE_ISM && limit > base)
fib.pal = limit + (1 << 12);
else
fib.pal = limit;
fib.iota = iota | ZPCI_IOTA_RTTO_FLAG;
fib.iota = iota;
fib.gd = zdev->gisa;
cc = zpci_mod_fc(req, &fib, status);
if (cc)
Expand Down Expand Up @@ -690,6 +689,23 @@ int zpci_enable_device(struct zpci_dev *zdev)
}
EXPORT_SYMBOL_GPL(zpci_enable_device);

int zpci_reenable_device(struct zpci_dev *zdev)
{
u8 status;
int rc;

rc = zpci_enable_device(zdev);
if (rc)
return rc;

rc = zpci_iommu_register_ioat(zdev, &status);
if (rc)
zpci_disable_device(zdev);

return rc;
}
EXPORT_SYMBOL_GPL(zpci_reenable_device);

int zpci_disable_device(struct zpci_dev *zdev)
{
u32 fh = zdev->fh;
Expand Down Expand Up @@ -739,7 +755,6 @@ EXPORT_SYMBOL_GPL(zpci_disable_device);
*/
int zpci_hot_reset_device(struct zpci_dev *zdev)
{
u8 status;
int rc;

lockdep_assert_held(&zdev->state_lock);
Expand All @@ -758,19 +773,9 @@ int zpci_hot_reset_device(struct zpci_dev *zdev)
return rc;
}

rc = zpci_enable_device(zdev);
if (rc)
return rc;

if (zdev->dma_table)
rc = zpci_register_ioat(zdev, 0, zdev->start_dma, zdev->end_dma,
virt_to_phys(zdev->dma_table), &status);
if (rc) {
zpci_disable_device(zdev);
return rc;
}
rc = zpci_reenable_device(zdev);

return 0;
return rc;
}

/**
Expand Down
25 changes: 25 additions & 0 deletions arch/s390/pci/pci_bus.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
#include <linux/jump_label.h>
#include <linux/pci.h>
#include <linux/printk.h>
#include <linux/dma-direct.h>

#include <asm/pci_clp.h>
#include <asm/pci_dma.h>
Expand Down Expand Up @@ -283,10 +284,34 @@ static struct zpci_bus *zpci_bus_alloc(int topo, bool topo_is_tid)
return zbus;
}

static void pci_dma_range_setup(struct pci_dev *pdev)
{
struct zpci_dev *zdev = to_zpci(pdev);
struct bus_dma_region *map;
u64 aligned_end;

map = kzalloc(sizeof(*map), GFP_KERNEL);
if (!map)
return;

map->cpu_start = 0;
map->dma_start = PAGE_ALIGN(zdev->start_dma);
aligned_end = PAGE_ALIGN_DOWN(zdev->end_dma + 1);
if (aligned_end >= map->dma_start)
map->size = aligned_end - map->dma_start;
else
map->size = 0;
WARN_ON_ONCE(map->size == 0);

pdev->dev.dma_range_map = map;
}

void pcibios_bus_add_device(struct pci_dev *pdev)
{
struct zpci_dev *zdev = to_zpci(pdev);

pci_dma_range_setup(pdev);

/*
* With pdev->no_vf_scan the common PCI probing code does not
* perform PF/VF linking.
Expand Down
1 change: 1 addition & 0 deletions arch/s390/pci/pci_clp.c
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,7 @@ static void clp_store_query_pci_fngrp(struct zpci_dev *zdev,
zdev->version = response->version;
zdev->maxstbl = response->maxstbl;
zdev->dtsm = response->dtsm;
zdev->rtr_avail = response->rtr;

switch (response->version) {
case 1:
Expand Down
11 changes: 1 addition & 10 deletions arch/s390/pci/pci_sysfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,6 @@ static DEVICE_ATTR_RO(mio_enabled);

static int _do_recover(struct pci_dev *pdev, struct zpci_dev *zdev)
{
u8 status;
int ret;

pci_stop_and_remove_bus_device(pdev);
Expand All @@ -70,16 +69,8 @@ static int _do_recover(struct pci_dev *pdev, struct zpci_dev *zdev)
return ret;
}

ret = zpci_enable_device(zdev);
if (ret)
return ret;
ret = zpci_reenable_device(zdev);

if (zdev->dma_table) {
ret = zpci_register_ioat(zdev, 0, zdev->start_dma, zdev->end_dma,
virt_to_phys(zdev->dma_table), &status);
if (ret)
zpci_disable_device(zdev);
}
return ret;
}

Expand Down
5 changes: 5 additions & 0 deletions drivers/acpi/arm64/dma.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,11 @@ void acpi_arch_dma_setup(struct device *dev)
else
end = (1ULL << 32) - 1;

if (dev->dma_range_map) {
dev_dbg(dev, "dma_range_map already set\n");
return;
}

ret = acpi_dma_get_range(dev, &map);
if (!ret && map) {
end = dma_range_map_max(map);
Expand Down
7 changes: 0 additions & 7 deletions drivers/acpi/scan.c
Original file line number Diff line number Diff line change
Expand Up @@ -1632,13 +1632,6 @@ static int acpi_iommu_configure_id(struct device *dev, const u32 *id_in)
err = viot_iommu_configure(dev);
mutex_unlock(&iommu_probe_device_lock);

/*
* If we have reason to believe the IOMMU driver missed the initial
* iommu_probe_device() call for dev, replay it to get things in order.
*/
if (!err && dev->bus)
err = iommu_probe_device(dev);

return err;
}

Expand Down
3 changes: 2 additions & 1 deletion drivers/amba/bus.c
Original file line number Diff line number Diff line change
Expand Up @@ -364,7 +364,8 @@ static int amba_dma_configure(struct device *dev)
ret = acpi_dma_configure(dev, attr);
}

if (!ret && !drv->driver_managed_dma) {
/* @drv may not be valid when we're called from the IOMMU layer */
if (!ret && dev->driver && !drv->driver_managed_dma) {
ret = iommu_device_use_default_domain(dev);
if (ret)
arch_teardown_dma_ops(dev);
Expand Down
3 changes: 2 additions & 1 deletion drivers/base/platform.c
Original file line number Diff line number Diff line change
Expand Up @@ -1451,7 +1451,8 @@ static int platform_dma_configure(struct device *dev)
attr = acpi_get_dma_attr(to_acpi_device_node(fwnode));
ret = acpi_dma_configure(dev, attr);
}
if (ret || drv->driver_managed_dma)
/* @drv may not be valid when we're called from the IOMMU layer */
if (ret || !dev->driver || drv->driver_managed_dma)
return ret;

ret = iommu_device_use_default_domain(dev);
Expand Down
3 changes: 2 additions & 1 deletion drivers/bus/fsl-mc/fsl-mc-bus.c
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,8 @@ static int fsl_mc_dma_configure(struct device *dev)
else
ret = acpi_dma_configure_id(dev, DEV_DMA_COHERENT, &input_id);

if (!ret && !mc_drv->driver_managed_dma) {
/* @mc_drv may not be valid when we're called from the IOMMU layer */
if (!ret && dev->driver && !mc_drv->driver_managed_dma) {
ret = iommu_device_use_default_domain(dev);
if (ret)
arch_teardown_dma_ops(dev);
Expand Down
3 changes: 2 additions & 1 deletion drivers/cdx/cdx.c
Original file line number Diff line number Diff line change
Expand Up @@ -360,7 +360,8 @@ static int cdx_dma_configure(struct device *dev)
return ret;
}

if (!ret && !cdx_drv->driver_managed_dma) {
/* @cdx_drv may not be valid when we're called from the IOMMU layer */
if (!ret && dev->driver && !cdx_drv->driver_managed_dma) {
ret = iommu_device_use_default_domain(dev);
if (ret)
arch_teardown_dma_ops(dev);
Expand Down
4 changes: 1 addition & 3 deletions drivers/iommu/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,6 @@ config IOMMU_DMA
select DMA_OPS_HELPERS
select IOMMU_API
select IOMMU_IOVA
select IRQ_MSI_IOMMU
select NEED_SG_DMA_LENGTH
select NEED_SG_DMA_FLAGS if SWIOTLB

Expand Down Expand Up @@ -483,8 +482,7 @@ config MTK_IOMMU

config MTK_IOMMU_V1
tristate "MediaTek IOMMU Version 1 (M4U gen1) Support"
depends on ARM
depends on ARCH_MEDIATEK || COMPILE_TEST
depends on (ARCH_MEDIATEK && ARM) || COMPILE_TEST
select ARM_DMA_USE_IOMMU
select IOMMU_API
select MEMORY
Expand Down
8 changes: 3 additions & 5 deletions drivers/iommu/amd/amd_iommu.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,6 @@ extern unsigned long amd_iommu_pgsize_bitmap;
/* Protection domain ops */
void amd_iommu_init_identity_domain(void);
struct protection_domain *protection_domain_alloc(void);
void protection_domain_free(struct protection_domain *domain);
struct iommu_domain *amd_iommu_domain_alloc_sva(struct device *dev,
struct mm_struct *mm);
void amd_iommu_domain_free(struct iommu_domain *dom);
Expand Down Expand Up @@ -176,12 +175,11 @@ void amd_iommu_apply_ivrs_quirks(void);
#else
static inline void amd_iommu_apply_ivrs_quirks(void) { }
#endif
struct dev_table_entry *amd_iommu_get_ivhd_dte_flags(u16 segid, u16 devid);

void amd_iommu_domain_set_pgtable(struct protection_domain *domain,
u64 *root, int mode);
struct dev_table_entry *get_dev_table(struct amd_iommu *iommu);

#endif

struct dev_table_entry *amd_iommu_get_ivhd_dte_flags(u16 segid, u16 devid);
struct iommu_dev_data *search_dev_data(struct amd_iommu *iommu, u16 devid);

#endif /* AMD_IOMMU_H */
Loading

0 comments on commit 336b4da

Please sign in to comment.