Re: [PATCH v4 06/15] iommupt: Add unmap_pages op

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi,

On 8/26/25 10:18 AM, Jason Gunthorpe wrote:
> 
> Tested-by: Alejandro Jimenez <alejandro.j.jimenez@xxxxxxxxxx>
> Signed-off-by: Jason Gunthorpe <jgg@xxxxxxxxxx>
> ---
>  drivers/iommu/generic_pt/iommu_pt.h | 155 ++++++++++++++++++++++++++++
>  include/linux/generic_pt/iommu.h    |  10 +-
>  2 files changed, 163 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/iommu/generic_pt/iommu_pt.h b/drivers/iommu/generic_pt/iommu_pt.h
> index 9413f868a65bfa..53901a4a977935 100644
> --- a/drivers/iommu/generic_pt/iommu_pt.h
> +++ b/drivers/iommu/generic_pt/iommu_pt.h
> @@ -14,6 +14,29 @@
>  #include <linux/iommu.h>
>  #include "../iommu-pages.h"
>  #include <linux/export.h>
> +#include <linux/cleanup.h>
> +#include <linux/dma-mapping.h>
> +
> +static void gather_range_pages(struct iommu_iotlb_gather *iotlb_gather,
> +			       struct pt_iommu *iommu_table, pt_vaddr_t iova,
> +			       pt_vaddr_t len,
> +			       struct iommu_pages_list *free_list)
> +{
> +	struct pt_common *common = common_from_iommu(iommu_table);
> +
> +	if (pt_feature(common, PT_FEAT_FLUSH_RANGE_NO_GAPS) &&
> +	    iommu_iotlb_gather_is_disjoint(iotlb_gather, iova, len)) {
> +		iommu_iotlb_sync(&iommu_table->domain, 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_pages_list_splice(free_list, &iotlb_gather->freelist);
> +}
>  
>  #define DOMAIN_NS(op) CONCATENATE(CONCATENATE(pt_iommu_, PTPFX), op)
>  
> @@ -167,6 +190,138 @@ static inline struct pt_table_p *table_alloc_top(struct pt_common *common,
>  		log2_to_int(pt_top_memsize_lg2(common, top_of_table)));
>  }
>  

[snip]

> +
> +/**
> + * unmap_pages() - Make a range of IOVA empty/not present
> + * @iommu_table: Table to manipulate
> + * @iova: IO virtual address to start
> + * @pgsize: Length of each page
> + * @pgcount: Length of the range in pgsize units starting from @iova
> + * @gather: Gather struct that must be flushed on return

Eh, 2 of these @params don't match the function's arguments (names).

> + *
> + * unmap_pages() will remove a translation created by map_pages(). It cannot
> + * subdivide a mapping created by map_pages(), so it should be called with IOVA
> + * ranges that match those passed to map_pages(). The IOVA range can aggregate
> + * contiguous map_pages() calls so long as no individual range is split.
> + *
> + * Context: The caller must hold a write range lock that includes
> + * the whole range.
> + *
> + * Returns: Number of bytes of VA unmapped. iova + res will be the point
> + * unmapping stopped.
> + */
> +size_t DOMAIN_NS(unmap_pages)(struct iommu_domain *domain, unsigned long iova,
> +			      size_t pgsize, size_t pgcount,
> +			      struct iommu_iotlb_gather *iotlb_gather)
> +{
> +	struct pt_iommu *iommu_table =
> +		container_of(domain, struct pt_iommu, domain);
> +	struct pt_unmap_args unmap = { .free_list = IOMMU_PAGES_LIST_INIT(
> +					       unmap.free_list) };
> +	pt_vaddr_t len = pgsize * pgcount;
> +	struct pt_range range;
> +	int ret;
> +
> +	ret = make_range(common_from_iommu(iommu_table), &range, iova, len);
> +	if (ret)
> +		return 0;
> +
> +	pt_walk_range(&range, __unmap_range, &unmap);
> +
> +	gather_range_pages(iotlb_gather, iommu_table, iova, len,
> +			   &unmap.free_list);
> +
> +	return unmap.unmapped;
> +}
> +EXPORT_SYMBOL_NS_GPL(DOMAIN_NS(unmap_pages), "GENERIC_PT_IOMMU");
-- 
~Randy





[Index of Archives]     [Kernel Newbies]     [Security]     [Netfilter]     [Bugtraq]     [Linux FS]     [Yosemite Forum]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Samba]     [Video 4 Linux]     [Device Mapper]     [Linux Resources]

  Powered by Linux