xref: /openbsd-src/regress/sys/uvm/mmap_hint/mmap_hint.c (revision 91f110e064cd7c194e59e019b83bb7496c1c84d4)
1 /*	$OpenBSD: mmap_hint.c,v 1.2 2013/03/21 21:59:55 deraadt Exp $	*/
2 /*
3  * Copyright (c) 2011 Ariane van der Steldt <ariane@stack.nl>
4  *
5  * Permission to use, copy, modify, and distribute this software for any
6  * purpose with or without fee is hereby granted, provided that the above
7  * copyright notice and this permission notice appear in all copies.
8  *
9  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16  */
17 
18 #include <sys/param.h>
19 #include <sys/types.h>
20 #include <sys/mman.h>
21 #include <machine/vmparam.h>
22 #include <err.h>
23 #include <sysexits.h>
24 #include <stdio.h>
25 
26 #define MAX_HINT_DIST	(2UL * 1024 * 1024 * 1024)
27 
28 int	errors = 0;
29 
30 void *
31 mmap_hint(void *hint)
32 {
33 	void	*p;
34 	size_t	 pd;
35 
36 	p = mmap(hint, 1, PROT_READ|PROT_WRITE, MAP_ANON|MAP_PRIVATE, -1, 0);
37 	if (p == MAP_FAILED) {
38 		warn("mmap(addr=%p, len=1) failed", hint);
39 		errors++;
40 		return MAP_FAILED;
41 	} else if (p == NULL) {
42 		warnx("mmap(addr=%p, len=1) mapped at address 0", hint);
43 		errors++;
44 		return MAP_FAILED;
45 	} else
46 		fprintf(stderr, "    -> %p\n", p);
47 
48 	if (hint > p)
49 		pd = hint - p;
50 	else
51 		pd = p - hint;
52 
53 	if (hint != NULL && pd > MAX_HINT_DIST) {
54 		warnx("hinted allocation more than 0x%lx "
55 		    "bytes away from hint: "
56 		    "hint %p, result %p", pd, hint, p);
57 		errors++;
58 		return MAP_FAILED;
59 	}
60 	return p;
61 }
62 
63 int
64 main()
65 {
66 	void	*p, *p_prev;
67 
68 	/* Check that unhinted allocation works properly. */
69 	fprintf(stderr, "1: Checking hint NULL mmap\n");
70 	p = mmap_hint(NULL);
71 
72 	/* Check hinted allocation at top of map. */
73 	fprintf(stderr, "2: Checking hint VM_MAXUSER_ADDRESS 0x%lx mmap\n",
74 	    (unsigned long)VM_MAXUSER_ADDRESS);
75 	p = mmap_hint((void*)VM_MAXUSER_ADDRESS);
76 
77 	/* Check hinted allocation at bottom of map. */
78 	fprintf(stderr, "3: Checking hint VM_MIN_ADDRESS 0x%lx mmap\n",
79 	    (unsigned long)VM_MIN_ADDRESS);
80 	p = mmap_hint((void*)VM_MIN_ADDRESS);
81 
82 	/*
83 	 * Check that hinted allocation doesn't overwrite existing allocation.
84 	 */
85 	if (p == MAP_FAILED) {
86 		fprintf(stderr, "4: Skipping test: required previous test "
87 		    "to succeed");
88 		goto skip4;
89 	}
90 	p_prev = p;
91 	fprintf(stderr, "4: Checking hint 0x%lx mmap, which is in use\n",
92 	    p_prev);
93 	p = mmap_hint(p_prev);
94 	if (p == p_prev) {
95 		warnx("hinted allocation %p "
96 		    "overwrites previous allocation", p_prev);
97 		errors++;
98 	}
99 skip4:
100 
101 	return errors;
102 }
103