diff options
author | Artur Grabowski <art@cvs.openbsd.org> | 2007-05-21 07:27:38 +0000 |
---|---|---|
committer | Artur Grabowski <art@cvs.openbsd.org> | 2007-05-21 07:27:38 +0000 |
commit | 52cfba5eb85a2f8dc35d5903d684c73669b2dcad (patch) | |
tree | 86646bbb2827bf35e8ce0830a2566958d02c0d8d | |
parent | 0ee94271e89f93fd778e45ae27e6cb9c3aca5e9d (diff) |
A test for a corner-case that some pmaps get wrong.
-rw-r--r-- | regress/sys/uvm/mmap_mod/Makefile | 5 | ||||
-rw-r--r-- | regress/sys/uvm/mmap_mod/mmap_mod.c | 74 |
2 files changed, 79 insertions, 0 deletions
diff --git a/regress/sys/uvm/mmap_mod/Makefile b/regress/sys/uvm/mmap_mod/Makefile new file mode 100644 index 00000000000..336408c1ada --- /dev/null +++ b/regress/sys/uvm/mmap_mod/Makefile @@ -0,0 +1,5 @@ +# $OpenBSD: Makefile,v 1.1 2007/05/21 07:27:37 art Exp $ + +PROG=mmap_mod + +.include <bsd.regress.mk> diff --git a/regress/sys/uvm/mmap_mod/mmap_mod.c b/regress/sys/uvm/mmap_mod/mmap_mod.c new file mode 100644 index 00000000000..eb931ad24f5 --- /dev/null +++ b/regress/sys/uvm/mmap_mod/mmap_mod.c @@ -0,0 +1,74 @@ +/* $OpenBSD: mmap_mod.c,v 1.1 2007/05/21 07:27:37 art Exp $ */ + +/* + * Public domain. 2007, Artur Grabowski <art@openbsd.org> + */ + +#include <sys/types.h> +#include <sys/mman.h> +#include <err.h> +#include <stdlib.h> +#include <stdio.h> +#include <unistd.h> + +/* + * Test a corner case where a pmap can lose mod/ref bits after unmapping + * and remapping a page. + */ +int +main() +{ + char name[20] = "/tmp/fluff.XXXXXX"; + char *buf, *pat; + size_t ps; + int fd; + + ps = getpagesize(); + + if ((fd = mkstemp(name)) == -1) + err(1, "mkstemp"); + + if (unlink(name) == -1) + err(1, "unlink"); + + if (ftruncate(fd, ps)) + err(1, "ftruncate"); + + if ((pat = malloc(ps)) == NULL) + err(1, "malloc"); + + memset(pat, 'a', ps); + + if (pwrite(fd, pat, ps, 0) != ps) + err(1, "write"); + + buf = mmap(NULL, ps, PROT_READ|PROT_WRITE, MAP_FILE|MAP_SHARED, fd, 0); + if (buf == MAP_FAILED) + err(1, "mmap"); + + if (*buf != 'a') + errx(1, "mapped area - no file data ('%c' != 'a')", *buf); + + memset(buf, 'x', ps); + + if (munmap(buf, ps) == -1) + err(1, "munmap"); + + buf = mmap(NULL, ps, PROT_READ|PROT_WRITE, MAP_FILE|MAP_SHARED, fd, 0); + if (buf == MAP_FAILED) + err(1, "mmap 2"); + + if (*buf != 'x') + errx(1, "mapped area lost modifications ('%c' != 'x')", *buf); + + if (msync(buf, ps, MS_SYNC) == -1) + err(1, "msync"); + + if (pread(fd, pat, ps, 0) != ps) + err(1, "pread"); + + if (*pat != 'x') + errx(1, "synced area lost modifications ('%c' != 'x')", *pat); + + return (0); +} |