diff options
author | Jason Gunthorpe <jgg@nvidia.com> | 2023-10-17 21:11:42 +0300 |
---|---|---|
committer | Will Deacon <will@kernel.org> | 2023-12-13 16:03:29 +0300 |
commit | bbbf11eea38c0cb167edc5ce5fe76324e87ad074 (patch) | |
tree | c3edda7aa78165e912f1e52820f27179130b51f4 | |
parent | 22bb7b41476a1b8dc282dc5b3ca5470090b52e46 (diff) | |
download | linux-bbbf11eea38c0cb167edc5ce5fe76324e87ad074.tar.xz |
iommu/arm-smmu: Implement IOMMU_DOMAIN_BLOCKED
Using the same design as IDENTITY setup a S2CR_TYPE_FAULT s2cr for the
device.
Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
Link: https://lore.kernel.org/r/3-v2-c86cc8c2230e+160bb-smmu_newapi_jgg@nvidia.com
Signed-off-by: Will Deacon <will@kernel.org>
-rw-r--r-- | drivers/iommu/arm/arm-smmu/arm-smmu.c | 28 |
1 files changed, 25 insertions, 3 deletions
diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu.c b/drivers/iommu/arm/arm-smmu/arm-smmu.c index dec912c27141..c76b68a296bc 100644 --- a/drivers/iommu/arm/arm-smmu/arm-smmu.c +++ b/drivers/iommu/arm/arm-smmu/arm-smmu.c @@ -1164,8 +1164,8 @@ rpm_put: return ret; } -static int arm_smmu_attach_dev_identity(struct iommu_domain *domain, - struct device *dev) +static int arm_smmu_attach_dev_type(struct device *dev, + enum arm_smmu_s2cr_type type) { struct arm_smmu_master_cfg *cfg = dev_iommu_priv_get(dev); struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev); @@ -1180,12 +1180,18 @@ static int arm_smmu_attach_dev_identity(struct iommu_domain *domain, if (ret < 0) return ret; - arm_smmu_master_install_s2crs(cfg, S2CR_TYPE_BYPASS, 0, fwspec); + arm_smmu_master_install_s2crs(cfg, type, 0, fwspec); arm_smmu_rpm_use_autosuspend(smmu); arm_smmu_rpm_put(smmu); return 0; } +static int arm_smmu_attach_dev_identity(struct iommu_domain *domain, + struct device *dev) +{ + return arm_smmu_attach_dev_type(dev, S2CR_TYPE_BYPASS); +} + static const struct iommu_domain_ops arm_smmu_identity_ops = { .attach_dev = arm_smmu_attach_dev_identity, }; @@ -1195,6 +1201,21 @@ static struct iommu_domain arm_smmu_identity_domain = { .ops = &arm_smmu_identity_ops, }; +static int arm_smmu_attach_dev_blocked(struct iommu_domain *domain, + struct device *dev) +{ + return arm_smmu_attach_dev_type(dev, S2CR_TYPE_FAULT); +} + +static const struct iommu_domain_ops arm_smmu_blocked_ops = { + .attach_dev = arm_smmu_attach_dev_blocked, +}; + +static struct iommu_domain arm_smmu_blocked_domain = { + .type = IOMMU_DOMAIN_BLOCKED, + .ops = &arm_smmu_blocked_ops, +}; + static int arm_smmu_map_pages(struct iommu_domain *domain, unsigned long iova, phys_addr_t paddr, size_t pgsize, size_t pgcount, int prot, gfp_t gfp, size_t *mapped) @@ -1582,6 +1603,7 @@ static int arm_smmu_def_domain_type(struct device *dev) static struct iommu_ops arm_smmu_ops = { .identity_domain = &arm_smmu_identity_domain, + .blocked_domain = &arm_smmu_blocked_domain, .capable = arm_smmu_capable, .domain_alloc = arm_smmu_domain_alloc, .probe_device = arm_smmu_probe_device, |