File Index
Files and directories
Sign in
FILE

hmm-tests.c

File preview with syntax highlighting.

linux-6.19.14/tools/testing/selftests/mm/hmm-tests.c C
   1// SPDX-License-Identifier: GPL-2.0
   2/*
   3 * HMM stands for Heterogeneous Memory Management, it is a helper layer inside
   4 * the linux kernel to help device drivers mirror a process address space in
   5 * the device. This allows the device to use the same address space which
   6 * makes communication and data exchange a lot easier.
   7 *
   8 * This framework's sole purpose is to exercise various code paths inside
   9 * the kernel to make sure that HMM performs as expected and to flush out any
  10 * bugs.
  11 */
  12
  13#include "kselftest_harness.h"
  14
  15#include <errno.h>
  16#include <fcntl.h>
  17#include <stdio.h>
  18#include <stdlib.h>
  19#include <stdint.h>
  20#include <unistd.h>
  21#include <strings.h>
  22#include <time.h>
  23#include <pthread.h>
  24#include <sys/types.h>
  25#include <sys/stat.h>
  26#include <sys/mman.h>
  27#include <sys/ioctl.h>
  28#include <sys/time.h>
  29
  30
  31/*
  32 * This is a private UAPI to the kernel test module so it isn't exported
  33 * in the usual include/uapi/... directory.
  34 */
  35#include <lib/test_hmm_uapi.h>
  36#include <mm/gup_test.h>
  37#include <mm/vm_util.h>
  38
  39struct hmm_buffer {
  40	void		*ptr;
  41	void		*mirror;
  42	unsigned long	size;
  43	int		fd;
  44	uint64_t	cpages;
  45	uint64_t	faults;
  46};
  47
  48enum {
  49	HMM_PRIVATE_DEVICE_ONE,
  50	HMM_PRIVATE_DEVICE_TWO,
  51	HMM_COHERENCE_DEVICE_ONE,
  52	HMM_COHERENCE_DEVICE_TWO,
  53};
  54
  55#define ONEKB		(1 << 10)
  56#define ONEMEG		(1 << 20)
  57#define TWOMEG		(1 << 21)
  58#define HMM_BUFFER_SIZE (1024 << 12)
  59#define HMM_PATH_MAX    64
  60#define NTIMES		10
  61
  62#define ALIGN(x, a) (((x) + (a - 1)) & (~((a) - 1)))
  63/* Just the flags we need, copied from mm.h: */
  64
  65#ifndef FOLL_WRITE
  66#define FOLL_WRITE	0x01	/* check pte is writable */
  67#endif
  68
  69#ifndef FOLL_LONGTERM
  70#define FOLL_LONGTERM   0x100 /* mapping lifetime is indefinite */
  71#endif
  72FIXTURE(hmm)
  73{
  74	int		fd;
  75	unsigned int	page_size;
  76	unsigned int	page_shift;
  77};
  78
  79FIXTURE_VARIANT(hmm)
  80{
  81	int     device_number;
  82};
  83
  84FIXTURE_VARIANT_ADD(hmm, hmm_device_private)
  85{
  86	.device_number = HMM_PRIVATE_DEVICE_ONE,
  87};
  88
  89FIXTURE_VARIANT_ADD(hmm, hmm_device_coherent)
  90{
  91	.device_number = HMM_COHERENCE_DEVICE_ONE,
  92};
  93
  94FIXTURE(hmm2)
  95{
  96	int		fd0;
  97	int		fd1;
  98	unsigned int	page_size;
  99	unsigned int	page_shift;
 100};
 101
 102FIXTURE_VARIANT(hmm2)
 103{
 104	int     device_number0;
 105	int     device_number1;
 106};
 107
 108FIXTURE_VARIANT_ADD(hmm2, hmm2_device_private)
 109{
 110	.device_number0 = HMM_PRIVATE_DEVICE_ONE,
 111	.device_number1 = HMM_PRIVATE_DEVICE_TWO,
 112};
 113
 114FIXTURE_VARIANT_ADD(hmm2, hmm2_device_coherent)
 115{
 116	.device_number0 = HMM_COHERENCE_DEVICE_ONE,
 117	.device_number1 = HMM_COHERENCE_DEVICE_TWO,
 118};
 119
 120static int hmm_open(int unit)
 121{
 122	char pathname[HMM_PATH_MAX];
 123	int fd;
 124
 125	snprintf(pathname, sizeof(pathname), "/dev/hmm_dmirror%d", unit);
 126	fd = open(pathname, O_RDWR, 0);
 127	if (fd < 0)
 128		fprintf(stderr, "could not open hmm dmirror driver (%s)\n",
 129			pathname);
 130	return fd;
 131}
 132
 133static bool hmm_is_coherent_type(int dev_num)
 134{
 135	return (dev_num >= HMM_COHERENCE_DEVICE_ONE);
 136}
 137
 138FIXTURE_SETUP(hmm)
 139{
 140	self->page_size = sysconf(_SC_PAGE_SIZE);
 141	self->page_shift = ffs(self->page_size) - 1;
 142
 143	self->fd = hmm_open(variant->device_number);
 144	if (self->fd < 0 && hmm_is_coherent_type(variant->device_number))
 145		SKIP(return, "DEVICE_COHERENT not available");
 146	ASSERT_GE(self->fd, 0);
 147}
 148
 149FIXTURE_SETUP(hmm2)
 150{
 151	self->page_size = sysconf(_SC_PAGE_SIZE);
 152	self->page_shift = ffs(self->page_size) - 1;
 153
 154	self->fd0 = hmm_open(variant->device_number0);
 155	if (self->fd0 < 0 && hmm_is_coherent_type(variant->device_number0))
 156		SKIP(return, "DEVICE_COHERENT not available");
 157	ASSERT_GE(self->fd0, 0);
 158	self->fd1 = hmm_open(variant->device_number1);
 159	ASSERT_GE(self->fd1, 0);
 160}
 161
 162FIXTURE_TEARDOWN(hmm)
 163{
 164	int ret = close(self->fd);
 165
 166	ASSERT_EQ(ret, 0);
 167	self->fd = -1;
 168}
 169
 170FIXTURE_TEARDOWN(hmm2)
 171{
 172	int ret = close(self->fd0);
 173
 174	ASSERT_EQ(ret, 0);
 175	self->fd0 = -1;
 176
 177	ret = close(self->fd1);
 178	ASSERT_EQ(ret, 0);
 179	self->fd1 = -1;
 180}
 181
 182static int hmm_dmirror_cmd(int fd,
 183			   unsigned long request,
 184			   struct hmm_buffer *buffer,
 185			   unsigned long npages)
 186{
 187	struct hmm_dmirror_cmd cmd;
 188	int ret;
 189
 190	/* Simulate a device reading system memory. */
 191	cmd.addr = (__u64)buffer->ptr;
 192	cmd.ptr = (__u64)buffer->mirror;
 193	cmd.npages = npages;
 194
 195	for (;;) {
 196		ret = ioctl(fd, request, &cmd);
 197		if (ret == 0)
 198			break;
 199		if (errno == EINTR)
 200			continue;
 201		return -errno;
 202	}
 203	buffer->cpages = cmd.cpages;
 204	buffer->faults = cmd.faults;
 205
 206	return 0;
 207}
 208
 209static void hmm_buffer_free(struct hmm_buffer *buffer)
 210{
 211	if (buffer == NULL)
 212		return;
 213
 214	if (buffer->ptr) {
 215		munmap(buffer->ptr, buffer->size);
 216		buffer->ptr = NULL;
 217	}
 218	free(buffer->mirror);
 219	free(buffer);
 220}
 221
 222/*
 223 * Create a temporary file that will be deleted on close.
 224 */
 225static int hmm_create_file(unsigned long size)
 226{
 227	char path[HMM_PATH_MAX];
 228	int fd;
 229
 230	strcpy(path, "/tmp");
 231	fd = open(path, O_TMPFILE | O_EXCL | O_RDWR, 0600);
 232	if (fd >= 0) {
 233		int r;
 234
 235		do {
 236			r = ftruncate(fd, size);
 237		} while (r == -1 && errno == EINTR);
 238		if (!r)
 239			return fd;
 240		close(fd);
 241	}
 242	return -1;
 243}
 244
 245/*
 246 * Return a random unsigned number.
 247 */
 248static unsigned int hmm_random(void)
 249{
 250	static int fd = -1;
 251	unsigned int r;
 252
 253	if (fd < 0) {
 254		fd = open("/dev/urandom", O_RDONLY);
 255		if (fd < 0) {
 256			fprintf(stderr, "%s:%d failed to open /dev/urandom\n",
 257					__FILE__, __LINE__);
 258			return ~0U;
 259		}
 260	}
 261	read(fd, &r, sizeof(r));
 262	return r;
 263}
 264
 265static void hmm_nanosleep(unsigned int n)
 266{
 267	struct timespec t;
 268
 269	t.tv_sec = 0;
 270	t.tv_nsec = n;
 271	nanosleep(&t, NULL);
 272}
 273
 274static int hmm_migrate_sys_to_dev(int fd,
 275				   struct hmm_buffer *buffer,
 276				   unsigned long npages)
 277{
 278	return hmm_dmirror_cmd(fd, HMM_DMIRROR_MIGRATE_TO_DEV, buffer, npages);
 279}
 280
 281static int hmm_migrate_dev_to_sys(int fd,
 282				   struct hmm_buffer *buffer,
 283				   unsigned long npages)
 284{
 285	return hmm_dmirror_cmd(fd, HMM_DMIRROR_MIGRATE_TO_SYS, buffer, npages);
 286}
 287
 288/*
 289 * Simple NULL test of device open/close.
 290 */
 291TEST_F(hmm, open_close)
 292{
 293}
 294
 295/*
 296 * Read private anonymous memory.
 297 */
 298TEST_F(hmm, anon_read)
 299{
 300	struct hmm_buffer *buffer;
 301	unsigned long npages;
 302	unsigned long size;
 303	unsigned long i;
 304	int *ptr;
 305	int ret;
 306	int val;
 307
 308	npages = ALIGN(HMM_BUFFER_SIZE, self->page_size) >> self->page_shift;
 309	ASSERT_NE(npages, 0);
 310	size = npages << self->page_shift;
 311
 312	buffer = malloc(sizeof(*buffer));
 313	ASSERT_NE(buffer, NULL);
 314
 315	buffer->fd = -1;
 316	buffer->size = size;
 317	buffer->mirror = malloc(size);
 318	ASSERT_NE(buffer->mirror, NULL);
 319
 320	buffer->ptr = mmap(NULL, size,
 321			   PROT_READ | PROT_WRITE,
 322			   MAP_PRIVATE | MAP_ANONYMOUS,
 323			   buffer->fd, 0);
 324	ASSERT_NE(buffer->ptr, MAP_FAILED);
 325
 326	/*
 327	 * Initialize buffer in system memory but leave the first two pages
 328	 * zero (pte_none and pfn_zero).
 329	 */
 330	i = 2 * self->page_size / sizeof(*ptr);
 331	for (ptr = buffer->ptr; i < size / sizeof(*ptr); ++i)
 332		ptr[i] = i;
 333
 334	/* Set buffer permission to read-only. */
 335	ret = mprotect(buffer->ptr, size, PROT_READ);
 336	ASSERT_EQ(ret, 0);
 337
 338	/* Populate the CPU page table with a special zero page. */
 339	val = *(int *)(buffer->ptr + self->page_size);
 340	ASSERT_EQ(val, 0);
 341
 342	/* Simulate a device reading system memory. */
 343	ret = hmm_dmirror_cmd(self->fd, HMM_DMIRROR_READ, buffer, npages);
 344	ASSERT_EQ(ret, 0);
 345	ASSERT_EQ(buffer->cpages, npages);
 346	ASSERT_EQ(buffer->faults, 1);
 347
 348	/* Check what the device read. */
 349	ptr = buffer->mirror;
 350	for (i = 0; i < 2 * self->page_size / sizeof(*ptr); ++i)
 351		ASSERT_EQ(ptr[i], 0);
 352	for (; i < size / sizeof(*ptr); ++i)
 353		ASSERT_EQ(ptr[i], i);
 354
 355	hmm_buffer_free(buffer);
 356}
 357
 358/*
 359 * Read private anonymous memory which has been protected with
 360 * mprotect() PROT_NONE.
 361 */
 362TEST_F(hmm, anon_read_prot)
 363{
 364	struct hmm_buffer *buffer;
 365	unsigned long npages;
 366	unsigned long size;
 367	unsigned long i;
 368	int *ptr;
 369	int ret;
 370
 371	npages = ALIGN(HMM_BUFFER_SIZE, self->page_size) >> self->page_shift;
 372	ASSERT_NE(npages, 0);
 373	size = npages << self->page_shift;
 374
 375	buffer = malloc(sizeof(*buffer));
 376	ASSERT_NE(buffer, NULL);
 377
 378	buffer->fd = -1;
 379	buffer->size = size;
 380	buffer->mirror = malloc(size);
 381	ASSERT_NE(buffer->mirror, NULL);
 382
 383	buffer->ptr = mmap(NULL, size,
 384			   PROT_READ | PROT_WRITE,
 385			   MAP_PRIVATE | MAP_ANONYMOUS,
 386			   buffer->fd, 0);
 387	ASSERT_NE(buffer->ptr, MAP_FAILED);
 388
 389	/* Initialize buffer in system memory. */
 390	for (i = 0, ptr = buffer->ptr; i < size / sizeof(*ptr); ++i)
 391		ptr[i] = i;
 392
 393	/* Initialize mirror buffer so we can verify it isn't written. */
 394	for (i = 0, ptr = buffer->mirror; i < size / sizeof(*ptr); ++i)
 395		ptr[i] = -i;
 396
 397	/* Protect buffer from reading. */
 398	ret = mprotect(buffer->ptr, size, PROT_NONE);
 399	ASSERT_EQ(ret, 0);
 400
 401	/* Simulate a device reading system memory. */
 402	ret = hmm_dmirror_cmd(self->fd, HMM_DMIRROR_READ, buffer, npages);
 403	ASSERT_EQ(ret, -EFAULT);
 404
 405	/* Allow CPU to read the buffer so we can check it. */
 406	ret = mprotect(buffer->ptr, size, PROT_READ);
 407	ASSERT_EQ(ret, 0);
 408	for (i = 0, ptr = buffer->ptr; i < size / sizeof(*ptr); ++i)
 409		ASSERT_EQ(ptr[i], i);
 410
 411	/* Check what the device read. */
 412	for (i = 0, ptr = buffer->mirror; i < size / sizeof(*ptr); ++i)
 413		ASSERT_EQ(ptr[i], -i);
 414
 415	hmm_buffer_free(buffer);
 416}
 417
 418/*
 419 * Write private anonymous memory.
 420 */
 421TEST_F(hmm, anon_write)
 422{
 423	struct hmm_buffer *buffer;
 424	unsigned long npages;
 425	unsigned long size;
 426	unsigned long i;
 427	int *ptr;
 428	int ret;
 429
 430	npages = ALIGN(HMM_BUFFER_SIZE, self->page_size) >> self->page_shift;
 431	ASSERT_NE(npages, 0);
 432	size = npages << self->page_shift;
 433
 434	buffer = malloc(sizeof(*buffer));
 435	ASSERT_NE(buffer, NULL);
 436
 437	buffer->fd = -1;
 438	buffer->size = size;
 439	buffer->mirror = malloc(size);
 440	ASSERT_NE(buffer->mirror, NULL);
 441
 442	buffer->ptr = mmap(NULL, size,
 443			   PROT_READ | PROT_WRITE,
 444			   MAP_PRIVATE | MAP_ANONYMOUS,
 445			   buffer->fd, 0);
 446	ASSERT_NE(buffer->ptr, MAP_FAILED);
 447
 448	/* Initialize data that the device will write to buffer->ptr. */
 449	for (i = 0, ptr = buffer->mirror; i < size / sizeof(*ptr); ++i)
 450		ptr[i] = i;
 451
 452	/* Simulate a device writing system memory. */
 453	ret = hmm_dmirror_cmd(self->fd, HMM_DMIRROR_WRITE, buffer, npages);
 454	ASSERT_EQ(ret, 0);
 455	ASSERT_EQ(buffer->cpages, npages);
 456	ASSERT_EQ(buffer->faults, 1);
 457
 458	/* Check what the device wrote. */
 459	for (i = 0, ptr = buffer->ptr; i < size / sizeof(*ptr); ++i)
 460		ASSERT_EQ(ptr[i], i);
 461
 462	hmm_buffer_free(buffer);
 463}
 464
 465/*
 466 * Write private anonymous memory which has been protected with
 467 * mprotect() PROT_READ.
 468 */
 469TEST_F(hmm, anon_write_prot)
 470{
 471	struct hmm_buffer *buffer;
 472	unsigned long npages;
 473	unsigned long size;
 474	unsigned long i;
 475	int *ptr;
 476	int ret;
 477
 478	npages = ALIGN(HMM_BUFFER_SIZE, self->page_size) >> self->page_shift;
 479	ASSERT_NE(npages, 0);
 480	size = npages << self->page_shift;
 481
 482	buffer = malloc(sizeof(*buffer));
 483	ASSERT_NE(buffer, NULL);
 484
 485	buffer->fd = -1;
 486	buffer->size = size;
 487	buffer->mirror = malloc(size);
 488	ASSERT_NE(buffer->mirror, NULL);
 489
 490	buffer->ptr = mmap(NULL, size,
 491			   PROT_READ,
 492			   MAP_PRIVATE | MAP_ANONYMOUS,
 493			   buffer->fd, 0);
 494	ASSERT_NE(buffer->ptr, MAP_FAILED);
 495
 496	/* Simulate a device reading a zero page of memory. */
 497	ret = hmm_dmirror_cmd(self->fd, HMM_DMIRROR_READ, buffer, 1);
 498	ASSERT_EQ(ret, 0);
 499	ASSERT_EQ(buffer->cpages, 1);
 500	ASSERT_EQ(buffer->faults, 1);
 501
 502	/* Initialize data that the device will write to buffer->ptr. */
 503	for (i = 0, ptr = buffer->mirror; i < size / sizeof(*ptr); ++i)
 504		ptr[i] = i;
 505
 506	/* Simulate a device writing system memory. */
 507	ret = hmm_dmirror_cmd(self->fd, HMM_DMIRROR_WRITE, buffer, npages);
 508	ASSERT_EQ(ret, -EPERM);
 509
 510	/* Check what the device wrote. */
 511	for (i = 0, ptr = buffer->ptr; i < size / sizeof(*ptr); ++i)
 512		ASSERT_EQ(ptr[i], 0);
 513
 514	/* Now allow writing and see that the zero page is replaced. */
 515	ret = mprotect(buffer->ptr, size, PROT_WRITE | PROT_READ);
 516	ASSERT_EQ(ret, 0);
 517
 518	/* Simulate a device writing system memory. */
 519	ret = hmm_dmirror_cmd(self->fd, HMM_DMIRROR_WRITE, buffer, npages);
 520	ASSERT_EQ(ret, 0);
 521	ASSERT_EQ(buffer->cpages, npages);
 522	ASSERT_EQ(buffer->faults, 1);
 523
 524	/* Check what the device wrote. */
 525	for (i = 0, ptr = buffer->ptr; i < size / sizeof(*ptr); ++i)
 526		ASSERT_EQ(ptr[i], i);
 527
 528	hmm_buffer_free(buffer);
 529}
 530
 531/*
 532 * Check that a device writing an anonymous private mapping
 533 * will copy-on-write if a child process inherits the mapping.
 534 *
 535 * Also verifies after fork() memory the device can be read by child.
 536 */
 537TEST_F(hmm, anon_write_child)
 538{
 539	struct hmm_buffer *buffer;
 540	unsigned long npages;
 541	unsigned long size;
 542	unsigned long i;
 543	void *old_ptr;
 544	void *map;
 545	int *ptr;
 546	pid_t pid;
 547	int child_fd;
 548	int ret, use_thp, migrate;
 549
 550	for (migrate = 0; migrate < 2; ++migrate) {
 551		for (use_thp = 0; use_thp < 2; ++use_thp) {
 552			npages = ALIGN(use_thp ? read_pmd_pagesize() : HMM_BUFFER_SIZE,
 553				       self->page_size) >> self->page_shift;
 554			ASSERT_NE(npages, 0);
 555			size = npages << self->page_shift;
 556
 557			buffer = malloc(sizeof(*buffer));
 558			ASSERT_NE(buffer, NULL);
 559
 560			buffer->fd = -1;
 561			buffer->size = size * 2;
 562			buffer->mirror = malloc(size);
 563			ASSERT_NE(buffer->mirror, NULL);
 564
 565			buffer->ptr = mmap(NULL, size * 2,
 566					   PROT_READ | PROT_WRITE,
 567					   MAP_PRIVATE | MAP_ANONYMOUS,
 568					   buffer->fd, 0);
 569			ASSERT_NE(buffer->ptr, MAP_FAILED);
 570
 571			old_ptr = buffer->ptr;
 572			if (use_thp) {
 573				map = (void *)ALIGN((uintptr_t)buffer->ptr, size);
 574				ret = madvise(map, size, MADV_HUGEPAGE);
 575				ASSERT_EQ(ret, 0);
 576				buffer->ptr = map;
 577			}
 578
 579			/* Initialize buffer->ptr so we can tell if it is written. */
 580			for (i = 0, ptr = buffer->ptr; i < size / sizeof(*ptr); ++i)
 581				ptr[i] = i;
 582
 583			/* Initialize data that the device will write to buffer->ptr. */
 584			for (i = 0, ptr = buffer->mirror; i < size / sizeof(*ptr); ++i)
 585				ptr[i] = -i;
 586
 587			if (migrate) {
 588				ret = hmm_migrate_sys_to_dev(self->fd, buffer, npages);
 589				ASSERT_EQ(ret, 0);
 590				ASSERT_EQ(buffer->cpages, npages);
 591
 592			}
 593
 594			pid = fork();
 595			if (pid == -1)
 596				ASSERT_EQ(pid, 0);
 597			if (pid != 0) {
 598				waitpid(pid, &ret, 0);
 599				ASSERT_EQ(WIFEXITED(ret), 1);
 600
 601				/* Check that the parent's buffer did not change. */
 602				for (i = 0, ptr = buffer->ptr; i < size / sizeof(*ptr); ++i)
 603					ASSERT_EQ(ptr[i], i);
 604
 605				buffer->ptr = old_ptr;
 606				hmm_buffer_free(buffer);
 607				continue;
 608			}
 609
 610			/* Check that we see the parent's values. */
 611			for (i = 0, ptr = buffer->ptr; i < size / sizeof(*ptr); ++i)
 612				ASSERT_EQ(ptr[i], i);
 613			if (!migrate) {
 614				for (i = 0, ptr = buffer->mirror; i < size / sizeof(*ptr); ++i)
 615					ASSERT_EQ(ptr[i], -i);
 616			}
 617
 618			/* The child process needs its own mirror to its own mm. */
 619			child_fd = hmm_open(0);
 620			ASSERT_GE(child_fd, 0);
 621
 622			/* Simulate a device writing system memory. */
 623			ret = hmm_dmirror_cmd(child_fd, HMM_DMIRROR_WRITE, buffer, npages);
 624			ASSERT_EQ(ret, 0);
 625			ASSERT_EQ(buffer->cpages, npages);
 626			ASSERT_EQ(buffer->faults, 1);
 627
 628			/* Check what the device wrote. */
 629			if (!migrate) {
 630				for (i = 0, ptr = buffer->ptr; i < size / sizeof(*ptr); ++i)
 631					ASSERT_EQ(ptr[i], -i);
 632			}
 633
 634			close(child_fd);
 635			exit(0);
 636		}
 637	}
 638}
 639
 640/*
 641 * Check that a device writing an anonymous shared mapping
 642 * will not copy-on-write if a child process inherits the mapping.
 643 */
 644TEST_F(hmm, anon_write_child_shared)
 645{
 646	struct hmm_buffer *buffer;
 647	unsigned long npages;
 648	unsigned long size;
 649	unsigned long i;
 650	int *ptr;
 651	pid_t pid;
 652	int child_fd;
 653	int ret;
 654
 655	npages = ALIGN(HMM_BUFFER_SIZE, self->page_size) >> self->page_shift;
 656	ASSERT_NE(npages, 0);
 657	size = npages << self->page_shift;
 658
 659	buffer = malloc(sizeof(*buffer));
 660	ASSERT_NE(buffer, NULL);
 661
 662	buffer->fd = -1;
 663	buffer->size = size;
 664	buffer->mirror = malloc(size);
 665	ASSERT_NE(buffer->mirror, NULL);
 666
 667	buffer->ptr = mmap(NULL, size,
 668			   PROT_READ | PROT_WRITE,
 669			   MAP_SHARED | MAP_ANONYMOUS,
 670			   buffer->fd, 0);
 671	ASSERT_NE(buffer->ptr, MAP_FAILED);
 672
 673	/* Initialize buffer->ptr so we can tell if it is written. */
 674	for (i = 0, ptr = buffer->ptr; i < size / sizeof(*ptr); ++i)
 675		ptr[i] = i;
 676
 677	/* Initialize data that the device will write to buffer->ptr. */
 678	for (i = 0, ptr = buffer->mirror; i < size / sizeof(*ptr); ++i)
 679		ptr[i] = -i;
 680
 681	pid = fork();
 682	if (pid == -1)
 683		ASSERT_EQ(pid, 0);
 684	if (pid != 0) {
 685		waitpid(pid, &ret, 0);
 686		ASSERT_EQ(WIFEXITED(ret), 1);
 687
 688		/* Check that the parent's buffer did change. */
 689		for (i = 0, ptr = buffer->ptr; i < size / sizeof(*ptr); ++i)
 690			ASSERT_EQ(ptr[i], -i);
 691		return;
 692	}
 693
 694	/* Check that we see the parent's values. */
 695	for (i = 0, ptr = buffer->ptr; i < size / sizeof(*ptr); ++i)
 696		ASSERT_EQ(ptr[i], i);
 697	for (i = 0, ptr = buffer->mirror; i < size / sizeof(*ptr); ++i)
 698		ASSERT_EQ(ptr[i], -i);
 699
 700	/* The child process needs its own mirror to its own mm. */
 701	child_fd = hmm_open(0);
 702	ASSERT_GE(child_fd, 0);
 703
 704	/* Simulate a device writing system memory. */
 705	ret = hmm_dmirror_cmd(child_fd, HMM_DMIRROR_WRITE, buffer, npages);
 706	ASSERT_EQ(ret, 0);
 707	ASSERT_EQ(buffer->cpages, npages);
 708	ASSERT_EQ(buffer->faults, 1);
 709
 710	/* Check what the device wrote. */
 711	for (i = 0, ptr = buffer->ptr; i < size / sizeof(*ptr); ++i)
 712		ASSERT_EQ(ptr[i], -i);
 713
 714	close(child_fd);
 715	exit(0);
 716}
 717
 718/*
 719 * Write private anonymous huge page.
 720 */
 721TEST_F(hmm, anon_write_huge)
 722{
 723	struct hmm_buffer *buffer;
 724	unsigned long npages;
 725	unsigned long size;
 726	unsigned long i;
 727	void *old_ptr;
 728	void *map;
 729	int *ptr;
 730	int ret;
 731
 732	size = 2 * read_pmd_pagesize();
 733
 734	buffer = malloc(sizeof(*buffer));
 735	ASSERT_NE(buffer, NULL);
 736
 737	buffer->fd = -1;
 738	buffer->size = size;
 739	buffer->mirror = malloc(size);
 740	ASSERT_NE(buffer->mirror, NULL);
 741
 742	buffer->ptr = mmap(NULL, size,
 743			   PROT_READ | PROT_WRITE,
 744			   MAP_PRIVATE | MAP_ANONYMOUS,
 745			   buffer->fd, 0);
 746	ASSERT_NE(buffer->ptr, MAP_FAILED);
 747
 748	size /= 2;
 749	npages = size >> self->page_shift;
 750	map = (void *)ALIGN((uintptr_t)buffer->ptr, size);
 751	ret = madvise(map, size, MADV_HUGEPAGE);
 752	ASSERT_EQ(ret, 0);
 753	old_ptr = buffer->ptr;
 754	buffer->ptr = map;
 755
 756	/* Initialize data that the device will write to buffer->ptr. */
 757	for (i = 0, ptr = buffer->mirror; i < size / sizeof(*ptr); ++i)
 758		ptr[i] = i;
 759
 760	/* Simulate a device writing system memory. */
 761	ret = hmm_dmirror_cmd(self->fd, HMM_DMIRROR_WRITE, buffer, npages);
 762	ASSERT_EQ(ret, 0);
 763	ASSERT_EQ(buffer->cpages, npages);
 764	ASSERT_EQ(buffer->faults, 1);
 765
 766	/* Check what the device wrote. */
 767	for (i = 0, ptr = buffer->ptr; i < size / sizeof(*ptr); ++i)
 768		ASSERT_EQ(ptr[i], i);
 769
 770	buffer->ptr = old_ptr;
 771	hmm_buffer_free(buffer);
 772}
 773
 774/*
 775 * Write huge TLBFS page.
 776 */
 777TEST_F(hmm, anon_write_hugetlbfs)
 778{
 779	struct hmm_buffer *buffer;
 780	unsigned long npages;
 781	unsigned long size;
 782	unsigned long default_hsize = default_huge_page_size();
 783	unsigned long i;
 784	int *ptr;
 785	int ret;
 786
 787	if (!default_hsize)
 788		SKIP(return, "Huge page size could not be determined");
 789
 790	size = ALIGN(TWOMEG, default_hsize);
 791	npages = size >> self->page_shift;
 792
 793	buffer = malloc(sizeof(*buffer));
 794	ASSERT_NE(buffer, NULL);
 795
 796	buffer->ptr = mmap(NULL, size,
 797				   PROT_READ | PROT_WRITE,
 798				   MAP_PRIVATE | MAP_ANONYMOUS | MAP_HUGETLB,
 799				   -1, 0);
 800	if (buffer->ptr == MAP_FAILED) {
 801		free(buffer);
 802		SKIP(return, "Huge page could not be allocated");
 803	}
 804
 805	buffer->fd = -1;
 806	buffer->size = size;
 807	buffer->mirror = malloc(size);
 808	ASSERT_NE(buffer->mirror, NULL);
 809
 810	/* Initialize data that the device will write to buffer->ptr. */
 811	for (i = 0, ptr = buffer->mirror; i < size / sizeof(*ptr); ++i)
 812		ptr[i] = i;
 813
 814	/* Simulate a device writing system memory. */
 815	ret = hmm_dmirror_cmd(self->fd, HMM_DMIRROR_WRITE, buffer, npages);
 816	ASSERT_EQ(ret, 0);
 817	ASSERT_EQ(buffer->cpages, npages);
 818	ASSERT_EQ(buffer->faults, 1);
 819
 820	/* Check what the device wrote. */
 821	for (i = 0, ptr = buffer->ptr; i < size / sizeof(*ptr); ++i)
 822		ASSERT_EQ(ptr[i], i);
 823
 824	munmap(buffer->ptr, buffer->size);
 825	buffer->ptr = NULL;
 826	hmm_buffer_free(buffer);
 827}
 828
 829/*
 830 * Read mmap'ed file memory.
 831 */
 832TEST_F(hmm, file_read)
 833{
 834	struct hmm_buffer *buffer;
 835	unsigned long npages;
 836	unsigned long size;
 837	unsigned long i;
 838	int *ptr;
 839	int ret;
 840	int fd;
 841	ssize_t len;
 842
 843	npages = ALIGN(HMM_BUFFER_SIZE, self->page_size) >> self->page_shift;
 844	ASSERT_NE(npages, 0);
 845	size = npages << self->page_shift;
 846
 847	fd = hmm_create_file(size);
 848	ASSERT_GE(fd, 0);
 849
 850	buffer = malloc(sizeof(*buffer));
 851	ASSERT_NE(buffer, NULL);
 852
 853	buffer->fd = fd;
 854	buffer->size = size;
 855	buffer->mirror = malloc(size);
 856	ASSERT_NE(buffer->mirror, NULL);
 857
 858	/* Write initial contents of the file. */
 859	for (i = 0, ptr = buffer->mirror; i < size / sizeof(*ptr); ++i)
 860		ptr[i] = i;
 861	len = pwrite(fd, buffer->mirror, size, 0);
 862	ASSERT_EQ(len, size);
 863	memset(buffer->mirror, 0, size);
 864
 865	buffer->ptr = mmap(NULL, size,
 866			   PROT_READ,
 867			   MAP_SHARED,
 868			   buffer->fd, 0);
 869	ASSERT_NE(buffer->ptr, MAP_FAILED);
 870
 871	/* Simulate a device reading system memory. */
 872	ret = hmm_dmirror_cmd(self->fd, HMM_DMIRROR_READ, buffer, npages);
 873	ASSERT_EQ(ret, 0);
 874	ASSERT_EQ(buffer->cpages, npages);
 875	ASSERT_EQ(buffer->faults, 1);
 876
 877	/* Check what the device read. */
 878	for (i = 0, ptr = buffer->mirror; i < size / sizeof(*ptr); ++i)
 879		ASSERT_EQ(ptr[i], i);
 880
 881	hmm_buffer_free(buffer);
 882}
 883
 884/*
 885 * Write mmap'ed file memory.
 886 */
 887TEST_F(hmm, file_write)
 888{
 889	struct hmm_buffer *buffer;
 890	unsigned long npages;
 891	unsigned long size;
 892	unsigned long i;
 893	int *ptr;
 894	int ret;
 895	int fd;
 896	ssize_t len;
 897
 898	npages = ALIGN(HMM_BUFFER_SIZE, self->page_size) >> self->page_shift;
 899	ASSERT_NE(npages, 0);
 900	size = npages << self->page_shift;
 901
 902	fd = hmm_create_file(size);
 903	ASSERT_GE(fd, 0);
 904
 905	buffer = malloc(sizeof(*buffer));
 906	ASSERT_NE(buffer, NULL);
 907
 908	buffer->fd = fd;
 909	buffer->size = size;
 910	buffer->mirror = malloc(size);
 911	ASSERT_NE(buffer->mirror, NULL);
 912
 913	buffer->ptr = mmap(NULL, size,
 914			   PROT_READ | PROT_WRITE,
 915			   MAP_SHARED,
 916			   buffer->fd, 0);
 917	ASSERT_NE(buffer->ptr, MAP_FAILED);
 918
 919	/* Initialize data that the device will write to buffer->ptr. */
 920	for (i = 0, ptr = buffer->mirror; i < size / sizeof(*ptr); ++i)
 921		ptr[i] = i;
 922
 923	/* Simulate a device writing system memory. */
 924	ret = hmm_dmirror_cmd(self->fd, HMM_DMIRROR_WRITE, buffer, npages);
 925	ASSERT_EQ(ret, 0);
 926	ASSERT_EQ(buffer->cpages, npages);
 927	ASSERT_EQ(buffer->faults, 1);
 928
 929	/* Check what the device wrote. */
 930	for (i = 0, ptr = buffer->ptr; i < size / sizeof(*ptr); ++i)
 931		ASSERT_EQ(ptr[i], i);
 932
 933	/* Check that the device also wrote the file. */
 934	len = pread(fd, buffer->mirror, size, 0);
 935	ASSERT_EQ(len, size);
 936	for (i = 0, ptr = buffer->mirror; i < size / sizeof(*ptr); ++i)
 937		ASSERT_EQ(ptr[i], i);
 938
 939	hmm_buffer_free(buffer);
 940}
 941
 942/*
 943 * Migrate anonymous memory to device private memory.
 944 */
 945TEST_F(hmm, migrate)
 946{
 947	struct hmm_buffer *buffer;
 948	unsigned long npages;
 949	unsigned long size;
 950	unsigned long i;
 951	int *ptr;
 952	int ret;
 953
 954	npages = ALIGN(HMM_BUFFER_SIZE, self->page_size) >> self->page_shift;
 955	ASSERT_NE(npages, 0);
 956	size = npages << self->page_shift;
 957
 958	buffer = malloc(sizeof(*buffer));
 959	ASSERT_NE(buffer, NULL);
 960
 961	buffer->fd = -1;
 962	buffer->size = size;
 963	buffer->mirror = malloc(size);
 964	ASSERT_NE(buffer->mirror, NULL);
 965
 966	buffer->ptr = mmap(NULL, size,
 967			   PROT_READ | PROT_WRITE,
 968			   MAP_PRIVATE | MAP_ANONYMOUS,
 969			   buffer->fd, 0);
 970	ASSERT_NE(buffer->ptr, MAP_FAILED);
 971
 972	/* Initialize buffer in system memory. */
 973	for (i = 0, ptr = buffer->ptr; i < size / sizeof(*ptr); ++i)
 974		ptr[i] = i;
 975
 976	/* Migrate memory to device. */
 977	ret = hmm_migrate_sys_to_dev(self->fd, buffer, npages);
 978	ASSERT_EQ(ret, 0);
 979	ASSERT_EQ(buffer->cpages, npages);
 980
 981	/* Check what the device read. */
 982	for (i = 0, ptr = buffer->mirror; i < size / sizeof(*ptr); ++i)
 983		ASSERT_EQ(ptr[i], i);
 984
 985	hmm_buffer_free(buffer);
 986}
 987
 988/*
 989 * Migrate anonymous memory to device private memory and fault some of it back
 990 * to system memory, then try migrating the resulting mix of system and device
 991 * private memory to the device.
 992 */
 993TEST_F(hmm, migrate_fault)
 994{
 995	struct hmm_buffer *buffer;
 996	unsigned long npages;
 997	unsigned long size;
 998	unsigned long i;
 999	int *ptr;
1000	int ret;
1001
1002	npages = ALIGN(HMM_BUFFER_SIZE, self->page_size) >> self->page_shift;
1003	ASSERT_NE(npages, 0);
1004	size = npages << self->page_shift;
1005
1006	buffer = malloc(sizeof(*buffer));
1007	ASSERT_NE(buffer, NULL);
1008
1009	buffer->fd = -1;
1010	buffer->size = size;
1011	buffer->mirror = malloc(size);
1012	ASSERT_NE(buffer->mirror, NULL);
1013
1014	buffer->ptr = mmap(NULL, size,
1015			   PROT_READ | PROT_WRITE,
1016			   MAP_PRIVATE | MAP_ANONYMOUS,
1017			   buffer->fd, 0);
1018	ASSERT_NE(buffer->ptr, MAP_FAILED);
1019
1020	/* Initialize buffer in system memory. */
1021	for (i = 0, ptr = buffer->ptr; i < size / sizeof(*ptr); ++i)
1022		ptr[i] = i;
1023
1024	/* Migrate memory to device. */
1025	ret = hmm_migrate_sys_to_dev(self->fd, buffer, npages);
1026	ASSERT_EQ(ret, 0);
1027	ASSERT_EQ(buffer->cpages, npages);
1028
1029	/* Check what the device read. */
1030	for (i = 0, ptr = buffer->mirror; i < size / sizeof(*ptr); ++i)
1031		ASSERT_EQ(ptr[i], i);
1032
1033	/* Fault half the pages back to system memory and check them. */
1034	for (i = 0, ptr = buffer->ptr; i < size / (2 * sizeof(*ptr)); ++i)
1035		ASSERT_EQ(ptr[i], i);
1036
1037	/* Migrate memory to the device again. */
1038	ret = hmm_migrate_sys_to_dev(self->fd, buffer, npages);
1039	ASSERT_EQ(ret, 0);
1040	ASSERT_EQ(buffer->cpages, npages);
1041
1042	/* Check what the device read. */
1043	for (i = 0, ptr = buffer->mirror; i < size / sizeof(*ptr); ++i)
1044		ASSERT_EQ(ptr[i], i);
1045
1046	hmm_buffer_free(buffer);
1047}
1048
1049TEST_F(hmm, migrate_release)
1050{
1051	struct hmm_buffer *buffer;
1052	unsigned long npages;
1053	unsigned long size;
1054	unsigned long i;
1055	int *ptr;
1056	int ret;
1057
1058	npages = ALIGN(HMM_BUFFER_SIZE, self->page_size) >> self->page_shift;
1059	ASSERT_NE(npages, 0);
1060	size = npages << self->page_shift;
1061
1062	buffer = malloc(sizeof(*buffer));
1063	ASSERT_NE(buffer, NULL);
1064
1065	buffer->fd = -1;
1066	buffer->size = size;
1067	buffer->mirror = malloc(size);
1068	ASSERT_NE(buffer->mirror, NULL);
1069
1070	buffer->ptr = mmap(NULL, size, PROT_READ | PROT_WRITE,
1071			   MAP_PRIVATE | MAP_ANONYMOUS, buffer->fd, 0);
1072	ASSERT_NE(buffer->ptr, MAP_FAILED);
1073
1074	/* Initialize buffer in system memory. */
1075	for (i = 0, ptr = buffer->ptr; i < size / sizeof(*ptr); ++i)
1076		ptr[i] = i;
1077
1078	/* Migrate memory to device. */
1079	ret = hmm_migrate_sys_to_dev(self->fd, buffer, npages);
1080	ASSERT_EQ(ret, 0);
1081	ASSERT_EQ(buffer->cpages, npages);
1082
1083	/* Check what the device read. */
1084	for (i = 0, ptr = buffer->mirror; i < size / sizeof(*ptr); ++i)
1085		ASSERT_EQ(ptr[i], i);
1086
1087	/* Release device memory. */
1088	ret = hmm_dmirror_cmd(self->fd, HMM_DMIRROR_RELEASE, buffer, npages);
1089	ASSERT_EQ(ret, 0);
1090
1091	/* Fault pages back to system memory and check them. */
1092	for (i = 0, ptr = buffer->ptr; i < size / (2 * sizeof(*ptr)); ++i)
1093		ASSERT_EQ(ptr[i], i);
1094
1095	hmm_buffer_free(buffer);
1096}
1097
1098/*
1099 * Migrate anonymous shared memory to device private memory.
1100 */
1101TEST_F(hmm, migrate_shared)
1102{
1103	struct hmm_buffer *buffer;
1104	unsigned long npages;
1105	unsigned long size;
1106	int ret;
1107
1108	npages = ALIGN(HMM_BUFFER_SIZE, self->page_size) >> self->page_shift;
1109	ASSERT_NE(npages, 0);
1110	size = npages << self->page_shift;
1111
1112	buffer = malloc(sizeof(*buffer));
1113	ASSERT_NE(buffer, NULL);
1114
1115	buffer->fd = -1;
1116	buffer->size = size;
1117	buffer->mirror = malloc(size);
1118	ASSERT_NE(buffer->mirror, NULL);
1119
1120	buffer->ptr = mmap(NULL, size,
1121			   PROT_READ | PROT_WRITE,
1122			   MAP_SHARED | MAP_ANONYMOUS,
1123			   buffer->fd, 0);
1124	ASSERT_NE(buffer->ptr, MAP_FAILED);
1125
1126	/* Migrate memory to device. */
1127	ret = hmm_migrate_sys_to_dev(self->fd, buffer, npages);
1128	ASSERT_EQ(ret, -ENOENT);
1129
1130	hmm_buffer_free(buffer);
1131}
1132
1133/*
1134 * Try to migrate various memory types to device private memory.
1135 */
1136TEST_F(hmm2, migrate_mixed)
1137{
1138	struct hmm_buffer *buffer;
1139	unsigned long npages;
1140	unsigned long size;
1141	int *ptr;
1142	unsigned char *p;
1143	int ret;
1144	int val;
1145
1146	npages = 6;
1147	size = npages << self->page_shift;
1148
1149	buffer = malloc(sizeof(*buffer));
1150	ASSERT_NE(buffer, NULL);
1151
1152	buffer->fd = -1;
1153	buffer->size = size;
1154	buffer->mirror = malloc(size);
1155	ASSERT_NE(buffer->mirror, NULL);
1156
1157	/* Reserve a range of addresses. */
1158	buffer->ptr = mmap(NULL, size,
1159			   PROT_NONE,
1160			   MAP_PRIVATE | MAP_ANONYMOUS,
1161			   buffer->fd, 0);
1162	ASSERT_NE(buffer->ptr, MAP_FAILED);
1163	p = buffer->ptr;
1164
1165	/* Migrating a protected area should be an error. */
1166	ret = hmm_migrate_sys_to_dev(self->fd1, buffer, npages);
1167	ASSERT_EQ(ret, -EINVAL);
1168
1169	/* Punch a hole after the first page address. */
1170	ret = munmap(buffer->ptr + self->page_size, self->page_size);
1171	ASSERT_EQ(ret, 0);
1172
1173	/* We expect an error if the vma doesn't cover the range. */
1174	ret = hmm_migrate_sys_to_dev(self->fd1, buffer, 3);
1175	ASSERT_EQ(ret, -EINVAL);
1176
1177	/* Page 2 will be a read-only zero page. */
1178	ret = mprotect(buffer->ptr + 2 * self->page_size, self->page_size,
1179				PROT_READ);
1180	ASSERT_EQ(ret, 0);
1181	ptr = (int *)(buffer->ptr + 2 * self->page_size);
1182	val = *ptr + 3;
1183	ASSERT_EQ(val, 3);
1184
1185	/* Page 3 will be read-only. */
1186	ret = mprotect(buffer->ptr + 3 * self->page_size, self->page_size,
1187				PROT_READ | PROT_WRITE);
1188	ASSERT_EQ(ret, 0);
1189	ptr = (int *)(buffer->ptr + 3 * self->page_size);
1190	*ptr = val;
1191	ret = mprotect(buffer->ptr + 3 * self->page_size, self->page_size,
1192				PROT_READ);
1193	ASSERT_EQ(ret, 0);
1194
1195	/* Page 4-5 will be read-write. */
1196	ret = mprotect(buffer->ptr + 4 * self->page_size, 2 * self->page_size,
1197				PROT_READ | PROT_WRITE);
1198	ASSERT_EQ(ret, 0);
1199	ptr = (int *)(buffer->ptr + 4 * self->page_size);
1200	*ptr = val;
1201	ptr = (int *)(buffer->ptr + 5 * self->page_size);
1202	*ptr = val;
1203
1204	/* Now try to migrate pages 2-5 to device 1. */
1205	buffer->ptr = p + 2 * self->page_size;
1206	ret = hmm_migrate_sys_to_dev(self->fd1, buffer, 4);
1207	ASSERT_EQ(ret, 0);
1208	ASSERT_EQ(buffer->cpages, 4);
1209
1210	/* Page 5 won't be migrated to device 0 because it's on device 1. */
1211	buffer->ptr = p + 5 * self->page_size;
1212	ret = hmm_migrate_sys_to_dev(self->fd0, buffer, 1);
1213	ASSERT_EQ(ret, -ENOENT);
1214	buffer->ptr = p;
1215
1216	buffer->ptr = p;
1217	hmm_buffer_free(buffer);
1218}
1219
1220/*
1221 * Migrate anonymous memory to device memory and back to system memory
1222 * multiple times. In case of private zone configuration, this is done
1223 * through fault pages accessed by CPU. In case of coherent zone configuration,
1224 * the pages from the device should be explicitly migrated back to system memory.
1225 * The reason is Coherent device zone has coherent access by CPU, therefore
1226 * it will not generate any page fault.
1227 */
1228TEST_F(hmm, migrate_multiple)
1229{
1230	struct hmm_buffer *buffer;
1231	unsigned long npages;
1232	unsigned long size;
1233	unsigned long i;
1234	unsigned long c;
1235	int *ptr;
1236	int ret;
1237
1238	npages = ALIGN(HMM_BUFFER_SIZE, self->page_size) >> self->page_shift;
1239	ASSERT_NE(npages, 0);
1240	size = npages << self->page_shift;
1241
1242	for (c = 0; c < NTIMES; c++) {
1243		buffer = malloc(sizeof(*buffer));
1244		ASSERT_NE(buffer, NULL);
1245
1246		buffer->fd = -1;
1247		buffer->size = size;
1248		buffer->mirror = malloc(size);
1249		ASSERT_NE(buffer->mirror, NULL);
1250
1251		buffer->ptr = mmap(NULL, size,
1252				   PROT_READ | PROT_WRITE,
1253				   MAP_PRIVATE | MAP_ANONYMOUS,
1254				   buffer->fd, 0);
1255		ASSERT_NE(buffer->ptr, MAP_FAILED);
1256
1257		/* Initialize buffer in system memory. */
1258		for (i = 0, ptr = buffer->ptr; i < size / sizeof(*ptr); ++i)
1259			ptr[i] = i;
1260
1261		/* Migrate memory to device. */
1262		ret = hmm_migrate_sys_to_dev(self->fd, buffer, npages);
1263		ASSERT_EQ(ret, 0);
1264		ASSERT_EQ(buffer->cpages, npages);
1265
1266		/* Check what the device read. */
1267		for (i = 0, ptr = buffer->mirror; i < size / sizeof(*ptr); ++i)
1268			ASSERT_EQ(ptr[i], i);
1269
1270		/* Migrate back to system memory and check them. */
1271		if (hmm_is_coherent_type(variant->device_number)) {
1272			ret = hmm_migrate_dev_to_sys(self->fd, buffer, npages);
1273			ASSERT_EQ(ret, 0);
1274			ASSERT_EQ(buffer->cpages, npages);
1275		}
1276
1277		for (i = 0, ptr = buffer->ptr; i < size / sizeof(*ptr); ++i)
1278			ASSERT_EQ(ptr[i], i);
1279
1280		hmm_buffer_free(buffer);
1281	}
1282}
1283
1284/*
1285 * Read anonymous memory multiple times.
1286 */
1287TEST_F(hmm, anon_read_multiple)
1288{
1289	struct hmm_buffer *buffer;
1290	unsigned long npages;
1291	unsigned long size;
1292	unsigned long i;
1293	unsigned long c;
1294	int *ptr;
1295	int ret;
1296
1297	npages = ALIGN(HMM_BUFFER_SIZE, self->page_size) >> self->page_shift;
1298	ASSERT_NE(npages, 0);
1299	size = npages << self->page_shift;
1300
1301	for (c = 0; c < NTIMES; c++) {
1302		buffer = malloc(sizeof(*buffer));
1303		ASSERT_NE(buffer, NULL);
1304
1305		buffer->fd = -1;
1306		buffer->size = size;
1307		buffer->mirror = malloc(size);
1308		ASSERT_NE(buffer->mirror, NULL);
1309
1310		buffer->ptr = mmap(NULL, size,
1311				   PROT_READ | PROT_WRITE,
1312				   MAP_PRIVATE | MAP_ANONYMOUS,
1313				   buffer->fd, 0);
1314		ASSERT_NE(buffer->ptr, MAP_FAILED);
1315
1316		/* Initialize buffer in system memory. */
1317		for (i = 0, ptr = buffer->ptr; i < size / sizeof(*ptr); ++i)
1318			ptr[i] = i + c;
1319
1320		/* Simulate a device reading system memory. */
1321		ret = hmm_dmirror_cmd(self->fd, HMM_DMIRROR_READ, buffer,
1322				      npages);
1323		ASSERT_EQ(ret, 0);
1324		ASSERT_EQ(buffer->cpages, npages);
1325		ASSERT_EQ(buffer->faults, 1);
1326
1327		/* Check what the device read. */
1328		for (i = 0, ptr = buffer->mirror; i < size / sizeof(*ptr); ++i)
1329			ASSERT_EQ(ptr[i], i + c);
1330
1331		hmm_buffer_free(buffer);
1332	}
1333}
1334
1335void *unmap_buffer(void *p)
1336{
1337	struct hmm_buffer *buffer = p;
1338
1339	/* Delay for a bit and then unmap buffer while it is being read. */
1340	hmm_nanosleep(hmm_random() % 32000);
1341	munmap(buffer->ptr + buffer->size / 2, buffer->size / 2);
1342	buffer->ptr = NULL;
1343
1344	return NULL;
1345}
1346
1347/*
1348 * Try reading anonymous memory while it is being unmapped.
1349 */
1350TEST_F(hmm, anon_teardown)
1351{
1352	unsigned long npages;
1353	unsigned long size;
1354	unsigned long c;
1355	void *ret;
1356
1357	npages = ALIGN(HMM_BUFFER_SIZE, self->page_size) >> self->page_shift;
1358	ASSERT_NE(npages, 0);
1359	size = npages << self->page_shift;
1360
1361	for (c = 0; c < NTIMES; ++c) {
1362		pthread_t thread;
1363		struct hmm_buffer *buffer;
1364		unsigned long i;
1365		int *ptr;
1366		int rc;
1367
1368		buffer = malloc(sizeof(*buffer));
1369		ASSERT_NE(buffer, NULL);
1370
1371		buffer->fd = -1;
1372		buffer->size = size;
1373		buffer->mirror = malloc(size);
1374		ASSERT_NE(buffer->mirror, NULL);
1375
1376		buffer->ptr = mmap(NULL, size,
1377				   PROT_READ | PROT_WRITE,
1378				   MAP_PRIVATE | MAP_ANONYMOUS,
1379				   buffer->fd, 0);
1380		ASSERT_NE(buffer->ptr, MAP_FAILED);
1381
1382		/* Initialize buffer in system memory. */
1383		for (i = 0, ptr = buffer->ptr; i < size / sizeof(*ptr); ++i)
1384			ptr[i] = i + c;
1385
1386		rc = pthread_create(&thread, NULL, unmap_buffer, buffer);
1387		ASSERT_EQ(rc, 0);
1388
1389		/* Simulate a device reading system memory. */
1390		rc = hmm_dmirror_cmd(self->fd, HMM_DMIRROR_READ, buffer,
1391				     npages);
1392		if (rc == 0) {
1393			ASSERT_EQ(buffer->cpages, npages);
1394			ASSERT_EQ(buffer->faults, 1);
1395
1396			/* Check what the device read. */
1397			for (i = 0, ptr = buffer->mirror;
1398			     i < size / sizeof(*ptr);
1399			     ++i)
1400				ASSERT_EQ(ptr[i], i + c);
1401		}
1402
1403		pthread_join(thread, &ret);
1404		hmm_buffer_free(buffer);
1405	}
1406}
1407
1408/*
1409 * Test memory snapshot without faulting in pages accessed by the device.
1410 */
1411TEST_F(hmm, mixedmap)
1412{
1413	struct hmm_buffer *buffer;
1414	unsigned long npages;
1415	unsigned long size;
1416	unsigned char *m;
1417	int ret;
1418
1419	npages = 1;
1420	size = npages << self->page_shift;
1421
1422	buffer = malloc(sizeof(*buffer));
1423	ASSERT_NE(buffer, NULL);
1424
1425	buffer->fd = -1;
1426	buffer->size = size;
1427	buffer->mirror = malloc(npages);
1428	ASSERT_NE(buffer->mirror, NULL);
1429
1430
1431	/* Reserve a range of addresses. */
1432	buffer->ptr = mmap(NULL, size,
1433			   PROT_READ | PROT_WRITE,
1434			   MAP_PRIVATE,
1435			   self->fd, 0);
1436	ASSERT_NE(buffer->ptr, MAP_FAILED);
1437
1438	/* Simulate a device snapshotting CPU pagetables. */
1439	ret = hmm_dmirror_cmd(self->fd, HMM_DMIRROR_SNAPSHOT, buffer, npages);
1440	ASSERT_EQ(ret, 0);
1441	ASSERT_EQ(buffer->cpages, npages);
1442
1443	/* Check what the device saw. */
1444	m = buffer->mirror;
1445	ASSERT_EQ(m[0], HMM_DMIRROR_PROT_READ);
1446
1447	hmm_buffer_free(buffer);
1448}
1449
1450/*
1451 * Test memory snapshot without faulting in pages accessed by the device.
1452 */
1453TEST_F(hmm2, snapshot)
1454{
1455	struct hmm_buffer *buffer;
1456	unsigned long npages;
1457	unsigned long size;
1458	int *ptr;
1459	unsigned char *p;
1460	unsigned char *m;
1461	int ret;
1462	int val;
1463
1464	npages = 7;
1465	size = npages << self->page_shift;
1466
1467	buffer = malloc(sizeof(*buffer));
1468	ASSERT_NE(buffer, NULL);
1469
1470	buffer->fd = -1;
1471	buffer->size = size;
1472	buffer->mirror = malloc(npages);
1473	ASSERT_NE(buffer->mirror, NULL);
1474
1475	/* Reserve a range of addresses. */
1476	buffer->ptr = mmap(NULL, size,
1477			   PROT_NONE,
1478			   MAP_PRIVATE | MAP_ANONYMOUS,
1479			   buffer->fd, 0);
1480	ASSERT_NE(buffer->ptr, MAP_FAILED);
1481	p = buffer->ptr;
1482
1483	/* Punch a hole after the first page address. */
1484	ret = munmap(buffer->ptr + self->page_size, self->page_size);
1485	ASSERT_EQ(ret, 0);
1486
1487	/* Page 2 will be read-only zero page. */
1488	ret = mprotect(buffer->ptr + 2 * self->page_size, self->page_size,
1489				PROT_READ);
1490	ASSERT_EQ(ret, 0);
1491	ptr = (int *)(buffer->ptr + 2 * self->page_size);
1492	val = *ptr + 3;
1493	ASSERT_EQ(val, 3);
1494
1495	/* Page 3 will be read-only. */
1496	ret = mprotect(buffer->ptr + 3 * self->page_size, self->page_size,
1497				PROT_READ | PROT_WRITE);
1498	ASSERT_EQ(ret, 0);
1499	ptr = (int *)(buffer->ptr + 3 * self->page_size);
1500	*ptr = val;
1501	ret = mprotect(buffer->ptr + 3 * self->page_size, self->page_size,
1502				PROT_READ);
1503	ASSERT_EQ(ret, 0);
1504
1505	/* Page 4-6 will be read-write. */
1506	ret = mprotect(buffer->ptr + 4 * self->page_size, 3 * self->page_size,
1507				PROT_READ | PROT_WRITE);
1508	ASSERT_EQ(ret, 0);
1509	ptr = (int *)(buffer->ptr + 4 * self->page_size);
1510	*ptr = val;
1511
1512	/* Page 5 will be migrated to device 0. */
1513	buffer->ptr = p + 5 * self->page_size;
1514	ret = hmm_migrate_sys_to_dev(self->fd0, buffer, 1);
1515	ASSERT_EQ(ret, 0);
1516	ASSERT_EQ(buffer->cpages, 1);
1517
1518	/* Page 6 will be migrated to device 1. */
1519	buffer->ptr = p + 6 * self->page_size;
1520	ret = hmm_migrate_sys_to_dev(self->fd1, buffer, 1);
1521	ASSERT_EQ(ret, 0);
1522	ASSERT_EQ(buffer->cpages, 1);
1523
1524	/* Simulate a device snapshotting CPU pagetables. */
1525	buffer->ptr = p;
1526	ret = hmm_dmirror_cmd(self->fd0, HMM_DMIRROR_SNAPSHOT, buffer, npages);
1527	ASSERT_EQ(ret, 0);
1528	ASSERT_EQ(buffer->cpages, npages);
1529
1530	/* Check what the device saw. */
1531	m = buffer->mirror;
1532	ASSERT_EQ(m[0], HMM_DMIRROR_PROT_ERROR);
1533	ASSERT_EQ(m[1], HMM_DMIRROR_PROT_ERROR);
1534	ASSERT_EQ(m[2], HMM_DMIRROR_PROT_ZERO | HMM_DMIRROR_PROT_READ);
1535	ASSERT_EQ(m[3], HMM_DMIRROR_PROT_READ);
1536	ASSERT_EQ(m[4], HMM_DMIRROR_PROT_WRITE);
1537	if (!hmm_is_coherent_type(variant->device_number0)) {
1538		ASSERT_EQ(m[5], HMM_DMIRROR_PROT_DEV_PRIVATE_LOCAL |
1539				HMM_DMIRROR_PROT_WRITE);
1540		ASSERT_EQ(m[6], HMM_DMIRROR_PROT_NONE);
1541	} else {
1542		ASSERT_EQ(m[5], HMM_DMIRROR_PROT_DEV_COHERENT_LOCAL |
1543				HMM_DMIRROR_PROT_WRITE);
1544		ASSERT_EQ(m[6], HMM_DMIRROR_PROT_DEV_COHERENT_REMOTE |
1545				HMM_DMIRROR_PROT_WRITE);
1546	}
1547
1548	hmm_buffer_free(buffer);
1549}
1550
1551/*
1552 * Test the hmm_range_fault() HMM_PFN_PMD flag for large pages that
1553 * should be mapped by a large page table entry.
1554 */
1555TEST_F(hmm, compound)
1556{
1557	struct hmm_buffer *buffer;
1558	unsigned long npages;
1559	unsigned long size;
1560	unsigned long default_hsize = default_huge_page_size();
1561	int *ptr;
1562	unsigned char *m;
1563	int ret;
1564	unsigned long i;
1565
1566	/* Skip test if we can't allocate a hugetlbfs page. */
1567
1568	if (!default_hsize)
1569		SKIP(return, "Huge page size could not be determined");
1570
1571	size = ALIGN(TWOMEG, default_hsize);
1572	npages = size >> self->page_shift;
1573
1574	buffer = malloc(sizeof(*buffer));
1575	ASSERT_NE(buffer, NULL);
1576
1577	buffer->ptr = mmap(NULL, size,
1578				   PROT_READ | PROT_WRITE,
1579				   MAP_PRIVATE | MAP_ANONYMOUS | MAP_HUGETLB,
1580				   -1, 0);
1581	if (buffer->ptr == MAP_FAILED) {
1582		free(buffer);
1583		return;
1584	}
1585
1586	buffer->size = size;
1587	buffer->mirror = malloc(npages);
1588	ASSERT_NE(buffer->mirror, NULL);
1589
1590	/* Initialize the pages the device will snapshot in buffer->ptr. */
1591	for (i = 0, ptr = buffer->ptr; i < size / sizeof(*ptr); ++i)
1592		ptr[i] = i;
1593
1594	/* Simulate a device snapshotting CPU pagetables. */
1595	ret = hmm_dmirror_cmd(self->fd, HMM_DMIRROR_SNAPSHOT, buffer, npages);
1596	ASSERT_EQ(ret, 0);
1597	ASSERT_EQ(buffer->cpages, npages);
1598
1599	/* Check what the device saw. */
1600	m = buffer->mirror;
1601	for (i = 0; i < npages; ++i)
1602		ASSERT_EQ(m[i], HMM_DMIRROR_PROT_WRITE |
1603				HMM_DMIRROR_PROT_PMD);
1604
1605	/* Make the region read-only. */
1606	ret = mprotect(buffer->ptr, size, PROT_READ);
1607	ASSERT_EQ(ret, 0);
1608
1609	/* Simulate a device snapshotting CPU pagetables. */
1610	ret = hmm_dmirror_cmd(self->fd, HMM_DMIRROR_SNAPSHOT, buffer, npages);
1611	ASSERT_EQ(ret, 0);
1612	ASSERT_EQ(buffer->cpages, npages);
1613
1614	/* Check what the device saw. */
1615	m = buffer->mirror;
1616	for (i = 0; i < npages; ++i)
1617		ASSERT_EQ(m[i], HMM_DMIRROR_PROT_READ |
1618				HMM_DMIRROR_PROT_PMD);
1619
1620	munmap(buffer->ptr, buffer->size);
1621	buffer->ptr = NULL;
1622	hmm_buffer_free(buffer);
1623}
1624
1625/*
1626 * Test two devices reading the same memory (double mapped).
1627 */
1628TEST_F(hmm2, double_map)
1629{
1630	struct hmm_buffer *buffer;
1631	unsigned long npages;
1632	unsigned long size;
1633	unsigned long i;
1634	int *ptr;
1635	int ret;
1636
1637	npages = 6;
1638	size = npages << self->page_shift;
1639
1640	buffer = malloc(sizeof(*buffer));
1641	ASSERT_NE(buffer, NULL);
1642
1643	buffer->fd = -1;
1644	buffer->size = size;
1645	buffer->mirror = malloc(size);
1646	ASSERT_NE(buffer->mirror, NULL);
1647
1648	/* Reserve a range of addresses. */
1649	buffer->ptr = mmap(NULL, size,
1650			   PROT_READ | PROT_WRITE,
1651			   MAP_PRIVATE | MAP_ANONYMOUS,
1652			   buffer->fd, 0);
1653	ASSERT_NE(buffer->ptr, MAP_FAILED);
1654
1655	/* Initialize buffer in system memory. */
1656	for (i = 0, ptr = buffer->ptr; i < size / sizeof(*ptr); ++i)
1657		ptr[i] = i;
1658
1659	/* Make region read-only. */
1660	ret = mprotect(buffer->ptr, size, PROT_READ);
1661	ASSERT_EQ(ret, 0);
1662
1663	/* Simulate device 0 reading system memory. */
1664	ret = hmm_dmirror_cmd(self->fd0, HMM_DMIRROR_READ, buffer, npages);
1665	ASSERT_EQ(ret, 0);
1666	ASSERT_EQ(buffer->cpages, npages);
1667	ASSERT_EQ(buffer->faults, 1);
1668
1669	/* Check what the device read. */
1670	for (i = 0, ptr = buffer->mirror; i < size / sizeof(*ptr); ++i)
1671		ASSERT_EQ(ptr[i], i);
1672
1673	/* Simulate device 1 reading system memory. */
1674	ret = hmm_dmirror_cmd(self->fd1, HMM_DMIRROR_READ, buffer, npages);
1675	ASSERT_EQ(ret, 0);
1676	ASSERT_EQ(buffer->cpages, npages);
1677	ASSERT_EQ(buffer->faults, 1);
1678
1679	/* Check what the device read. */
1680	for (i = 0, ptr = buffer->mirror; i < size / sizeof(*ptr); ++i)
1681		ASSERT_EQ(ptr[i], i);
1682
1683	/* Migrate pages to device 1 and try to read from device 0. */
1684	ret = hmm_migrate_sys_to_dev(self->fd1, buffer, npages);
1685	ASSERT_EQ(ret, 0);
1686	ASSERT_EQ(buffer->cpages, npages);
1687
1688	ret = hmm_dmirror_cmd(self->fd0, HMM_DMIRROR_READ, buffer, npages);
1689	ASSERT_EQ(ret, 0);
1690	ASSERT_EQ(buffer->cpages, npages);
1691	ASSERT_EQ(buffer->faults, 1);
1692
1693	/* Check what device 0 read. */
1694	for (i = 0, ptr = buffer->mirror; i < size / sizeof(*ptr); ++i)
1695		ASSERT_EQ(ptr[i], i);
1696
1697	hmm_buffer_free(buffer);
1698}
1699
1700/*
1701 * Basic check of exclusive faulting.
1702 */
1703TEST_F(hmm, exclusive)
1704{
1705	struct hmm_buffer *buffer;
1706	unsigned long npages;
1707	unsigned long size;
1708	unsigned long i;
1709	int *ptr;
1710	int ret;
1711
1712	npages = ALIGN(HMM_BUFFER_SIZE, self->page_size) >> self->page_shift;
1713	ASSERT_NE(npages, 0);
1714	size = npages << self->page_shift;
1715
1716	buffer = malloc(sizeof(*buffer));
1717	ASSERT_NE(buffer, NULL);
1718
1719	buffer->fd = -1;
1720	buffer->size = size;
1721	buffer->mirror = malloc(size);
1722	ASSERT_NE(buffer->mirror, NULL);
1723
1724	buffer->ptr = mmap(NULL, size,
1725			   PROT_READ | PROT_WRITE,
1726			   MAP_PRIVATE | MAP_ANONYMOUS,
1727			   buffer->fd, 0);
1728	ASSERT_NE(buffer->ptr, MAP_FAILED);
1729
1730	/* Initialize buffer in system memory. */
1731	for (i = 0, ptr = buffer->ptr; i < size / sizeof(*ptr); ++i)
1732		ptr[i] = i;
1733
1734	/* Map memory exclusively for device access. */
1735	ret = hmm_dmirror_cmd(self->fd, HMM_DMIRROR_EXCLUSIVE, buffer, npages);
1736	ASSERT_EQ(ret, 0);
1737	ASSERT_EQ(buffer->cpages, npages);
1738
1739	/* Check what the device read. */
1740	for (i = 0, ptr = buffer->mirror; i < size / sizeof(*ptr); ++i)
1741		ASSERT_EQ(ptr[i], i);
1742
1743	/* Fault pages back to system memory and check them. */
1744	for (i = 0, ptr = buffer->ptr; i < size / sizeof(*ptr); ++i)
1745		ASSERT_EQ(ptr[i]++, i);
1746
1747	for (i = 0, ptr = buffer->ptr; i < size / sizeof(*ptr); ++i)
1748		ASSERT_EQ(ptr[i], i+1);
1749
1750	/* Check atomic access revoked */
1751	ret = hmm_dmirror_cmd(self->fd, HMM_DMIRROR_CHECK_EXCLUSIVE, buffer, npages);
1752	ASSERT_EQ(ret, 0);
1753
1754	hmm_buffer_free(buffer);
1755}
1756
1757TEST_F(hmm, exclusive_mprotect)
1758{
1759	struct hmm_buffer *buffer;
1760	unsigned long npages;
1761	unsigned long size;
1762	unsigned long i;
1763	int *ptr;
1764	int ret;
1765
1766	npages = ALIGN(HMM_BUFFER_SIZE, self->page_size) >> self->page_shift;
1767	ASSERT_NE(npages, 0);
1768	size = npages << self->page_shift;
1769
1770	buffer = malloc(sizeof(*buffer));
1771	ASSERT_NE(buffer, NULL);
1772
1773	buffer->fd = -1;
1774	buffer->size = size;
1775	buffer->mirror = malloc(size);
1776	ASSERT_NE(buffer->mirror, NULL);
1777
1778	buffer->ptr = mmap(NULL, size,
1779			   PROT_READ | PROT_WRITE,
1780			   MAP_PRIVATE | MAP_ANONYMOUS,
1781			   buffer->fd, 0);
1782	ASSERT_NE(buffer->ptr, MAP_FAILED);
1783
1784	/* Initialize buffer in system memory. */
1785	for (i = 0, ptr = buffer->ptr; i < size / sizeof(*ptr); ++i)
1786		ptr[i] = i;
1787
1788	/* Map memory exclusively for device access. */
1789	ret = hmm_dmirror_cmd(self->fd, HMM_DMIRROR_EXCLUSIVE, buffer, npages);
1790	ASSERT_EQ(ret, 0);
1791	ASSERT_EQ(buffer->cpages, npages);
1792
1793	/* Check what the device read. */
1794	for (i = 0, ptr = buffer->mirror; i < size / sizeof(*ptr); ++i)
1795		ASSERT_EQ(ptr[i], i);
1796
1797	ret = mprotect(buffer->ptr, size, PROT_READ);
1798	ASSERT_EQ(ret, 0);
1799
1800	/* Simulate a device writing system memory. */
1801	ret = hmm_dmirror_cmd(self->fd, HMM_DMIRROR_WRITE, buffer, npages);
1802	ASSERT_EQ(ret, -EPERM);
1803
1804	hmm_buffer_free(buffer);
1805}
1806
1807/*
1808 * Check copy-on-write works.
1809 */
1810TEST_F(hmm, exclusive_cow)
1811{
1812	struct hmm_buffer *buffer;
1813	unsigned long npages;
1814	unsigned long size;
1815	unsigned long i;
1816	int *ptr;
1817	int ret;
1818
1819	npages = ALIGN(HMM_BUFFER_SIZE, self->page_size) >> self->page_shift;
1820	ASSERT_NE(npages, 0);
1821	size = npages << self->page_shift;
1822
1823	buffer = malloc(sizeof(*buffer));
1824	ASSERT_NE(buffer, NULL);
1825
1826	buffer->fd = -1;
1827	buffer->size = size;
1828	buffer->mirror = malloc(size);
1829	ASSERT_NE(buffer->mirror, NULL);
1830
1831	buffer->ptr = mmap(NULL, size,
1832			   PROT_READ | PROT_WRITE,
1833			   MAP_PRIVATE | MAP_ANONYMOUS,
1834			   buffer->fd, 0);
1835	ASSERT_NE(buffer->ptr, MAP_FAILED);
1836
1837	/* Initialize buffer in system memory. */
1838	for (i = 0, ptr = buffer->ptr; i < size / sizeof(*ptr); ++i)
1839		ptr[i] = i;
1840
1841	/* Map memory exclusively for device access. */
1842	ret = hmm_dmirror_cmd(self->fd, HMM_DMIRROR_EXCLUSIVE, buffer, npages);
1843	ASSERT_EQ(ret, 0);
1844	ASSERT_EQ(buffer->cpages, npages);
1845
1846	fork();
1847
1848	/* Fault pages back to system memory and check them. */
1849	for (i = 0, ptr = buffer->ptr; i < size / sizeof(*ptr); ++i)
1850		ASSERT_EQ(ptr[i]++, i);
1851
1852	for (i = 0, ptr = buffer->ptr; i < size / sizeof(*ptr); ++i)
1853		ASSERT_EQ(ptr[i], i+1);
1854
1855	hmm_buffer_free(buffer);
1856}
1857
1858static int gup_test_exec(int gup_fd, unsigned long addr, int cmd,
1859			 int npages, int size, int flags)
1860{
1861	struct gup_test gup = {
1862		.nr_pages_per_call	= npages,
1863		.addr			= addr,
1864		.gup_flags		= FOLL_WRITE | flags,
1865		.size			= size,
1866	};
1867
1868	if (ioctl(gup_fd, cmd, &gup)) {
1869		perror("ioctl on error\n");
1870		return errno;
1871	}
1872
1873	return 0;
1874}
1875
1876/*
1877 * Test get user device pages through gup_test. Setting PIN_LONGTERM flag.
1878 * This should trigger a migration back to system memory for both, private
1879 * and coherent type pages.
1880 * This test makes use of gup_test module. Make sure GUP_TEST_CONFIG is added
1881 * to your configuration before you run it.
1882 */
1883TEST_F(hmm, hmm_gup_test)
1884{
1885	struct hmm_buffer *buffer;
1886	int gup_fd;
1887	unsigned long npages;
1888	unsigned long size;
1889	unsigned long i;
1890	int *ptr;
1891	int ret;
1892	unsigned char *m;
1893
1894	gup_fd = open("/sys/kernel/debug/gup_test", O_RDWR);
1895	if (gup_fd == -1)
1896		SKIP(return, "Skipping test, could not find gup_test driver");
1897
1898	npages = 4;
1899	size = npages << self->page_shift;
1900
1901	buffer = malloc(sizeof(*buffer));
1902	ASSERT_NE(buffer, NULL);
1903
1904	buffer->fd = -1;
1905	buffer->size = size;
1906	buffer->mirror = malloc(size);
1907	ASSERT_NE(buffer->mirror, NULL);
1908
1909	buffer->ptr = mmap(NULL, size,
1910			   PROT_READ | PROT_WRITE,
1911			   MAP_PRIVATE | MAP_ANONYMOUS,
1912			   buffer->fd, 0);
1913	ASSERT_NE(buffer->ptr, MAP_FAILED);
1914
1915	/* Initialize buffer in system memory. */
1916	for (i = 0, ptr = buffer->ptr; i < size / sizeof(*ptr); ++i)
1917		ptr[i] = i;
1918
1919	/* Migrate memory to device. */
1920	ret = hmm_migrate_sys_to_dev(self->fd, buffer, npages);
1921	ASSERT_EQ(ret, 0);
1922	ASSERT_EQ(buffer->cpages, npages);
1923	/* Check what the device read. */
1924	for (i = 0, ptr = buffer->mirror; i < size / sizeof(*ptr); ++i)
1925		ASSERT_EQ(ptr[i], i);
1926
1927	ASSERT_EQ(gup_test_exec(gup_fd,
1928				(unsigned long)buffer->ptr,
1929				GUP_BASIC_TEST, 1, self->page_size, 0), 0);
1930	ASSERT_EQ(gup_test_exec(gup_fd,
1931				(unsigned long)buffer->ptr + 1 * self->page_size,
1932				GUP_FAST_BENCHMARK, 1, self->page_size, 0), 0);
1933	ASSERT_EQ(gup_test_exec(gup_fd,
1934				(unsigned long)buffer->ptr + 2 * self->page_size,
1935				PIN_FAST_BENCHMARK, 1, self->page_size, FOLL_LONGTERM), 0);
1936	ASSERT_EQ(gup_test_exec(gup_fd,
1937				(unsigned long)buffer->ptr + 3 * self->page_size,
1938				PIN_LONGTERM_BENCHMARK, 1, self->page_size, 0), 0);
1939
1940	/* Take snapshot to CPU pagetables */
1941	ret = hmm_dmirror_cmd(self->fd, HMM_DMIRROR_SNAPSHOT, buffer, npages);
1942	ASSERT_EQ(ret, 0);
1943	ASSERT_EQ(buffer->cpages, npages);
1944	m = buffer->mirror;
1945	if (hmm_is_coherent_type(variant->device_number)) {
1946		ASSERT_EQ(HMM_DMIRROR_PROT_DEV_COHERENT_LOCAL | HMM_DMIRROR_PROT_WRITE, m[0]);
1947		ASSERT_EQ(HMM_DMIRROR_PROT_DEV_COHERENT_LOCAL | HMM_DMIRROR_PROT_WRITE, m[1]);
1948	} else {
1949		ASSERT_EQ(HMM_DMIRROR_PROT_WRITE, m[0]);
1950		ASSERT_EQ(HMM_DMIRROR_PROT_WRITE, m[1]);
1951	}
1952	ASSERT_EQ(HMM_DMIRROR_PROT_WRITE, m[2]);
1953	ASSERT_EQ(HMM_DMIRROR_PROT_WRITE, m[3]);
1954	/*
1955	 * Check again the content on the pages. Make sure there's no
1956	 * corrupted data.
1957	 */
1958	for (i = 0, ptr = buffer->ptr; i < size / sizeof(*ptr); ++i)
1959		ASSERT_EQ(ptr[i], i);
1960
1961	close(gup_fd);
1962	hmm_buffer_free(buffer);
1963}
1964
1965/*
1966 * Test copy-on-write in device pages.
1967 * In case of writing to COW private page(s), a page fault will migrate pages
1968 * back to system memory first. Then, these pages will be duplicated. In case
1969 * of COW device coherent type, pages are duplicated directly from device
1970 * memory.
1971 */
1972TEST_F(hmm, hmm_cow_in_device)
1973{
1974	struct hmm_buffer *buffer;
1975	unsigned long npages;
1976	unsigned long size;
1977	unsigned long i;
1978	int *ptr;
1979	int ret;
1980	unsigned char *m;
1981	pid_t pid;
1982	int status;
1983
1984	npages = 4;
1985	size = npages << self->page_shift;
1986
1987	buffer = malloc(sizeof(*buffer));
1988	ASSERT_NE(buffer, NULL);
1989
1990	buffer->fd = -1;
1991	buffer->size = size;
1992	buffer->mirror = malloc(size);
1993	ASSERT_NE(buffer->mirror, NULL);
1994
1995	buffer->ptr = mmap(NULL, size,
1996			   PROT_READ | PROT_WRITE,
1997			   MAP_PRIVATE | MAP_ANONYMOUS,
1998			   buffer->fd, 0);
1999	ASSERT_NE(buffer->ptr, MAP_FAILED);
2000
2001	/* Initialize buffer in system memory. */
2002	for (i = 0, ptr = buffer->ptr; i < size / sizeof(*ptr); ++i)
2003		ptr[i] = i;
2004
2005	/* Migrate memory to device. */
2006
2007	ret = hmm_migrate_sys_to_dev(self->fd, buffer, npages);
2008	ASSERT_EQ(ret, 0);
2009	ASSERT_EQ(buffer->cpages, npages);
2010
2011	pid = fork();
2012	if (pid == -1)
2013		ASSERT_EQ(pid, 0);
2014	if (!pid) {
2015		/* Child process waits for SIGTERM from the parent. */
2016		while (1) {
2017		}
2018		/* Should not reach this */
2019	}
2020	/* Parent process writes to COW pages(s) and gets a
2021	 * new copy in system. In case of device private pages,
2022	 * this write causes a migration to system mem first.
2023	 */
2024	for (i = 0, ptr = buffer->ptr; i < size / sizeof(*ptr); ++i)
2025		ptr[i] = i;
2026
2027	/* Terminate child and wait */
2028	EXPECT_EQ(0, kill(pid, SIGTERM));
2029	EXPECT_EQ(pid, waitpid(pid, &status, 0));
2030	EXPECT_NE(0, WIFSIGNALED(status));
2031	EXPECT_EQ(SIGTERM, WTERMSIG(status));
2032
2033	/* Take snapshot to CPU pagetables */
2034	ret = hmm_dmirror_cmd(self->fd, HMM_DMIRROR_SNAPSHOT, buffer, npages);
2035	ASSERT_EQ(ret, 0);
2036	ASSERT_EQ(buffer->cpages, npages);
2037	m = buffer->mirror;
2038	for (i = 0; i < npages; i++)
2039		ASSERT_EQ(HMM_DMIRROR_PROT_WRITE, m[i]);
2040
2041	hmm_buffer_free(buffer);
2042}
2043
2044/*
2045 * Migrate private anonymous huge empty page.
2046 */
2047TEST_F(hmm, migrate_anon_huge_empty)
2048{
2049	struct hmm_buffer *buffer;
2050	unsigned long npages;
2051	unsigned long size;
2052	unsigned long i;
2053	void *old_ptr;
2054	void *map;
2055	int *ptr;
2056	int ret;
2057
2058	size = read_pmd_pagesize();
2059
2060	buffer = malloc(sizeof(*buffer));
2061	ASSERT_NE(buffer, NULL);
2062
2063	buffer->fd = -1;
2064	buffer->size = 2 * size;
2065	buffer->mirror = malloc(size);
2066	ASSERT_NE(buffer->mirror, NULL);
2067	memset(buffer->mirror, 0xFF, size);
2068
2069	buffer->ptr = mmap(NULL, 2 * size,
2070			   PROT_READ,
2071			   MAP_PRIVATE | MAP_ANONYMOUS,
2072			   buffer->fd, 0);
2073	ASSERT_NE(buffer->ptr, MAP_FAILED);
2074
2075	npages = size >> self->page_shift;
2076	map = (void *)ALIGN((uintptr_t)buffer->ptr, size);
2077	ret = madvise(map, size, MADV_HUGEPAGE);
2078	ASSERT_EQ(ret, 0);
2079	old_ptr = buffer->ptr;
2080	buffer->ptr = map;
2081
2082	/* Migrate memory to device. */
2083	ret = hmm_migrate_sys_to_dev(self->fd, buffer, npages);
2084	ASSERT_EQ(ret, 0);
2085	ASSERT_EQ(buffer->cpages, npages);
2086
2087	/* Check what the device read. */
2088	for (i = 0, ptr = buffer->mirror; i < size / sizeof(*ptr); ++i)
2089		ASSERT_EQ(ptr[i], 0);
2090
2091	buffer->ptr = old_ptr;
2092	hmm_buffer_free(buffer);
2093}
2094
2095/*
2096 * Migrate private anonymous huge zero page.
2097 */
2098TEST_F(hmm, migrate_anon_huge_zero)
2099{
2100	struct hmm_buffer *buffer;
2101	unsigned long npages;
2102	unsigned long size;
2103	unsigned long i;
2104	void *old_ptr;
2105	void *map;
2106	int *ptr;
2107	int ret;
2108	int val;
2109
2110	size = read_pmd_pagesize();
2111
2112	buffer = malloc(sizeof(*buffer));
2113	ASSERT_NE(buffer, NULL);
2114
2115	buffer->fd = -1;
2116	buffer->size = 2 * size;
2117	buffer->mirror = malloc(size);
2118	ASSERT_NE(buffer->mirror, NULL);
2119	memset(buffer->mirror, 0xFF, size);
2120
2121	buffer->ptr = mmap(NULL, 2 * size,
2122			   PROT_READ,
2123			   MAP_PRIVATE | MAP_ANONYMOUS,
2124			   buffer->fd, 0);
2125	ASSERT_NE(buffer->ptr, MAP_FAILED);
2126
2127	npages = size >> self->page_shift;
2128	map = (void *)ALIGN((uintptr_t)buffer->ptr, size);
2129	ret = madvise(map, size, MADV_HUGEPAGE);
2130	ASSERT_EQ(ret, 0);
2131	old_ptr = buffer->ptr;
2132	buffer->ptr = map;
2133
2134	/* Initialize a read-only zero huge page. */
2135	val = *(int *)buffer->ptr;
2136	ASSERT_EQ(val, 0);
2137
2138	/* Migrate memory to device. */
2139	ret = hmm_migrate_sys_to_dev(self->fd, buffer, npages);
2140	ASSERT_EQ(ret, 0);
2141	ASSERT_EQ(buffer->cpages, npages);
2142
2143	/* Check what the device read. */
2144	for (i = 0, ptr = buffer->mirror; i < size / sizeof(*ptr); ++i)
2145		ASSERT_EQ(ptr[i], 0);
2146
2147	/* Fault pages back to system memory and check them. */
2148	for (i = 0, ptr = buffer->ptr; i < size / sizeof(*ptr); ++i) {
2149		ASSERT_EQ(ptr[i], 0);
2150		/* If it asserts once, it probably will 500,000 times */
2151		if (ptr[i] != 0)
2152			break;
2153	}
2154
2155	buffer->ptr = old_ptr;
2156	hmm_buffer_free(buffer);
2157}
2158
2159/*
2160 * Migrate private anonymous huge page and free.
2161 */
2162TEST_F(hmm, migrate_anon_huge_free)
2163{
2164	struct hmm_buffer *buffer;
2165	unsigned long npages;
2166	unsigned long size;
2167	unsigned long i;
2168	void *old_ptr;
2169	void *map;
2170	int *ptr;
2171	int ret;
2172
2173	size = read_pmd_pagesize();
2174
2175	buffer = malloc(sizeof(*buffer));
2176	ASSERT_NE(buffer, NULL);
2177
2178	buffer->fd = -1;
2179	buffer->size = 2 * size;
2180	buffer->mirror = malloc(size);
2181	ASSERT_NE(buffer->mirror, NULL);
2182	memset(buffer->mirror, 0xFF, size);
2183
2184	buffer->ptr = mmap(NULL, 2 * size,
2185			   PROT_READ | PROT_WRITE,
2186			   MAP_PRIVATE | MAP_ANONYMOUS,
2187			   buffer->fd, 0);
2188	ASSERT_NE(buffer->ptr, MAP_FAILED);
2189
2190	npages = size >> self->page_shift;
2191	map = (void *)ALIGN((uintptr_t)buffer->ptr, size);
2192	ret = madvise(map, size, MADV_HUGEPAGE);
2193	ASSERT_EQ(ret, 0);
2194	old_ptr = buffer->ptr;
2195	buffer->ptr = map;
2196
2197	/* Initialize buffer in system memory. */
2198	for (i = 0, ptr = buffer->ptr; i < size / sizeof(*ptr); ++i)
2199		ptr[i] = i;
2200
2201	/* Migrate memory to device. */
2202	ret = hmm_migrate_sys_to_dev(self->fd, buffer, npages);
2203	ASSERT_EQ(ret, 0);
2204	ASSERT_EQ(buffer->cpages, npages);
2205
2206	/* Check what the device read. */
2207	for (i = 0, ptr = buffer->mirror; i < size / sizeof(*ptr); ++i)
2208		ASSERT_EQ(ptr[i], i);
2209
2210	/* Try freeing it. */
2211	ret = madvise(map, size, MADV_FREE);
2212	ASSERT_EQ(ret, 0);
2213
2214	buffer->ptr = old_ptr;
2215	hmm_buffer_free(buffer);
2216}
2217
2218/*
2219 * Migrate private anonymous huge page and fault back to sysmem.
2220 */
2221TEST_F(hmm, migrate_anon_huge_fault)
2222{
2223	struct hmm_buffer *buffer;
2224	unsigned long npages;
2225	unsigned long size;
2226	unsigned long i;
2227	void *old_ptr;
2228	void *map;
2229	int *ptr;
2230	int ret;
2231
2232	size = read_pmd_pagesize();
2233
2234	buffer = malloc(sizeof(*buffer));
2235	ASSERT_NE(buffer, NULL);
2236
2237	buffer->fd = -1;
2238	buffer->size = 2 * size;
2239	buffer->mirror = malloc(size);
2240	ASSERT_NE(buffer->mirror, NULL);
2241	memset(buffer->mirror, 0xFF, size);
2242
2243	buffer->ptr = mmap(NULL, 2 * size,
2244			   PROT_READ | PROT_WRITE,
2245			   MAP_PRIVATE | MAP_ANONYMOUS,
2246			   buffer->fd, 0);
2247	ASSERT_NE(buffer->ptr, MAP_FAILED);
2248
2249	npages = size >> self->page_shift;
2250	map = (void *)ALIGN((uintptr_t)buffer->ptr, size);
2251	ret = madvise(map, size, MADV_HUGEPAGE);
2252	ASSERT_EQ(ret, 0);
2253	old_ptr = buffer->ptr;
2254	buffer->ptr = map;
2255
2256	/* Initialize buffer in system memory. */
2257	for (i = 0, ptr = buffer->ptr; i < size / sizeof(*ptr); ++i)
2258		ptr[i] = i;
2259
2260	/* Migrate memory to device. */
2261	ret = hmm_migrate_sys_to_dev(self->fd, buffer, npages);
2262	ASSERT_EQ(ret, 0);
2263	ASSERT_EQ(buffer->cpages, npages);
2264
2265	/* Check what the device read. */
2266	for (i = 0, ptr = buffer->mirror; i < size / sizeof(*ptr); ++i)
2267		ASSERT_EQ(ptr[i], i);
2268
2269	/* Fault pages back to system memory and check them. */
2270	for (i = 0, ptr = buffer->ptr; i < size / sizeof(*ptr); ++i)
2271		ASSERT_EQ(ptr[i], i);
2272
2273	buffer->ptr = old_ptr;
2274	hmm_buffer_free(buffer);
2275}
2276
2277/*
2278 * Migrate memory and fault back to sysmem after partially unmapping.
2279 */
2280TEST_F(hmm, migrate_partial_unmap_fault)
2281{
2282	struct hmm_buffer *buffer;
2283	unsigned long npages;
2284	unsigned long size = read_pmd_pagesize();
2285	unsigned long i;
2286	void *old_ptr;
2287	void *map;
2288	int *ptr;
2289	int ret, j, use_thp;
2290	int offsets[] = { 0, 512 * ONEKB, ONEMEG };
2291
2292	for (use_thp = 0; use_thp < 2; ++use_thp) {
2293		for (j = 0; j < ARRAY_SIZE(offsets); ++j) {
2294			buffer = malloc(sizeof(*buffer));
2295			ASSERT_NE(buffer, NULL);
2296
2297			buffer->fd = -1;
2298			buffer->size = 2 * size;
2299			buffer->mirror = malloc(size);
2300			ASSERT_NE(buffer->mirror, NULL);
2301			memset(buffer->mirror, 0xFF, size);
2302
2303			buffer->ptr = mmap(NULL, 2 * size,
2304					   PROT_READ | PROT_WRITE,
2305					   MAP_PRIVATE | MAP_ANONYMOUS,
2306					   buffer->fd, 0);
2307			ASSERT_NE(buffer->ptr, MAP_FAILED);
2308
2309			npages = size >> self->page_shift;
2310			map = (void *)ALIGN((uintptr_t)buffer->ptr, size);
2311			if (use_thp)
2312				ret = madvise(map, size, MADV_HUGEPAGE);
2313			else
2314				ret = madvise(map, size, MADV_NOHUGEPAGE);
2315			ASSERT_EQ(ret, 0);
2316			old_ptr = buffer->ptr;
2317			buffer->ptr = map;
2318
2319			/* Initialize buffer in system memory. */
2320			for (i = 0, ptr = buffer->ptr; i < size / sizeof(*ptr); ++i)
2321				ptr[i] = i;
2322
2323			/* Migrate memory to device. */
2324			ret = hmm_migrate_sys_to_dev(self->fd, buffer, npages);
2325			ASSERT_EQ(ret, 0);
2326			ASSERT_EQ(buffer->cpages, npages);
2327
2328			/* Check what the device read. */
2329			for (i = 0, ptr = buffer->mirror; i < size / sizeof(*ptr); ++i)
2330				ASSERT_EQ(ptr[i], i);
2331
2332			munmap(buffer->ptr + offsets[j], ONEMEG);
2333
2334			/* Fault pages back to system memory and check them. */
2335			for (i = 0, ptr = buffer->ptr; i < size / sizeof(*ptr); ++i)
2336				if (i * sizeof(int) < offsets[j] ||
2337				    i * sizeof(int) >= offsets[j] + ONEMEG)
2338					ASSERT_EQ(ptr[i], i);
2339
2340			buffer->ptr = old_ptr;
2341			hmm_buffer_free(buffer);
2342		}
2343	}
2344}
2345
2346TEST_F(hmm, migrate_remap_fault)
2347{
2348	struct hmm_buffer *buffer;
2349	unsigned long npages;
2350	unsigned long size = read_pmd_pagesize();
2351	unsigned long i;
2352	void *old_ptr, *new_ptr = NULL;
2353	void *map;
2354	int *ptr;
2355	int ret, j, use_thp, dont_unmap, before;
2356	int offsets[] = { 0, 512 * ONEKB, ONEMEG };
2357
2358	for (before = 0; before < 2; ++before) {
2359		for (dont_unmap = 0; dont_unmap < 2; ++dont_unmap) {
2360			for (use_thp = 0; use_thp < 2; ++use_thp) {
2361				for (j = 0; j < ARRAY_SIZE(offsets); ++j) {
2362					int flags = MREMAP_MAYMOVE | MREMAP_FIXED;
2363
2364					if (dont_unmap)
2365						flags |= MREMAP_DONTUNMAP;
2366
2367					buffer = malloc(sizeof(*buffer));
2368					ASSERT_NE(buffer, NULL);
2369
2370					buffer->fd = -1;
2371					buffer->size = 8 * size;
2372					buffer->mirror = malloc(size);
2373					ASSERT_NE(buffer->mirror, NULL);
2374					memset(buffer->mirror, 0xFF, size);
2375
2376					buffer->ptr = mmap(NULL, buffer->size,
2377							   PROT_READ | PROT_WRITE,
2378							   MAP_PRIVATE | MAP_ANONYMOUS,
2379							   buffer->fd, 0);
2380					ASSERT_NE(buffer->ptr, MAP_FAILED);
2381
2382					npages = size >> self->page_shift;
2383					map = (void *)ALIGN((uintptr_t)buffer->ptr, size);
2384					if (use_thp)
2385						ret = madvise(map, size, MADV_HUGEPAGE);
2386					else
2387						ret = madvise(map, size, MADV_NOHUGEPAGE);
2388					ASSERT_EQ(ret, 0);
2389					old_ptr = buffer->ptr;
2390					munmap(map + size, size * 2);
2391					buffer->ptr = map;
2392
2393					/* Initialize buffer in system memory. */
2394					for (i = 0, ptr = buffer->ptr;
2395					     i < size / sizeof(*ptr); ++i)
2396						ptr[i] = i;
2397
2398					if (before) {
2399						new_ptr = mremap((void *)map, size, size, flags,
2400								 map + size + offsets[j]);
2401						ASSERT_NE(new_ptr, MAP_FAILED);
2402						buffer->ptr = new_ptr;
2403					}
2404
2405					/* Migrate memory to device. */
2406					ret = hmm_migrate_sys_to_dev(self->fd, buffer, npages);
2407					ASSERT_EQ(ret, 0);
2408					ASSERT_EQ(buffer->cpages, npages);
2409
2410					/* Check what the device read. */
2411					for (i = 0, ptr = buffer->mirror;
2412					     i < size / sizeof(*ptr); ++i)
2413						ASSERT_EQ(ptr[i], i);
2414
2415					if (!before) {
2416						new_ptr = mremap((void *)map, size, size, flags,
2417								 map + size + offsets[j]);
2418						ASSERT_NE(new_ptr, MAP_FAILED);
2419						buffer->ptr = new_ptr;
2420					}
2421
2422					/* Fault pages back to system memory and check them. */
2423					for (i = 0, ptr = buffer->ptr;
2424					     i < size / sizeof(*ptr); ++i)
2425						ASSERT_EQ(ptr[i], i);
2426
2427					munmap(new_ptr, size);
2428					buffer->ptr = old_ptr;
2429					hmm_buffer_free(buffer);
2430				}
2431			}
2432		}
2433	}
2434}
2435
2436/*
2437 * Migrate private anonymous huge page with allocation errors.
2438 */
2439TEST_F(hmm, migrate_anon_huge_err)
2440{
2441	struct hmm_buffer *buffer;
2442	unsigned long npages;
2443	unsigned long size;
2444	unsigned long i;
2445	void *old_ptr;
2446	void *map;
2447	int *ptr;
2448	int ret;
2449
2450	size = read_pmd_pagesize();
2451
2452	buffer = malloc(sizeof(*buffer));
2453	ASSERT_NE(buffer, NULL);
2454
2455	buffer->fd = -1;
2456	buffer->size = 2 * size;
2457	buffer->mirror = malloc(2 * size);
2458	ASSERT_NE(buffer->mirror, NULL);
2459	memset(buffer->mirror, 0xFF, 2 * size);
2460
2461	old_ptr = mmap(NULL, 2 * size, PROT_READ | PROT_WRITE,
2462			MAP_PRIVATE | MAP_ANONYMOUS, buffer->fd, 0);
2463	ASSERT_NE(old_ptr, MAP_FAILED);
2464
2465	npages = size >> self->page_shift;
2466	map = (void *)ALIGN((uintptr_t)old_ptr, size);
2467	ret = madvise(map, size, MADV_HUGEPAGE);
2468	ASSERT_EQ(ret, 0);
2469	buffer->ptr = map;
2470
2471	/* Initialize buffer in system memory. */
2472	for (i = 0, ptr = buffer->ptr; i < size / sizeof(*ptr); ++i)
2473		ptr[i] = i;
2474
2475	/* Migrate memory to device but force a THP allocation error. */
2476	ret = hmm_dmirror_cmd(self->fd, HMM_DMIRROR_FLAGS, buffer,
2477			      HMM_DMIRROR_FLAG_FAIL_ALLOC);
2478	ASSERT_EQ(ret, 0);
2479	ret = hmm_migrate_sys_to_dev(self->fd, buffer, npages);
2480	ASSERT_EQ(ret, 0);
2481	ASSERT_EQ(buffer->cpages, npages);
2482
2483	/* Check what the device read. */
2484	for (i = 0, ptr = buffer->mirror; i < size / sizeof(*ptr); ++i) {
2485		ASSERT_EQ(ptr[i], i);
2486		if (ptr[i] != i)
2487			break;
2488	}
2489
2490	/* Try faulting back a single (PAGE_SIZE) page. */
2491	ptr = buffer->ptr;
2492	ASSERT_EQ(ptr[2048], 2048);
2493
2494	/* unmap and remap the region to reset things. */
2495	ret = munmap(old_ptr, 2 * size);
2496	ASSERT_EQ(ret, 0);
2497	old_ptr = mmap(NULL, 2 * size, PROT_READ | PROT_WRITE,
2498			MAP_PRIVATE | MAP_ANONYMOUS, buffer->fd, 0);
2499	ASSERT_NE(old_ptr, MAP_FAILED);
2500	map = (void *)ALIGN((uintptr_t)old_ptr, size);
2501	ret = madvise(map, size, MADV_HUGEPAGE);
2502	ASSERT_EQ(ret, 0);
2503	buffer->ptr = map;
2504
2505	/* Initialize buffer in system memory. */
2506	for (i = 0, ptr = buffer->ptr; i < size / sizeof(*ptr); ++i)
2507		ptr[i] = i;
2508
2509	/* Migrate THP to device. */
2510	ret = hmm_migrate_sys_to_dev(self->fd, buffer, npages);
2511	ASSERT_EQ(ret, 0);
2512	ASSERT_EQ(buffer->cpages, npages);
2513
2514	/*
2515	 * Force an allocation error when faulting back a THP resident in the
2516	 * device.
2517	 */
2518	ret = hmm_dmirror_cmd(self->fd, HMM_DMIRROR_FLAGS, buffer,
2519			      HMM_DMIRROR_FLAG_FAIL_ALLOC);
2520	ASSERT_EQ(ret, 0);
2521
2522	ret = hmm_migrate_dev_to_sys(self->fd, buffer, npages);
2523	ASSERT_EQ(ret, 0);
2524	ptr = buffer->ptr;
2525	ASSERT_EQ(ptr[2048], 2048);
2526
2527	buffer->ptr = old_ptr;
2528	hmm_buffer_free(buffer);
2529}
2530
2531/*
2532 * Migrate private anonymous huge zero page with allocation errors.
2533 */
2534TEST_F(hmm, migrate_anon_huge_zero_err)
2535{
2536	struct hmm_buffer *buffer;
2537	unsigned long npages;
2538	unsigned long size;
2539	unsigned long i;
2540	void *old_ptr;
2541	void *map;
2542	int *ptr;
2543	int ret;
2544
2545	size = read_pmd_pagesize();
2546
2547	buffer = malloc(sizeof(*buffer));
2548	ASSERT_NE(buffer, NULL);
2549
2550	buffer->fd = -1;
2551	buffer->size = 2 * size;
2552	buffer->mirror = malloc(2 * size);
2553	ASSERT_NE(buffer->mirror, NULL);
2554	memset(buffer->mirror, 0xFF, 2 * size);
2555
2556	old_ptr = mmap(NULL, 2 * size, PROT_READ,
2557			MAP_PRIVATE | MAP_ANONYMOUS, buffer->fd, 0);
2558	ASSERT_NE(old_ptr, MAP_FAILED);
2559
2560	npages = size >> self->page_shift;
2561	map = (void *)ALIGN((uintptr_t)old_ptr, size);
2562	ret = madvise(map, size, MADV_HUGEPAGE);
2563	ASSERT_EQ(ret, 0);
2564	buffer->ptr = map;
2565
2566	/* Migrate memory to device but force a THP allocation error. */
2567	ret = hmm_dmirror_cmd(self->fd, HMM_DMIRROR_FLAGS, buffer,
2568			      HMM_DMIRROR_FLAG_FAIL_ALLOC);
2569	ASSERT_EQ(ret, 0);
2570	ret = hmm_migrate_sys_to_dev(self->fd, buffer, npages);
2571	ASSERT_EQ(ret, 0);
2572	ASSERT_EQ(buffer->cpages, npages);
2573
2574	/* Check what the device read. */
2575	for (i = 0, ptr = buffer->mirror; i < size / sizeof(*ptr); ++i)
2576		ASSERT_EQ(ptr[i], 0);
2577
2578	/* Try faulting back a single (PAGE_SIZE) page. */
2579	ptr = buffer->ptr;
2580	ASSERT_EQ(ptr[2048], 0);
2581
2582	/* unmap and remap the region to reset things. */
2583	ret = munmap(old_ptr, 2 * size);
2584	ASSERT_EQ(ret, 0);
2585	old_ptr = mmap(NULL, 2 * size, PROT_READ,
2586			MAP_PRIVATE | MAP_ANONYMOUS, buffer->fd, 0);
2587	ASSERT_NE(old_ptr, MAP_FAILED);
2588	map = (void *)ALIGN((uintptr_t)old_ptr, size);
2589	ret = madvise(map, size, MADV_HUGEPAGE);
2590	ASSERT_EQ(ret, 0);
2591	buffer->ptr = map;
2592
2593	/* Initialize buffer in system memory (zero THP page). */
2594	ret = ptr[0];
2595	ASSERT_EQ(ret, 0);
2596
2597	/* Migrate memory to device but force a THP allocation error. */
2598	ret = hmm_dmirror_cmd(self->fd, HMM_DMIRROR_FLAGS, buffer,
2599			      HMM_DMIRROR_FLAG_FAIL_ALLOC);
2600	ASSERT_EQ(ret, 0);
2601	ret = hmm_migrate_sys_to_dev(self->fd, buffer, npages);
2602	ASSERT_EQ(ret, 0);
2603	ASSERT_EQ(buffer->cpages, npages);
2604
2605	/* Fault the device memory back and check it. */
2606	for (i = 0, ptr = buffer->ptr; i < size / sizeof(*ptr); ++i)
2607		ASSERT_EQ(ptr[i], 0);
2608
2609	buffer->ptr = old_ptr;
2610	hmm_buffer_free(buffer);
2611}
2612
2613struct benchmark_results {
2614	double sys_to_dev_time;
2615	double dev_to_sys_time;
2616	double throughput_s2d;
2617	double throughput_d2s;
2618};
2619
2620static double get_time_ms(void)
2621{
2622	struct timeval tv;
2623
2624	gettimeofday(&tv, NULL);
2625	return (tv.tv_sec * 1000.0) + (tv.tv_usec / 1000.0);
2626}
2627
2628static inline struct hmm_buffer *hmm_buffer_alloc(unsigned long size)
2629{
2630	struct hmm_buffer *buffer;
2631
2632	buffer = malloc(sizeof(*buffer));
2633
2634	buffer->fd = -1;
2635	buffer->size = size;
2636	buffer->mirror = malloc(size);
2637	memset(buffer->mirror, 0xFF, size);
2638	return buffer;
2639}
2640
2641static void print_benchmark_results(const char *test_name, size_t buffer_size,
2642				     struct benchmark_results *thp,
2643				     struct benchmark_results *regular)
2644{
2645	double s2d_improvement = ((regular->sys_to_dev_time - thp->sys_to_dev_time) /
2646				 regular->sys_to_dev_time) * 100.0;
2647	double d2s_improvement = ((regular->dev_to_sys_time - thp->dev_to_sys_time) /
2648				 regular->dev_to_sys_time) * 100.0;
2649	double throughput_s2d_improvement = ((thp->throughput_s2d - regular->throughput_s2d) /
2650					    regular->throughput_s2d) * 100.0;
2651	double throughput_d2s_improvement = ((thp->throughput_d2s - regular->throughput_d2s) /
2652					    regular->throughput_d2s) * 100.0;
2653
2654	printf("\n=== %s (%.1f MB) ===\n", test_name, buffer_size / (1024.0 * 1024.0));
2655	printf("                     | With THP        | Without THP     | Improvement\n");
2656	printf("---------------------------------------------------------------------\n");
2657	printf("Sys->Dev Migration   | %.3f ms        | %.3f ms        | %.1f%%\n",
2658	       thp->sys_to_dev_time, regular->sys_to_dev_time, s2d_improvement);
2659	printf("Dev->Sys Migration   | %.3f ms        | %.3f ms        | %.1f%%\n",
2660	       thp->dev_to_sys_time, regular->dev_to_sys_time, d2s_improvement);
2661	printf("S->D Throughput      | %.2f GB/s      | %.2f GB/s      | %.1f%%\n",
2662	       thp->throughput_s2d, regular->throughput_s2d, throughput_s2d_improvement);
2663	printf("D->S Throughput      | %.2f GB/s      | %.2f GB/s      | %.1f%%\n",
2664	       thp->throughput_d2s, regular->throughput_d2s, throughput_d2s_improvement);
2665}
2666
2667/*
2668 * Run a single migration benchmark
2669 * fd: file descriptor for hmm device
2670 * use_thp: whether to use THP
2671 * buffer_size: size of buffer to allocate
2672 * iterations: number of iterations
2673 * results: where to store results
2674 */
2675static inline int run_migration_benchmark(int fd, int use_thp, size_t buffer_size,
2676					   int iterations, struct benchmark_results *results)
2677{
2678	struct hmm_buffer *buffer;
2679	unsigned long npages = buffer_size / sysconf(_SC_PAGESIZE);
2680	double start, end;
2681	double s2d_total = 0, d2s_total = 0;
2682	int ret, i;
2683	int *ptr;
2684
2685	buffer = hmm_buffer_alloc(buffer_size);
2686
2687	/* Map memory */
2688	buffer->ptr = mmap(NULL, buffer_size, PROT_READ | PROT_WRITE,
2689			  MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
2690
2691	if (!buffer->ptr)
2692		return -1;
2693
2694	/* Apply THP hint if requested */
2695	if (use_thp)
2696		ret = madvise(buffer->ptr, buffer_size, MADV_HUGEPAGE);
2697	else
2698		ret = madvise(buffer->ptr, buffer_size, MADV_NOHUGEPAGE);
2699
2700	if (ret)
2701		return ret;
2702
2703	/* Initialize memory to make sure pages are allocated */
2704	ptr = (int *)buffer->ptr;
2705	for (i = 0; i < buffer_size / sizeof(int); i++)
2706		ptr[i] = i & 0xFF;
2707
2708	/* Warmup iteration */
2709	ret = hmm_migrate_sys_to_dev(fd, buffer, npages);
2710	if (ret)
2711		return ret;
2712
2713	ret = hmm_migrate_dev_to_sys(fd, buffer, npages);
2714	if (ret)
2715		return ret;
2716
2717	/* Benchmark iterations */
2718	for (i = 0; i < iterations; i++) {
2719		/* System to device migration */
2720		start = get_time_ms();
2721
2722		ret = hmm_migrate_sys_to_dev(fd, buffer, npages);
2723		if (ret)
2724			return ret;
2725
2726		end = get_time_ms();
2727		s2d_total += (end - start);
2728
2729		/* Device to system migration */
2730		start = get_time_ms();
2731
2732		ret = hmm_migrate_dev_to_sys(fd, buffer, npages);
2733		if (ret)
2734			return ret;
2735
2736		end = get_time_ms();
2737		d2s_total += (end - start);
2738	}
2739
2740	/* Calculate average times and throughput */
2741	results->sys_to_dev_time = s2d_total / iterations;
2742	results->dev_to_sys_time = d2s_total / iterations;
2743	results->throughput_s2d = (buffer_size / (1024.0 * 1024.0 * 1024.0)) /
2744				 (results->sys_to_dev_time / 1000.0);
2745	results->throughput_d2s = (buffer_size / (1024.0 * 1024.0 * 1024.0)) /
2746				 (results->dev_to_sys_time / 1000.0);
2747
2748	/* Cleanup */
2749	hmm_buffer_free(buffer);
2750	return 0;
2751}
2752
2753/*
2754 * Benchmark THP migration with different buffer sizes
2755 */
2756TEST_F_TIMEOUT(hmm, benchmark_thp_migration, 120)
2757{
2758	struct benchmark_results thp_results, regular_results;
2759	size_t thp_size = 2 * 1024 * 1024; /* 2MB - typical THP size */
2760	int iterations = 5;
2761
2762	printf("\nHMM THP Migration Benchmark\n");
2763	printf("---------------------------\n");
2764	printf("System page size: %ld bytes\n", sysconf(_SC_PAGESIZE));
2765
2766	/* Test different buffer sizes */
2767	size_t test_sizes[] = {
2768		thp_size / 4,      /* 512KB - smaller than THP */
2769		thp_size / 2,      /* 1MB - half THP */
2770		thp_size,          /* 2MB - single THP */
2771		thp_size * 2,      /* 4MB - two THPs */
2772		thp_size * 4,      /* 8MB - four THPs */
2773		thp_size * 8,       /* 16MB - eight THPs */
2774		thp_size * 128,       /* 256MB - one twenty eight THPs */
2775	};
2776
2777	static const char *const test_names[] = {
2778		"Small Buffer (512KB)",
2779		"Half THP Size (1MB)",
2780		"Single THP Size (2MB)",
2781		"Two THP Size (4MB)",
2782		"Four THP Size (8MB)",
2783		"Eight THP Size (16MB)",
2784		"One twenty eight THP Size (256MB)"
2785	};
2786
2787	int num_tests = ARRAY_SIZE(test_sizes);
2788
2789	/* Run all tests */
2790	for (int i = 0; i < num_tests; i++) {
2791		/* Test with THP */
2792		ASSERT_EQ(run_migration_benchmark(self->fd, 1, test_sizes[i],
2793					iterations, &thp_results), 0);
2794
2795		/* Test without THP */
2796		ASSERT_EQ(run_migration_benchmark(self->fd, 0, test_sizes[i],
2797					iterations, &regular_results), 0);
2798
2799		/* Print results */
2800		print_benchmark_results(test_names[i], test_sizes[i],
2801					&thp_results, &regular_results);
2802	}
2803}
2804TEST_HARNESS_MAIN
~/ Read-only file preview.