forked from luck/tmp_suning_uos_patched
mm/hmm: add tests for hmm_pfn_to_map_order()
Add a sanity test for hmm_range_fault() returning the page mapping size order. Link: https://lore.kernel.org/r/20200701225352.9649-6-rcampbell@nvidia.com Signed-off-by: Ralph Campbell <rcampbell@nvidia.com> Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
This commit is contained in:
parent
3b50a6e536
commit
e478425bec
|
@ -766,6 +766,10 @@ static void dmirror_mkentry(struct dmirror *dmirror, struct hmm_range *range,
|
||||||
*perm |= HMM_DMIRROR_PROT_WRITE;
|
*perm |= HMM_DMIRROR_PROT_WRITE;
|
||||||
else
|
else
|
||||||
*perm |= HMM_DMIRROR_PROT_READ;
|
*perm |= HMM_DMIRROR_PROT_READ;
|
||||||
|
if (hmm_pfn_to_map_order(entry) + PAGE_SHIFT == PMD_SHIFT)
|
||||||
|
*perm |= HMM_DMIRROR_PROT_PMD;
|
||||||
|
else if (hmm_pfn_to_map_order(entry) + PAGE_SHIFT == PUD_SHIFT)
|
||||||
|
*perm |= HMM_DMIRROR_PROT_PUD;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool dmirror_snapshot_invalidate(struct mmu_interval_notifier *mni,
|
static bool dmirror_snapshot_invalidate(struct mmu_interval_notifier *mni,
|
||||||
|
|
|
@ -40,6 +40,8 @@ struct hmm_dmirror_cmd {
|
||||||
* HMM_DMIRROR_PROT_NONE: unpopulated PTE or PTE with no access
|
* HMM_DMIRROR_PROT_NONE: unpopulated PTE or PTE with no access
|
||||||
* HMM_DMIRROR_PROT_READ: read-only PTE
|
* HMM_DMIRROR_PROT_READ: read-only PTE
|
||||||
* HMM_DMIRROR_PROT_WRITE: read/write PTE
|
* HMM_DMIRROR_PROT_WRITE: read/write PTE
|
||||||
|
* HMM_DMIRROR_PROT_PMD: PMD sized page is fully mapped by same permissions
|
||||||
|
* HMM_DMIRROR_PROT_PUD: PUD sized page is fully mapped by same permissions
|
||||||
* HMM_DMIRROR_PROT_ZERO: special read-only zero page
|
* HMM_DMIRROR_PROT_ZERO: special read-only zero page
|
||||||
* HMM_DMIRROR_PROT_DEV_PRIVATE_LOCAL: Migrated device private page on the
|
* HMM_DMIRROR_PROT_DEV_PRIVATE_LOCAL: Migrated device private page on the
|
||||||
* device the ioctl() is made
|
* device the ioctl() is made
|
||||||
|
@ -51,6 +53,8 @@ enum {
|
||||||
HMM_DMIRROR_PROT_NONE = 0x00,
|
HMM_DMIRROR_PROT_NONE = 0x00,
|
||||||
HMM_DMIRROR_PROT_READ = 0x01,
|
HMM_DMIRROR_PROT_READ = 0x01,
|
||||||
HMM_DMIRROR_PROT_WRITE = 0x02,
|
HMM_DMIRROR_PROT_WRITE = 0x02,
|
||||||
|
HMM_DMIRROR_PROT_PMD = 0x04,
|
||||||
|
HMM_DMIRROR_PROT_PUD = 0x08,
|
||||||
HMM_DMIRROR_PROT_ZERO = 0x10,
|
HMM_DMIRROR_PROT_ZERO = 0x10,
|
||||||
HMM_DMIRROR_PROT_DEV_PRIVATE_LOCAL = 0x20,
|
HMM_DMIRROR_PROT_DEV_PRIVATE_LOCAL = 0x20,
|
||||||
HMM_DMIRROR_PROT_DEV_PRIVATE_REMOTE = 0x30,
|
HMM_DMIRROR_PROT_DEV_PRIVATE_REMOTE = 0x30,
|
||||||
|
|
|
@ -1291,6 +1291,82 @@ TEST_F(hmm2, snapshot)
|
||||||
hmm_buffer_free(buffer);
|
hmm_buffer_free(buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Test the hmm_range_fault() HMM_PFN_PMD flag for large pages that
|
||||||
|
* should be mapped by a large page table entry.
|
||||||
|
*/
|
||||||
|
TEST_F(hmm, compound)
|
||||||
|
{
|
||||||
|
struct hmm_buffer *buffer;
|
||||||
|
unsigned long npages;
|
||||||
|
unsigned long size;
|
||||||
|
int *ptr;
|
||||||
|
unsigned char *m;
|
||||||
|
int ret;
|
||||||
|
long pagesizes[4];
|
||||||
|
int n, idx;
|
||||||
|
unsigned long i;
|
||||||
|
|
||||||
|
/* Skip test if we can't allocate a hugetlbfs page. */
|
||||||
|
|
||||||
|
n = gethugepagesizes(pagesizes, 4);
|
||||||
|
if (n <= 0)
|
||||||
|
return;
|
||||||
|
for (idx = 0; --n > 0; ) {
|
||||||
|
if (pagesizes[n] < pagesizes[idx])
|
||||||
|
idx = n;
|
||||||
|
}
|
||||||
|
size = ALIGN(TWOMEG, pagesizes[idx]);
|
||||||
|
npages = size >> self->page_shift;
|
||||||
|
|
||||||
|
buffer = malloc(sizeof(*buffer));
|
||||||
|
ASSERT_NE(buffer, NULL);
|
||||||
|
|
||||||
|
buffer->ptr = get_hugepage_region(size, GHR_STRICT);
|
||||||
|
if (buffer->ptr == NULL) {
|
||||||
|
free(buffer);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
buffer->size = size;
|
||||||
|
buffer->mirror = malloc(npages);
|
||||||
|
ASSERT_NE(buffer->mirror, NULL);
|
||||||
|
|
||||||
|
/* Initialize the pages the device will snapshot in buffer->ptr. */
|
||||||
|
for (i = 0, ptr = buffer->ptr; i < size / sizeof(*ptr); ++i)
|
||||||
|
ptr[i] = i;
|
||||||
|
|
||||||
|
/* Simulate a device snapshotting CPU pagetables. */
|
||||||
|
ret = hmm_dmirror_cmd(self->fd, HMM_DMIRROR_SNAPSHOT, buffer, npages);
|
||||||
|
ASSERT_EQ(ret, 0);
|
||||||
|
ASSERT_EQ(buffer->cpages, npages);
|
||||||
|
|
||||||
|
/* Check what the device saw. */
|
||||||
|
m = buffer->mirror;
|
||||||
|
for (i = 0; i < npages; ++i)
|
||||||
|
ASSERT_EQ(m[i], HMM_DMIRROR_PROT_WRITE |
|
||||||
|
HMM_DMIRROR_PROT_PMD);
|
||||||
|
|
||||||
|
/* Make the region read-only. */
|
||||||
|
ret = mprotect(buffer->ptr, size, PROT_READ);
|
||||||
|
ASSERT_EQ(ret, 0);
|
||||||
|
|
||||||
|
/* Simulate a device snapshotting CPU pagetables. */
|
||||||
|
ret = hmm_dmirror_cmd(self->fd, HMM_DMIRROR_SNAPSHOT, buffer, npages);
|
||||||
|
ASSERT_EQ(ret, 0);
|
||||||
|
ASSERT_EQ(buffer->cpages, npages);
|
||||||
|
|
||||||
|
/* Check what the device saw. */
|
||||||
|
m = buffer->mirror;
|
||||||
|
for (i = 0; i < npages; ++i)
|
||||||
|
ASSERT_EQ(m[i], HMM_DMIRROR_PROT_READ |
|
||||||
|
HMM_DMIRROR_PROT_PMD);
|
||||||
|
|
||||||
|
free_hugepage_region(buffer->ptr);
|
||||||
|
buffer->ptr = NULL;
|
||||||
|
hmm_buffer_free(buffer);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Test two devices reading the same memory (double mapped).
|
* Test two devices reading the same memory (double mapped).
|
||||||
*/
|
*/
|
||||||
|
|
Loading…
Reference in New Issue
Block a user