iommufd/selftest: Fix dirty bitmap tests with u8 bitmaps
With 64k base pages, the first 128k iova length test requires less than a byte for a bitmap, exposing a bug in the tests that assume that bitmaps are at least a byte. Rather than dealing with bytes, have _test_mock_dirty_bitmaps() pass the number of bits. The caller functions are adjusted to also use bits as well, and converting to bytes when clearing, allocating and freeing the bitmap. Link: https://lore.kernel.org/r/20240627110105.62325-2-joao.m.martins@oracle.com Reported-by: Matt Ochs <mochs@nvidia.com> Fixes: a9af47e382a4 ("iommufd/selftest: Test IOMMU_HWPT_GET_DIRTY_BITMAP") Signed-off-by: Joao Martins <joao.m.martins@oracle.com> Reviewed-by: Kevin Tian <kevin.tian@intel.com> Tested-by: Matt Ochs <mochs@nvidia.com> Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
This commit is contained in:
parent
f2661062f1
commit
ec61f820a2
@ -1722,6 +1722,7 @@ FIXTURE_VARIANT(iommufd_dirty_tracking)
|
||||
|
||||
FIXTURE_SETUP(iommufd_dirty_tracking)
|
||||
{
|
||||
unsigned long size;
|
||||
int mmap_flags;
|
||||
void *vrc;
|
||||
int rc;
|
||||
@ -1749,12 +1750,11 @@ FIXTURE_SETUP(iommufd_dirty_tracking)
|
||||
assert(vrc == self->buffer);
|
||||
|
||||
self->page_size = MOCK_PAGE_SIZE;
|
||||
self->bitmap_size =
|
||||
variant->buffer_size / self->page_size / BITS_PER_BYTE;
|
||||
self->bitmap_size = variant->buffer_size / self->page_size;
|
||||
|
||||
/* Provision with an extra (PAGE_SIZE) for the unaligned case */
|
||||
rc = posix_memalign(&self->bitmap, PAGE_SIZE,
|
||||
self->bitmap_size + PAGE_SIZE);
|
||||
size = DIV_ROUND_UP(self->bitmap_size, BITS_PER_BYTE);
|
||||
rc = posix_memalign(&self->bitmap, PAGE_SIZE, size + PAGE_SIZE);
|
||||
assert(!rc);
|
||||
assert(self->bitmap);
|
||||
assert((uintptr_t)self->bitmap % PAGE_SIZE == 0);
|
||||
@ -1775,7 +1775,7 @@ FIXTURE_SETUP(iommufd_dirty_tracking)
|
||||
FIXTURE_TEARDOWN(iommufd_dirty_tracking)
|
||||
{
|
||||
munmap(self->buffer, variant->buffer_size);
|
||||
munmap(self->bitmap, self->bitmap_size);
|
||||
munmap(self->bitmap, DIV_ROUND_UP(self->bitmap_size, BITS_PER_BYTE));
|
||||
teardown_iommufd(self->fd, _metadata);
|
||||
}
|
||||
|
||||
|
@ -22,6 +22,8 @@
|
||||
#define BIT_MASK(nr) (1UL << ((nr) % __BITS_PER_LONG))
|
||||
#define BIT_WORD(nr) ((nr) / __BITS_PER_LONG)
|
||||
|
||||
#define DIV_ROUND_UP(n, d) (((n) + (d) - 1) / (d))
|
||||
|
||||
static inline void set_bit(unsigned int nr, unsigned long *addr)
|
||||
{
|
||||
unsigned long mask = BIT_MASK(nr);
|
||||
@ -346,12 +348,12 @@ static int _test_cmd_mock_domain_set_dirty(int fd, __u32 hwpt_id, size_t length,
|
||||
static int _test_mock_dirty_bitmaps(int fd, __u32 hwpt_id, size_t length,
|
||||
__u64 iova, size_t page_size,
|
||||
size_t pte_page_size, __u64 *bitmap,
|
||||
__u64 bitmap_size, __u32 flags,
|
||||
__u64 nbits, __u32 flags,
|
||||
struct __test_metadata *_metadata)
|
||||
{
|
||||
unsigned long npte = pte_page_size / page_size, pteset = 2 * npte;
|
||||
unsigned long nbits = bitmap_size * BITS_PER_BYTE;
|
||||
unsigned long j, i, nr = nbits / pteset ?: 1;
|
||||
unsigned long bitmap_size = DIV_ROUND_UP(nbits, BITS_PER_BYTE);
|
||||
__u64 out_dirty = 0;
|
||||
|
||||
/* Mark all even bits as dirty in the mock domain */
|
||||
|
Loading…
x
Reference in New Issue
Block a user