// SPDX-License-Identifier: GPL-2.0
/* Copyright (c) 2021-2022, NVIDIA CORPORATION & AFFILIATES.
 *
 * The iopt_pages is the center of the storage and motion of PFNs. Each
 * iopt_pages represents a logical linear array of full PFNs. The array is 0
 * based and has npages in it. Accessors use 'index' to refer to the entry in
 * this logical array, regardless of its storage location.
 *
 * PFNs are stored in a tiered scheme:
 *  1) iopt_pages::pinned_pfns xarray
 *  2) An iommu_domain
 *  3) The origin of the PFNs, i.e. the userspace pointer
 *
 * PFN have to be copied between all combinations of tiers, depending on the
 * configuration.
 *
 * When a PFN is taken out of the userspace pointer it is pinned exactly once.
 * The storage locations of the PFN's index are tracked in the two interval
 * trees. If no interval includes the index then it is not pinned.
 *
 * If access_itree includes the PFN's index then an in-kernel access has
 * requested the page. The PFN is stored in the xarray so other requestors can
 * continue to find it.
 *
 * If the domains_itree includes the PFN's index then an iommu_domain is storing
 * the PFN and it can be read back using iommu_iova_to_phys(). To avoid
 * duplicating storage the xarray is not used if only iommu_domains are using
 * the PFN's index.
 *
 * As a general principle this is designed so that destroy never fails. This
 * means removing an iommu_domain or releasing a in-kernel access will not fail
 * due to insufficient memory. In practice this means some cases have to hold
 * PFNs in the xarray even though they are also being stored in an iommu_domain.
 *
 * While the iopt_pages can use an iommu_domain as storage, it does not have an
 * IOVA itself. Instead the iopt_area represents a range of IOVA and uses the
 * iopt_pages as the PFN provider. Multiple iopt_areas can share the iopt_pages
 * and reference their own slice of the PFN array, with sub page granularity.
 *
 * In this file the term 'last' indicates an inclusive and closed interval, eg
 * [0,0] refers to a single PFN. 'end' means an open range, eg [0,0) refers to
 * no PFNs.
 *
 * Be cautious of overflow. An IOVA can go all the way up to U64_MAX, so
 * last_iova + 1 can overflow. An iopt_pages index will always be much less than
 * ULONG_MAX so last_index + 1 cannot overflow.
 */
#include <linux/overflow.h>
#include <linux/slab.h>
#include <linux/iommu.h>
#include <linux/sched/mm.h>
#include <linux/highmem.h>
#include <linux/kthread.h>
#include <linux/iommufd.h>

#include "io_pagetable.h"
#include "double_span.h"

#ifndef CONFIG_IOMMUFD_TEST
#define TEMP_MEMORY_LIMIT 65536
#else
#define TEMP_MEMORY_LIMIT iommufd_test_memory_limit
#endif
#define BATCH_BACKUP_SIZE 32

/*
 * More memory makes pin_user_pages() and the batching more efficient, but as
 * this is only a performance optimization don't try too hard to get it. A 64k
 * allocation can hold about 26M of 4k pages and 13G of 2M pages in an
 * pfn_batch. Various destroy paths cannot fail and provide a small amount of
 * stack memory as a backup contingency. If backup_len is given this cannot
 * fail.
 */
static void *temp_kmalloc(size_t *size, void *backup, size_t backup_len)
{
	void *res;

	if (WARN_ON(*size == 0))
		return NULL;

	if (*size < backup_len)
		return backup;

	if (!backup && iommufd_should_fail())
		return NULL;

	*size = min_t(size_t, *size, TEMP_MEMORY_LIMIT);
	res = kmalloc(*size, GFP_KERNEL | __GFP_NOWARN | __GFP_NORETRY);
	if (res)
		return res;
	*size = PAGE_SIZE;
	if (backup_len) {
		res = kmalloc(*size, GFP_KERNEL | __GFP_NOWARN | __GFP_NORETRY);
		if (res)
			return res;
		*size = backup_len;
		return backup;
	}
	return kmalloc(*size, GFP_KERNEL);
}

void interval_tree_double_span_iter_update(
	struct interval_tree_double_span_iter *iter)
{
	unsigned long last_hole = ULONG_MAX;
	unsigned int i;

	for (i = 0; i != ARRAY_SIZE(iter->spans); i++) {
		if (interval_tree_span_iter_done(&iter->spans[i])) {
			iter->is_used = -1;
			return;
		}

		if (iter->spans[i].is_hole) {
			last_hole = min(last_hole, iter->spans[i].last_hole);
			continue;
		}

		iter->is_used = i + 1;
		iter->start_used = iter->spans[i].start_used;
		iter->last_used = min(iter->spans[i].last_used, last_hole);
		return;
	}

	iter->is_used = 0;
	iter->start_hole = iter->spans[0].start_hole;
	iter->last_hole =
		min(iter->spans[0].last_hole, iter->spans[1].last_hole);
}

void interval_tree_double_span_iter_first(
	struct interval_tree_double_span_iter *iter,
	struct rb_root_cached *itree1, struct rb_root_cached *itree2,
	unsigned long first_index, unsigned long last_index)
{
	unsigned int i;

	iter->itrees[0] = itree1;
	iter->itrees[1] = itree2;
	for (i = 0; i != ARRAY_SIZE(iter->spans); i++)
		interval_tree_span_iter_first(&iter->spans[i], iter->itrees[i],
					      first_index, last_index);
	interval_tree_double_span_iter_update(iter);
}

void interval_tree_double_span_iter_next(
	struct interval_tree_double_span_iter *iter)
{
	unsigned int i;

	if (iter->is_used == -1 ||
	    iter->last_hole == iter->spans[0].last_index) {
		iter->is_used = -1;
		return;
	}

	for (i = 0; i != ARRAY_SIZE(iter->spans); i++)
		interval_tree_span_iter_advance(
			&iter->spans[i], iter->itrees[i], iter->last_hole + 1);
	interval_tree_double_span_iter_update(iter);
}

static void iopt_pages_add_npinned(struct iopt_pages *pages, size_t npages)
{
	int rc;

	rc = check_add_overflow(pages->npinned, npages, &pages->npinned);
	if (IS_ENABLED(CONFIG_IOMMUFD_TEST))
		WARN_ON(rc || pages->npinned > pages->npages);
}

static void iopt_pages_sub_npinned(struct iopt_pages *pages, size_t npages)
{
	int rc;

	rc = check_sub_overflow(pages->npinned, npages, &pages->npinned);
	if (IS_ENABLED(CONFIG_IOMMUFD_TEST))
		WARN_ON(rc || pages->npinned > pages->npages);
}

static void iopt_pages_err_unpin(struct iopt_pages *pages,
				 unsigned long start_index,
				 unsigned long last_index,
				 struct page **page_list)
{
	unsigned long npages = last_index - start_index + 1;

	unpin_user_pages(page_list, npages);
	iopt_pages_sub_npinned(pages, npages);
}

/*
 * index is the number of PAGE_SIZE units from the start of the area's
 * iopt_pages. If the iova is sub page-size then the area has an iova that
 * covers a portion of the first and last pages in the range.
 */
static unsigned long iopt_area_index_to_iova(struct iopt_area *area,
					     unsigned long index)
{
	if (IS_ENABLED(CONFIG_IOMMUFD_TEST))
		WARN_ON(index < iopt_area_index(area) ||
			index > iopt_area_last_index(area));
	index -= iopt_area_index(area);
	if (index == 0)
		return iopt_area_iova(area);
	return iopt_area_iova(area) - area->page_offset + index * PAGE_SIZE;
}

static unsigned long iopt_area_index_to_iova_last(struct iopt_area *area,
						  unsigned long index)
{
	if (IS_ENABLED(CONFIG_IOMMUFD_TEST))
		WARN_ON(index < iopt_area_index(area) ||
			index > iopt_area_last_index(area));
	if (index == iopt_area_last_index(area))
		return iopt_area_last_iova(area);
	return iopt_area_iova(area) - area->page_offset +
	       (index - iopt_area_index(area) + 1) * PAGE_SIZE - 1;
}

static void iommu_unmap_nofail(struct iommu_domain *domain, unsigned long iova,
			       size_t size)
{
	size_t ret;

	ret = iommu_unmap(domain, iova, size);
	/*
	 * It is a logic error in this code or a driver bug if the IOMMU unmaps
	 * something other than exactly as requested. This implies that the
	 * iommu driver may not fail unmap for reasons beyond bad agruments.
	 * Particularly, the iommu driver may not do a memory allocation on the
	 * unmap path.
	 */
	WARN_ON(ret != size);
}

static void iopt_area_unmap_domain_range(struct iopt_area *area,
					 struct iommu_domain *domain,
					 unsigned long start_index,
					 unsigned long last_index)
{
	unsigned long start_iova = iopt_area_index_to_iova(area, start_index);

	iommu_unmap_nofail(domain, start_iova,
			   iopt_area_index_to_iova_last(area, last_index) -
				   start_iova + 1);
}

static struct iopt_area *iopt_pages_find_domain_area(struct iopt_pages *pages,
						     unsigned long index)
{
	struct interval_tree_node *node;

	node = interval_tree_iter_first(&pages->domains_itree, index, index);
	if (!node)
		return NULL;
	return container_of(node, struct iopt_area, pages_node);
}

/*
 * A simple datastructure to hold a vector of PFNs, optimized for contiguous
 * PFNs. This is used as a temporary holding memory for shuttling pfns from one
 * place to another. Generally everything is made more efficient if operations
 * work on the largest possible grouping of pfns. eg fewer lock/unlock cycles,
 * better cache locality, etc
 */
struct pfn_batch {
	unsigned long *pfns;
	u32 *npfns;
	unsigned int array_size;
	unsigned int end;
	unsigned int total_pfns;
};

static void batch_clear(struct pfn_batch *batch)
{
	batch->total_pfns = 0;
	batch->end = 0;
	batch->pfns[0] = 0;
	batch->npfns[0] = 0;
}

/*
 * Carry means we carry a portion of the final hugepage over to the front of the
 * batch
 */
static void batch_clear_carry(struct pfn_batch *batch, unsigned int keep_pfns)
{
	if (!keep_pfns)
		return batch_clear(batch);

	if (IS_ENABLED(CONFIG_IOMMUFD_TEST))
		WARN_ON(!batch->end ||
			batch->npfns[batch->end - 1] < keep_pfns);

	batch->total_pfns = keep_pfns;
	batch->pfns[0] = batch->pfns[batch->end - 1] +
			 (batch->npfns[batch->end - 1] - keep_pfns);
	batch->npfns[0] = keep_pfns;
	batch->end = 1;
}

static void batch_skip_carry(struct pfn_batch *batch, unsigned int skip_pfns)
{
	if (!batch->total_pfns)
		return;
	if (IS_ENABLED(CONFIG_IOMMUFD_TEST))
		WARN_ON(batch->total_pfns != batch->npfns[0]);
	skip_pfns = min(batch->total_pfns, skip_pfns);
	batch->pfns[0] += skip_pfns;
	batch->npfns[0] -= skip_pfns;
	batch->total_pfns -= skip_pfns;
}

static int __batch_init(struct pfn_batch *batch, size_t max_pages, void *backup,
			size_t backup_len)
{
	const size_t elmsz = sizeof(*batch->pfns) + sizeof(*batch->npfns);
	size_t size = max_pages * elmsz;

	batch->pfns = temp_kmalloc(&size, backup, backup_len);
	if (!batch->pfns)
		return -ENOMEM;
	if (IS_ENABLED(CONFIG_IOMMUFD_TEST) && WARN_ON(size < elmsz))
		return -EINVAL;
	batch->array_size = size / elmsz;
	batch->npfns = (u32 *)(batch->pfns + batch->array_size);
	batch_clear(batch);
	return 0;
}

static int batch_init(struct pfn_batch *batch, size_t max_pages)
{
	return __batch_init(batch, max_pages, NULL, 0);
}

static void batch_init_backup(struct pfn_batch *batch, size_t max_pages,
			      void *backup, size_t backup_len)
{
	__batch_init(batch, max_pages, backup, backup_len);
}

static void batch_destroy(struct pfn_batch *batch, void *backup)
{
	if (batch->pfns != backup)
		kfree(batch->pfns);
}

/* true if the pfn was added, false otherwise */
static bool batch_add_pfn(struct pfn_batch *batch, unsigned long pfn)
{
	const unsigned int MAX_NPFNS = type_max(typeof(*batch->npfns));

	if (batch->end &&
	    pfn == batch->pfns[batch->end - 1] + batch->npfns[batch->end - 1] &&
	    batch->npfns[batch->end - 1] != MAX_NPFNS) {
		batch->npfns[batch->end - 1]++;
		batch->total_pfns++;
		return true;
	}
	if (batch->end == batch->array_size)
		return false;
	batch->total_pfns++;
	batch->pfns[batch->end] = pfn;
	batch->npfns[batch->end] = 1;
	batch->end++;
	return true;
}

/*
 * Fill the batch with pfns from the domain. When the batch is full, or it
 * reaches last_index, the function will return. The caller should use
 * batch->total_pfns to determine the starting point for the next iteration.
 */
static void batch_from_domain(struct pfn_batch *batch,
			      struct iommu_domain *domain,
			      struct iopt_area *area, unsigned long start_index,
			      unsigned long last_index)
{
	unsigned int page_offset = 0;
	unsigned long iova;
	phys_addr_t phys;

	iova = iopt_area_index_to_iova(area, start_index);
	if (start_index == iopt_area_index(area))
		page_offset = area->page_offset;
	while (start_index <= last_index) {
		/*
		 * This is pretty slow, it would be nice to get the page size
		 * back from the driver, or have the driver directly fill the
		 * batch.
		 */
		phys = iommu_iova_to_phys(domain, iova) - page_offset;
		if (!batch_add_pfn(batch, PHYS_PFN(phys)))
			return;
		iova += PAGE_SIZE - page_offset;
		page_offset = 0;
		start_index++;
	}
}

static struct page **raw_pages_from_domain(struct iommu_domain *domain,
					   struct iopt_area *area,
					   unsigned long start_index,
					   unsigned long last_index,
					   struct page **out_pages)
{
	unsigned int page_offset = 0;
	unsigned long iova;
	phys_addr_t phys;

	iova = iopt_area_index_to_iova(area, start_index);
	if (start_index == iopt_area_index(area))
		page_offset = area->page_offset;
	while (start_index <= last_index) {
		phys = iommu_iova_to_phys(domain, iova) - page_offset;
		*(out_pages++) = pfn_to_page(PHYS_PFN(phys));
		iova += PAGE_SIZE - page_offset;
		page_offset = 0;
		start_index++;
	}
	return out_pages;
}

/* Continues reading a domain until we reach a discontinuity in the pfns. */
static void batch_from_domain_continue(struct pfn_batch *batch,
				       struct iommu_domain *domain,
				       struct iopt_area *area,
				       unsigned long start_index,
				       unsigned long last_index)
{
	unsigned int array_size = batch->array_size;

	batch->array_size = batch->end;
	batch_from_domain(batch, domain, area, start_index, last_index);
	batch->array_size = array_size;
}

/*
 * This is part of the VFIO compatibility support for VFIO_TYPE1_IOMMU. That
 * mode permits splitting a mapped area up, and then one of the splits is
 * unmapped. Doing this normally would cause us to violate our invariant of
 * pairing map/unmap. Thus, to support old VFIO compatibility disable support
 * for batching consecutive PFNs. All PFNs mapped into the iommu are done in
 * PAGE_SIZE units, not larger or smaller.
 */
static int batch_iommu_map_small(struct iommu_domain *domain,
				 unsigned long iova, phys_addr_t paddr,
				 size_t size, int prot)
{
	unsigned long start_iova = iova;
	int rc;

	if (IS_ENABLED(CONFIG_IOMMUFD_TEST))
		WARN_ON(paddr % PAGE_SIZE || iova % PAGE_SIZE ||
			size % PAGE_SIZE);

	while (size) {
		rc = iommu_map(domain, iova, paddr, PAGE_SIZE, prot,
			       GFP_KERNEL_ACCOUNT);
		if (rc)
			goto err_unmap;
		iova += PAGE_SIZE;
		paddr += PAGE_SIZE;
		size -= PAGE_SIZE;
	}
	return 0;

err_unmap:
	if (start_iova != iova)
		iommu_unmap_nofail(domain, start_iova, iova - start_iova);
	return rc;
}

static int batch_to_domain(struct pfn_batch *batch, struct iommu_domain *domain,
			   struct iopt_area *area, unsigned long start_index)
{
	bool disable_large_pages = area->iopt->disable_large_pages;
	unsigned long last_iova = iopt_area_last_iova(area);
	unsigned int page_offset = 0;
	unsigned long start_iova;
	unsigned long next_iova;
	unsigned int cur = 0;
	unsigned long iova;
	int rc;

	/* The first index might be a partial page */
	if (start_index == iopt_area_index(area))
		page_offset = area->page_offset;
	next_iova = iova = start_iova =
		iopt_area_index_to_iova(area, start_index);
	while (cur < batch->end) {
		next_iova = min(last_iova + 1,
				next_iova + batch->npfns[cur] * PAGE_SIZE -
					page_offset);
		if (disable_large_pages)
			rc = batch_iommu_map_small(
				domain, iova,
				PFN_PHYS(batch->pfns[cur]) + page_offset,
				next_iova - iova, area->iommu_prot);
		else
			rc = iommu_map(domain, iova,
				       PFN_PHYS(batch->pfns[cur]) + page_offset,
				       next_iova - iova, area->iommu_prot,
				       GFP_KERNEL_ACCOUNT);
		if (rc)
			goto err_unmap;
		iova = next_iova;
		page_offset = 0;
		cur++;
	}
	return 0;
err_unmap:
	if (start_iova != iova)
		iommu_unmap_nofail(domain, start_iova, iova - start_iova);
	return rc;
}

static void batch_from_xarray(struct pfn_batch *batch, struct xarray *xa,
			      unsigned long start_index,
			      unsigned long last_index)
{
	XA_STATE(xas, xa, start_index);
	void *entry;

	rcu_read_lock();
	while (true) {
		entry = xas_next(&xas);
		if (xas_retry(&xas, entry))
			continue;
		WARN_ON(!xa_is_value(entry));
		if (!batch_add_pfn(batch, xa_to_value(entry)) ||
		    start_index == last_index)
			break;
		start_index++;
	}
	rcu_read_unlock();
}

static void batch_from_xarray_clear(struct pfn_batch *batch, struct xarray *xa,
				    unsigned long start_index,
				    unsigned long last_index)
{
	XA_STATE(xas, xa, start_index);
	void *entry;

	xas_lock(&xas);
	while (true) {
		entry = xas_next(&xas);
		if (xas_retry(&xas, entry))
			continue;
		WARN_ON(!xa_is_value(entry));
		if (!batch_add_pfn(batch, xa_to_value(entry)))
			break;
		xas_store(&xas, NULL);
		if (start_index == last_index)
			break;
		start_index++;
	}
	xas_unlock(&xas);
}

static void clear_xarray(struct xarray *xa, unsigned long start_index,
			 unsigned long last_index)
{
	XA_STATE(xas, xa, start_index);
	void *entry;

	xas_lock(&xas);
	xas_for_each(&xas, entry, last_index)
		xas_store(&xas, NULL);
	xas_unlock(&xas);
}

static int pages_to_xarray(struct xarray *xa, unsigned long start_index,
			   unsigned long last_index, struct page **pages)
{
	struct page **end_pages = pages + (last_index - start_index) + 1;
	struct page **half_pages = pages + (end_pages - pages) / 2;
	XA_STATE(xas, xa, start_index);

	do {
		void *old;

		xas_lock(&xas);
		while (pages != end_pages) {
			/* xarray does not participate in fault injection */
			if (pages == half_pages && iommufd_should_fail()) {
				xas_set_err(&xas, -EINVAL);
				xas_unlock(&xas);
				/* aka xas_destroy() */
				xas_nomem(&xas, GFP_KERNEL);
				goto err_clear;
			}

			old = xas_store(&xas, xa_mk_value(page_to_pfn(*pages)));
			if (xas_error(&xas))
				break;
			WARN_ON(old);
			pages++;
			xas_next(&xas);
		}
		xas_unlock(&xas);
	} while (xas_nomem(&xas, GFP_KERNEL));

err_clear:
	if (xas_error(&xas)) {
		if (xas.xa_index != start_index)
			clear_xarray(xa, start_index, xas.xa_index - 1);
		return xas_error(&xas);
	}
	return 0;
}

static void batch_from_pages(struct pfn_batch *batch, struct page **pages,
			     size_t npages)
{
	struct page **end = pages + npages;

	for (; pages != end; pages++)
		if (!batch_add_pfn(batch, page_to_pfn(*pages)))
			break;
}

static void batch_unpin(struct pfn_batch *batch, struct iopt_pages *pages,
			unsigned int first_page_off, size_t npages)
{
	unsigned int cur = 0;

	while (first_page_off) {
		if (batch->npfns[cur] > first_page_off)
			break;
		first_page_off -= batch->npfns[cur];
		cur++;
	}

	while (npages) {
		size_t to_unpin = min_t(size_t, npages,
					batch->npfns[cur] - first_page_off);

		unpin_user_page_range_dirty_lock(
			pfn_to_page(batch->pfns[cur] + first_page_off),
			to_unpin, pages->writable);
		iopt_pages_sub_npinned(pages, to_unpin);
		cur++;
		first_page_off = 0;
		npages -= to_unpin;
	}
}

static void copy_data_page(struct page *page, void *data, unsigned long offset,
			   size_t length, unsigned int flags)
{
	void *mem;

	mem = kmap_local_page(page);
	if (flags & IOMMUFD_ACCESS_RW_WRITE) {
		memcpy(mem + offset, data, length);
		set_page_dirty_lock(page);
	} else {
		memcpy(data, mem + offset, length);
	}
	kunmap_local(mem);
}

static unsigned long batch_rw(struct pfn_batch *batch, void *data,
			      unsigned long offset, unsigned long length,
			      unsigned int flags)
{
	unsigned long copied = 0;
	unsigned int npage = 0;
	unsigned int cur = 0;

	while (cur < batch->end) {
		unsigned long bytes = min(length, PAGE_SIZE - offset);

		copy_data_page(pfn_to_page(batch->pfns[cur] + npage), data,
			       offset, bytes, flags);
		offset = 0;
		length -= bytes;
		data += bytes;
		copied += bytes;
		npage++;
		if (npage == batch->npfns[cur]) {
			npage = 0;
			cur++;
		}
		if (!length)
			break;
	}
	return copied;
}

/* pfn_reader_user is just the pin_user_pages() path */
struct pfn_reader_user {
	struct page **upages;
	size_t upages_len;
	unsigned long upages_start;
	unsigned long upages_end;
	unsigned int gup_flags;
	/*
	 * 1 means mmget() and mmap_read_lock(), 0 means only mmget(), -1 is
	 * neither
	 */
	int locked;
};

static void pfn_reader_user_init(struct pfn_reader_user *user,
				 struct iopt_pages *pages)
{
	user->upages = NULL;
	user->upages_start = 0;
	user->upages_end = 0;
	user->locked = -1;

	user->gup_flags = FOLL_LONGTERM;
	if (pages->writable)
		user->gup_flags |= FOLL_WRITE;
}

static void pfn_reader_user_destroy(struct pfn_reader_user *user,
				    struct iopt_pages *pages)
{
	if (user->locked != -1) {
		if (user->locked)
			mmap_read_unlock(pages->source_mm);
		if (pages->source_mm != current->mm)
			mmput(pages->source_mm);
		user->locked = -1;
	}

	kfree(user->upages);
	user->upages = NULL;
}

static int pfn_reader_user_pin(struct pfn_reader_user *user,
			       struct iopt_pages *pages,
			       unsigned long start_index,
			       unsigned long last_index)
{
	bool remote_mm = pages->source_mm != current->mm;
	unsigned long npages;
	uintptr_t uptr;
	long rc;

	if (IS_ENABLED(CONFIG_IOMMUFD_TEST) &&
	    WARN_ON(last_index < start_index))
		return -EINVAL;

	if (!user->upages) {
		/* All undone in pfn_reader_destroy() */
		user->upages_len =
			(last_index - start_index + 1) * sizeof(*user->upages);
		user->upages = temp_kmalloc(&user->upages_len, NULL, 0);
		if (!user->upages)
			return -ENOMEM;
	}

	if (user->locked == -1) {
		/*
		 * The majority of usages will run the map task within the mm
		 * providing the pages, so we can optimize into
		 * get_user_pages_fast()
		 */
		if (remote_mm) {
			if (!mmget_not_zero(pages->source_mm))
				return -EFAULT;
		}
		user->locked = 0;
	}

	npages = min_t(unsigned long, last_index - start_index + 1,
		       user->upages_len / sizeof(*user->upages));


	if (iommufd_should_fail())
		return -EFAULT;

	uptr = (uintptr_t)(pages->uptr + start_index * PAGE_SIZE);
	if (!remote_mm)
		rc = pin_user_pages_fast(uptr, npages, user->gup_flags,
					 user->upages);
	else {
		if (!user->locked) {
			mmap_read_lock(pages->source_mm);
			user->locked = 1;
		}
		rc = pin_user_pages_remote(pages->source_mm, uptr, npages,
					   user->gup_flags, user->upages,
					   &user->locked);
	}
	if (rc <= 0) {
		if (WARN_ON(!rc))
			return -EFAULT;
		return rc;
	}
	iopt_pages_add_npinned(pages, rc);
	user->upages_start = start_index;
	user->upages_end = start_index + rc;
	return 0;
}

/* This is the "modern" and faster accounting method used by io_uring */
static int incr_user_locked_vm(struct iopt_pages *pages, unsigned long npages)
{
	unsigned long lock_limit;
	unsigned long cur_pages;
	unsigned long new_pages;

	lock_limit = task_rlimit(pages->source_task, RLIMIT_MEMLOCK) >>
		     PAGE_SHIFT;
	do {
		cur_pages = atomic_long_read(&pages->source_user->locked_vm);
		new_pages = cur_pages + npages;
		if (new_pages > lock_limit)
			return -ENOMEM;
	} while (atomic_long_cmpxchg(&pages->source_user->locked_vm, cur_pages,
				     new_pages) != cur_pages);
	return 0;
}

static void decr_user_locked_vm(struct iopt_pages *pages, unsigned long npages)
{
	if (WARN_ON(atomic_long_read(&pages->source_user->locked_vm) < npages))
		return;
	atomic_long_sub(npages, &pages->source_user->locked_vm);
}

/* This is the accounting method used for compatibility with VFIO */
static int update_mm_locked_vm(struct iopt_pages *pages, unsigned long npages,
			       bool inc, struct pfn_reader_user *user)
{
	bool do_put = false;
	int rc;

	if (user && user->locked) {
		mmap_read_unlock(pages->source_mm);
		user->locked = 0;
		/* If we had the lock then we also have a get */
	} else if ((!user || !user->upages) &&
		   pages->source_mm != current->mm) {
		if (!mmget_not_zero(pages->source_mm))
			return -EINVAL;
		do_put = true;
	}

	mmap_write_lock(pages->source_mm);
	rc = __account_locked_vm(pages->source_mm, npages, inc,
				 pages->source_task, false);
	mmap_write_unlock(pages->source_mm);

	if (do_put)
		mmput(pages->source_mm);
	return rc;
}

static int do_update_pinned(struct iopt_pages *pages, unsigned long npages,
			    bool inc, struct pfn_reader_user *user)
{
	int rc = 0;

	switch (pages->account_mode) {
	case IOPT_PAGES_ACCOUNT_NONE:
		break;
	case IOPT_PAGES_ACCOUNT_USER:
		if (inc)
			rc = incr_user_locked_vm(pages, npages);
		else
			decr_user_locked_vm(pages, npages);
		break;
	case IOPT_PAGES_ACCOUNT_MM:
		rc = update_mm_locked_vm(pages, npages, inc, user);
		break;
	}
	if (rc)
		return rc;

	pages->last_npinned = pages->npinned;
	if (inc)
		atomic64_add(npages, &pages->source_mm->pinned_vm);
	else
		atomic64_sub(npages, &pages->source_mm->pinned_vm);
	return 0;
}

static void update_unpinned(struct iopt_pages *pages)
{
	if (WARN_ON(pages->npinned > pages->last_npinned))
		return;
	if (pages->npinned == pages->last_npinned)
		return;
	do_update_pinned(pages, pages->last_npinned - pages->npinned, false,
			 NULL);
}

/*
 * Changes in the number of pages pinned is done after the pages have been read
 * and processed. If the user lacked the limit then the error unwind will unpin
 * everything that was just pinned. This is because it is expensive to calculate
 * how many pages we have already pinned within a range to generate an accurate
 * prediction in advance of doing the work to actually pin them.
 */
static int pfn_reader_user_update_pinned(struct pfn_reader_user *user,
					 struct iopt_pages *pages)
{
	unsigned long npages;
	bool inc;

	lockdep_assert_held(&pages->mutex);

	if (pages->npinned == pages->last_npinned)
		return 0;

	if (pages->npinned < pages->last_npinned) {
		npages = pages->last_npinned - pages->npinned;
		inc = false;
	} else {
		if (iommufd_should_fail())
			return -ENOMEM;
		npages = pages->npinned - pages->last_npinned;
		inc = true;
	}
	return do_update_pinned(pages, npages, inc, user);
}

/*
 * PFNs are stored in three places, in order of preference:
 * - The iopt_pages xarray. This is only populated if there is a
 *   iopt_pages_access
 * - The iommu_domain under an area
 * - The original PFN source, ie pages->source_mm
 *
 * This iterator reads the pfns optimizing to load according to the
 * above order.
 */
struct pfn_reader {
	struct iopt_pages *pages;
	struct interval_tree_double_span_iter span;
	struct pfn_batch batch;
	unsigned long batch_start_index;
	unsigned long batch_end_index;
	unsigned long last_index;

	struct pfn_reader_user user;
};

static int pfn_reader_update_pinned(struct pfn_reader *pfns)
{
	return pfn_reader_user_update_pinned(&pfns->user, pfns->pages);
}

/*
 * The batch can contain a mixture of pages that are still in use and pages that
 * need to be unpinned. Unpin only pages that are not held anywhere else.
 */
static void pfn_reader_unpin(struct pfn_reader *pfns)
{
	unsigned long last = pfns->batch_end_index - 1;
	unsigned long start = pfns->batch_start_index;
	struct interval_tree_double_span_iter span;
	struct iopt_pages *pages = pfns->pages;

	lockdep_assert_held(&pages->mutex);

	interval_tree_for_each_double_span(&span, &pages->access_itree,
					   &pages->domains_itree, start, last) {
		if (span.is_used)
			continue;

		batch_unpin(&pfns->batch, pages, span.start_hole - start,
			    span.last_hole - span.start_hole + 1);
	}
}

/* Process a single span to load it from the proper storage */
static int pfn_reader_fill_span(struct pfn_reader *pfns)
{
	struct interval_tree_double_span_iter *span = &pfns->span;
	unsigned long start_index = pfns->batch_end_index;
	struct iopt_area *area;
	int rc;

	if (IS_ENABLED(CONFIG_IOMMUFD_TEST) &&
	    WARN_ON(span->last_used < start_index))
		return -EINVAL;

	if (span->is_used == 1) {
		batch_from_xarray(&pfns->batch, &pfns->pages->pinned_pfns,
				  start_index, span->last_used);
		return 0;
	}

	if (span->is_used == 2) {
		/*
		 * Pull as many pages from the first domain we find in the
		 * target span. If it is too small then we will be called again
		 * and we'll find another area.
		 */
		area = iopt_pages_find_domain_area(pfns->pages, start_index);
		if (WARN_ON(!area))
			return -EINVAL;

		/* The storage_domain cannot change without the pages mutex */
		batch_from_domain(
			&pfns->batch, area->storage_domain, area, start_index,
			min(iopt_area_last_index(area), span->last_used));
		return 0;
	}

	if (start_index >= pfns->user.upages_end) {
		rc = pfn_reader_user_pin(&pfns->user, pfns->pages, start_index,
					 span->last_hole);
		if (rc)
			return rc;
	}

	batch_from_pages(&pfns->batch,
			 pfns->user.upages +
				 (start_index - pfns->user.upages_start),
			 pfns->user.upages_end - start_index);
	return 0;
}

static bool pfn_reader_done(struct pfn_reader *pfns)
{
	return pfns->batch_start_index == pfns->last_index + 1;
}

static int pfn_reader_next(struct pfn_reader *pfns)
{
	int rc;

	batch_clear(&pfns->batch);
	pfns->batch_start_index = pfns->batch_end_index;

	while (pfns->batch_end_index != pfns->last_index + 1) {
		unsigned int npfns = pfns->batch.total_pfns;

		if (IS_ENABLED(CONFIG_IOMMUFD_TEST) &&
		    WARN_ON(interval_tree_double_span_iter_done(&pfns->span)))
			return -EINVAL;

		rc = pfn_reader_fill_span(pfns);
		if (rc)
			return rc;

		if (WARN_ON(!pfns->batch.total_pfns))
			return -EINVAL;

		pfns->batch_end_index =
			pfns->batch_start_index + pfns->batch.total_pfns;
		if (pfns->batch_end_index == pfns->span.last_used + 1)
			interval_tree_double_span_iter_next(&pfns->span);

		/* Batch is full */
		if (npfns == pfns->batch.total_pfns)
			return 0;
	}
	return 0;
}

static int pfn_reader_init(struct pfn_reader *pfns, struct iopt_pages *pages,
			   unsigned long start_index, unsigned long last_index)
{
	int rc;

	lockdep_assert_held(&pages->mutex);

	pfns->pages = pages;
	pfns->batch_start_index = start_index;
	pfns->batch_end_index = start_index;
	pfns->last_index = last_index;
	pfn_reader_user_init(&pfns->user, pages);
	rc = batch_init(&pfns->batch, last_index - start_index + 1);
	if (rc)
		return rc;
	interval_tree_double_span_iter_first(&pfns->span, &pages->access_itree,
					     &pages->domains_itree, start_index,
					     last_index);
	return 0;
}

/*
 * There are many assertions regarding the state of pages->npinned vs
 * pages->last_pinned, for instance something like unmapping a domain must only
 * decrement the npinned, and pfn_reader_destroy() must be called only after all
 * the pins are updated. This is fine for success flows, but error flows
 * sometimes need to release the pins held inside the pfn_reader before going on
 * to complete unmapping and releasing pins held in domains.
 */
static void pfn_reader_release_pins(struct pfn_reader *pfns)
{
	struct iopt_pages *pages = pfns->pages;

	if (pfns->user.upages_end > pfns->batch_end_index) {
		size_t npages = pfns->user.upages_end - pfns->batch_end_index;

		/* Any pages not transferred to the batch are just unpinned */
		unpin_user_pages(pfns->user.upages + (pfns->batch_end_index -
						      pfns->user.upages_start),
				 npages);
		iopt_pages_sub_npinned(pages, npages);
		pfns->user.upages_end = pfns->batch_end_index;
	}
	if (pfns->batch_start_index != pfns->batch_end_index) {
		pfn_reader_unpin(pfns);
		pfns->batch_start_index = pfns->batch_end_index;
	}
}

static void pfn_reader_destroy(struct pfn_reader *pfns)
{
	struct iopt_pages *pages = pfns->pages;

	pfn_reader_release_pins(pfns);
	pfn_reader_user_destroy(&pfns->user, pfns->pages);
	batch_destroy(&pfns->batch, NULL);
	WARN_ON(pages->last_npinned != pages->npinned);
}

static int pfn_reader_first(struct pfn_reader *pfns, struct iopt_pages *pages,
			    unsigned long start_index, unsigned long last_index)
{
	int rc;

	if (IS_ENABLED(CONFIG_IOMMUFD_TEST) &&
	    WARN_ON(last_index < start_index))
		return -EINVAL;

	rc = pfn_reader_init(pfns, pages, start_index, last_index);
	if (rc)
		return rc;
	rc = pfn_reader_next(pfns);
	if (rc) {
		pfn_reader_destroy(pfns);
		return rc;
	}
	return 0;
}

struct iopt_pages *iopt_alloc_pages(void __user *uptr, unsigned long length,
				    bool writable)
{
	struct iopt_pages *pages;
	unsigned long end;

	/*
	 * The iommu API uses size_t as the length, and protect the DIV_ROUND_UP
	 * below from overflow
	 */
	if (length > SIZE_MAX - PAGE_SIZE || length == 0)
		return ERR_PTR(-EINVAL);

	if (check_add_overflow((unsigned long)uptr, length, &end))
		return ERR_PTR(-EOVERFLOW);

	pages = kzalloc(sizeof(*pages), GFP_KERNEL_ACCOUNT);
	if (!pages)
		return ERR_PTR(-ENOMEM);

	kref_init(&pages->kref);
	xa_init_flags(&pages->pinned_pfns, XA_FLAGS_ACCOUNT);
	mutex_init(&pages->mutex);
	pages->source_mm = current->mm;
	mmgrab(pages->source_mm);
	pages->uptr = (void __user *)ALIGN_DOWN((uintptr_t)uptr, PAGE_SIZE);
	pages->npages = DIV_ROUND_UP(length + (uptr - pages->uptr), PAGE_SIZE);
	pages->access_itree = RB_ROOT_CACHED;
	pages->domains_itree = RB_ROOT_CACHED;
	pages->writable = writable;
	if (capable(CAP_IPC_LOCK))
		pages->account_mode = IOPT_PAGES_ACCOUNT_NONE;
	else
		pages->account_mode = IOPT_PAGES_ACCOUNT_USER;
	pages->source_task = current->group_leader;
	get_task_struct(current->group_leader);
	pages->source_user = get_uid(current_user());
	return pages;
}

void iopt_release_pages(struct kref *kref)
{
	struct iopt_pages *pages = container_of(kref, struct iopt_pages, kref);

	WARN_ON(!RB_EMPTY_ROOT(&pages->access_itree.rb_root));
	WARN_ON(!RB_EMPTY_ROOT(&pages->domains_itree.rb_root));
	WARN_ON(pages->npinned);
	WARN_ON(!xa_empty(&pages->pinned_pfns));
	mmdrop(pages->source_mm);
	mutex_destroy(&pages->mutex);
	put_task_struct(pages->source_task);
	free_uid(pages->source_user);
	kfree(pages);
}

static void
iopt_area_unpin_domain(struct pfn_batch *batch, struct iopt_area *area,
		       struct iopt_pages *pages, struct iommu_domain *domain,
		       unsigned long start_index, unsigned long last_index,
		       unsigned long *unmapped_end_index,
		       unsigned long real_last_index)
{
	while (start_index <= last_index) {
		unsigned long batch_last_index;

		if (*unmapped_end_index <= last_index) {
			unsigned long start =
				max(start_index, *unmapped_end_index);

			if (IS_ENABLED(CONFIG_IOMMUFD_TEST) &&
			    batch->total_pfns)
				WARN_ON(*unmapped_end_index -
						batch->total_pfns !=
					start_index);
			batch_from_domain(batch, domain, area, start,
					  last_index);
			batch_last_index = start_index + batch->total_pfns - 1;
		} else {
			batch_last_index = last_index;
		}

		if (IS_ENABLED(CONFIG_IOMMUFD_TEST))
			WARN_ON(batch_last_index > real_last_index);

		/*
		 * unmaps must always 'cut' at a place where the pfns are not
		 * contiguous to pair with the maps that always install
		 * contiguous pages. Thus, if we have to stop unpinning in the
		 * middle of the domains we need to keep reading pfns until we
		 * find a cut point to do the unmap. The pfns we read are
		 * carried over and either skipped or integrated into the next
		 * batch.
		 */
		if (batch_last_index == last_index &&
		    last_index != real_last_index)
			batch_from_domain_continue(batch, domain, area,
						   last_index + 1,
						   real_last_index);

		if (*unmapped_end_index <= batch_last_index) {
			iopt_area_unmap_domain_range(
				area, domain, *unmapped_end_index,
				start_index + batch->total_pfns - 1);
			*unmapped_end_index = start_index + batch->total_pfns;
		}

		/* unpin must follow unmap */
		batch_unpin(batch, pages, 0,
			    batch_last_index - start_index + 1);
		start_index = batch_last_index + 1;

		batch_clear_carry(batch,
				  *unmapped_end_index - batch_last_index - 1);
	}
}

static void __iopt_area_unfill_domain(struct iopt_area *area,
				      struct iopt_pages *pages,
				      struct iommu_domain *domain,
				      unsigned long last_index)
{
	struct interval_tree_double_span_iter span;
	unsigned long start_index = iopt_area_index(area);
	unsigned long unmapped_end_index = start_index;
	u64 backup[BATCH_BACKUP_SIZE];
	struct pfn_batch batch;

	lockdep_assert_held(&pages->mutex);

	/*
	 * For security we must not unpin something that is still DMA mapped,
	 * so this must unmap any IOVA before we go ahead and unpin the pages.
	 * This creates a complexity where we need to skip over unpinning pages
	 * held in the xarray, but continue to unmap from the domain.
	 *
	 * The domain unmap cannot stop in the middle of a contiguous range of
	 * PFNs. To solve this problem the unpinning step will read ahead to the
	 * end of any contiguous span, unmap that whole span, and then only
	 * unpin the leading part that does not have any accesses. The residual
	 * PFNs that were unmapped but not unpinned are called a "carry" in the
	 * batch as they are moved to the front of the PFN list and continue on
	 * to the next iteration(s).
	 */
	batch_init_backup(&batch, last_index + 1, backup, sizeof(backup));
	interval_tree_for_each_double_span(&span, &pages->domains_itree,
					   &pages->access_itree, start_index,
					   last_index) {
		if (span.is_used) {
			batch_skip_carry(&batch,
					 span.last_used - span.start_used + 1);
			continue;
		}
		iopt_area_unpin_domain(&batch, area, pages, domain,
				       span.start_hole, span.last_hole,
				       &unmapped_end_index, last_index);
	}
	/*
	 * If the range ends in a access then we do the residual unmap without
	 * any unpins.
	 */
	if (unmapped_end_index != last_index + 1)
		iopt_area_unmap_domain_range(area, domain, unmapped_end_index,
					     last_index);
	WARN_ON(batch.total_pfns);
	batch_destroy(&batch, backup);
	update_unpinned(pages);
}

static void iopt_area_unfill_partial_domain(struct iopt_area *area,
					    struct iopt_pages *pages,
					    struct iommu_domain *domain,
					    unsigned long end_index)
{
	if (end_index != iopt_area_index(area))
		__iopt_area_unfill_domain(area, pages, domain, end_index - 1);
}

/**
 * iopt_area_unmap_domain() - Unmap without unpinning PFNs in a domain
 * @area: The IOVA range to unmap
 * @domain: The domain to unmap
 *
 * The caller must know that unpinning is not required, usually because there
 * are other domains in the iopt.
 */
void iopt_area_unmap_domain(struct iopt_area *area, struct iommu_domain *domain)
{
	iommu_unmap_nofail(domain, iopt_area_iova(area),
			   iopt_area_length(area));
}

/**
 * iopt_area_unfill_domain() - Unmap and unpin PFNs in a domain
 * @area: IOVA area to use
 * @pages: page supplier for the area (area->pages is NULL)
 * @domain: Domain to unmap from
 *
 * The domain should be removed from the domains_itree before calling. The
 * domain will always be unmapped, but the PFNs may not be unpinned if there are
 * still accesses.
 */
void iopt_area_unfill_domain(struct iopt_area *area, struct iopt_pages *pages,
			     struct iommu_domain *domain)
{
	__iopt_area_unfill_domain(area, pages, domain,
				  iopt_area_last_index(area));
}

/**
 * iopt_area_fill_domain() - Map PFNs from the area into a domain
 * @area: IOVA area to use
 * @domain: Domain to load PFNs into
 *
 * Read the pfns from the area's underlying iopt_pages and map them into the
 * given domain. Called when attaching a new domain to an io_pagetable.
 */
int iopt_area_fill_domain(struct iopt_area *area, struct iommu_domain *domain)
{
	unsigned long done_end_index;
	struct pfn_reader pfns;
	int rc;

	lockdep_assert_held(&area->pages->mutex);

	rc = pfn_reader_first(&pfns, area->pages, iopt_area_index(area),
			      iopt_area_last_index(area));
	if (rc)
		return rc;

	while (!pfn_reader_done(&pfns)) {
		done_end_index = pfns.batch_start_index;
		rc = batch_to_domain(&pfns.batch, domain, area,
				     pfns.batch_start_index);
		if (rc)
			goto out_unmap;
		done_end_index = pfns.batch_end_index;

		rc = pfn_reader_next(&pfns);
		if (rc)
			goto out_unmap;
	}

	rc = pfn_reader_update_pinned(&pfns);
	if (rc)
		goto out_unmap;
	goto out_destroy;

out_unmap:
	pfn_reader_release_pins(&pfns);
	iopt_area_unfill_partial_domain(area, area->pages, domain,
					done_end_index);
out_destroy:
	pfn_reader_destroy(&pfns);
	return rc;
}

/**
 * iopt_area_fill_domains() - Install PFNs into the area's domains
 * @area: The area to act on
 * @pages: The pages associated with the area (area->pages is NULL)
 *
 * Called during area creation. The area is freshly created and not inserted in
 * the domains_itree yet. PFNs are read and loaded into every domain held in the
 * area's io_pagetable and the area is installed in the domains_itree.
 *
 * On failure all domains are left unchanged.
 */
int iopt_area_fill_domains(struct iopt_area *area, struct iopt_pages *pages)
{
	unsigned long done_first_end_index;
	unsigned long done_all_end_index;
	struct iommu_domain *domain;
	unsigned long unmap_index;
	struct pfn_reader pfns;
	unsigned long index;
	int rc;

	lockdep_assert_held(&area->iopt->domains_rwsem);

	if (xa_empty(&area->iopt->domains))
		return 0;

	mutex_lock(&pages->mutex);
	rc = pfn_reader_first(&pfns, pages, iopt_area_index(area),
			      iopt_area_last_index(area));
	if (rc)
		goto out_unlock;

	while (!pfn_reader_done(&pfns)) {
		done_first_end_index = pfns.batch_end_index;
		done_all_end_index = pfns.batch_start_index;
		xa_for_each(&area->iopt->domains, index, domain) {
			rc = batch_to_domain(&pfns.batch, domain, area,
					     pfns.batch_start_index);
			if (rc)
				goto out_unmap;
		}
		done_all_end_index = done_first_end_index;

		rc = pfn_reader_next(&pfns);
		if (rc)
			goto out_unmap;
	}
	rc = pfn_reader_update_pinned(&pfns);
	if (rc)
		goto out_unmap;

	area->storage_domain = xa_load(&area->iopt->domains, 0);
	interval_tree_insert(&area->pages_node, &pages->domains_itree);
	goto out_destroy;

out_unmap:
	pfn_reader_release_pins(&pfns);
	xa_for_each(&area->iopt->domains, unmap_index, domain) {
		unsigned long end_index;

		if (unmap_index < index)
			end_index = done_first_end_index;
		else
			end_index = done_all_end_index;

		/*
		 * The area is not yet part of the domains_itree so we have to
		 * manage the unpinning specially. The last domain does the
		 * unpin, every other domain is just unmapped.
		 */
		if (unmap_index != area->iopt->next_domain_id - 1) {
			if (end_index != iopt_area_index(area))
				iopt_area_unmap_domain_range(
					area, domain, iopt_area_index(area),
					end_index - 1);
		} else {
			iopt_area_unfill_partial_domain(area, pages, domain,
							end_index);
		}
	}
out_destroy:
	pfn_reader_destroy(&pfns);
out_unlock:
	mutex_unlock(&pages->mutex);
	return rc;
}

/**
 * iopt_area_unfill_domains() - unmap PFNs from the area's domains
 * @area: The area to act on
 * @pages: The pages associated with the area (area->pages is NULL)
 *
 * Called during area destruction. This unmaps the iova's covered by all the
 * area's domains and releases the PFNs.
 */
void iopt_area_unfill_domains(struct iopt_area *area, struct iopt_pages *pages)
{
	struct io_pagetable *iopt = area->iopt;
	struct iommu_domain *domain;
	unsigned long index;

	lockdep_assert_held(&iopt->domains_rwsem);

	mutex_lock(&pages->mutex);
	if (!area->storage_domain)
		goto out_unlock;

	xa_for_each(&iopt->domains, index, domain)
		if (domain != area->storage_domain)
			iopt_area_unmap_domain_range(
				area, domain, iopt_area_index(area),
				iopt_area_last_index(area));

	if (IS_ENABLED(CONFIG_IOMMUFD_TEST))
		WARN_ON(RB_EMPTY_NODE(&area->pages_node.rb));
	interval_tree_remove(&area->pages_node, &pages->domains_itree);
	iopt_area_unfill_domain(area, pages, area->storage_domain);
	area->storage_domain = NULL;
out_unlock:
	mutex_unlock(&pages->mutex);
}

static void iopt_pages_unpin_xarray(struct pfn_batch *batch,
				    struct iopt_pages *pages,
				    unsigned long start_index,
				    unsigned long end_index)
{
	while (start_index <= end_index) {
		batch_from_xarray_clear(batch, &pages->pinned_pfns, start_index,
					end_index);
		batch_unpin(batch, pages, 0, batch->total_pfns);
		start_index += batch->total_pfns;
		batch_clear(batch);
	}
}

/**
 * iopt_pages_unfill_xarray() - Update the xarry after removing an access
 * @pages: The pages to act on
 * @start_index: Starting PFN index
 * @last_index: Last PFN index
 *
 * Called when an iopt_pages_access is removed, removes pages from the itree.
 * The access should already be removed from the access_itree.
 */
void iopt_pages_unfill_xarray(struct iopt_pages *pages,
			      unsigned long start_index,
			      unsigned long last_index)
{
	struct interval_tree_double_span_iter span;
	u64 backup[BATCH_BACKUP_SIZE];
	struct pfn_batch batch;
	bool batch_inited = false;

	lockdep_assert_held(&pages->mutex);

	interval_tree_for_each_double_span(&span, &pages->access_itree,
					   &pages->domains_itree, start_index,
					   last_index) {
		if (!span.is_used) {
			if (!batch_inited) {
				batch_init_backup(&batch,
						  last_index - start_index + 1,
						  backup, sizeof(backup));
				batch_inited = true;
			}
			iopt_pages_unpin_xarray(&batch, pages, span.start_hole,
						span.last_hole);
		} else if (span.is_used == 2) {
			/* Covered by a domain */
			clear_xarray(&pages->pinned_pfns, span.start_used,
				     span.last_used);
		}
		/* Otherwise covered by an existing access */
	}
	if (batch_inited)
		batch_destroy(&batch, backup);
	update_unpinned(pages);
}

/**
 * iopt_pages_fill_from_xarray() - Fast path for reading PFNs
 * @pages: The pages to act on
 * @start_index: The first page index in the range
 * @last_index: The last page index in the range
 * @out_pages: The output array to return the pages
 *
 * This can be called if the caller is holding a refcount on an
 * iopt_pages_access that is known to have already been filled. It quickly reads
 * the pages directly from the xarray.
 *
 * This is part of the SW iommu interface to read pages for in-kernel use.
 */
void iopt_pages_fill_from_xarray(struct iopt_pages *pages,
				 unsigned long start_index,
				 unsigned long last_index,
				 struct page **out_pages)
{
	XA_STATE(xas, &pages->pinned_pfns, start_index);
	void *entry;

	rcu_read_lock();
	while (start_index <= last_index) {
		entry = xas_next(&xas);
		if (xas_retry(&xas, entry))
			continue;
		WARN_ON(!xa_is_value(entry));
		*(out_pages++) = pfn_to_page(xa_to_value(entry));
		start_index++;
	}
	rcu_read_unlock();
}

static int iopt_pages_fill_from_domain(struct iopt_pages *pages,
				       unsigned long start_index,
				       unsigned long last_index,
				       struct page **out_pages)
{
	while (start_index != last_index + 1) {
		unsigned long domain_last;
		struct iopt_area *area;

		area = iopt_pages_find_domain_area(pages, start_index);
		if (WARN_ON(!area))
			return -EINVAL;

		domain_last = min(iopt_area_last_index(area), last_index);
		out_pages = raw_pages_from_domain(area->storage_domain, area,
						  start_index, domain_last,
						  out_pages);
		start_index = domain_last + 1;
	}
	return 0;
}

static int iopt_pages_fill_from_mm(struct iopt_pages *pages,
				   struct pfn_reader_user *user,
				   unsigned long start_index,
				   unsigned long last_index,
				   struct page **out_pages)
{
	unsigned long cur_index = start_index;
	int rc;

	while (cur_index != last_index + 1) {
		user->upages = out_pages + (cur_index - start_index);
		rc = pfn_reader_user_pin(user, pages, cur_index, last_index);
		if (rc)
			goto out_unpin;
		cur_index = user->upages_end;
	}
	return 0;

out_unpin:
	if (start_index != cur_index)
		iopt_pages_err_unpin(pages, start_index, cur_index - 1,
				     out_pages);
	return rc;
}

/**
 * iopt_pages_fill_xarray() - Read PFNs
 * @pages: The pages to act on
 * @start_index: The first page index in the range
 * @last_index: The last page index in the range
 * @out_pages: The output array to return the pages, may be NULL
 *
 * This populates the xarray and returns the pages in out_pages. As the slow
 * path this is able to copy pages from other storage tiers into the xarray.
 *
 * On failure the xarray is left unchanged.
 *
 * This is part of the SW iommu interface to read pages for in-kernel use.
 */
int iopt_pages_fill_xarray(struct iopt_pages *pages, unsigned long start_index,
			   unsigned long last_index, struct page **out_pages)
{
	struct interval_tree_double_span_iter span;
	unsigned long xa_end = start_index;
	struct pfn_reader_user user;
	int rc;

	lockdep_assert_held(&pages->mutex);

	pfn_reader_user_init(&user, pages);
	user.upages_len = (last_index - start_index + 1) * sizeof(*out_pages);
	interval_tree_for_each_double_span(&span, &pages->access_itree,
					   &pages->domains_itree, start_index,
					   last_index) {
		struct page **cur_pages;

		if (span.is_used == 1) {
			cur_pages = out_pages + (span.start_used - start_index);
			iopt_pages_fill_from_xarray(pages, span.start_used,
						    span.last_used, cur_pages);
			continue;
		}

		if (span.is_used == 2) {
			cur_pages = out_pages + (span.start_used - start_index);
			iopt_pages_fill_from_domain(pages, span.start_used,
						    span.last_used, cur_pages);
			rc = pages_to_xarray(&pages->pinned_pfns,
					     span.start_used, span.last_used,
					     cur_pages);
			if (rc)
				goto out_clean_xa;
			xa_end = span.last_used + 1;
			continue;
		}

		/* hole */
		cur_pages = out_pages + (span.start_hole - start_index);
		rc = iopt_pages_fill_from_mm(pages, &user, span.start_hole,
					     span.last_hole, cur_pages);
		if (rc)
			goto out_clean_xa;
		rc = pages_to_xarray(&pages->pinned_pfns, span.start_hole,
				     span.last_hole, cur_pages);
		if (rc) {
			iopt_pages_err_unpin(pages, span.start_hole,
					     span.last_hole, cur_pages);
			goto out_clean_xa;
		}
		xa_end = span.last_hole + 1;
	}
	rc = pfn_reader_user_update_pinned(&user, pages);
	if (rc)
		goto out_clean_xa;
	user.upages = NULL;
	pfn_reader_user_destroy(&user, pages);
	return 0;

out_clean_xa:
	if (start_index != xa_end)
		iopt_pages_unfill_xarray(pages, start_index, xa_end - 1);
	user.upages = NULL;
	pfn_reader_user_destroy(&user, pages);
	return rc;
}

/*
 * This uses the pfn_reader instead of taking a shortcut by using the mm. It can
 * do every scenario and is fully consistent with what an iommu_domain would
 * see.
 */
static int iopt_pages_rw_slow(struct iopt_pages *pages,
			      unsigned long start_index,
			      unsigned long last_index, unsigned long offset,
			      void *data, unsigned long length,
			      unsigned int flags)
{
	struct pfn_reader pfns;
	int rc;

	mutex_lock(&pages->mutex);

	rc = pfn_reader_first(&pfns, pages, start_index, last_index);
	if (rc)
		goto out_unlock;

	while (!pfn_reader_done(&pfns)) {
		unsigned long done;

		done = batch_rw(&pfns.batch, data, offset, length, flags);
		data += done;
		length -= done;
		offset = 0;
		pfn_reader_unpin(&pfns);

		rc = pfn_reader_next(&pfns);
		if (rc)
			goto out_destroy;
	}
	if (WARN_ON(length != 0))
		rc = -EINVAL;
out_destroy:
	pfn_reader_destroy(&pfns);
out_unlock:
	mutex_unlock(&pages->mutex);
	return rc;
}

/*
 * A medium speed path that still allows DMA inconsistencies, but doesn't do any
 * memory allocations or interval tree searches.
 */
static int iopt_pages_rw_page(struct iopt_pages *pages, unsigned long index,
			      unsigned long offset, void *data,
			      unsigned long length, unsigned int flags)
{
	struct page *page = NULL;
	int rc;

	if (!mmget_not_zero(pages->source_mm))
		return iopt_pages_rw_slow(pages, index, index, offset, data,
					  length, flags);

	if (iommufd_should_fail()) {
		rc = -EINVAL;
		goto out_mmput;
	}

	mmap_read_lock(pages->source_mm);
	rc = pin_user_pages_remote(
		pages->source_mm, (uintptr_t)(pages->uptr + index * PAGE_SIZE),
		1, (flags & IOMMUFD_ACCESS_RW_WRITE) ? FOLL_WRITE : 0, &page,
		NULL);
	mmap_read_unlock(pages->source_mm);
	if (rc != 1) {
		if (WARN_ON(rc >= 0))
			rc = -EINVAL;
		goto out_mmput;
	}
	copy_data_page(page, data, offset, length, flags);
	unpin_user_page(page);
	rc = 0;

out_mmput:
	mmput(pages->source_mm);
	return rc;
}

/**
 * iopt_pages_rw_access - Copy to/from a linear slice of the pages
 * @pages: pages to act on
 * @start_byte: First byte of pages to copy to/from
 * @data: Kernel buffer to get/put the data
 * @length: Number of bytes to copy
 * @flags: IOMMUFD_ACCESS_RW_* flags
 *
 * This will find each page in the range, kmap it and then memcpy to/from
 * the given kernel buffer.
 */
int iopt_pages_rw_access(struct iopt_pages *pages, unsigned long start_byte,
			 void *data, unsigned long length, unsigned int flags)
{
	unsigned long start_index = start_byte / PAGE_SIZE;
	unsigned long last_index = (start_byte + length - 1) / PAGE_SIZE;
	bool change_mm = current->mm != pages->source_mm;
	int rc = 0;

	if (IS_ENABLED(CONFIG_IOMMUFD_TEST) &&
	    (flags & __IOMMUFD_ACCESS_RW_SLOW_PATH))
		change_mm = true;

	if ((flags & IOMMUFD_ACCESS_RW_WRITE) && !pages->writable)
		return -EPERM;

	if (!(flags & IOMMUFD_ACCESS_RW_KTHREAD) && change_mm) {
		if (start_index == last_index)
			return iopt_pages_rw_page(pages, start_index,
						  start_byte % PAGE_SIZE, data,
						  length, flags);
		return iopt_pages_rw_slow(pages, start_index, last_index,
					  start_byte % PAGE_SIZE, data, length,
					  flags);
	}

	/*
	 * Try to copy using copy_to_user(). We do this as a fast path and
	 * ignore any pinning inconsistencies, unlike a real DMA path.
	 */
	if (change_mm) {
		if (!mmget_not_zero(pages->source_mm))
			return iopt_pages_rw_slow(pages, start_index,
						  last_index,
						  start_byte % PAGE_SIZE, data,
						  length, flags);
		kthread_use_mm(pages->source_mm);
	}

	if (flags & IOMMUFD_ACCESS_RW_WRITE) {
		if (copy_to_user(pages->uptr + start_byte, data, length))
			rc = -EFAULT;
	} else {
		if (copy_from_user(data, pages->uptr + start_byte, length))
			rc = -EFAULT;
	}

	if (change_mm) {
		kthread_unuse_mm(pages->source_mm);
		mmput(pages->source_mm);
	}

	return rc;
}

static struct iopt_pages_access *
iopt_pages_get_exact_access(struct iopt_pages *pages, unsigned long index,
			    unsigned long last)
{
	struct interval_tree_node *node;

	lockdep_assert_held(&pages->mutex);

	/* There can be overlapping ranges in this interval tree */
	for (node = interval_tree_iter_first(&pages->access_itree, index, last);
	     node; node = interval_tree_iter_next(node, index, last))
		if (node->start == index && node->last == last)
			return container_of(node, struct iopt_pages_access,
					    node);
	return NULL;
}

/**
 * iopt_area_add_access() - Record an in-knerel access for PFNs
 * @area: The source of PFNs
 * @start_index: First page index
 * @last_index: Inclusive last page index
 * @out_pages: Output list of struct page's representing the PFNs
 * @flags: IOMMUFD_ACCESS_RW_* flags
 *
 * Record that an in-kernel access will be accessing the pages, ensure they are
 * pinned, and return the PFNs as a simple list of 'struct page *'.
 *
 * This should be undone through a matching call to iopt_area_remove_access()
 */
int iopt_area_add_access(struct iopt_area *area, unsigned long start_index,
			  unsigned long last_index, struct page **out_pages,
			  unsigned int flags)
{
	struct iopt_pages *pages = area->pages;
	struct iopt_pages_access *access;
	int rc;

	if ((flags & IOMMUFD_ACCESS_RW_WRITE) && !pages->writable)
		return -EPERM;

	mutex_lock(&pages->mutex);
	access = iopt_pages_get_exact_access(pages, start_index, last_index);
	if (access) {
		area->num_accesses++;
		access->users++;
		iopt_pages_fill_from_xarray(pages, start_index, last_index,
					    out_pages);
		mutex_unlock(&pages->mutex);
		return 0;
	}

	access = kzalloc(sizeof(*access), GFP_KERNEL_ACCOUNT);
	if (!access) {
		rc = -ENOMEM;
		goto err_unlock;
	}

	rc = iopt_pages_fill_xarray(pages, start_index, last_index, out_pages);
	if (rc)
		goto err_free;

	access->node.start = start_index;
	access->node.last = last_index;
	access->users = 1;
	area->num_accesses++;
	interval_tree_insert(&access->node, &pages->access_itree);
	mutex_unlock(&pages->mutex);
	return 0;

err_free:
	kfree(access);
err_unlock:
	mutex_unlock(&pages->mutex);
	return rc;
}

/**
 * iopt_area_remove_access() - Release an in-kernel access for PFNs
 * @area: The source of PFNs
 * @start_index: First page index
 * @last_index: Inclusive last page index
 *
 * Undo iopt_area_add_access() and unpin the pages if necessary. The caller
 * must stop using the PFNs before calling this.
 */
void iopt_area_remove_access(struct iopt_area *area, unsigned long start_index,
			     unsigned long last_index)
{
	struct iopt_pages *pages = area->pages;
	struct iopt_pages_access *access;

	mutex_lock(&pages->mutex);
	access = iopt_pages_get_exact_access(pages, start_index, last_index);
	if (WARN_ON(!access))
		goto out_unlock;

	WARN_ON(area->num_accesses == 0 || access->users == 0);
	area->num_accesses--;
	access->users--;
	if (access->users)
		goto out_unlock;

	interval_tree_remove(&access->node, &pages->access_itree);
	iopt_pages_unfill_xarray(pages, start_index, last_index);
	kfree(access);
out_unlock:
	mutex_unlock(&pages->mutex);
}
