iommu/arm-smmu: Implement IOMMU_DOMAIN_BLOCKED
authorJason Gunthorpe <jgg@nvidia.com>
Tue, 17 Oct 2023 18:11:42 +0000 (15:11 -0300)
committerWill Deacon <will@kernel.org>
Wed, 13 Dec 2023 13:03:29 +0000 (13:03 +0000)
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>
drivers/iommu/arm/arm-smmu/arm-smmu.c

index dec912c2714123d03ad3f54c946a538170e59adc..c76b68a296bcb7fb5128a0be103da59116686fc3 100644 (file)
@@ -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,