xref: /openbsd-src/regress/sys/uvm/mmap_hint/mmap_hint.c (revision 49a6e16f2c2c8e509184b1f777366d1a6f337e1c)
1*49a6e16fSderaadt /*	$OpenBSD: mmap_hint.c,v 1.6 2021/12/13 16:56:50 deraadt Exp $	*/
2faca773dSariane /*
3faca773dSariane  * Copyright (c) 2011 Ariane van der Steldt <ariane@stack.nl>
4faca773dSariane  *
5faca773dSariane  * Permission to use, copy, modify, and distribute this software for any
6faca773dSariane  * purpose with or without fee is hereby granted, provided that the above
7faca773dSariane  * copyright notice and this permission notice appear in all copies.
8faca773dSariane  *
9faca773dSariane  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10faca773dSariane  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11faca773dSariane  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12faca773dSariane  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13faca773dSariane  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14faca773dSariane  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15faca773dSariane  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16faca773dSariane  */
17faca773dSariane 
18*49a6e16fSderaadt #include <sys/param.h>	/* PAGE_SIZE PAGE_MASK */
19faca773dSariane #include <sys/types.h>
20faca773dSariane #include <sys/mman.h>
21c4613df5Sbluhm #include <sys/tree.h>
22c4613df5Sbluhm #include <machine/pmap.h>
23faca773dSariane #include <machine/vmparam.h>
24faca773dSariane #include <err.h>
25faca773dSariane #include <sysexits.h>
26faca773dSariane #include <stdio.h>
27faca773dSariane 
28faca773dSariane #define MAX_HINT_DIST	(2UL * 1024 * 1024 * 1024)
29faca773dSariane 
30faca773dSariane int	errors = 0;
31faca773dSariane 
32faca773dSariane void *
mmap_hint(void * hint)33faca773dSariane mmap_hint(void *hint)
34faca773dSariane {
35faca773dSariane 	void	*p;
369e720447Sbluhm 	size_t	 delta;
37faca773dSariane 
38faca773dSariane 	p = mmap(hint, 1, PROT_READ|PROT_WRITE, MAP_ANON|MAP_PRIVATE, -1, 0);
39faca773dSariane 	if (p == MAP_FAILED) {
40faca773dSariane 		warn("mmap(addr=%p, len=1) failed", hint);
41faca773dSariane 		errors++;
42faca773dSariane 		return MAP_FAILED;
43faca773dSariane 	} else if (p == NULL) {
44faca773dSariane 		warnx("mmap(addr=%p, len=1) mapped at address 0", hint);
45faca773dSariane 		errors++;
46faca773dSariane 		return MAP_FAILED;
47faca773dSariane 	} else
48faca773dSariane 		fprintf(stderr, "    -> %p\n", p);
49faca773dSariane 
50faca773dSariane 	if (hint > p)
519e720447Sbluhm 		delta = hint - p;
52faca773dSariane 	else
539e720447Sbluhm 		delta = p - hint;
54faca773dSariane 
559e720447Sbluhm 	if (hint != NULL && delta > MAX_HINT_DIST) {
569e720447Sbluhm 		warnx("hinted allocation more than %#zx bytes away from hint: "
579e720447Sbluhm 		    "hint %p, result %p", delta, hint, p);
58faca773dSariane 		errors++;
59faca773dSariane 		return MAP_FAILED;
60faca773dSariane 	}
61faca773dSariane 	return p;
62faca773dSariane }
63faca773dSariane 
64faca773dSariane int
main()65faca773dSariane main()
66faca773dSariane {
679e720447Sbluhm 	void	*p, *hint;
68faca773dSariane 
69faca773dSariane 	/* Check that unhinted allocation works properly. */
709e720447Sbluhm 	hint = NULL;
719e720447Sbluhm 	fprintf(stderr, "1: Checking hint %p mmap\n", hint);
729e720447Sbluhm 	p = mmap_hint(hint);
73faca773dSariane 
74faca773dSariane 	/* Check hinted allocation at top of map. */
759e720447Sbluhm 	hint = (void *)((VM_MAXUSER_ADDRESS & ~PAGE_MASK) - PAGE_SIZE);
769e720447Sbluhm 	fprintf(stderr, "2: Checking hint page below "
779e720447Sbluhm 	    "VM_MAXUSER_ADDRESS %p mmap\n", hint);
789e720447Sbluhm 	p = mmap_hint(hint);
79faca773dSariane 
80faca773dSariane 	/* Check hinted allocation at bottom of map. */
819e720447Sbluhm 	hint = (void *)VM_MIN_ADDRESS;
829e720447Sbluhm 	fprintf(stderr, "3: Checking hint VM_MIN_ADDRESS %p mmap\n", hint);
839e720447Sbluhm 	p = mmap_hint(hint);
84faca773dSariane 
85faca773dSariane 	/*
86faca773dSariane 	 * Check that hinted allocation doesn't overwrite existing allocation.
87faca773dSariane 	 */
88faca773dSariane 	if (p == MAP_FAILED) {
89faca773dSariane 		fprintf(stderr, "4: Skipping test: required previous test "
90faca773dSariane 		    "to succeed");
91faca773dSariane 		goto skip4;
92faca773dSariane 	}
939e720447Sbluhm 	hint = p;
949e720447Sbluhm 	fprintf(stderr, "4: Checking hint %p mmap, which is in use\n", hint);
959e720447Sbluhm 	p = mmap_hint(hint);
969e720447Sbluhm 	if (p == hint) {
979e720447Sbluhm 		warnx("hinted allocation %p overwrites previous allocation %p",
989e720447Sbluhm 		    hint, p);
99faca773dSariane 		errors++;
100faca773dSariane 	}
101faca773dSariane 
1029e720447Sbluhm skip4:
103faca773dSariane 	return errors;
104faca773dSariane }
105