diff options
Diffstat (limited to 'drivers/iommu/generic_pt/iommu_pt.h')
| -rw-r--r-- | drivers/iommu/generic_pt/iommu_pt.h | 16 |
1 files changed, 12 insertions, 4 deletions
diff --git a/drivers/iommu/generic_pt/iommu_pt.h b/drivers/iommu/generic_pt/iommu_pt.h index 3327116a441c..3e33fe64feab 100644 --- a/drivers/iommu/generic_pt/iommu_pt.h +++ b/drivers/iommu/generic_pt/iommu_pt.h @@ -58,10 +58,9 @@ static void gather_range_pages(struct iommu_iotlb_gather *iotlb_gather, * Note that the sync frees the gather's free list, so we must * not have any pages on that list that are covered by iova/len */ - } else if (pt_feature(common, PT_FEAT_FLUSH_RANGE)) { - iommu_iotlb_gather_add_range(iotlb_gather, iova, len); } + iommu_iotlb_gather_add_range(iotlb_gather, iova, len); iommu_pages_list_splice(free_list, &iotlb_gather->freelist); } @@ -645,7 +644,7 @@ static __always_inline int __do_map_single_page(struct pt_range *range, struct pt_iommu_map_args *map = arg; pts.type = pt_load_single_entry(&pts); - if (level == 0) { + if (pts.level == 0) { if (pts.type != PT_ENTRY_EMPTY) return -EADDRINUSE; pt_install_leaf_entry(&pts, map->oa, PAGE_SHIFT, @@ -931,6 +930,8 @@ static __maybe_unused int __unmap_range(struct pt_range *range, void *arg, struct pt_table_p *table) { struct pt_state pts = pt_init(range, level, table); + unsigned int flush_start_index = UINT_MAX; + unsigned int flush_end_index = UINT_MAX; struct pt_unmap_args *unmap = arg; unsigned int num_oas = 0; unsigned int start_index; @@ -986,6 +987,9 @@ static __maybe_unused int __unmap_range(struct pt_range *range, void *arg, iommu_pages_list_add(&unmap->free_list, pts.table_lower); pt_clear_entries(&pts, ilog2(1)); + if (pts.index < flush_start_index) + flush_start_index = pts.index; + flush_end_index = pts.index + 1; } pts.index++; } else { @@ -999,7 +1003,10 @@ start_oa: num_contig_lg2 = pt_entry_num_contig_lg2(&pts); pt_clear_entries(&pts, num_contig_lg2); num_oas += log2_to_int(num_contig_lg2); + if (pts.index < flush_start_index) + flush_start_index = pts.index; pts.index += log2_to_int(num_contig_lg2); + flush_end_index = pts.index; } if (pts.index >= pts.end_index) break; @@ -1007,7 +1014,8 @@ start_oa: } while (true); unmap->unmapped += log2_mul(num_oas, pt_table_item_lg2sz(&pts)); - flush_writes_range(&pts, start_index, pts.index); + if (flush_start_index != flush_end_index) + flush_writes_range(&pts, flush_start_index, flush_end_index); return ret; } |
