// SPDX-License-Identifier: GPL-2.0
/*
* HMM stands for Heterogeneous Memory Management, it is a helper layer inside
* the linux kernel to help device drivers mirror a process address space in
* the device. This allows the device to use the same address space which
* makes communication and data exchange a lot easier.
*
* This framework's sole purpose is to exercise various code paths inside
* the kernel to make sure that HMM performs as expected and to flush out any
* bugs.
*/
#include "../kselftest_harness.h"
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <unistd.h>
#include <strings.h>
#include <time.h>
#include <pthread.h>
#include <hugetlbfs.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <sys/ioctl.h>
/*
* This is a private UAPI to the kernel test module so it isn't exported
* in the usual include/uapi/... directory.
*/
#include "../../../../lib/test_hmm_uapi.h"
struct hmm_buffer {
void *ptr;
void *mirror;
unsigned long size;
int fd;
uint64_t cpages;
uint64_t faults;
};
#define TWOMEG (1 << 21)
#define HMM_BUFFER_SIZE (1024 << 12)
#define HMM_PATH_MAX 64
#define NTIMES 256
#define ALIGN(x, a) (((x) + (a - 1)) & (~((a) - 1)))
FIXTURE(hmm)
{
int fd;
unsigned int page_size;
unsigned int page_shift;
};
FIXTURE(hmm2)
{
int fd0;
int fd1;
unsigned int page_size;
unsigned int page_shift;
};
static int hmm_open(int unit)
{
char pathname[HMM_PATH_MAX];
int fd;
snprintf(pathname, sizeof(pathname), "/dev/hmm_dmirror%d", unit);
fd = open(pathname, O_RDWR, 0);
if (fd < 0)
fprintf(stderr, "could not open hmm dmirror driver (%s)\n",
pathname);
return fd;
}
FIXTURE_SETUP(hmm)
{
self->page_size = sysconf(_SC_PAGE_SIZE);
self->page_shift = ffs(self->page_size) - 1;
self->fd = hmm_open(0);
ASSERT_GE(self->fd, 0);
}
FIXTURE_SETUP(hmm2)
{
self->page_size =