2020-06-25 13:11:01

by Joerg Roedel

[permalink] [raw]
Subject: [PATCH 00/13] iommu: Remove usage of dev->archdata.iommu

From: Joerg Roedel <[email protected]>

Hi,

here is a patch-set to remove the usage of dev->archdata.iommu from
the IOMMU code in the kernel and replace its uses by the iommu per-device
private data field. The changes also remove the field entirely from
the architectures which no longer need it.

On PowerPC the field is called dev->archdata.iommu_domain and was only
used by the PAMU IOMMU driver. It gets removed as well.

The patches have been runtime tested on Intel VT-d and compile tested
with allyesconfig for:

* x86 (32 and 64 bit)
* arm and arm64
* ia64 (only drivers/ because build failed for me in
arch/ia64)
* PPC64

Besides that the changes also survived my IOMMU tree compile tests.

Please review.

Regards,

Joerg

Joerg Roedel (13):
iommu/exynos: Use dev_iommu_priv_get/set()
iommu/vt-d: Use dev_iommu_priv_get/set()
iommu/msm: Use dev_iommu_priv_get/set()
iommu/omap: Use dev_iommu_priv_get/set()
iommu/rockchip: Use dev_iommu_priv_get/set()
iommu/tegra: Use dev_iommu_priv_get/set()
iommu/pamu: Use dev_iommu_priv_get/set()
iommu/mediatek: Do no use dev->archdata.iommu
x86: Remove dev->archdata.iommu pointer
ia64: Remove dev->archdata.iommu pointer
arm: Remove dev->archdata.iommu pointer
arm64: Remove dev->archdata.iommu pointer
powerpc/dma: Remove dev->archdata.iommu_domain

arch/arm/include/asm/device.h | 3 ---
arch/arm64/include/asm/device.h | 3 ---
arch/ia64/include/asm/device.h | 3 ---
arch/powerpc/include/asm/device.h | 3 ---
arch/x86/include/asm/device.h | 3 ---
.../gpu/drm/i915/selftests/mock_gem_device.c | 10 ++++++++--
drivers/iommu/exynos-iommu.c | 20 +++++++++----------
drivers/iommu/fsl_pamu_domain.c | 8 ++++----
drivers/iommu/intel/iommu.c | 18 ++++++++---------
drivers/iommu/msm_iommu.c | 4 ++--
drivers/iommu/mtk_iommu.h | 2 ++
drivers/iommu/mtk_iommu_v1.c | 10 ++++------
drivers/iommu/omap-iommu.c | 20 +++++++++----------
drivers/iommu/rockchip-iommu.c | 8 ++++----
drivers/iommu/tegra-gart.c | 8 ++++----
drivers/iommu/tegra-smmu.c | 8 ++++----
.../media/platform/s5p-mfc/s5p_mfc_iommu.h | 4 +++-
17 files changed, 64 insertions(+), 71 deletions(-)

--
2.27.0


2020-06-25 13:11:26

by Joerg Roedel

[permalink] [raw]
Subject: [PATCH 05/13] iommu/rockchip: Use dev_iommu_priv_get/set()

From: Joerg Roedel <[email protected]>

Remove the use of dev->archdata.iommu and use the private per-device
pointer provided by IOMMU core code instead.

Signed-off-by: Joerg Roedel <[email protected]>
---
drivers/iommu/rockchip-iommu.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/iommu/rockchip-iommu.c b/drivers/iommu/rockchip-iommu.c
index d25c2486ca07..e5d86b7177de 100644
--- a/drivers/iommu/rockchip-iommu.c
+++ b/drivers/iommu/rockchip-iommu.c
@@ -836,7 +836,7 @@ static size_t rk_iommu_unmap(struct iommu_domain *domain, unsigned long _iova,

static struct rk_iommu *rk_iommu_from_dev(struct device *dev)
{
- struct rk_iommudata *data = dev->archdata.iommu;
+ struct rk_iommudata *data = dev_iommu_priv_get(dev);

return data ? data->iommu : NULL;
}
@@ -1059,7 +1059,7 @@ static struct iommu_device *rk_iommu_probe_device(struct device *dev)
struct rk_iommudata *data;
struct rk_iommu *iommu;

- data = dev->archdata.iommu;
+ data = dev_iommu_priv_get(dev);
if (!data)
return ERR_PTR(-ENODEV);

@@ -1073,7 +1073,7 @@ static struct iommu_device *rk_iommu_probe_device(struct device *dev)

static void rk_iommu_release_device(struct device *dev)
{
- struct rk_iommudata *data = dev->archdata.iommu;
+ struct rk_iommudata *data = dev_iommu_priv_get(dev);

device_link_del(data->link);
}
@@ -1100,7 +1100,7 @@ static int rk_iommu_of_xlate(struct device *dev,
iommu_dev = of_find_device_by_node(args->np);

data->iommu = platform_get_drvdata(iommu_dev);
- dev->archdata.iommu = data;
+ dev_iommu_priv_set(dev, data);

platform_device_put(iommu_dev);

--
2.27.0

2020-06-25 13:11:38

by Joerg Roedel

[permalink] [raw]
Subject: [PATCH 07/13] iommu/pamu: Use dev_iommu_priv_get/set()

From: Joerg Roedel <[email protected]>

Remove the use of dev->archdata.iommu_domain and use the private
per-device pointer provided by IOMMU core code instead.

Signed-off-by: Joerg Roedel <[email protected]>
---
drivers/iommu/fsl_pamu_domain.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/iommu/fsl_pamu_domain.c b/drivers/iommu/fsl_pamu_domain.c
index 928d37771ece..b2110767caf4 100644
--- a/drivers/iommu/fsl_pamu_domain.c
+++ b/drivers/iommu/fsl_pamu_domain.c
@@ -323,7 +323,7 @@ static void remove_device_ref(struct device_domain_info *info, u32 win_cnt)
pamu_disable_liodn(info->liodn);
spin_unlock_irqrestore(&iommu_lock, flags);
spin_lock_irqsave(&device_domain_lock, flags);
- info->dev->archdata.iommu_domain = NULL;
+ dev_iommu_priv_set(info->dev, NULL);
kmem_cache_free(iommu_devinfo_cache, info);
spin_unlock_irqrestore(&device_domain_lock, flags);
}
@@ -352,7 +352,7 @@ static void attach_device(struct fsl_dma_domain *dma_domain, int liodn, struct d
* Check here if the device is already attached to domain or not.
* If the device is already attached to a domain detach it.
*/
- old_domain_info = dev->archdata.iommu_domain;
+ old_domain_info = dev_iommu_priv_get(dev);
if (old_domain_info && old_domain_info->domain != dma_domain) {
spin_unlock_irqrestore(&device_domain_lock, flags);
detach_device(dev, old_domain_info->domain);
@@ -371,8 +371,8 @@ static void attach_device(struct fsl_dma_domain *dma_domain, int liodn, struct d
* the info for the first LIODN as all
* LIODNs share the same domain
*/
- if (!dev->archdata.iommu_domain)
- dev->archdata.iommu_domain = info;
+ if (!dev_iommu_priv_get(dev))
+ dev_iommu_priv_set(dev, info);
spin_unlock_irqrestore(&device_domain_lock, flags);
}

--
2.27.0

2020-06-25 13:12:31

by Joerg Roedel

[permalink] [raw]
Subject: [PATCH 09/13] x86: Remove dev->archdata.iommu pointer

From: Joerg Roedel <[email protected]>

There are no users left, all drivers have been converted to use the
per-device private pointer offered by IOMMU core.

Signed-off-by: Joerg Roedel <[email protected]>
---
arch/x86/include/asm/device.h | 3 ---
1 file changed, 3 deletions(-)

diff --git a/arch/x86/include/asm/device.h b/arch/x86/include/asm/device.h
index 49bd6cf3eec9..7c0a52ca2f4d 100644
--- a/arch/x86/include/asm/device.h
+++ b/arch/x86/include/asm/device.h
@@ -3,9 +3,6 @@
#define _ASM_X86_DEVICE_H

struct dev_archdata {
-#ifdef CONFIG_IOMMU_API
- void *iommu; /* hook for IOMMU specific extension */
-#endif
};

struct pdev_archdata {
--
2.27.0

2020-06-25 13:13:18

by Joerg Roedel

[permalink] [raw]
Subject: [PATCH 08/13] iommu/mediatek: Do no use dev->archdata.iommu

From: Joerg Roedel <[email protected]>

The iommu private pointer is already used in the Mediatek IOMMU v1
driver, so move the dma_iommu_mapping pointer into 'struct
mtk_iommu_data' and do not use dev->archdata.iommu anymore.

Signed-off-by: Joerg Roedel <[email protected]>
---
drivers/iommu/mtk_iommu.h | 2 ++
drivers/iommu/mtk_iommu_v1.c | 10 ++++------
2 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/drivers/iommu/mtk_iommu.h b/drivers/iommu/mtk_iommu.h
index ea949a324e33..1682406e98dc 100644
--- a/drivers/iommu/mtk_iommu.h
+++ b/drivers/iommu/mtk_iommu.h
@@ -62,6 +62,8 @@ struct mtk_iommu_data {
struct iommu_device iommu;
const struct mtk_iommu_plat_data *plat_data;

+ struct dma_iommu_mapping *mapping; /* For mtk_iommu_v1.c */
+
struct list_head list;
struct mtk_smi_larb_iommu larb_imu[MTK_LARB_NR_MAX];
};
diff --git a/drivers/iommu/mtk_iommu_v1.c b/drivers/iommu/mtk_iommu_v1.c
index c9d79cff4d17..82ddfe9170d4 100644
--- a/drivers/iommu/mtk_iommu_v1.c
+++ b/drivers/iommu/mtk_iommu_v1.c
@@ -269,7 +269,7 @@ static int mtk_iommu_attach_device(struct iommu_domain *domain,
int ret;

/* Only allow the domain created internally. */
- mtk_mapping = data->dev->archdata.iommu;
+ mtk_mapping = data->mapping;
if (mtk_mapping->domain != domain)
return 0;

@@ -369,7 +369,6 @@ static int mtk_iommu_create_mapping(struct device *dev,
struct mtk_iommu_data *data;
struct platform_device *m4updev;
struct dma_iommu_mapping *mtk_mapping;
- struct device *m4udev;
int ret;

if (args->args_count != 1) {
@@ -401,8 +400,7 @@ static int mtk_iommu_create_mapping(struct device *dev,
return ret;

data = dev_iommu_priv_get(dev);
- m4udev = data->dev;
- mtk_mapping = m4udev->archdata.iommu;
+ mtk_mapping = data->mapping;
if (!mtk_mapping) {
/* MTK iommu support 4GB iova address space. */
mtk_mapping = arm_iommu_create_mapping(&platform_bus_type,
@@ -410,7 +408,7 @@ static int mtk_iommu_create_mapping(struct device *dev,
if (IS_ERR(mtk_mapping))
return PTR_ERR(mtk_mapping);

- m4udev->archdata.iommu = mtk_mapping;
+ data->mapping = mtk_mapping;
}

return 0;
@@ -459,7 +457,7 @@ static void mtk_iommu_probe_finalize(struct device *dev)
int err;

data = dev_iommu_priv_get(dev);
- mtk_mapping = data->dev->archdata.iommu;
+ mtk_mapping = data->mapping;

err = arm_iommu_attach_device(dev, mtk_mapping);
if (err)
--
2.27.0

2020-06-25 13:13:37

by Joerg Roedel

[permalink] [raw]
Subject: [PATCH 02/13] iommu/vt-d: Use dev_iommu_priv_get/set()

From: Joerg Roedel <[email protected]>

Remove the use of dev->archdata.iommu and use the private per-device
pointer provided by IOMMU core code instead.

Signed-off-by: Joerg Roedel <[email protected]>
---
.../gpu/drm/i915/selftests/mock_gem_device.c | 10 ++++++++--
drivers/iommu/intel/iommu.c | 18 +++++++++---------
2 files changed, 17 insertions(+), 11 deletions(-)

diff --git a/drivers/gpu/drm/i915/selftests/mock_gem_device.c b/drivers/gpu/drm/i915/selftests/mock_gem_device.c
index 9b105b811f1f..e08601905a64 100644
--- a/drivers/gpu/drm/i915/selftests/mock_gem_device.c
+++ b/drivers/gpu/drm/i915/selftests/mock_gem_device.c
@@ -24,6 +24,7 @@

#include <linux/pm_domain.h>
#include <linux/pm_runtime.h>
+#include <linux/iommu.h>

#include <drm/drm_managed.h>

@@ -118,6 +119,9 @@ struct drm_i915_private *mock_gem_device(void)
{
struct drm_i915_private *i915;
struct pci_dev *pdev;
+#if IS_ENABLED(CONFIG_IOMMU_API) && defined(CONFIG_INTEL_IOMMU)
+ struct dev_iommu iommu;
+#endif
int err;

pdev = kzalloc(sizeof(*pdev), GFP_KERNEL);
@@ -136,8 +140,10 @@ struct drm_i915_private *mock_gem_device(void)
dma_coerce_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64));

#if IS_ENABLED(CONFIG_IOMMU_API) && defined(CONFIG_INTEL_IOMMU)
- /* hack to disable iommu for the fake device; force identity mapping */
- pdev->dev.archdata.iommu = (void *)-1;
+ /* HACK HACK HACK to disable iommu for the fake device; force identity mapping */
+ memset(&iommu, 0, sizeof(iommu));
+ iommu.priv = (void *)-1;
+ pdev->dev.iommu = &iommu;
#endif

pci_set_drvdata(pdev, i915);
diff --git a/drivers/iommu/intel/iommu.c b/drivers/iommu/intel/iommu.c
index d759e7234e98..2ce490c2eab8 100644
--- a/drivers/iommu/intel/iommu.c
+++ b/drivers/iommu/intel/iommu.c
@@ -372,7 +372,7 @@ struct device_domain_info *get_domain_info(struct device *dev)
if (!dev)
return NULL;

- info = dev->archdata.iommu;
+ info = dev_iommu_priv_get(dev);
if (unlikely(info == DUMMY_DEVICE_DOMAIN_INFO ||
info == DEFER_DEVICE_DOMAIN_INFO))
return NULL;
@@ -743,12 +743,12 @@ struct context_entry *iommu_context_addr(struct intel_iommu *iommu, u8 bus,

static int iommu_dummy(struct device *dev)
{
- return dev->archdata.iommu == DUMMY_DEVICE_DOMAIN_INFO;
+ return dev_iommu_priv_get(dev) == DUMMY_DEVICE_DOMAIN_INFO;
}

static bool attach_deferred(struct device *dev)
{
- return dev->archdata.iommu == DEFER_DEVICE_DOMAIN_INFO;
+ return dev_iommu_priv_get(dev) == DEFER_DEVICE_DOMAIN_INFO;
}

/**
@@ -2420,7 +2420,7 @@ static inline void unlink_domain_info(struct device_domain_info *info)
list_del(&info->link);
list_del(&info->global);
if (info->dev)
- info->dev->archdata.iommu = NULL;
+ dev_iommu_priv_set(info->dev, NULL);
}

static void domain_remove_dev_info(struct dmar_domain *domain)
@@ -2453,7 +2453,7 @@ static void do_deferred_attach(struct device *dev)
{
struct iommu_domain *domain;

- dev->archdata.iommu = NULL;
+ dev_iommu_priv_set(dev, NULL);
domain = iommu_get_domain_for_dev(dev);
if (domain)
intel_iommu_attach_device(domain, dev);
@@ -2599,7 +2599,7 @@ static struct dmar_domain *dmar_insert_one_dev_info(struct intel_iommu *iommu,
list_add(&info->link, &domain->devices);
list_add(&info->global, &device_domain_list);
if (dev)
- dev->archdata.iommu = info;
+ dev_iommu_priv_set(dev, info);
spin_unlock_irqrestore(&device_domain_lock, flags);

/* PASID table is mandatory for a PCI device in scalable mode. */
@@ -4004,7 +4004,7 @@ static void quirk_ioat_snb_local_iommu(struct pci_dev *pdev)
if (!drhd || drhd->reg_base_addr - vtbar != 0xa000) {
pr_warn_once(FW_BUG "BIOS assigned incorrect VT-d unit for Intel(R) QuickData Technology device\n");
add_taint(TAINT_FIRMWARE_WORKAROUND, LOCKDEP_STILL_OK);
- pdev->dev.archdata.iommu = DUMMY_DEVICE_DOMAIN_INFO;
+ dev_iommu_priv_set(&pdev->dev, DUMMY_DEVICE_DOMAIN_INFO);
}
}
DECLARE_PCI_FIXUP_ENABLE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IOAT_SNB, quirk_ioat_snb_local_iommu);
@@ -4043,7 +4043,7 @@ static void __init init_no_remapping_devices(void)
drhd->ignored = 1;
for_each_active_dev_scope(drhd->devices,
drhd->devices_cnt, i, dev)
- dev->archdata.iommu = DUMMY_DEVICE_DOMAIN_INFO;
+ dev_iommu_priv_set(dev, DUMMY_DEVICE_DOMAIN_INFO);
}
}
}
@@ -5665,7 +5665,7 @@ static struct iommu_device *intel_iommu_probe_device(struct device *dev)
return ERR_PTR(-ENODEV);

if (translation_pre_enabled(iommu))
- dev->archdata.iommu = DEFER_DEVICE_DOMAIN_INFO;
+ dev_iommu_priv_set(dev, DEFER_DEVICE_DOMAIN_INFO);

return &iommu->iommu;
}
--
2.27.0

2020-06-25 13:13:37

by Joerg Roedel

[permalink] [raw]
Subject: [PATCH 01/13] iommu/exynos: Use dev_iommu_priv_get/set()

From: Joerg Roedel <[email protected]>

Remove the use of dev->archdata.iommu and use the private per-device
pointer provided by IOMMU core code instead.

Signed-off-by: Joerg Roedel <[email protected]>
---
drivers/iommu/exynos-iommu.c | 20 +++++++++----------
.../media/platform/s5p-mfc/s5p_mfc_iommu.h | 4 +++-
2 files changed, 13 insertions(+), 11 deletions(-)

diff --git a/drivers/iommu/exynos-iommu.c b/drivers/iommu/exynos-iommu.c
index 60c8a56e4a3f..6a9b67302369 100644
--- a/drivers/iommu/exynos-iommu.c
+++ b/drivers/iommu/exynos-iommu.c
@@ -173,7 +173,7 @@ static u32 lv2ent_offset(sysmmu_iova_t iova)
#define REG_V5_FAULT_AR_VA 0x070
#define REG_V5_FAULT_AW_VA 0x080

-#define has_sysmmu(dev) (dev->archdata.iommu != NULL)
+#define has_sysmmu(dev) (dev_iommu_priv_get(dev) != NULL)

static struct device *dma_dev;
static struct kmem_cache *lv2table_kmem_cache;
@@ -226,7 +226,7 @@ static const struct sysmmu_fault_info sysmmu_v5_faults[] = {
};

/*
- * This structure is attached to dev.archdata.iommu of the master device
+ * This structure is attached to dev->iommu->priv of the master device
* on device add, contains a list of SYSMMU controllers defined by device tree,
* which are bound to given master device. It is usually referenced by 'owner'
* pointer.
@@ -670,7 +670,7 @@ static int __maybe_unused exynos_sysmmu_suspend(struct device *dev)
struct device *master = data->master;

if (master) {
- struct exynos_iommu_owner *owner = master->archdata.iommu;
+ struct exynos_iommu_owner *owner = dev_iommu_priv_get(master);

mutex_lock(&owner->rpm_lock);
if (data->domain) {
@@ -688,7 +688,7 @@ static int __maybe_unused exynos_sysmmu_resume(struct device *dev)
struct device *master = data->master;

if (master) {
- struct exynos_iommu_owner *owner = master->archdata.iommu;
+ struct exynos_iommu_owner *owner = dev_iommu_priv_get(master);

mutex_lock(&owner->rpm_lock);
if (data->domain) {
@@ -837,8 +837,8 @@ static void exynos_iommu_domain_free(struct iommu_domain *iommu_domain)
static void exynos_iommu_detach_device(struct iommu_domain *iommu_domain,
struct device *dev)
{
- struct exynos_iommu_owner *owner = dev->archdata.iommu;
struct exynos_iommu_domain *domain = to_exynos_domain(iommu_domain);
+ struct exynos_iommu_owner *owner = dev_iommu_priv_get(dev);
phys_addr_t pagetable = virt_to_phys(domain->pgtable);
struct sysmmu_drvdata *data, *next;
unsigned long flags;
@@ -875,8 +875,8 @@ static void exynos_iommu_detach_device(struct iommu_domain *iommu_domain,
static int exynos_iommu_attach_device(struct iommu_domain *iommu_domain,
struct device *dev)
{
- struct exynos_iommu_owner *owner = dev->archdata.iommu;
struct exynos_iommu_domain *domain = to_exynos_domain(iommu_domain);
+ struct exynos_iommu_owner *owner = dev_iommu_priv_get(dev);
struct sysmmu_drvdata *data;
phys_addr_t pagetable = virt_to_phys(domain->pgtable);
unsigned long flags;
@@ -1237,7 +1237,7 @@ static phys_addr_t exynos_iommu_iova_to_phys(struct iommu_domain *iommu_domain,

static struct iommu_device *exynos_iommu_probe_device(struct device *dev)
{
- struct exynos_iommu_owner *owner = dev->archdata.iommu;
+ struct exynos_iommu_owner *owner = dev_iommu_priv_get(dev);
struct sysmmu_drvdata *data;

if (!has_sysmmu(dev))
@@ -1263,7 +1263,7 @@ static struct iommu_device *exynos_iommu_probe_device(struct device *dev)

static void exynos_iommu_release_device(struct device *dev)
{
- struct exynos_iommu_owner *owner = dev->archdata.iommu;
+ struct exynos_iommu_owner *owner = dev_iommu_priv_get(dev);
struct sysmmu_drvdata *data;

if (!has_sysmmu(dev))
@@ -1287,8 +1287,8 @@ static void exynos_iommu_release_device(struct device *dev)
static int exynos_iommu_of_xlate(struct device *dev,
struct of_phandle_args *spec)
{
- struct exynos_iommu_owner *owner = dev->archdata.iommu;
struct platform_device *sysmmu = of_find_device_by_node(spec->np);
+ struct exynos_iommu_owner *owner = dev_iommu_priv_get(dev);
struct sysmmu_drvdata *data, *entry;

if (!sysmmu)
@@ -1305,7 +1305,7 @@ static int exynos_iommu_of_xlate(struct device *dev,

INIT_LIST_HEAD(&owner->controllers);
mutex_init(&owner->rpm_lock);
- dev->archdata.iommu = owner;
+ dev_iommu_priv_set(dev, owner);
}

list_for_each_entry(entry, &owner->controllers, owner_node)
diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_iommu.h b/drivers/media/platform/s5p-mfc/s5p_mfc_iommu.h
index 152a713fff78..1a32266b7ddc 100644
--- a/drivers/media/platform/s5p-mfc/s5p_mfc_iommu.h
+++ b/drivers/media/platform/s5p-mfc/s5p_mfc_iommu.h
@@ -9,9 +9,11 @@

#if defined(CONFIG_EXYNOS_IOMMU)

+#include <linux/iommu.h>
+
static inline bool exynos_is_iommu_available(struct device *dev)
{
- return dev->archdata.iommu != NULL;
+ return dev_iommu_priv_get(dev) != NULL;
}

#else
--
2.27.0

2020-06-25 13:13:59

by Joerg Roedel

[permalink] [raw]
Subject: [PATCH 06/13] iommu/tegra: Use dev_iommu_priv_get/set()

From: Joerg Roedel <[email protected]>

Remove the use of dev->archdata.iommu and use the private per-device
pointer provided by IOMMU core code instead.

Signed-off-by: Joerg Roedel <[email protected]>
---
drivers/iommu/tegra-gart.c | 8 ++++----
drivers/iommu/tegra-smmu.c | 8 ++++----
2 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/drivers/iommu/tegra-gart.c b/drivers/iommu/tegra-gart.c
index 5fbdff6ff41a..fac720273889 100644
--- a/drivers/iommu/tegra-gart.c
+++ b/drivers/iommu/tegra-gart.c
@@ -113,8 +113,8 @@ static int gart_iommu_attach_dev(struct iommu_domain *domain,

if (gart->active_domain && gart->active_domain != domain) {
ret = -EBUSY;
- } else if (dev->archdata.iommu != domain) {
- dev->archdata.iommu = domain;
+ } else if (dev_iommu_priv_get(dev) != domain) {
+ dev_iommu_priv_set(dev, domain);
gart->active_domain = domain;
gart->active_devices++;
}
@@ -131,8 +131,8 @@ static void gart_iommu_detach_dev(struct iommu_domain *domain,

spin_lock(&gart->dom_lock);

- if (dev->archdata.iommu == domain) {
- dev->archdata.iommu = NULL;
+ if (dev_iommu_priv_get(dev) == domain) {
+ dev_iommu_priv_set(dev, NULL);

if (--gart->active_devices == 0)
gart->active_domain = NULL;
diff --git a/drivers/iommu/tegra-smmu.c b/drivers/iommu/tegra-smmu.c
index 7426b7666e2b..124c8848ab7e 100644
--- a/drivers/iommu/tegra-smmu.c
+++ b/drivers/iommu/tegra-smmu.c
@@ -465,7 +465,7 @@ static void tegra_smmu_as_unprepare(struct tegra_smmu *smmu,
static int tegra_smmu_attach_dev(struct iommu_domain *domain,
struct device *dev)
{
- struct tegra_smmu *smmu = dev->archdata.iommu;
+ struct tegra_smmu *smmu = dev_iommu_priv_get(dev);
struct tegra_smmu_as *as = to_smmu_as(domain);
struct device_node *np = dev->of_node;
struct of_phandle_args args;
@@ -780,7 +780,7 @@ static struct iommu_device *tegra_smmu_probe_device(struct device *dev)
* supported by the Linux kernel, so abort after the
* first match.
*/
- dev->archdata.iommu = smmu;
+ dev_iommu_priv_set(dev, smmu);

break;
}
@@ -797,7 +797,7 @@ static struct iommu_device *tegra_smmu_probe_device(struct device *dev)

static void tegra_smmu_release_device(struct device *dev)
{
- dev->archdata.iommu = NULL;
+ dev_iommu_priv_set(dev, NULL);
}

static const struct tegra_smmu_group_soc *
@@ -856,7 +856,7 @@ static struct iommu_group *tegra_smmu_group_get(struct tegra_smmu *smmu,
static struct iommu_group *tegra_smmu_device_group(struct device *dev)
{
struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev);
- struct tegra_smmu *smmu = dev->archdata.iommu;
+ struct tegra_smmu *smmu = dev_iommu_priv_get(dev);
struct iommu_group *group;

group = tegra_smmu_group_get(smmu, fwspec->ids[0]);
--
2.27.0

2020-06-25 13:27:03

by Lu Baolu

[permalink] [raw]
Subject: Re: [PATCH 02/13] iommu/vt-d: Use dev_iommu_priv_get/set()

Hi Joerg,

On 2020/6/25 21:08, Joerg Roedel wrote:
> From: Joerg Roedel <[email protected]>
>
> Remove the use of dev->archdata.iommu and use the private per-device
> pointer provided by IOMMU core code instead.
>
> Signed-off-by: Joerg Roedel <[email protected]>
> ---
> .../gpu/drm/i915/selftests/mock_gem_device.c | 10 ++++++++--
> drivers/iommu/intel/iommu.c | 18 +++++++++---------

For changes in VT-d driver,

Reviewed-by: Lu Baolu <[email protected]>

Best regards,
baolu

> 2 files changed, 17 insertions(+), 11 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/selftests/mock_gem_device.c b/drivers/gpu/drm/i915/selftests/mock_gem_device.c
> index 9b105b811f1f..e08601905a64 100644
> --- a/drivers/gpu/drm/i915/selftests/mock_gem_device.c
> +++ b/drivers/gpu/drm/i915/selftests/mock_gem_device.c
> @@ -24,6 +24,7 @@
>
> #include <linux/pm_domain.h>
> #include <linux/pm_runtime.h>
> +#include <linux/iommu.h>
>
> #include <drm/drm_managed.h>
>
> @@ -118,6 +119,9 @@ struct drm_i915_private *mock_gem_device(void)
> {
> struct drm_i915_private *i915;
> struct pci_dev *pdev;
> +#if IS_ENABLED(CONFIG_IOMMU_API) && defined(CONFIG_INTEL_IOMMU)
> + struct dev_iommu iommu;
> +#endif
> int err;
>
> pdev = kzalloc(sizeof(*pdev), GFP_KERNEL);
> @@ -136,8 +140,10 @@ struct drm_i915_private *mock_gem_device(void)
> dma_coerce_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64));
>
> #if IS_ENABLED(CONFIG_IOMMU_API) && defined(CONFIG_INTEL_IOMMU)
> - /* hack to disable iommu for the fake device; force identity mapping */
> - pdev->dev.archdata.iommu = (void *)-1;
> + /* HACK HACK HACK to disable iommu for the fake device; force identity mapping */
> + memset(&iommu, 0, sizeof(iommu));
> + iommu.priv = (void *)-1;
> + pdev->dev.iommu = &iommu;
> #endif
>
> pci_set_drvdata(pdev, i915);
> diff --git a/drivers/iommu/intel/iommu.c b/drivers/iommu/intel/iommu.c
> index d759e7234e98..2ce490c2eab8 100644
> --- a/drivers/iommu/intel/iommu.c
> +++ b/drivers/iommu/intel/iommu.c
> @@ -372,7 +372,7 @@ struct device_domain_info *get_domain_info(struct device *dev)
> if (!dev)
> return NULL;
>
> - info = dev->archdata.iommu;
> + info = dev_iommu_priv_get(dev);
> if (unlikely(info == DUMMY_DEVICE_DOMAIN_INFO ||
> info == DEFER_DEVICE_DOMAIN_INFO))
> return NULL;
> @@ -743,12 +743,12 @@ struct context_entry *iommu_context_addr(struct intel_iommu *iommu, u8 bus,
>
> static int iommu_dummy(struct device *dev)
> {
> - return dev->archdata.iommu == DUMMY_DEVICE_DOMAIN_INFO;
> + return dev_iommu_priv_get(dev) == DUMMY_DEVICE_DOMAIN_INFO;
> }
>
> static bool attach_deferred(struct device *dev)
> {
> - return dev->archdata.iommu == DEFER_DEVICE_DOMAIN_INFO;
> + return dev_iommu_priv_get(dev) == DEFER_DEVICE_DOMAIN_INFO;
> }
>
> /**
> @@ -2420,7 +2420,7 @@ static inline void unlink_domain_info(struct device_domain_info *info)
> list_del(&info->link);
> list_del(&info->global);
> if (info->dev)
> - info->dev->archdata.iommu = NULL;
> + dev_iommu_priv_set(info->dev, NULL);
> }
>
> static void domain_remove_dev_info(struct dmar_domain *domain)
> @@ -2453,7 +2453,7 @@ static void do_deferred_attach(struct device *dev)
> {
> struct iommu_domain *domain;
>
> - dev->archdata.iommu = NULL;
> + dev_iommu_priv_set(dev, NULL);
> domain = iommu_get_domain_for_dev(dev);
> if (domain)
> intel_iommu_attach_device(domain, dev);
> @@ -2599,7 +2599,7 @@ static struct dmar_domain *dmar_insert_one_dev_info(struct intel_iommu *iommu,
> list_add(&info->link, &domain->devices);
> list_add(&info->global, &device_domain_list);
> if (dev)
> - dev->archdata.iommu = info;
> + dev_iommu_priv_set(dev, info);
> spin_unlock_irqrestore(&device_domain_lock, flags);
>
> /* PASID table is mandatory for a PCI device in scalable mode. */
> @@ -4004,7 +4004,7 @@ static void quirk_ioat_snb_local_iommu(struct pci_dev *pdev)
> if (!drhd || drhd->reg_base_addr - vtbar != 0xa000) {
> pr_warn_once(FW_BUG "BIOS assigned incorrect VT-d unit for Intel(R) QuickData Technology device\n");
> add_taint(TAINT_FIRMWARE_WORKAROUND, LOCKDEP_STILL_OK);
> - pdev->dev.archdata.iommu = DUMMY_DEVICE_DOMAIN_INFO;
> + dev_iommu_priv_set(&pdev->dev, DUMMY_DEVICE_DOMAIN_INFO);
> }
> }
> DECLARE_PCI_FIXUP_ENABLE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IOAT_SNB, quirk_ioat_snb_local_iommu);
> @@ -4043,7 +4043,7 @@ static void __init init_no_remapping_devices(void)
> drhd->ignored = 1;
> for_each_active_dev_scope(drhd->devices,
> drhd->devices_cnt, i, dev)
> - dev->archdata.iommu = DUMMY_DEVICE_DOMAIN_INFO;
> + dev_iommu_priv_set(dev, DUMMY_DEVICE_DOMAIN_INFO);
> }
> }
> }
> @@ -5665,7 +5665,7 @@ static struct iommu_device *intel_iommu_probe_device(struct device *dev)
> return ERR_PTR(-ENODEV);
>
> if (translation_pre_enabled(iommu))
> - dev->archdata.iommu = DEFER_DEVICE_DOMAIN_INFO;
> + dev_iommu_priv_set(dev, DEFER_DEVICE_DOMAIN_INFO);
>
> return &iommu->iommu;
> }
>

2020-06-26 04:33:46

by Jerry Snitselaar

[permalink] [raw]
Subject: Re: [PATCH 00/13] iommu: Remove usage of dev->archdata.iommu

On Thu Jun 25 20, Joerg Roedel wrote:
>From: Joerg Roedel <[email protected]>
>
>Hi,
>
>here is a patch-set to remove the usage of dev->archdata.iommu from
>the IOMMU code in the kernel and replace its uses by the iommu per-device
>private data field. The changes also remove the field entirely from
>the architectures which no longer need it.
>
>On PowerPC the field is called dev->archdata.iommu_domain and was only
>used by the PAMU IOMMU driver. It gets removed as well.
>
>The patches have been runtime tested on Intel VT-d and compile tested
>with allyesconfig for:
>
> * x86 (32 and 64 bit)
> * arm and arm64
> * ia64 (only drivers/ because build failed for me in
> arch/ia64)
> * PPC64
>
>Besides that the changes also survived my IOMMU tree compile tests.
>
>Please review.
>
>Regards,
>
> Joerg
>
>Joerg Roedel (13):
> iommu/exynos: Use dev_iommu_priv_get/set()
> iommu/vt-d: Use dev_iommu_priv_get/set()
> iommu/msm: Use dev_iommu_priv_get/set()
> iommu/omap: Use dev_iommu_priv_get/set()
> iommu/rockchip: Use dev_iommu_priv_get/set()
> iommu/tegra: Use dev_iommu_priv_get/set()
> iommu/pamu: Use dev_iommu_priv_get/set()
> iommu/mediatek: Do no use dev->archdata.iommu
> x86: Remove dev->archdata.iommu pointer
> ia64: Remove dev->archdata.iommu pointer
> arm: Remove dev->archdata.iommu pointer
> arm64: Remove dev->archdata.iommu pointer
> powerpc/dma: Remove dev->archdata.iommu_domain
>
> arch/arm/include/asm/device.h | 3 ---
> arch/arm64/include/asm/device.h | 3 ---
> arch/ia64/include/asm/device.h | 3 ---
> arch/powerpc/include/asm/device.h | 3 ---
> arch/x86/include/asm/device.h | 3 ---
> .../gpu/drm/i915/selftests/mock_gem_device.c | 10 ++++++++--
> drivers/iommu/exynos-iommu.c | 20 +++++++++----------
> drivers/iommu/fsl_pamu_domain.c | 8 ++++----
> drivers/iommu/intel/iommu.c | 18 ++++++++---------
> drivers/iommu/msm_iommu.c | 4 ++--
> drivers/iommu/mtk_iommu.h | 2 ++
> drivers/iommu/mtk_iommu_v1.c | 10 ++++------
> drivers/iommu/omap-iommu.c | 20 +++++++++----------
> drivers/iommu/rockchip-iommu.c | 8 ++++----
> drivers/iommu/tegra-gart.c | 8 ++++----
> drivers/iommu/tegra-smmu.c | 8 ++++----
> .../media/platform/s5p-mfc/s5p_mfc_iommu.h | 4 +++-
> 17 files changed, 64 insertions(+), 71 deletions(-)
>
>--
>2.27.0
>

Reviewed-by: Jerry Snitselaar <[email protected]>

2020-06-26 12:34:25

by Borislav Petkov

[permalink] [raw]
Subject: Re: [PATCH 09/13] x86: Remove dev->archdata.iommu pointer

On Thu, Jun 25, 2020 at 03:08:32PM +0200, Joerg Roedel wrote:
> From: Joerg Roedel <[email protected]>
>
> There are no users left, all drivers have been converted to use the
> per-device private pointer offered by IOMMU core.
>
> Signed-off-by: Joerg Roedel <[email protected]>
> ---
> arch/x86/include/asm/device.h | 3 ---
> 1 file changed, 3 deletions(-)
>
> diff --git a/arch/x86/include/asm/device.h b/arch/x86/include/asm/device.h
> index 49bd6cf3eec9..7c0a52ca2f4d 100644
> --- a/arch/x86/include/asm/device.h
> +++ b/arch/x86/include/asm/device.h
> @@ -3,9 +3,6 @@
> #define _ASM_X86_DEVICE_H
>
> struct dev_archdata {
> -#ifdef CONFIG_IOMMU_API
> - void *iommu; /* hook for IOMMU specific extension */
> -#endif
> };
>
> struct pdev_archdata {
> --

Acked-by: Borislav Petkov <[email protected]>

--
Regards/Gruss,
Boris.

https://people.kernel.org/tglx/notes-about-netiquette

2020-06-29 19:38:47

by Marek Szyprowski

[permalink] [raw]
Subject: Re: [PATCH 01/13] iommu/exynos: Use dev_iommu_priv_get/set()

On 25.06.2020 15:08, Joerg Roedel wrote:
> From: Joerg Roedel <[email protected]>
>
> Remove the use of dev->archdata.iommu and use the private per-device
> pointer provided by IOMMU core code instead.
>
> Signed-off-by: Joerg Roedel <[email protected]>
Acked-by: Marek Szyprowski <[email protected]>
> ---
> drivers/iommu/exynos-iommu.c | 20 +++++++++----------
> .../media/platform/s5p-mfc/s5p_mfc_iommu.h | 4 +++-
> 2 files changed, 13 insertions(+), 11 deletions(-)
>
> diff --git a/drivers/iommu/exynos-iommu.c b/drivers/iommu/exynos-iommu.c
> index 60c8a56e4a3f..6a9b67302369 100644
> --- a/drivers/iommu/exynos-iommu.c
> +++ b/drivers/iommu/exynos-iommu.c
> @@ -173,7 +173,7 @@ static u32 lv2ent_offset(sysmmu_iova_t iova)
> #define REG_V5_FAULT_AR_VA 0x070
> #define REG_V5_FAULT_AW_VA 0x080
>
> -#define has_sysmmu(dev) (dev->archdata.iommu != NULL)
> +#define has_sysmmu(dev) (dev_iommu_priv_get(dev) != NULL)
>
> static struct device *dma_dev;
> static struct kmem_cache *lv2table_kmem_cache;
> @@ -226,7 +226,7 @@ static const struct sysmmu_fault_info sysmmu_v5_faults[] = {
> };
>
> /*
> - * This structure is attached to dev.archdata.iommu of the master device
> + * This structure is attached to dev->iommu->priv of the master device
> * on device add, contains a list of SYSMMU controllers defined by device tree,
> * which are bound to given master device. It is usually referenced by 'owner'
> * pointer.
> @@ -670,7 +670,7 @@ static int __maybe_unused exynos_sysmmu_suspend(struct device *dev)
> struct device *master = data->master;
>
> if (master) {
> - struct exynos_iommu_owner *owner = master->archdata.iommu;
> + struct exynos_iommu_owner *owner = dev_iommu_priv_get(master);
>
> mutex_lock(&owner->rpm_lock);
> if (data->domain) {
> @@ -688,7 +688,7 @@ static int __maybe_unused exynos_sysmmu_resume(struct device *dev)
> struct device *master = data->master;
>
> if (master) {
> - struct exynos_iommu_owner *owner = master->archdata.iommu;
> + struct exynos_iommu_owner *owner = dev_iommu_priv_get(master);
>
> mutex_lock(&owner->rpm_lock);
> if (data->domain) {
> @@ -837,8 +837,8 @@ static void exynos_iommu_domain_free(struct iommu_domain *iommu_domain)
> static void exynos_iommu_detach_device(struct iommu_domain *iommu_domain,
> struct device *dev)
> {
> - struct exynos_iommu_owner *owner = dev->archdata.iommu;
> struct exynos_iommu_domain *domain = to_exynos_domain(iommu_domain);
> + struct exynos_iommu_owner *owner = dev_iommu_priv_get(dev);
> phys_addr_t pagetable = virt_to_phys(domain->pgtable);
> struct sysmmu_drvdata *data, *next;
> unsigned long flags;
> @@ -875,8 +875,8 @@ static void exynos_iommu_detach_device(struct iommu_domain *iommu_domain,
> static int exynos_iommu_attach_device(struct iommu_domain *iommu_domain,
> struct device *dev)
> {
> - struct exynos_iommu_owner *owner = dev->archdata.iommu;
> struct exynos_iommu_domain *domain = to_exynos_domain(iommu_domain);
> + struct exynos_iommu_owner *owner = dev_iommu_priv_get(dev);
> struct sysmmu_drvdata *data;
> phys_addr_t pagetable = virt_to_phys(domain->pgtable);
> unsigned long flags;
> @@ -1237,7 +1237,7 @@ static phys_addr_t exynos_iommu_iova_to_phys(struct iommu_domain *iommu_domain,
>
> static struct iommu_device *exynos_iommu_probe_device(struct device *dev)
> {
> - struct exynos_iommu_owner *owner = dev->archdata.iommu;
> + struct exynos_iommu_owner *owner = dev_iommu_priv_get(dev);
> struct sysmmu_drvdata *data;
>
> if (!has_sysmmu(dev))
> @@ -1263,7 +1263,7 @@ static struct iommu_device *exynos_iommu_probe_device(struct device *dev)
>
> static void exynos_iommu_release_device(struct device *dev)
> {
> - struct exynos_iommu_owner *owner = dev->archdata.iommu;
> + struct exynos_iommu_owner *owner = dev_iommu_priv_get(dev);
> struct sysmmu_drvdata *data;
>
> if (!has_sysmmu(dev))
> @@ -1287,8 +1287,8 @@ static void exynos_iommu_release_device(struct device *dev)
> static int exynos_iommu_of_xlate(struct device *dev,
> struct of_phandle_args *spec)
> {
> - struct exynos_iommu_owner *owner = dev->archdata.iommu;
> struct platform_device *sysmmu = of_find_device_by_node(spec->np);
> + struct exynos_iommu_owner *owner = dev_iommu_priv_get(dev);
> struct sysmmu_drvdata *data, *entry;
>
> if (!sysmmu)
> @@ -1305,7 +1305,7 @@ static int exynos_iommu_of_xlate(struct device *dev,
>
> INIT_LIST_HEAD(&owner->controllers);
> mutex_init(&owner->rpm_lock);
> - dev->archdata.iommu = owner;
> + dev_iommu_priv_set(dev, owner);
> }
>
> list_for_each_entry(entry, &owner->controllers, owner_node)
> diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_iommu.h b/drivers/media/platform/s5p-mfc/s5p_mfc_iommu.h
> index 152a713fff78..1a32266b7ddc 100644
> --- a/drivers/media/platform/s5p-mfc/s5p_mfc_iommu.h
> +++ b/drivers/media/platform/s5p-mfc/s5p_mfc_iommu.h
> @@ -9,9 +9,11 @@
>
> #if defined(CONFIG_EXYNOS_IOMMU)
>
> +#include <linux/iommu.h>
> +
> static inline bool exynos_is_iommu_available(struct device *dev)
> {
> - return dev->archdata.iommu != NULL;
> + return dev_iommu_priv_get(dev) != NULL;
> }
>
> #else

Best regards
--
Marek Szyprowski, PhD
Samsung R&D Institute Poland

2020-06-30 10:03:08

by Joerg Roedel

[permalink] [raw]
Subject: Re: [PATCH 00/13] iommu: Remove usage of dev->archdata.iommu

On Thu, Jun 25, 2020 at 03:08:23PM +0200, Joerg Roedel wrote:
> Joerg Roedel (13):
> iommu/exynos: Use dev_iommu_priv_get/set()
> iommu/vt-d: Use dev_iommu_priv_get/set()
> iommu/msm: Use dev_iommu_priv_get/set()
> iommu/omap: Use dev_iommu_priv_get/set()
> iommu/rockchip: Use dev_iommu_priv_get/set()
> iommu/tegra: Use dev_iommu_priv_get/set()
> iommu/pamu: Use dev_iommu_priv_get/set()
> iommu/mediatek: Do no use dev->archdata.iommu
> x86: Remove dev->archdata.iommu pointer
> ia64: Remove dev->archdata.iommu pointer
> arm: Remove dev->archdata.iommu pointer
> arm64: Remove dev->archdata.iommu pointer
> powerpc/dma: Remove dev->archdata.iommu_domain

Applied.