From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1JQTX8-00044p-4E for qemu-devel@nongnu.org; Sat, 16 Feb 2008 15:21:14 -0500 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1JQTX6-00043e-Bk for qemu-devel@nongnu.org; Sat, 16 Feb 2008 15:21:13 -0500 Received: from [199.232.76.173] (helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1JQTX6-00043a-7S for qemu-devel@nongnu.org; Sat, 16 Feb 2008 15:21:12 -0500 Received: from miranda.se.axis.com ([193.13.178.8]) by monty-python.gnu.org with esmtps (TLS-1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.60) (envelope-from ) id 1JQTX5-0008IV-Q1 for qemu-devel@nongnu.org; Sat, 16 Feb 2008 15:21:12 -0500 Received: from axis.com (edgar.se.axis.com [10.93.151.1]) by miranda.se.axis.com (8.13.4/8.13.4/Debian-3sarge3) with ESMTP id m1GKL8mF017311 for ; Sat, 16 Feb 2008 21:21:08 +0100 Date: Sat, 16 Feb 2008 21:21:08 +0100 From: "Edgar E. Iglesias" Message-ID: <20080216202108.GB7603@edgar.se.axis.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Subject: [Qemu-devel] [PATCH] Small testsuite for mmap. Reply-To: qemu-devel@nongnu.org List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Hello, This patch adds a small test program to help verify mmap behaviour, at the moment it only does some very basic tests. Unfortunately, current qemu fails to pass. I'll send a patch for that in a moment. Best regards, -- Edgar E. Iglesias Axis Communications AB diff --git a/tests/Makefile b/tests/Makefile index 1775be8..6000c73 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -51,6 +51,12 @@ ifeq ($(ARCH),i386) @if diff -u test-i386.ref test-i386.out ; then echo "Auto Test OK (no code copy)"; fi endif +.PHONY: test-mmap +test-mmap: test-mmap.c + $(CC) $(CFLAGS) -Wall -static -O2 $(LDFLAGS) -o $@ $< + $(QEMU) ./test-mmap + $(QEMU) -p 8192 ./test-mmap 8192 + # generic Linux and CPU test linux-test: linux-test.c $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $< -lm diff --git a/tests/test-mmap.c b/tests/test-mmap.c new file mode 100644 index 0000000..3711115 --- /dev/null +++ b/tests/test-mmap.c @@ -0,0 +1,171 @@ +/* + * Small test program to verify simulated mmap behaviour. + * + * When running qemu-linux-user with the -p flag, you may need to tell + * this test program about the pagesize cause getpagesize will not reflect the + * -p choice. Simply pass one argument beeing the pagesize. + */ +#include +#include +#include +#include + +#include + +#define fail_unless(x) \ +do \ +{ \ + if (!(x)) { \ + fprintf (stderr, "FAILED at %s:%d\n", __FILE__, __LINE__); \ + exit (EXIT_FAILURE); \ + } \ +} while (0); + + +static unsigned int pagesize; +static unsigned int pagemask; +int test_fd; + +void check_aligned_anonymous_unfixed_mmaps(void) +{ + void *p1; + void *p2; + void *p3; + uintptr_t p; + int i; + + printf ("%s\n", __func__); + for (i = 0; i < 0xffff; i++) + { + size_t len; + + len = pagesize + (pagesize * i & 7); + p1 = mmap(NULL, len, PROT_READ, + MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); + p2 = mmap(NULL, len, PROT_READ, + MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); + p3 = mmap(NULL, len, PROT_READ, + MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); + + /* Make sure we get pages aligned with the pagesize. The + target expects this. */ + fail_unless (p1 != MAP_FAILED); + fail_unless (p2 != MAP_FAILED); + fail_unless (p3 != MAP_FAILED); + p = (uintptr_t) p1; + fail_unless ((p & pagemask) == 0); + p = (uintptr_t) p2; + fail_unless ((p & pagemask) == 0); + p = (uintptr_t) p3; + fail_unless ((p & pagemask) == 0); + munmap (p1, len); + munmap (p2, len); + munmap (p3, len); + } +} + +void check_aligned_anonymous_fixed_mmaps(void) +{ + char *addr; + void *p1; + uintptr_t p; + int i; + + /* Find a suitable address to start with. */ + addr = mmap(NULL, pagesize * 40, PROT_READ, + MAP_PRIVATE | MAP_ANONYMOUS, + -1, 0); + printf ("%s addr=%p\n", __func__, addr); + fail_unless (addr != MAP_FAILED); + + for (i = 0; i < 40; i++) + { + p1 = mmap(addr, pagesize, PROT_READ, + MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED, + -1, 0); + /* Make sure we get pages aligned with the pagesize. + The target expects this. */ + p = (uintptr_t) p1; + fail_unless (p1 != MAP_FAILED); + fail_unless ((p & pagemask) == 0); + munmap (p1, pagesize); + addr += pagesize; + } +} + +void check_file_unfixed_mmaps(void) +{ + unsigned int *p1, *p2, *p3; + uintptr_t p; + int i; + + printf ("%s\n", __func__); + for (i = 0; i < 0x10; i++) + { + size_t len; + + len = pagesize; + p1 = mmap(NULL, len, PROT_READ, + MAP_PRIVATE, + test_fd, 0); + p2 = mmap(NULL, len, PROT_READ, + MAP_PRIVATE, + test_fd, pagesize); + p3 = mmap(NULL, len, PROT_READ, + MAP_PRIVATE, + test_fd, pagesize * 2); + + fail_unless (p1 != MAP_FAILED); + fail_unless (p2 != MAP_FAILED); + fail_unless (p3 != MAP_FAILED); + + /* Make sure we get pages aligned with the pagesize. The + target expects this. */ + p = (uintptr_t) p1; + fail_unless ((p & pagemask) == 0); + p = (uintptr_t) p2; + fail_unless ((p & pagemask) == 0); + p = (uintptr_t) p3; + fail_unless ((p & pagemask) == 0); + + /* Verify that the file maps was made correctly. */ + fail_unless (*p1 == 0); + fail_unless (*p2 == (pagesize / sizeof *p2)); + fail_unless (*p3 == ((pagesize * 2) / sizeof *p3)); + + munmap (p1, len); + munmap (p2, len); + munmap (p3, len); + } +} + +int main(int argc, char **argv) +{ + char tempname[] = "/tmp/.cmmapXXXXXX"; + unsigned int i; + + /* Trust the first argument, otherwise probe the system for our + pagesize. */ + if (argc > 1) + pagesize = strtoul(argv[1], NULL, 0); + else + pagesize = sysconf(_SC_PAGESIZE); + + /* Assume pagesize is a power of two. */ + pagemask = pagesize - 1; + printf ("pagesize=%u pagemask=%x\n", pagesize, pagemask); + + test_fd = mkstemp(tempname); + unlink(tempname); + + /* Fill the file with int's counting from zero and up. */ + for (i = 0; i < (pagesize * 4) / sizeof i; i++) + write (test_fd, &i, sizeof i); + + /* Run the tests. */ + check_aligned_anonymous_unfixed_mmaps(); + check_aligned_anonymous_fixed_mmaps(); + check_file_unfixed_mmaps(); + + return EXIT_SUCCESS; +}