struct iommupt_pending_gather {
struct iommu_iotlb_gather *iotlb_gather;
struct iommu_pages_list free_list;
+ u8 leaf_levels_bitmap;
+ u8 table_levels_bitmap;
};
static void gather_add_table(struct iommupt_pending_gather *pending,
struct pt_table_p *table)
{
iommu_pages_list_add(&pending->free_list, table);
+ if (pts_feature(pts, PT_FEAT_DETAILED_GATHER))
+ pending->table_levels_bitmap |= BIT(pts->level);
+}
+
+static void gather_add_leaf(struct iommupt_pending_gather *pending,
+ const struct pt_state *pts)
+{
+ if (!pts_feature(pts, PT_FEAT_DETAILED_GATHER))
+ return;
+
+ pending->leaf_levels_bitmap |= BIT(pts->level);
}
static void gather_range_pending(struct iommupt_pending_gather *pending,
iommu_pages_list_splice(&pending->free_list, &iotlb_gather->freelist);
INIT_LIST_HEAD(&pending->free_list.pages);
+
+ if (pt_feature(common, PT_FEAT_DETAILED_GATHER)) {
+ iotlb_gather->pt.leaf_levels_bitmap |=
+ pending->leaf_levels_bitmap;
+ iotlb_gather->pt.table_levels_bitmap |=
+ pending->table_levels_bitmap;
+ pending->leaf_levels_bitmap = 0;
+ pending->table_levels_bitmap = 0;
+ }
}
#define DOMAIN_NS(op) CONCATENATE(CONCATENATE(pt_iommu_, PTPFX), op)
*/
num_contig_lg2 = pt_entry_num_contig_lg2(&pts);
pt_clear_entries(&pts, num_contig_lg2);
+ gather_add_leaf(&unmap->pending, &pts);
num_oas += log2_to_int(num_contig_lg2);
if (pts.index < flush_start_index)
flush_start_index = pts.index;
* flushed (inclusive)
*/
unsigned long end;
- /**
- * @pgsize: The interval at which to perform the flush, only used
- * by arm-smmu-v3
- */
- size_t pgsize;
+
+ union {
+ /**
+ * @pgsize: The interval at which to perform the flush, only
+ * used by arm-smmu-v3
+ */
+ size_t pgsize;
+ struct {
+ /**
+ * @pt.leaf_levels_bitmap: Bitmap of generic_pt
+ * levels where leaf entries were unmapped. Bit 0
+ * means the leaf only level. If 0 no leafs
+ * were unmapped.
+ */
+ u8 leaf_levels_bitmap;
+ /**
+ * @pt.table_levels_bitmap: Bitmap of generic_pt levels
+ * of table entries that were removed. Bit 0 is never
+ * set, bit 1 means a table of all leafs was removed.
+ * When freelist is empty this must be 0.
+ */
+ u8 table_levels_bitmap;
+ } pt;
+ };
+
/**
* @freelist: Removed pages to free after sync, only used by
* iommupt