Hi Jean,

On 27.02.2017 20:54, Jean-Philippe Brucker wrote:
@@ -1213,17 +1356,59 @@ static void arm_smmu_free_cd_tables(struct 
arm_smmu_master_data *master)
 __maybe_unused
 static int arm_smmu_alloc_cd(struct arm_smmu_master_data *master)
 {
+       int ssid;
+       int i, ret;
        struct arm_smmu_cd_cfg *cfg = &master->ste.cd_cfg;

-       return arm_smmu_bitmap_alloc(cfg->context_map, ilog2(cfg->num_entries));
+       if (cfg->linear)
+               return arm_smmu_bitmap_alloc(cfg->table.context_map,
+                                            ilog2(cfg->num_entries));
+
+       /* Find first leaf table with an empty slot, or allocate a new leaf */
+       for (i = cfg->l1.cur_table; i < cfg->num_entries; i++) {
+               struct arm_smmu_cd_table *table = &cfg->l1.tables[i];
+
+               if (!table->cdptr) {
+                       __le64 *l1ptr = cfg->l1.ptr + i * CTXDESC_L1_DESC_DWORD;
+
+                       ret = arm_smmu_alloc_cd_leaf_table(master->smmu, table,
+                                                          
CTXDESC_NUM_L2_ENTRIES);
+                       if (ret)
+                               return ret;
+
+                       arm_smmu_write_cd_l1_desc(l1ptr, table);
+                       arm_smmu_sync_cd(master, i << CTXDESC_SPLIT, false);
+               }
+
+               ssid = arm_smmu_bitmap_alloc(table->context_map, CTXDESC_SPLIT);
+               if (ssid < 0)
+                       continue;
+
+               cfg->l1.cur_table = i;
+               return i << CTXDESC_SPLIT | ssid;
+       }
+
+       return -ENOSPC;
 }

 __maybe_unused
 static void arm_smmu_free_cd(struct arm_smmu_master_data *master, u32 ssid)
 {
+       unsigned long l1_idx, idx;
        struct arm_smmu_cd_cfg *cfg = &master->ste.cd_cfg;

-       arm_smmu_bitmap_free(cfg->context_map, ssid);
+       if (cfg->linear) {
+               arm_smmu_bitmap_free(cfg->table.context_map, ssid);
+               return;
+       }
+
+       l1_idx = ssid >> CTXDESC_SPLIT;
+       idx = ssid & ((1 << CTXDESC_SPLIT) - 1);
+       arm_smmu_bitmap_free(cfg->l1.tables[l1_idx].context_map, idx);
+
+       /* Prepare next allocation */
+       if (cfg->l1.cur_table > idx)
+               cfg->l1.cur_table = idx;
 }

I am not sure what is the logic here. idx becomes index of l1.tables in arm_smmu_alloc_cd() which in turn may be out of allocated memory. I may miss something. Can you please elaborate on this?

Thanks,
Tomasz
_______________________________________________
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu

Reply via email to