summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorArtur Grabowski <art@cvs.openbsd.org>2007-05-21 07:27:38 +0000
committerArtur Grabowski <art@cvs.openbsd.org>2007-05-21 07:27:38 +0000
commit52cfba5eb85a2f8dc35d5903d684c73669b2dcad (patch)
tree86646bbb2827bf35e8ce0830a2566958d02c0d8d
parent0ee94271e89f93fd778e45ae27e6cb9c3aca5e9d (diff)
A test for a corner-case that some pmaps get wrong.
-rw-r--r--regress/sys/uvm/mmap_mod/Makefile5
-rw-r--r--regress/sys/uvm/mmap_mod/mmap_mod.c74
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);
+}