Messages in this thread Patch in this message | | | From | Robin Murphy <> | Subject | [PATCH v2 23/24] iommu/arm-smmu: Allow non-strict in pgtable_quirks interface | Date | Wed, 28 Jul 2021 16:58:44 +0100 |
| |
To make io-pgtable aware of a flush queue being dynamically enabled, allow IO_PGTABLE_QUIRK_NON_STRICT to be set even after a domain has been attached to, and hook up the final piece of the puzzle in iommu-dma.
Signed-off-by: Robin Murphy <robin.murphy@arm.com> --- drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 15 +++++++++++++++ drivers/iommu/arm/arm-smmu/arm-smmu.c | 11 +++++++++++ drivers/iommu/dma-iommu.c | 3 +++ 3 files changed, 29 insertions(+)
diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c index 19400826eba7..40fa9cb382c3 100644 --- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c +++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c @@ -2711,6 +2711,20 @@ static int arm_smmu_enable_nesting(struct iommu_domain *domain) return ret; } +static int arm_smmu_set_pgtable_quirks(struct iommu_domain *domain, + unsigned long quirks) +{ + struct arm_smmu_domain *smmu_domain = to_smmu_domain(domain); + + if (quirks == IO_PGTABLE_QUIRK_NON_STRICT && smmu_domain->pgtbl_ops) { + struct io_pgtable *iop = io_pgtable_ops_to_pgtable(smmu_domain->pgtbl_ops); + + iop->cfg.quirks |= IO_PGTABLE_QUIRK_NON_STRICT; + return 0; + } + return -EINVAL; +} + static int arm_smmu_of_xlate(struct device *dev, struct of_phandle_args *args) { return iommu_fwspec_add_ids(dev, args->args, 1); @@ -2825,6 +2839,7 @@ static struct iommu_ops arm_smmu_ops = { .release_device = arm_smmu_release_device, .device_group = arm_smmu_device_group, .enable_nesting = arm_smmu_enable_nesting, + .set_pgtable_quirks = arm_smmu_set_pgtable_quirks, .of_xlate = arm_smmu_of_xlate, .get_resv_regions = arm_smmu_get_resv_regions, .put_resv_regions = generic_iommu_put_resv_regions, diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu.c b/drivers/iommu/arm/arm-smmu/arm-smmu.c index 109e4723f9f5..f18684f308b9 100644 --- a/drivers/iommu/arm/arm-smmu/arm-smmu.c +++ b/drivers/iommu/arm/arm-smmu/arm-smmu.c @@ -1518,6 +1518,17 @@ static int arm_smmu_set_pgtable_quirks(struct iommu_domain *domain, struct arm_smmu_domain *smmu_domain = to_smmu_domain(domain); int ret = 0; + if (quirks == IO_PGTABLE_QUIRK_NON_STRICT) { + struct io_pgtable *iop; + + if (!smmu_domain->pgtbl_ops) + return -EINVAL; + + iop = io_pgtable_ops_to_pgtable(smmu_domain->pgtbl_ops); + iop->cfg.quirks |= IO_PGTABLE_QUIRK_NON_STRICT; + return 0; + } + mutex_lock(&smmu_domain->init_mutex); if (smmu_domain->smmu) ret = -EPERM; diff --git a/drivers/iommu/dma-iommu.c b/drivers/iommu/dma-iommu.c index 304a3ec71223..6e3eca778267 100644 --- a/drivers/iommu/dma-iommu.c +++ b/drivers/iommu/dma-iommu.c @@ -16,6 +16,7 @@ #include <linux/huge_mm.h> #include <linux/iommu.h> #include <linux/iova.h> +#include <linux/io-pgtable.h> #include <linux/irq.h> #include <linux/mm.h> #include <linux/mutex.h> @@ -326,6 +327,8 @@ int iommu_dma_init_fq(struct iommu_domain *domain) return -ENODEV; } cookie->fq_domain = domain; + if (domain->ops->set_pgtable_quirks) + domain->ops->set_pgtable_quirks(domain, IO_PGTABLE_QUIRK_NON_STRICT); return 0; } -- 2.25.1
| |