Merge tag '6.6-rc-smb3-client-fixes-part2' of git://git.samba.org/sfrench/cifs-2.6
[sfrench/cifs-2.6.git] / drivers / iommu / arm / arm-smmu-v3 / arm-smmu-v3.c
index 9b0dc35056019e0fe095efeedbfc9eb7e320fa08..e82bf1c449a35dd300738f9b6b457dc9d3e3bca8 100644 (file)
@@ -1059,7 +1059,7 @@ int arm_smmu_write_ctx_desc(struct arm_smmu_domain *smmu_domain, int ssid,
        /*
         * This function handles the following cases:
         *
-        * (1) Install primary CD, for normal DMA traffic (SSID = 0).
+        * (1) Install primary CD, for normal DMA traffic (SSID = IOMMU_NO_PASID = 0).
         * (2) Install a secondary CD, for SID+SSID traffic.
         * (3) Update ASID of a CD. Atomically write the first 64 bits of the
         *     CD, then invalidate the old entry and mappings.
@@ -1607,7 +1607,7 @@ static void arm_smmu_handle_ppr(struct arm_smmu_device *smmu, u64 *evt)
 
        sid = FIELD_GET(PRIQ_0_SID, evt[0]);
        ssv = FIELD_GET(PRIQ_0_SSID_V, evt[0]);
-       ssid = ssv ? FIELD_GET(PRIQ_0_SSID, evt[0]) : 0;
+       ssid = ssv ? FIELD_GET(PRIQ_0_SSID, evt[0]) : IOMMU_NO_PASID;
        last = FIELD_GET(PRIQ_0_PRG_LAST, evt[0]);
        grpid = FIELD_GET(PRIQ_1_PRG_IDX, evt[1]);
 
@@ -1748,7 +1748,7 @@ arm_smmu_atc_inv_to_cmd(int ssid, unsigned long iova, size_t size,
         */
        *cmd = (struct arm_smmu_cmdq_ent) {
                .opcode                 = CMDQ_OP_ATC_INV,
-               .substream_valid        = !!ssid,
+               .substream_valid        = (ssid != IOMMU_NO_PASID),
                .atc.ssid               = ssid,
        };
 
@@ -1795,7 +1795,7 @@ static int arm_smmu_atc_inv_master(struct arm_smmu_master *master)
        struct arm_smmu_cmdq_ent cmd;
        struct arm_smmu_cmdq_batch cmds;
 
-       arm_smmu_atc_inv_to_cmd(0, 0, 0, &cmd);
+       arm_smmu_atc_inv_to_cmd(IOMMU_NO_PASID, 0, 0, &cmd);
 
        cmds.num = 0;
        for (i = 0; i < master->num_streams; i++) {
@@ -1875,7 +1875,7 @@ static void arm_smmu_tlb_inv_context(void *cookie)
                cmd.tlbi.vmid   = smmu_domain->s2_cfg.vmid;
                arm_smmu_cmdq_issue_cmd_with_sync(smmu, &cmd);
        }
-       arm_smmu_atc_inv_domain(smmu_domain, 0, 0, 0);
+       arm_smmu_atc_inv_domain(smmu_domain, IOMMU_NO_PASID, 0, 0);
 }
 
 static void __arm_smmu_tlb_inv_range(struct arm_smmu_cmdq_ent *cmd,
@@ -1968,7 +1968,7 @@ static void arm_smmu_tlb_inv_range_domain(unsigned long iova, size_t size,
         * Unfortunately, this can't be leaf-only since we may have
         * zapped an entire table.
         */
-       arm_smmu_atc_inv_domain(smmu_domain, 0, iova, size);
+       arm_smmu_atc_inv_domain(smmu_domain, IOMMU_NO_PASID, iova, size);
 }
 
 void arm_smmu_tlb_inv_range_asid(unsigned long iova, size_t size, int asid,
@@ -2055,24 +2055,6 @@ static struct iommu_domain *arm_smmu_domain_alloc(unsigned type)
        return &smmu_domain->domain;
 }
 
-static int arm_smmu_bitmap_alloc(unsigned long *map, int span)
-{
-       int idx, size = 1 << span;
-
-       do {
-               idx = find_first_zero_bit(map, size);
-               if (idx == size)
-                       return -ENOSPC;
-       } while (test_and_set_bit(idx, map));
-
-       return idx;
-}
-
-static void arm_smmu_bitmap_free(unsigned long *map, int idx)
-{
-       clear_bit(idx, map);
-}
-
 static void arm_smmu_domain_free(struct iommu_domain *domain)
 {
        struct arm_smmu_domain *smmu_domain = to_smmu_domain(domain);
@@ -2093,7 +2075,7 @@ static void arm_smmu_domain_free(struct iommu_domain *domain)
        } else {
                struct arm_smmu_s2_cfg *cfg = &smmu_domain->s2_cfg;
                if (cfg->vmid)
-                       arm_smmu_bitmap_free(smmu->vmid_map, cfg->vmid);
+                       ida_free(&smmu->vmid_map, cfg->vmid);
        }
 
        kfree(smmu_domain);
@@ -2142,7 +2124,7 @@ static int arm_smmu_domain_finalise_s1(struct arm_smmu_domain *smmu_domain,
         * the master has been added to the devices list for this domain.
         * This isn't an issue because the STE hasn't been installed yet.
         */
-       ret = arm_smmu_write_ctx_desc(smmu_domain, 0, &cfg->cd);
+       ret = arm_smmu_write_ctx_desc(smmu_domain, IOMMU_NO_PASID, &cfg->cd);
        if (ret)
                goto out_free_cd_tables;
 
@@ -2167,7 +2149,9 @@ static int arm_smmu_domain_finalise_s2(struct arm_smmu_domain *smmu_domain,
        struct arm_smmu_s2_cfg *cfg = &smmu_domain->s2_cfg;
        typeof(&pgtbl_cfg->arm_lpae_s2_cfg.vtcr) vtcr;
 
-       vmid = arm_smmu_bitmap_alloc(smmu->vmid_map, smmu->vmid_bits);
+       /* Reserve VMID 0 for stage-2 bypass STEs */
+       vmid = ida_alloc_range(&smmu->vmid_map, 1, (1 << smmu->vmid_bits) - 1,
+                              GFP_KERNEL);
        if (vmid < 0)
                return vmid;
 
@@ -2328,7 +2312,7 @@ static void arm_smmu_enable_ats(struct arm_smmu_master *master)
        pdev = to_pci_dev(master->dev);
 
        atomic_inc(&smmu_domain->nr_ats_masters);
-       arm_smmu_atc_inv_domain(smmu_domain, 0, 0, 0);
+       arm_smmu_atc_inv_domain(smmu_domain, IOMMU_NO_PASID, 0, 0);
        if (pci_enable_ats(pdev, stu))
                dev_err(master->dev, "Failed to enable ATS (STU %zu)\n", stu);
 }
@@ -3098,8 +3082,8 @@ static int arm_smmu_init_strtab(struct arm_smmu_device *smmu)
        reg |= STRTAB_BASE_RA;
        smmu->strtab_cfg.strtab_base = reg;
 
-       /* Allocate the first VMID for stage-2 bypass STEs */
-       set_bit(0, smmu->vmid_map);
+       ida_init(&smmu->vmid_map);
+
        return 0;
 }
 
@@ -3923,6 +3907,7 @@ static void arm_smmu_device_remove(struct platform_device *pdev)
        iommu_device_sysfs_remove(&smmu->iommu);
        arm_smmu_device_disable(smmu);
        iopf_queue_free(smmu->evtq.iopf);
+       ida_destroy(&smmu->vmid_map);
 }
 
 static void arm_smmu_device_shutdown(struct platform_device *pdev)