Skip to content

Commit 31ef3d5

Browse files
jpemartinsgregkh
authored andcommitted
vfio/iova_bitmap: Fix PAGE_SIZE unaligned bitmaps
[ Upstream commit f38044e ] iova_bitmap_set() doesn't consider the end of the page boundary when the first bitmap page offset isn't zero, and wrongly changes the consecutive page right after. Consequently this leads to missing dirty pages from reported by the device as seen from the VMM. The current logic iterates over a given number of base pages and clamps it to the remaining indexes to iterate in the last page. Instead of having to consider extra pages to pin (e.g. first and extra pages), just handle the first page as its own range and let the rest of the bitmap be handled as if it was base page aligned. This is done by changing iova_bitmap_mapped_remaining() to return PAGE_SIZE - pgoff (on the first bitmap page), and leads to pgoff being set to 0 on following iterations. Fixes: 58ccf01 ("vfio: Add an IOVA bitmap support") Reported-by: Avihai Horon <[email protected]> Tested-by: Avihai Horon <[email protected]> Signed-off-by: Joao Martins <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Alex Williamson <[email protected]> Signed-off-by: Sasha Levin <[email protected]>
1 parent f0865e4 commit 31ef3d5

File tree

1 file changed

+6
-2
lines changed

1 file changed

+6
-2
lines changed

drivers/vfio/iova_bitmap.c

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -295,11 +295,15 @@ void iova_bitmap_free(struct iova_bitmap *bitmap)
295295
*/
296296
static unsigned long iova_bitmap_mapped_remaining(struct iova_bitmap *bitmap)
297297
{
298-
unsigned long remaining;
298+
unsigned long remaining, bytes;
299+
300+
/* Cap to one page in the first iteration, if PAGE_SIZE unaligned. */
301+
bytes = !bitmap->mapped.pgoff ? bitmap->mapped.npages << PAGE_SHIFT :
302+
PAGE_SIZE - bitmap->mapped.pgoff;
299303

300304
remaining = bitmap->mapped_total_index - bitmap->mapped_base_index;
301305
remaining = min_t(unsigned long, remaining,
302-
(bitmap->mapped.npages << PAGE_SHIFT) / sizeof(*bitmap->bitmap));
306+
bytes / sizeof(*bitmap->bitmap));
303307

304308
return remaining;
305309
}

0 commit comments

Comments
 (0)