FROMLIST: selftests: Add a MREMAP_DONTUNMAP selftest for shmem

This test extends the current mremap tests to validate that
the MREMAP_DONTUNMAP operation can be performed on shmem mappings.

Signed-off-by: Brian Geffon <bgeffon@google.com>

Signed-off-by: Lokesh Gidra <lokeshgidra@google.com>
Link: https://lore.kernel.org/patchwork/patch/1401225/
Bug: 160737021
Bug: 169683130
Change-Id: Ib357e58526af739cf8df49fc9604372996a9a6b3
This commit is contained in:
Brian Geffon
2021-03-23 11:25:19 -07:00
committed by Alistair Delva
parent 1d695ccfc6
commit 0150526518

View File

@@ -127,6 +127,57 @@ static void mremap_dontunmap_simple()
"unable to unmap source mapping");
}
// This test validates that MREMAP_DONTUNMAP on a shared mapping works as expected.
static void mremap_dontunmap_simple_shmem()
{
unsigned long num_pages = 5;
int mem_fd = memfd_create("memfd", MFD_CLOEXEC);
BUG_ON(mem_fd < 0, "memfd_create");
BUG_ON(ftruncate(mem_fd, num_pages * page_size) < 0,
"ftruncate");
void *source_mapping =
mmap(NULL, num_pages * page_size, PROT_READ | PROT_WRITE,
MAP_FILE | MAP_SHARED, mem_fd, 0);
BUG_ON(source_mapping == MAP_FAILED, "mmap");
BUG_ON(close(mem_fd) < 0, "close");
memset(source_mapping, 'a', num_pages * page_size);
// Try to just move the whole mapping anywhere (not fixed).
void *dest_mapping =
mremap(source_mapping, num_pages * page_size, num_pages * page_size,
MREMAP_DONTUNMAP | MREMAP_MAYMOVE, NULL);
if (dest_mapping == MAP_FAILED && errno == EINVAL) {
// Old kernel which doesn't support MREMAP_DONTUNMAP on shmem.
BUG_ON(munmap(source_mapping, num_pages * page_size) == -1,
"unable to unmap source mapping");
return;
}
BUG_ON(dest_mapping == MAP_FAILED, "mremap");
// Validate that the pages have been moved, we know they were moved if
// the dest_mapping contains a's.
BUG_ON(check_region_contains_byte
(dest_mapping, num_pages * page_size, 'a') != 0,
"pages did not migrate");
// Because the region is backed by shmem, we will actually see the same
// memory at the source location still.
BUG_ON(check_region_contains_byte
(source_mapping, num_pages * page_size, 'a') != 0,
"source should have no ptes");
BUG_ON(munmap(dest_mapping, num_pages * page_size) == -1,
"unable to unmap destination mapping");
BUG_ON(munmap(source_mapping, num_pages * page_size) == -1,
"unable to unmap source mapping");
}
// This test validates MREMAP_DONTUNMAP will move page tables to a specific
// destination using MREMAP_FIXED, also while validating that the source
// remains intact.
@@ -300,6 +351,7 @@ int main(void)
BUG_ON(page_buffer == MAP_FAILED, "unable to mmap a page.");
mremap_dontunmap_simple();
mremap_dontunmap_simple_shmem();
mremap_dontunmap_simple_fixed();
mremap_dontunmap_partial_mapping();
mremap_dontunmap_partial_mapping_overwrite();