Merge tag 'for-linus-iommufd' of git://git.kernel.org/pub/scm/linux/kernel/git/jgg/iommufd
Pull iommufd fixes from Jason Gunthorpe:
"Some changes to the userspace selftest framework cause the iommufd
tests to start failing. This turned out to be bugs in the iommufd side
that were just getting uncovered.
- Deal with MAP_HUGETLB mmaping more than requested even when in
MAP_FIXED mode
- Fixup missing error flow cleanup in the test
- Check that the memory allocations suceeded
- Suppress some bogus gcc 'may be used uninitialized' warnings"
* tag 'for-linus-iommufd' of git://git.kernel.org/pub/scm/linux/kernel/git/jgg/iommufd:
iommufd/selftest: Fix build warnings due to uninitialized mfd
iommufd/selftest: Add asserts testing global mfd
iommufd/selftest: Add missing close(mfd) in memfd_mmap()
iommufd/selftest: Fix iommufd_dirty_tracking with large hugepage sizes
This commit is contained in:
@@ -54,6 +54,8 @@ static __attribute__((constructor)) void setup_sizes(void)
|
||||
|
||||
mfd_buffer = memfd_mmap(BUFFER_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED,
|
||||
&mfd);
|
||||
assert(mfd_buffer != MAP_FAILED);
|
||||
assert(mfd > 0);
|
||||
}
|
||||
|
||||
FIXTURE(iommufd)
|
||||
@@ -1746,13 +1748,15 @@ TEST_F(iommufd_mock_domain, all_aligns)
|
||||
unsigned int end;
|
||||
uint8_t *buf;
|
||||
int prot = PROT_READ | PROT_WRITE;
|
||||
int mfd;
|
||||
int mfd = -1;
|
||||
|
||||
if (variant->file)
|
||||
buf = memfd_mmap(buf_size, prot, MAP_SHARED, &mfd);
|
||||
else
|
||||
buf = mmap(0, buf_size, prot, self->mmap_flags, -1, 0);
|
||||
ASSERT_NE(MAP_FAILED, buf);
|
||||
if (variant->file)
|
||||
ASSERT_GT(mfd, 0);
|
||||
check_refs(buf, buf_size, 0);
|
||||
|
||||
/*
|
||||
@@ -1798,13 +1802,15 @@ TEST_F(iommufd_mock_domain, all_aligns_copy)
|
||||
unsigned int end;
|
||||
uint8_t *buf;
|
||||
int prot = PROT_READ | PROT_WRITE;
|
||||
int mfd;
|
||||
int mfd = -1;
|
||||
|
||||
if (variant->file)
|
||||
buf = memfd_mmap(buf_size, prot, MAP_SHARED, &mfd);
|
||||
else
|
||||
buf = mmap(0, buf_size, prot, self->mmap_flags, -1, 0);
|
||||
ASSERT_NE(MAP_FAILED, buf);
|
||||
if (variant->file)
|
||||
ASSERT_GT(mfd, 0);
|
||||
check_refs(buf, buf_size, 0);
|
||||
|
||||
/*
|
||||
@@ -2008,6 +2014,7 @@ FIXTURE_VARIANT(iommufd_dirty_tracking)
|
||||
|
||||
FIXTURE_SETUP(iommufd_dirty_tracking)
|
||||
{
|
||||
size_t mmap_buffer_size;
|
||||
unsigned long size;
|
||||
int mmap_flags;
|
||||
void *vrc;
|
||||
@@ -2022,22 +2029,33 @@ FIXTURE_SETUP(iommufd_dirty_tracking)
|
||||
self->fd = open("/dev/iommu", O_RDWR);
|
||||
ASSERT_NE(-1, self->fd);
|
||||
|
||||
rc = posix_memalign(&self->buffer, HUGEPAGE_SIZE, variant->buffer_size);
|
||||
if (rc || !self->buffer) {
|
||||
SKIP(return, "Skipping buffer_size=%lu due to errno=%d",
|
||||
variant->buffer_size, rc);
|
||||
}
|
||||
|
||||
mmap_flags = MAP_SHARED | MAP_ANONYMOUS | MAP_FIXED;
|
||||
mmap_buffer_size = variant->buffer_size;
|
||||
if (variant->hugepages) {
|
||||
/*
|
||||
* MAP_POPULATE will cause the kernel to fail mmap if THPs are
|
||||
* not available.
|
||||
*/
|
||||
mmap_flags |= MAP_HUGETLB | MAP_POPULATE;
|
||||
|
||||
/*
|
||||
* Allocation must be aligned to the HUGEPAGE_SIZE, because the
|
||||
* following mmap() will automatically align the length to be a
|
||||
* multiple of the underlying huge page size. Failing to do the
|
||||
* same at this allocation will result in a memory overwrite by
|
||||
* the mmap().
|
||||
*/
|
||||
if (mmap_buffer_size < HUGEPAGE_SIZE)
|
||||
mmap_buffer_size = HUGEPAGE_SIZE;
|
||||
}
|
||||
|
||||
rc = posix_memalign(&self->buffer, HUGEPAGE_SIZE, mmap_buffer_size);
|
||||
if (rc || !self->buffer) {
|
||||
SKIP(return, "Skipping buffer_size=%lu due to errno=%d",
|
||||
mmap_buffer_size, rc);
|
||||
}
|
||||
assert((uintptr_t)self->buffer % HUGEPAGE_SIZE == 0);
|
||||
vrc = mmap(self->buffer, variant->buffer_size, PROT_READ | PROT_WRITE,
|
||||
vrc = mmap(self->buffer, mmap_buffer_size, PROT_READ | PROT_WRITE,
|
||||
mmap_flags, -1, 0);
|
||||
assert(vrc == self->buffer);
|
||||
|
||||
@@ -2066,8 +2084,8 @@ FIXTURE_SETUP(iommufd_dirty_tracking)
|
||||
|
||||
FIXTURE_TEARDOWN(iommufd_dirty_tracking)
|
||||
{
|
||||
munmap(self->buffer, variant->buffer_size);
|
||||
munmap(self->bitmap, DIV_ROUND_UP(self->bitmap_size, BITS_PER_BYTE));
|
||||
free(self->buffer);
|
||||
free(self->bitmap);
|
||||
teardown_iommufd(self->fd, _metadata);
|
||||
}
|
||||
|
||||
|
||||
@@ -60,13 +60,18 @@ static inline void *memfd_mmap(size_t length, int prot, int flags, int *mfd_p)
|
||||
{
|
||||
int mfd_flags = (flags & MAP_HUGETLB) ? MFD_HUGETLB : 0;
|
||||
int mfd = memfd_create("buffer", mfd_flags);
|
||||
void *buf = MAP_FAILED;
|
||||
|
||||
if (mfd <= 0)
|
||||
return MAP_FAILED;
|
||||
if (ftruncate(mfd, length))
|
||||
return MAP_FAILED;
|
||||
goto out;
|
||||
*mfd_p = mfd;
|
||||
return mmap(0, length, prot, flags, mfd, 0);
|
||||
buf = mmap(0, length, prot, flags, mfd, 0);
|
||||
out:
|
||||
if (buf == MAP_FAILED)
|
||||
close(mfd);
|
||||
return buf;
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
Reference in New Issue
Block a user