xref: /openbmc/linux/drivers/vfio/iova_bitmap.c (revision 060f35a317ef09101b128f399dce7ed13d019461)
158ccf019SJoao Martins // SPDX-License-Identifier: GPL-2.0
258ccf019SJoao Martins /*
358ccf019SJoao Martins  * Copyright (c) 2022, Oracle and/or its affiliates.
458ccf019SJoao Martins  * Copyright (c) 2022, NVIDIA CORPORATION & AFFILIATES. All rights reserved
558ccf019SJoao Martins  */
658ccf019SJoao Martins #include <linux/iova_bitmap.h>
758ccf019SJoao Martins #include <linux/mm.h>
8ea00d4edSJoao Martins #include <linux/slab.h>
958ccf019SJoao Martins #include <linux/highmem.h>
1058ccf019SJoao Martins 
1158ccf019SJoao Martins #define BITS_PER_PAGE (PAGE_SIZE * BITS_PER_BYTE)
1258ccf019SJoao Martins 
1358ccf019SJoao Martins /*
1458ccf019SJoao Martins  * struct iova_bitmap_map - A bitmap representing an IOVA range
1558ccf019SJoao Martins  *
1658ccf019SJoao Martins  * Main data structure for tracking mapped user pages of bitmap data.
1758ccf019SJoao Martins  *
1858ccf019SJoao Martins  * For example, for something recording dirty IOVAs, it will be provided a
1958ccf019SJoao Martins  * struct iova_bitmap structure, as a general structure for iterating the
2058ccf019SJoao Martins  * total IOVA range. The struct iova_bitmap_map, though, represents the
2158ccf019SJoao Martins  * subset of said IOVA space that is pinned by its parent structure (struct
2258ccf019SJoao Martins  * iova_bitmap).
2358ccf019SJoao Martins  *
2458ccf019SJoao Martins  * The user does not need to exact location of the bits in the bitmap.
2558ccf019SJoao Martins  * From user perspective the only API available is iova_bitmap_set() which
2658ccf019SJoao Martins  * records the IOVA *range* in the bitmap by setting the corresponding
2758ccf019SJoao Martins  * bits.
2858ccf019SJoao Martins  *
2958ccf019SJoao Martins  * The bitmap is an array of u64 whereas each bit represents an IOVA of
3058ccf019SJoao Martins  * range of (1 << pgshift). Thus formula for the bitmap data to be set is:
3158ccf019SJoao Martins  *
3258ccf019SJoao Martins  *   data[(iova / page_size) / 64] & (1ULL << (iova % 64))
3358ccf019SJoao Martins  */
3458ccf019SJoao Martins struct iova_bitmap_map {
3558ccf019SJoao Martins 	/* base IOVA representing bit 0 of the first page */
3658ccf019SJoao Martins 	unsigned long iova;
3758ccf019SJoao Martins 
3858ccf019SJoao Martins 	/* page size order that each bit granules to */
3958ccf019SJoao Martins 	unsigned long pgshift;
4058ccf019SJoao Martins 
4158ccf019SJoao Martins 	/* page offset of the first user page pinned */
4258ccf019SJoao Martins 	unsigned long pgoff;
4358ccf019SJoao Martins 
4458ccf019SJoao Martins 	/* number of pages pinned */
4558ccf019SJoao Martins 	unsigned long npages;
4658ccf019SJoao Martins 
4758ccf019SJoao Martins 	/* pinned pages representing the bitmap data */
4858ccf019SJoao Martins 	struct page **pages;
4958ccf019SJoao Martins };
5058ccf019SJoao Martins 
5158ccf019SJoao Martins /*
5258ccf019SJoao Martins  * struct iova_bitmap - The IOVA bitmap object
5358ccf019SJoao Martins  *
5458ccf019SJoao Martins  * Main data structure for iterating over the bitmap data.
5558ccf019SJoao Martins  *
5658ccf019SJoao Martins  * Abstracts the pinning work and iterates in IOVA ranges.
5758ccf019SJoao Martins  * It uses a windowing scheme and pins the bitmap in relatively
5858ccf019SJoao Martins  * big ranges e.g.
5958ccf019SJoao Martins  *
6058ccf019SJoao Martins  * The bitmap object uses one base page to store all the pinned pages
6158ccf019SJoao Martins  * pointers related to the bitmap. For sizeof(struct page*) == 8 it stores
6258ccf019SJoao Martins  * 512 struct page pointers which, if the base page size is 4K, it means
6358ccf019SJoao Martins  * 2M of bitmap data is pinned at a time. If the iova_bitmap page size is
6458ccf019SJoao Martins  * also 4K then the range window to iterate is 64G.
6558ccf019SJoao Martins  *
6658ccf019SJoao Martins  * For example iterating on a total IOVA range of 4G..128G, it will walk
6758ccf019SJoao Martins  * through this set of ranges:
6858ccf019SJoao Martins  *
6958ccf019SJoao Martins  *    4G  -  68G-1 (64G)
7058ccf019SJoao Martins  *    68G - 128G-1 (64G)
7158ccf019SJoao Martins  *
7258ccf019SJoao Martins  * An example of the APIs on how to use/iterate over the IOVA bitmap:
7358ccf019SJoao Martins  *
7458ccf019SJoao Martins  *   bitmap = iova_bitmap_alloc(iova, length, page_size, data);
7558ccf019SJoao Martins  *   if (IS_ERR(bitmap))
7658ccf019SJoao Martins  *       return PTR_ERR(bitmap);
7758ccf019SJoao Martins  *
7858ccf019SJoao Martins  *   ret = iova_bitmap_for_each(bitmap, arg, dirty_reporter_fn);
7958ccf019SJoao Martins  *
8058ccf019SJoao Martins  *   iova_bitmap_free(bitmap);
8158ccf019SJoao Martins  *
8258ccf019SJoao Martins  * Each iteration of the @dirty_reporter_fn is called with a unique @iova
8358ccf019SJoao Martins  * and @length argument, indicating the current range available through the
8458ccf019SJoao Martins  * iova_bitmap. The @dirty_reporter_fn uses iova_bitmap_set() to mark dirty
8558ccf019SJoao Martins  * areas (@iova_length) within that provided range, as following:
8658ccf019SJoao Martins  *
8758ccf019SJoao Martins  *   iova_bitmap_set(bitmap, iova, iova_length);
8858ccf019SJoao Martins  *
8958ccf019SJoao Martins  * The internals of the object uses an index @mapped_base_index that indexes
9058ccf019SJoao Martins  * which u64 word of the bitmap is mapped, up to @mapped_total_index.
9158ccf019SJoao Martins  * Those keep being incremented until @mapped_total_index is reached while
9258ccf019SJoao Martins  * mapping up to PAGE_SIZE / sizeof(struct page*) maximum of pages.
9358ccf019SJoao Martins  *
9458ccf019SJoao Martins  * The IOVA bitmap is usually located on what tracks DMA mapped ranges or
9558ccf019SJoao Martins  * some form of IOVA range tracking that co-relates to the user passed
9658ccf019SJoao Martins  * bitmap.
9758ccf019SJoao Martins  */
9858ccf019SJoao Martins struct iova_bitmap {
9958ccf019SJoao Martins 	/* IOVA range representing the currently mapped bitmap data */
10058ccf019SJoao Martins 	struct iova_bitmap_map mapped;
10158ccf019SJoao Martins 
10258ccf019SJoao Martins 	/* userspace address of the bitmap */
103929766daSJoao Martins 	u8 __user *bitmap;
10458ccf019SJoao Martins 
10558ccf019SJoao Martins 	/* u64 index that @mapped points to */
10658ccf019SJoao Martins 	unsigned long mapped_base_index;
10758ccf019SJoao Martins 
10858ccf019SJoao Martins 	/* how many u64 can we walk in total */
10958ccf019SJoao Martins 	unsigned long mapped_total_index;
11058ccf019SJoao Martins 
11158ccf019SJoao Martins 	/* base IOVA of the whole bitmap */
11258ccf019SJoao Martins 	unsigned long iova;
11358ccf019SJoao Martins 
11458ccf019SJoao Martins 	/* length of the IOVA range for the whole bitmap */
11558ccf019SJoao Martins 	size_t length;
11658ccf019SJoao Martins };
11758ccf019SJoao Martins 
11858ccf019SJoao Martins /*
11958ccf019SJoao Martins  * Converts a relative IOVA to a bitmap index.
12058ccf019SJoao Martins  * This function provides the index into the u64 array (bitmap::bitmap)
12158ccf019SJoao Martins  * for a given IOVA offset.
12258ccf019SJoao Martins  * Relative IOVA means relative to the bitmap::mapped base IOVA
12358ccf019SJoao Martins  * (stored in mapped::iova). All computations in this file are done using
12458ccf019SJoao Martins  * relative IOVAs and thus avoid an extra subtraction against mapped::iova.
12558ccf019SJoao Martins  * The user API iova_bitmap_set() always uses a regular absolute IOVAs.
12658ccf019SJoao Martins  */
iova_bitmap_offset_to_index(struct iova_bitmap * bitmap,unsigned long iova)12758ccf019SJoao Martins static unsigned long iova_bitmap_offset_to_index(struct iova_bitmap *bitmap,
12858ccf019SJoao Martins 						 unsigned long iova)
12958ccf019SJoao Martins {
130*38ac76fcSQasim Ijaz 	unsigned long pgsize = 1UL << bitmap->mapped.pgshift;
13158ccf019SJoao Martins 
13258ccf019SJoao Martins 	return iova / (BITS_PER_TYPE(*bitmap->bitmap) * pgsize);
13358ccf019SJoao Martins }
13458ccf019SJoao Martins 
13558ccf019SJoao Martins /*
13658ccf019SJoao Martins  * Converts a bitmap index to a *relative* IOVA.
13758ccf019SJoao Martins  */
iova_bitmap_index_to_offset(struct iova_bitmap * bitmap,unsigned long index)13858ccf019SJoao Martins static unsigned long iova_bitmap_index_to_offset(struct iova_bitmap *bitmap,
13958ccf019SJoao Martins 						 unsigned long index)
14058ccf019SJoao Martins {
14158ccf019SJoao Martins 	unsigned long pgshift = bitmap->mapped.pgshift;
14258ccf019SJoao Martins 
14358ccf019SJoao Martins 	return (index * BITS_PER_TYPE(*bitmap->bitmap)) << pgshift;
14458ccf019SJoao Martins }
14558ccf019SJoao Martins 
14658ccf019SJoao Martins /*
14758ccf019SJoao Martins  * Returns the base IOVA of the mapped range.
14858ccf019SJoao Martins  */
iova_bitmap_mapped_iova(struct iova_bitmap * bitmap)14958ccf019SJoao Martins static unsigned long iova_bitmap_mapped_iova(struct iova_bitmap *bitmap)
15058ccf019SJoao Martins {
15158ccf019SJoao Martins 	unsigned long skip = bitmap->mapped_base_index;
15258ccf019SJoao Martins 
15358ccf019SJoao Martins 	return bitmap->iova + iova_bitmap_index_to_offset(bitmap, skip);
15458ccf019SJoao Martins }
15558ccf019SJoao Martins 
15658ccf019SJoao Martins /*
15758ccf019SJoao Martins  * Pins the bitmap user pages for the current range window.
15858ccf019SJoao Martins  * This is internal to IOVA bitmap and called when advancing the
15958ccf019SJoao Martins  * index (@mapped_base_index) or allocating the bitmap.
16058ccf019SJoao Martins  */
iova_bitmap_get(struct iova_bitmap * bitmap)16158ccf019SJoao Martins static int iova_bitmap_get(struct iova_bitmap *bitmap)
16258ccf019SJoao Martins {
16358ccf019SJoao Martins 	struct iova_bitmap_map *mapped = &bitmap->mapped;
16458ccf019SJoao Martins 	unsigned long npages;
165929766daSJoao Martins 	u8 __user *addr;
16658ccf019SJoao Martins 	long ret;
16758ccf019SJoao Martins 
16858ccf019SJoao Martins 	/*
16958ccf019SJoao Martins 	 * @mapped_base_index is the index of the currently mapped u64 words
17058ccf019SJoao Martins 	 * that we have access. Anything before @mapped_base_index is not
17158ccf019SJoao Martins 	 * mapped. The range @mapped_base_index .. @mapped_total_index-1 is
17258ccf019SJoao Martins 	 * mapped but capped at a maximum number of pages.
17358ccf019SJoao Martins 	 */
17458ccf019SJoao Martins 	npages = DIV_ROUND_UP((bitmap->mapped_total_index -
17558ccf019SJoao Martins 			       bitmap->mapped_base_index) *
17658ccf019SJoao Martins 			       sizeof(*bitmap->bitmap), PAGE_SIZE);
17758ccf019SJoao Martins 
17858ccf019SJoao Martins 	/*
17958ccf019SJoao Martins 	 * Bitmap address to be pinned is calculated via pointer arithmetic
18058ccf019SJoao Martins 	 * with bitmap u64 word index.
18158ccf019SJoao Martins 	 */
18258ccf019SJoao Martins 	addr = bitmap->bitmap + bitmap->mapped_base_index;
18358ccf019SJoao Martins 
184c99e6b26SJoao Martins 	/*
185c99e6b26SJoao Martins 	 * We always cap at max number of 'struct page' a base page can fit.
186c99e6b26SJoao Martins 	 * This is, for example, on x86 means 2M of bitmap data max.
187c99e6b26SJoao Martins 	 */
188c99e6b26SJoao Martins 	npages = min(npages + !!offset_in_page(addr),
189c99e6b26SJoao Martins 		     PAGE_SIZE / sizeof(struct page *));
190c99e6b26SJoao Martins 
19158ccf019SJoao Martins 	ret = pin_user_pages_fast((unsigned long)addr, npages,
19258ccf019SJoao Martins 				  FOLL_WRITE, mapped->pages);
19358ccf019SJoao Martins 	if (ret <= 0)
19458ccf019SJoao Martins 		return -EFAULT;
19558ccf019SJoao Martins 
19658ccf019SJoao Martins 	mapped->npages = (unsigned long)ret;
19758ccf019SJoao Martins 	/* Base IOVA where @pages point to i.e. bit 0 of the first page */
19858ccf019SJoao Martins 	mapped->iova = iova_bitmap_mapped_iova(bitmap);
19958ccf019SJoao Martins 
20058ccf019SJoao Martins 	/*
20158ccf019SJoao Martins 	 * offset of the page where pinned pages bit 0 is located.
20258ccf019SJoao Martins 	 * This handles the case where the bitmap is not PAGE_SIZE
20358ccf019SJoao Martins 	 * aligned.
20458ccf019SJoao Martins 	 */
20558ccf019SJoao Martins 	mapped->pgoff = offset_in_page(addr);
20658ccf019SJoao Martins 	return 0;
20758ccf019SJoao Martins }
20858ccf019SJoao Martins 
20958ccf019SJoao Martins /*
21058ccf019SJoao Martins  * Unpins the bitmap user pages and clears @npages
21158ccf019SJoao Martins  * (un)pinning is abstracted from API user and it's done when advancing
21258ccf019SJoao Martins  * the index or freeing the bitmap.
21358ccf019SJoao Martins  */
iova_bitmap_put(struct iova_bitmap * bitmap)21458ccf019SJoao Martins static void iova_bitmap_put(struct iova_bitmap *bitmap)
21558ccf019SJoao Martins {
21658ccf019SJoao Martins 	struct iova_bitmap_map *mapped = &bitmap->mapped;
21758ccf019SJoao Martins 
21858ccf019SJoao Martins 	if (mapped->npages) {
21958ccf019SJoao Martins 		unpin_user_pages(mapped->pages, mapped->npages);
22058ccf019SJoao Martins 		mapped->npages = 0;
22158ccf019SJoao Martins 	}
22258ccf019SJoao Martins }
22358ccf019SJoao Martins 
22458ccf019SJoao Martins /**
22558ccf019SJoao Martins  * iova_bitmap_alloc() - Allocates an IOVA bitmap object
22658ccf019SJoao Martins  * @iova: Start address of the IOVA range
22758ccf019SJoao Martins  * @length: Length of the IOVA range
22858ccf019SJoao Martins  * @page_size: Page size of the IOVA bitmap. It defines what each bit
22958ccf019SJoao Martins  *             granularity represents
23058ccf019SJoao Martins  * @data: Userspace address of the bitmap
23158ccf019SJoao Martins  *
23258ccf019SJoao Martins  * Allocates an IOVA object and initializes all its fields including the
23358ccf019SJoao Martins  * first user pages of @data.
23458ccf019SJoao Martins  *
23558ccf019SJoao Martins  * Return: A pointer to a newly allocated struct iova_bitmap
23658ccf019SJoao Martins  * or ERR_PTR() on error.
23758ccf019SJoao Martins  */
iova_bitmap_alloc(unsigned long iova,size_t length,unsigned long page_size,u64 __user * data)23858ccf019SJoao Martins struct iova_bitmap *iova_bitmap_alloc(unsigned long iova, size_t length,
23958ccf019SJoao Martins 				      unsigned long page_size, u64 __user *data)
24058ccf019SJoao Martins {
24158ccf019SJoao Martins 	struct iova_bitmap_map *mapped;
24258ccf019SJoao Martins 	struct iova_bitmap *bitmap;
24358ccf019SJoao Martins 	int rc;
24458ccf019SJoao Martins 
24558ccf019SJoao Martins 	bitmap = kzalloc(sizeof(*bitmap), GFP_KERNEL);
24658ccf019SJoao Martins 	if (!bitmap)
24758ccf019SJoao Martins 		return ERR_PTR(-ENOMEM);
24858ccf019SJoao Martins 
24958ccf019SJoao Martins 	mapped = &bitmap->mapped;
25058ccf019SJoao Martins 	mapped->pgshift = __ffs(page_size);
251929766daSJoao Martins 	bitmap->bitmap = (u8 __user *)data;
25258ccf019SJoao Martins 	bitmap->mapped_total_index =
25358ccf019SJoao Martins 		iova_bitmap_offset_to_index(bitmap, length - 1) + 1;
25458ccf019SJoao Martins 	bitmap->iova = iova;
25558ccf019SJoao Martins 	bitmap->length = length;
25658ccf019SJoao Martins 	mapped->iova = iova;
25758ccf019SJoao Martins 	mapped->pages = (struct page **)__get_free_page(GFP_KERNEL);
25858ccf019SJoao Martins 	if (!mapped->pages) {
25958ccf019SJoao Martins 		rc = -ENOMEM;
26058ccf019SJoao Martins 		goto err;
26158ccf019SJoao Martins 	}
26258ccf019SJoao Martins 
26358ccf019SJoao Martins 	rc = iova_bitmap_get(bitmap);
26458ccf019SJoao Martins 	if (rc)
26558ccf019SJoao Martins 		goto err;
26658ccf019SJoao Martins 	return bitmap;
26758ccf019SJoao Martins 
26858ccf019SJoao Martins err:
26958ccf019SJoao Martins 	iova_bitmap_free(bitmap);
27058ccf019SJoao Martins 	return ERR_PTR(rc);
27158ccf019SJoao Martins }
27258ccf019SJoao Martins 
27358ccf019SJoao Martins /**
27458ccf019SJoao Martins  * iova_bitmap_free() - Frees an IOVA bitmap object
27558ccf019SJoao Martins  * @bitmap: IOVA bitmap to free
27658ccf019SJoao Martins  *
27758ccf019SJoao Martins  * It unpins and releases pages array memory and clears any leftover
27858ccf019SJoao Martins  * state.
27958ccf019SJoao Martins  */
iova_bitmap_free(struct iova_bitmap * bitmap)28058ccf019SJoao Martins void iova_bitmap_free(struct iova_bitmap *bitmap)
28158ccf019SJoao Martins {
28258ccf019SJoao Martins 	struct iova_bitmap_map *mapped = &bitmap->mapped;
28358ccf019SJoao Martins 
28458ccf019SJoao Martins 	iova_bitmap_put(bitmap);
28558ccf019SJoao Martins 
28658ccf019SJoao Martins 	if (mapped->pages) {
28758ccf019SJoao Martins 		free_page((unsigned long)mapped->pages);
28858ccf019SJoao Martins 		mapped->pages = NULL;
28958ccf019SJoao Martins 	}
29058ccf019SJoao Martins 
29158ccf019SJoao Martins 	kfree(bitmap);
29258ccf019SJoao Martins }
29358ccf019SJoao Martins 
29458ccf019SJoao Martins /*
29558ccf019SJoao Martins  * Returns the remaining bitmap indexes from mapped_total_index to process for
29658ccf019SJoao Martins  * the currently pinned bitmap pages.
29758ccf019SJoao Martins  */
iova_bitmap_mapped_remaining(struct iova_bitmap * bitmap)29858ccf019SJoao Martins static unsigned long iova_bitmap_mapped_remaining(struct iova_bitmap *bitmap)
29958ccf019SJoao Martins {
300f38044e5SJoao Martins 	unsigned long remaining, bytes;
301f38044e5SJoao Martins 
302b058ea3aSJoao Martins 	bytes = (bitmap->mapped.npages << PAGE_SHIFT) - bitmap->mapped.pgoff;
30358ccf019SJoao Martins 
30458ccf019SJoao Martins 	remaining = bitmap->mapped_total_index - bitmap->mapped_base_index;
30558ccf019SJoao Martins 	remaining = min_t(unsigned long, remaining,
306929766daSJoao Martins 			  DIV_ROUND_UP(bytes, sizeof(*bitmap->bitmap)));
30758ccf019SJoao Martins 
30858ccf019SJoao Martins 	return remaining;
30958ccf019SJoao Martins }
31058ccf019SJoao Martins 
31158ccf019SJoao Martins /*
31258ccf019SJoao Martins  * Returns the length of the mapped IOVA range.
31358ccf019SJoao Martins  */
iova_bitmap_mapped_length(struct iova_bitmap * bitmap)31458ccf019SJoao Martins static unsigned long iova_bitmap_mapped_length(struct iova_bitmap *bitmap)
31558ccf019SJoao Martins {
31658ccf019SJoao Martins 	unsigned long max_iova = bitmap->iova + bitmap->length - 1;
31758ccf019SJoao Martins 	unsigned long iova = iova_bitmap_mapped_iova(bitmap);
31858ccf019SJoao Martins 	unsigned long remaining;
31958ccf019SJoao Martins 
32058ccf019SJoao Martins 	/*
32158ccf019SJoao Martins 	 * iova_bitmap_mapped_remaining() returns a number of indexes which
32258ccf019SJoao Martins 	 * when converted to IOVA gives us a max length that the bitmap
32358ccf019SJoao Martins 	 * pinned data can cover. Afterwards, that is capped to
32458ccf019SJoao Martins 	 * only cover the IOVA range in @bitmap::iova .. @bitmap::length.
32558ccf019SJoao Martins 	 */
32658ccf019SJoao Martins 	remaining = iova_bitmap_index_to_offset(bitmap,
32758ccf019SJoao Martins 			iova_bitmap_mapped_remaining(bitmap));
32858ccf019SJoao Martins 
32958ccf019SJoao Martins 	if (iova + remaining - 1 > max_iova)
33058ccf019SJoao Martins 		remaining -= ((iova + remaining - 1) - max_iova);
33158ccf019SJoao Martins 
33258ccf019SJoao Martins 	return remaining;
33358ccf019SJoao Martins }
33458ccf019SJoao Martins 
33558ccf019SJoao Martins /*
33658ccf019SJoao Martins  * Returns true if there's not more data to iterate.
33758ccf019SJoao Martins  */
iova_bitmap_done(struct iova_bitmap * bitmap)33858ccf019SJoao Martins static bool iova_bitmap_done(struct iova_bitmap *bitmap)
33958ccf019SJoao Martins {
34058ccf019SJoao Martins 	return bitmap->mapped_base_index >= bitmap->mapped_total_index;
34158ccf019SJoao Martins }
34258ccf019SJoao Martins 
34358ccf019SJoao Martins /*
34458ccf019SJoao Martins  * Advances to the next range, releases the current pinned
34558ccf019SJoao Martins  * pages and pins the next set of bitmap pages.
34658ccf019SJoao Martins  * Returns 0 on success or otherwise errno.
34758ccf019SJoao Martins  */
iova_bitmap_advance(struct iova_bitmap * bitmap)34858ccf019SJoao Martins static int iova_bitmap_advance(struct iova_bitmap *bitmap)
34958ccf019SJoao Martins {
35058ccf019SJoao Martins 	unsigned long iova = iova_bitmap_mapped_length(bitmap) - 1;
35158ccf019SJoao Martins 	unsigned long count = iova_bitmap_offset_to_index(bitmap, iova) + 1;
35258ccf019SJoao Martins 
35358ccf019SJoao Martins 	bitmap->mapped_base_index += count;
35458ccf019SJoao Martins 
35558ccf019SJoao Martins 	iova_bitmap_put(bitmap);
35658ccf019SJoao Martins 	if (iova_bitmap_done(bitmap))
35758ccf019SJoao Martins 		return 0;
35858ccf019SJoao Martins 
35958ccf019SJoao Martins 	/* When advancing the index we pin the next set of bitmap pages */
36058ccf019SJoao Martins 	return iova_bitmap_get(bitmap);
36158ccf019SJoao Martins }
36258ccf019SJoao Martins 
36358ccf019SJoao Martins /**
36458ccf019SJoao Martins  * iova_bitmap_for_each() - Iterates over the bitmap
36558ccf019SJoao Martins  * @bitmap: IOVA bitmap to iterate
36658ccf019SJoao Martins  * @opaque: Additional argument to pass to the callback
36758ccf019SJoao Martins  * @fn: Function that gets called for each IOVA range
36858ccf019SJoao Martins  *
36958ccf019SJoao Martins  * Helper function to iterate over bitmap data representing a portion of IOVA
37058ccf019SJoao Martins  * space. It hides the complexity of iterating bitmaps and translating the
37158ccf019SJoao Martins  * mapped bitmap user pages into IOVA ranges to process.
37258ccf019SJoao Martins  *
37358ccf019SJoao Martins  * Return: 0 on success, and an error on failure either upon
37458ccf019SJoao Martins  * iteration or when the callback returns an error.
37558ccf019SJoao Martins  */
iova_bitmap_for_each(struct iova_bitmap * bitmap,void * opaque,iova_bitmap_fn_t fn)37658ccf019SJoao Martins int iova_bitmap_for_each(struct iova_bitmap *bitmap, void *opaque,
37758ccf019SJoao Martins 			 iova_bitmap_fn_t fn)
37858ccf019SJoao Martins {
37958ccf019SJoao Martins 	int ret = 0;
38058ccf019SJoao Martins 
38158ccf019SJoao Martins 	for (; !iova_bitmap_done(bitmap) && !ret;
38258ccf019SJoao Martins 	     ret = iova_bitmap_advance(bitmap)) {
38358ccf019SJoao Martins 		ret = fn(bitmap, iova_bitmap_mapped_iova(bitmap),
38458ccf019SJoao Martins 			 iova_bitmap_mapped_length(bitmap), opaque);
38558ccf019SJoao Martins 		if (ret)
38658ccf019SJoao Martins 			break;
38758ccf019SJoao Martins 	}
38858ccf019SJoao Martins 
38958ccf019SJoao Martins 	return ret;
39058ccf019SJoao Martins }
39158ccf019SJoao Martins 
39258ccf019SJoao Martins /**
39358ccf019SJoao Martins  * iova_bitmap_set() - Records an IOVA range in bitmap
39458ccf019SJoao Martins  * @bitmap: IOVA bitmap
39558ccf019SJoao Martins  * @iova: IOVA to start
39658ccf019SJoao Martins  * @length: IOVA range length
39758ccf019SJoao Martins  *
39858ccf019SJoao Martins  * Set the bits corresponding to the range [iova .. iova+length-1] in
39958ccf019SJoao Martins  * the user bitmap.
40058ccf019SJoao Martins  *
40158ccf019SJoao Martins  */
iova_bitmap_set(struct iova_bitmap * bitmap,unsigned long iova,size_t length)40258ccf019SJoao Martins void iova_bitmap_set(struct iova_bitmap *bitmap,
40358ccf019SJoao Martins 		     unsigned long iova, size_t length)
40458ccf019SJoao Martins {
40558ccf019SJoao Martins 	struct iova_bitmap_map *mapped = &bitmap->mapped;
406b058ea3aSJoao Martins 	unsigned long cur_bit = ((iova - mapped->iova) >>
407b058ea3aSJoao Martins 			mapped->pgshift) + mapped->pgoff * BITS_PER_BYTE;
408b058ea3aSJoao Martins 	unsigned long last_bit = (((iova + length - 1) - mapped->iova) >>
409b058ea3aSJoao Martins 			mapped->pgshift) + mapped->pgoff * BITS_PER_BYTE;
41063474505SJoao Martins 	unsigned long last_page_idx = mapped->npages - 1;
41158ccf019SJoao Martins 
41258ccf019SJoao Martins 	do {
413b058ea3aSJoao Martins 		unsigned int page_idx = cur_bit / BITS_PER_PAGE;
414b058ea3aSJoao Martins 		unsigned int offset = cur_bit % BITS_PER_PAGE;
415b058ea3aSJoao Martins 		unsigned int nbits = min(BITS_PER_PAGE - offset,
416b058ea3aSJoao Martins 					 last_bit - cur_bit + 1);
417b058ea3aSJoao Martins 		void *kaddr;
41858ccf019SJoao Martins 
41963474505SJoao Martins 		if (unlikely(page_idx > last_page_idx))
42063474505SJoao Martins 			break;
42163474505SJoao Martins 
42258ccf019SJoao Martins 		kaddr = kmap_local_page(mapped->pages[page_idx]);
423b058ea3aSJoao Martins 		bitmap_set(kaddr, offset, nbits);
42458ccf019SJoao Martins 		kunmap_local(kaddr);
425b058ea3aSJoao Martins 		cur_bit += nbits;
426b058ea3aSJoao Martins 	} while (cur_bit <= last_bit);
42758ccf019SJoao Martins }
42858ccf019SJoao Martins EXPORT_SYMBOL_GPL(iova_bitmap_set);
429