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