static void dirty_anonymous_unmap(void) { char *page; page = checked_mmap(NULL, PS, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS|MAP_POPULATE, 0, 0); testmem("dirty", page, MWRITE); munmap_reserve(page, PS); }
static void nonlinear(void) { int fd; const int NPAGES = 10; int i; char *page; char *tmp; fd = tempfd(); tmp = xmalloc(PS); for (i = 0; i < NPAGES; i++) { memset(tmp, i, PS); write(fd, tmp, PS); } free(tmp); page = checked_mmap(NULL, PS*NPAGES, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0); int k = NPAGES - 1; for (i = 0; i < NPAGES; i++, k--) { if (remap_file_pages(page + i*PS, PS, 0, k, 0)) perror("remap_file_pages"); } *page = 1; testmem("rfp file dirty", page, MREAD); expecterr("rfp fsync expect error", fsync(fd) < 0); optionalerr("rfp msync expect error", msync(page, PS, MS_SYNC) < 0); close(fd); }
void anonymous(char *name, int flags) { char buf[100]; char *p = checked_mmap(NULL, PS, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS|flags, 0, 0); printf("anonymous\n"); *(volatile int *)p = 1; offline(ndesc(buf, "anonymous", name), p); *(volatile int *)p = 1; munmap(p, PS); }
/* TBD */ static void file_hole(void) { int fd = tempfd(); char *page; ftruncate(fd, PS); page = checked_mmap(NULL, PS, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0); *page = 1; testmem("hole file dirty", page, MREAD); expecterr("hole fsync expect error", fsync(fd) < 0); optionalerr("hole msync expect error", msync(page, PS, MS_SYNC) < 0); close(fd); }
static void file_dirty(void) { char *page; char fn[PATHBUFLEN]; fn[0] = 0; int fd = playfile(fn); page = checked_mmap(NULL, PS, PROT_READ, MAP_SHARED|MAP_POPULATE, fd, 0); testmem("dirty file initial", page, MREAD); expecterr("msync expect error", msync(page, PS, MS_SYNC) < 0); close(fd); munmap_reserve(page, PS); fd = open(fn, O_RDONLY); if (fd < 0) err("reopening temp file"); page = checked_mmap(NULL, PS, PROT_READ, MAP_SHARED|MAP_POPULATE, fd, 0); recover("dirty file populated", page, MREAD_OK); close(fd); munmap_reserve(page, PS); fd = open(fn, O_RDONLY); if (fd < 0) err("reopening temp file"); page = checked_mmap(NULL, PS, PROT_READ, MAP_SHARED, fd, 0); recover("dirty file fault", page, MREAD_OK); close(fd); munmap_reserve(page, PS); fd = open(fn, O_RDWR); char buf[128]; expecterr("explicit read after poison", read(fd, buf, sizeof buf) < 0); expecterr("explicit write after poison", write(fd, "foobar", 6) < 0); optionalerr("fsync expect error", fsync(fd) < 0); close(fd); /* should unlink return an error here? */ if (unlink(fn) < 0) perror("unlink"); }
void disk_backed(char *name, int flags) { char fn[100]; snprintf(fn, sizeof fn, TMPDIR "~test%u", getpid()); printf("shared, diskbacked\n"); int fd = open(fn, O_RDWR|O_CREAT|O_TRUNC, 0644); if (fd < 0) err("open tmpfile"); write(fd, empty, sizeof empty); char *p = checked_mmap(NULL, PS, PROT_READ|PROT_WRITE, MAP_SHARED|flags, fd, 0); *(volatile int *)p = 1; offline(ndesc(fn, "disk backed", name), p); munmap(p, PS); }
static void file_clean(void) { char *page; char fn[30]; snprintf(fn, 30, TMPDIR "test%d", tmpcount++); int fd = open(fn, O_RDWR|O_TRUNC|O_CREAT); if (fd < 0) err("open temp file"); write(fd, fn, 4); fsync(fd); page = checked_mmap(NULL, PS, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0); close(fd); testmem("file clean", page, MREAD_OK); printf("%x\n", *(unsigned char *)page); /* reread page from disk */ testmem("file clean", page, MWRITE_OK); }
int main(int argc, char *argv[]) { int nr = 2; char c; int mapflag = MAP_SHARED; unsigned long memsize = 0; int hugetlbfd1; char *phugetlbfile1; unsigned long address = ADDR_INPUT; char *filename; while ((c = getopt(argc, argv, "h:f:n:v")) != -1) { switch(c) { case 'h': HPS = strtoul(optarg, NULL, 10) * 1024; break; case 'f': filename = optarg; break; case 'n': nr = strtoul(optarg, NULL, 10); break; case 'v': verbose = 1; break; } } if (!filename) { errmsg("need to specify file path with -f\n"); } validate_hugepage_size(HPS); memsize = nr * HPS; signal(SIGUSR1, sig_handle); Dprintf("memsize = 0x%x, hpsize = %d, mapflag = 0x%x\n", memsize, HPS, mapflag); hugetlbfd1 = checked_open(filename, O_CREAT|O_RDWR); phugetlbfile1 = checked_mmap((void *)address, memsize, MMAP_PROT, mapflag, hugetlbfd1, 0); Dprintf("p %p\n", phugetlbfile1); memset(phugetlbfile1, 'a', memsize); munmap(phugetlbfile1, memsize); checked_close(hugetlbfd1); pprintf("%s exit\n", argv[0]); exit(EXIT_SUCCESS); }
static void mmap_bad_arguments( void ) { int devfd, pagesize, shmfd, zerofd; void* p; rtems_test_assert((pagesize = getpagesize()) > 0); rtems_test_assert((devfd = open(&test_driver_name[0], O_RDONLY)) >= 0); rtems_test_assert((shmfd = shm_open("/shm", O_CREAT | O_RDWR, 0644)) >= 0); rtems_test_assert(ftruncate(shmfd, pagesize) == 0); rtems_test_assert((zerofd = open("/dev/zero", O_RDONLY)) >= 0); /* * These should normally work on FREEBSD. Test cases below that fail are * due to unsupported features in RTEMS. */ checked_mmap(PROT_READ | PROT_WRITE, MAP_ANON, -1, 0, "simple MAP_ANON"); checked_mmap(PROT_READ | PROT_WRITE, MAP_SHARED, shmfd, 0, "simple shm fd shared"); checked_mmap(PROT_READ | PROT_WRITE, MAP_PRIVATE, shmfd, 0, "simple shm fd private"); /* RTEMS cannot protect against writes so this will fail */ checked_mmap(PROT_READ, MAP_SHARED, zerofd, ENOTSUP, "simple /dev/zero shared"); /* * Repeat with no write protection. Will fail because of unimplemented * mmap handler in /dev/zero. */ checked_mmap(PROT_READ | PROT_WRITE, MAP_SHARED, zerofd, ENOTSUP, "simple /dev/zero shared"); /* RTEMS /dev/zero is a character device so this will fail */ checked_mmap(PROT_READ | PROT_WRITE, MAP_PRIVATE, zerofd, EINVAL, "simple /dev/zero private"); /* RTEMS cannot protect against writes so this will fail */ checked_mmap(PROT_READ, MAP_SHARED, devfd, ENOTSUP, "simple test driver shared"); /* * Repeat with no write protection. Should fail because of unimplemented * mmap handler in /dev/null. */ p = checked_mmap(PROT_READ | PROT_WRITE, MAP_SHARED, devfd, 0, "simple test driver shared"); rtems_test_assert(p == &test_data[0]); /* Extra PROT flags. */ checked_mmap(PROT_READ | PROT_WRITE | 0x100000, MAP_ANON, -1, EINVAL, "MAP_ANON with extra PROT flags"); checked_mmap(0xffff, MAP_SHARED, shmfd, EINVAL, "shm fd with garbage PROT"); /* Undefined flag. */ checked_mmap(PROT_READ | PROT_WRITE, MAP_ANON | MAP_RESERVED0080, -1, EINVAL, "Undefined flag"); /* Both MAP_SHARED and MAP_PRIVATE */ checked_mmap(PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE | MAP_SHARED, -1, EINVAL, "MAP_ANON with both SHARED and PRIVATE"); checked_mmap(PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_SHARED, shmfd, EINVAL, "shm fd with both SHARED and PRIVATE"); /* At least one of MAP_SHARED or MAP_PRIVATE without ANON */ checked_mmap(PROT_READ | PROT_WRITE, 0, shmfd, EINVAL, "shm fd without sharing flag"); /* MAP_ANON with sharing flag. Will fail on RTEMS*/ checked_mmap(PROT_READ | PROT_WRITE, MAP_ANON | MAP_SHARED, -1, EINVAL, "shared MAP_ANON"); /* MAP_ANON with private flag*/ checked_mmap(PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE, -1, 0, "private MAP_ANON"); /* MAP_ANON should require an fd of -1. */ checked_mmap(PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE, 0, EINVAL, "MAP_ANON with fd != -1"); /* * Writable MAP_SHARED should fail on read-only descriptors. Will fail * on RTEMS because of unimplemented mmap handler in /dev/null and the fact * that there is no read only protection. */ checked_mmap(PROT_READ | PROT_WRITE, MAP_SHARED, zerofd, ENOTSUP, "MAP_SHARED of read-only /dev/zero"); /* * Character devices other than /dev/zero do not support private * mappings. RTEMS cannot protect against writes so this will fail with * ENOTSUP */ checked_mmap(PROT_READ, MAP_PRIVATE, devfd, ENOTSUP, "MAP_PRIVATE of test driver"); /* * Repeat with no write protection. */ checked_mmap(PROT_READ | PROT_WRITE, MAP_PRIVATE, devfd, EINVAL, "MAP_PRIVATE of test driver"); close(devfd); close(shmfd); close(zerofd); }
int main(int argc, char *argv[]) { int i; int nr = 2; char c; char *p; int mapflag = MAP_ANONYMOUS|MAP_SHARED; int protflag = PROT_READ|PROT_WRITE; int reserveonly = 0; unsigned long memsize = 0; while ((c = getopt(argc, argv, "h:rm:p:n:v")) != -1) { switch(c) { case 'h': HPS = strtoul(optarg, NULL, 10) * 1024; mapflag |= MAP_HUGETLB; break; case 'r': /* just reserve */ reserveonly = 1; break; case 'm': if (!strcmp(optarg, "private")) { mapflag |= MAP_PRIVATE; mapflag &= ~MAP_SHARED; } else if (!strcmp(optarg, "shared")) mapflag |= MAP_SHARED; else errmsg("invalid optarg for -m\n"); break; case 'p': testpipe = optarg; { struct stat stat; lstat(testpipe, &stat); if (!S_ISFIFO(stat.st_mode)) errmsg("Given file is not fifo.\n"); } break; case 'n': nr = strtoul(optarg, NULL, 10); break; case 'v': verbose = 1; break; } } signal(SIGUSR1, sig_handle); if (HPS > 0) { validate_hugepage_size(HPS); memsize = nr * HPS; } else memsize = nr * PS; Dprintf("memsize = 0x%x, hpsize = %d, mapflag = 0x%x\n", memsize, HPS, mapflag); p = checked_mmap((void *)ADDR_INPUT, memsize, protflag, mapflag, -1, 0); if (!reserveonly) memset(p, 'a', memsize); signal(SIGUSR1, sig_handle_flag); pprintf("busy loop to check pageflags\n"); while (flag) { usleep(1000); if (!reserveonly) memset(p, 'a', memsize); } pprintf("%s exit\n", argv[0]); pause(); exit(EXIT_SUCCESS); }
int main(int argc, char *argv[]) { int i; int ret; int nr = 2; char c; char *p; int mapflag = MAP_ANONYMOUS; int protflag = PROT_READ|PROT_WRITE; unsigned long nr_nodes = numa_max_node() + 1; struct bitmask *new_nodes; unsigned long nodemask; int do_unpoison = 0; int loop = 3; while ((c = getopt(argc, argv, "vp:m:n:ul:h:")) != -1) { switch(c) { case 'v': verbose = 1; break; case 'p': testpipe = optarg; { struct stat stat; lstat(testpipe, &stat); if (!S_ISFIFO(stat.st_mode)) errmsg("Given file is not fifo.\n"); } break; case 'm': if (!strcmp(optarg, "private")) mapflag |= MAP_PRIVATE; else if (!strcmp(optarg, "shared")) mapflag |= MAP_SHARED; else errmsg("invalid optarg for -m\n"); break; case 'n': nr = strtoul(optarg, NULL, 10); break; case 'u': do_unpoison = 1; break; case 'l': loop = strtoul(optarg, NULL, 10); break; case 'h': HPS = strtoul(optarg, NULL, 10) * 1024; mapflag |= MAP_HUGETLB; /* todo: arch independent */ if (HPS != 2097152 && HPS != 1073741824) errmsg("Invalid hugepage size\n"); break; default: errmsg("invalid option\n"); break; } } if (nr_nodes < 2) errmsg("A minimum of 2 nodes is required for this test.\n"); new_nodes = numa_bitmask_alloc(nr_nodes); numa_bitmask_setbit(new_nodes, 1); nodemask = 1; /* only node 0 allowed */ if (set_mempolicy(MPOL_BIND, &nodemask, nr_nodes) == -1) err("set_mempolicy"); signal(SIGUSR2, sig_handle); pprintf("start background migration\n"); pause(); signal(SIGUSR1, sig_handle_flag); pprintf("hugepages prepared\n"); while (flag) { p = checked_mmap((void *)ADDR_INPUT, nr * HPS, protflag, mapflag, -1, 0); /* fault in */ memset(p, 'a', nr * HPS); for (i = 0; i < nr; i++) { ret = madvise(p + i * HPS, 4096, MADV_HWPOISON); if (ret) { perror("madvise"); pprintf("madvise returned %d\n", ret); } } if (do_unpoison) { pprintf("need unpoison\n"); pause(); } checked_munmap(p, nr * HPS); if (loop-- <= 0) break; } pprintf("exit\n"); pause(); return 0; }
static void mlocked_anonymous(void) { char *page; page = checked_mmap(NULL, PS, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS|MAP_LOCKED, 0, 0); testmem("mlocked", page, MWRITE); }
ATF_TC_BODY(mmap__bad_arguments, tc) { int devstatfd, shmfd, zerofd; ATF_REQUIRE((devstatfd = open("/dev/devstat", O_RDONLY)) >= 0); ATF_REQUIRE((shmfd = shm_open(SHM_ANON, O_RDWR, 0644)) >= 0); ATF_REQUIRE(ftruncate(shmfd, getpagesize()) == 0); ATF_REQUIRE((zerofd = open("/dev/zero", O_RDONLY)) >= 0); /* These should work. */ checked_mmap(PROT_READ | PROT_WRITE, MAP_ANON, -1, 0, "simple MAP_ANON"); checked_mmap(PROT_READ | PROT_WRITE, MAP_SHARED, shmfd, 0, "simple shm fd shared"); checked_mmap(PROT_READ | PROT_WRITE, MAP_PRIVATE, shmfd, 0, "simple shm fd private"); checked_mmap(PROT_READ, MAP_SHARED, zerofd, 0, "simple /dev/zero shared"); checked_mmap(PROT_READ | PROT_WRITE, MAP_PRIVATE, zerofd, 0, "simple /dev/zero private"); checked_mmap(PROT_READ, MAP_SHARED, devstatfd, 0, "simple /dev/devstat shared"); /* Extra PROT flags. */ checked_mmap(PROT_READ | PROT_WRITE | 0x100000, MAP_ANON, -1, EINVAL, "MAP_ANON with extra PROT flags"); checked_mmap(0xffff, MAP_SHARED, shmfd, EINVAL, "shm fd with garbage PROT"); /* Undefined flag. */ checked_mmap(PROT_READ | PROT_WRITE, MAP_ANON | MAP_RESERVED0080, -1, EINVAL, "Undefined flag"); /* Both MAP_SHARED and MAP_PRIVATE */ checked_mmap(PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE | MAP_SHARED, -1, EINVAL, "MAP_ANON with both SHARED and PRIVATE"); checked_mmap(PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_SHARED, shmfd, EINVAL, "shm fd with both SHARED and PRIVATE"); /* At least one of MAP_SHARED or MAP_PRIVATE without ANON */ checked_mmap(PROT_READ | PROT_WRITE, 0, shmfd, EINVAL, "shm fd without sharing flag"); /* MAP_ANON with either sharing flag (impacts fork). */ checked_mmap(PROT_READ | PROT_WRITE, MAP_ANON | MAP_SHARED, -1, 0, "shared MAP_ANON"); checked_mmap(PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE, -1, 0, "private MAP_ANON"); /* MAP_ANON should require an fd of -1. */ checked_mmap(PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE, 0, EINVAL, "MAP_ANON with fd != -1"); /* Writable MAP_SHARED should fail on read-only descriptors. */ checked_mmap(PROT_READ | PROT_WRITE, MAP_SHARED, zerofd, EACCES, "MAP_SHARED of read-only /dev/zero"); /* * Character devices other than /dev/zero do not support private * mappings. */ checked_mmap(PROT_READ, MAP_PRIVATE, devstatfd, EINVAL, "MAP_PRIVATE of /dev/devstat"); }