Skip to content

Commit 8186255

Browse files
nicolincjgunthorpe
authored andcommitted
iommufd/selftest: Fix iommufd_dirty_tracking with large hugepage sizes
The hugepage test cases of iommufd_dirty_tracking have the 64MB and 128MB coverages. Both of them are smaller than the default hugepage size 512MB, when CONFIG_PAGE_SIZE_64KB=y. However, these test cases have a variant of using huge pages, which would mmap(MAP_HUGETLB) using these smaller sizes than the system hugepag size. This results in the kernel aligning up the smaller size to 512MB. If a memory was located between the upper 64/128MB size boundary and the hugepage 512MB boundary, it would get wiped out: https://lore.kernel.org/all/[email protected]/ Given that this aligning up behavior is well documented, we have no choice but to allocate a hugepage aligned size to avoid this unintended wipe out. Instead of relying on the kernel's internal force alignment, pass the same size to posix_memalign() and map(). Also, fix the FIXTURE_TEARDOWN() misusing munmap() to free the memory from posix_memalign(), as munmap() doesn't destroy the allocator meta data. So, call free() instead. Fixes: a9af47e ("iommufd/selftest: Test IOMMU_HWPT_GET_DIRTY_BITMAP") Link: https://patch.msgid.link/r/1ea8609ae6d523fdd4d8efb179ddee79c8582cb6.1750787928.git.nicolinc@nvidia.com Cc: [email protected] Suggested-by: Jason Gunthorpe <[email protected]> Signed-off-by: Nicolin Chen <[email protected]> Signed-off-by: Jason Gunthorpe <[email protected]>
1 parent 86731a2 commit 8186255

File tree

1 file changed

+21
-9
lines changed

1 file changed

+21
-9
lines changed

tools/testing/selftests/iommu/iommufd.c

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2008,6 +2008,7 @@ FIXTURE_VARIANT(iommufd_dirty_tracking)
20082008

20092009
FIXTURE_SETUP(iommufd_dirty_tracking)
20102010
{
2011+
size_t mmap_buffer_size;
20112012
unsigned long size;
20122013
int mmap_flags;
20132014
void *vrc;
@@ -2022,22 +2023,33 @@ FIXTURE_SETUP(iommufd_dirty_tracking)
20222023
self->fd = open("/dev/iommu", O_RDWR);
20232024
ASSERT_NE(-1, self->fd);
20242025

2025-
rc = posix_memalign(&self->buffer, HUGEPAGE_SIZE, variant->buffer_size);
2026-
if (rc || !self->buffer) {
2027-
SKIP(return, "Skipping buffer_size=%lu due to errno=%d",
2028-
variant->buffer_size, rc);
2029-
}
2030-
20312026
mmap_flags = MAP_SHARED | MAP_ANONYMOUS | MAP_FIXED;
2027+
mmap_buffer_size = variant->buffer_size;
20322028
if (variant->hugepages) {
20332029
/*
20342030
* MAP_POPULATE will cause the kernel to fail mmap if THPs are
20352031
* not available.
20362032
*/
20372033
mmap_flags |= MAP_HUGETLB | MAP_POPULATE;
2034+
2035+
/*
2036+
* Allocation must be aligned to the HUGEPAGE_SIZE, because the
2037+
* following mmap() will automatically align the length to be a
2038+
* multiple of the underlying huge page size. Failing to do the
2039+
* same at this allocation will result in a memory overwrite by
2040+
* the mmap().
2041+
*/
2042+
if (mmap_buffer_size < HUGEPAGE_SIZE)
2043+
mmap_buffer_size = HUGEPAGE_SIZE;
2044+
}
2045+
2046+
rc = posix_memalign(&self->buffer, HUGEPAGE_SIZE, mmap_buffer_size);
2047+
if (rc || !self->buffer) {
2048+
SKIP(return, "Skipping buffer_size=%lu due to errno=%d",
2049+
mmap_buffer_size, rc);
20382050
}
20392051
assert((uintptr_t)self->buffer % HUGEPAGE_SIZE == 0);
2040-
vrc = mmap(self->buffer, variant->buffer_size, PROT_READ | PROT_WRITE,
2052+
vrc = mmap(self->buffer, mmap_buffer_size, PROT_READ | PROT_WRITE,
20412053
mmap_flags, -1, 0);
20422054
assert(vrc == self->buffer);
20432055

@@ -2066,8 +2078,8 @@ FIXTURE_SETUP(iommufd_dirty_tracking)
20662078

20672079
FIXTURE_TEARDOWN(iommufd_dirty_tracking)
20682080
{
2069-
munmap(self->buffer, variant->buffer_size);
2070-
munmap(self->bitmap, DIV_ROUND_UP(self->bitmap_size, BITS_PER_BYTE));
2081+
free(self->buffer);
2082+
free(self->bitmap);
20712083
teardown_iommufd(self->fd, _metadata);
20722084
}
20732085

0 commit comments

Comments
 (0)