xref: /aosp_15_r20/external/strace/tests-m32/ioctl_uffdio.c (revision cf84ac9a129d8ea9952db616b4e9b904c4bdde56)
1*cf84ac9aSAndroid Build Coastguard Worker /*
2*cf84ac9aSAndroid Build Coastguard Worker  * Copyright (c) 2015-2016 Dmitry V. Levin <[email protected]>
3*cf84ac9aSAndroid Build Coastguard Worker  * Copyright (c)      2016 Red Hat, Inc.
4*cf84ac9aSAndroid Build Coastguard Worker  * Copyright (c) 2016-2017 The strace developers.
5*cf84ac9aSAndroid Build Coastguard Worker  * All rights reserved.
6*cf84ac9aSAndroid Build Coastguard Worker  *
7*cf84ac9aSAndroid Build Coastguard Worker  * Redistribution and use in source and binary forms, with or without
8*cf84ac9aSAndroid Build Coastguard Worker  * modification, are permitted provided that the following conditions
9*cf84ac9aSAndroid Build Coastguard Worker  * are met:
10*cf84ac9aSAndroid Build Coastguard Worker  * 1. Redistributions of source code must retain the above copyright
11*cf84ac9aSAndroid Build Coastguard Worker  *    notice, this list of conditions and the following disclaimer.
12*cf84ac9aSAndroid Build Coastguard Worker  * 2. Redistributions in binary form must reproduce the above copyright
13*cf84ac9aSAndroid Build Coastguard Worker  *    notice, this list of conditions and the following disclaimer in the
14*cf84ac9aSAndroid Build Coastguard Worker  *    documentation and/or other materials provided with the distribution.
15*cf84ac9aSAndroid Build Coastguard Worker  * 3. The name of the author may not be used to endorse or promote products
16*cf84ac9aSAndroid Build Coastguard Worker  *    derived from this software without specific prior written permission.
17*cf84ac9aSAndroid Build Coastguard Worker  *
18*cf84ac9aSAndroid Build Coastguard Worker  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19*cf84ac9aSAndroid Build Coastguard Worker  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20*cf84ac9aSAndroid Build Coastguard Worker  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21*cf84ac9aSAndroid Build Coastguard Worker  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22*cf84ac9aSAndroid Build Coastguard Worker  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23*cf84ac9aSAndroid Build Coastguard Worker  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24*cf84ac9aSAndroid Build Coastguard Worker  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25*cf84ac9aSAndroid Build Coastguard Worker  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26*cf84ac9aSAndroid Build Coastguard Worker  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27*cf84ac9aSAndroid Build Coastguard Worker  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28*cf84ac9aSAndroid Build Coastguard Worker  */
29*cf84ac9aSAndroid Build Coastguard Worker 
30*cf84ac9aSAndroid Build Coastguard Worker #include "tests.h"
31*cf84ac9aSAndroid Build Coastguard Worker #include <asm/unistd.h>
32*cf84ac9aSAndroid Build Coastguard Worker 
33*cf84ac9aSAndroid Build Coastguard Worker #if defined __NR_userfaultfd && defined HAVE_LINUX_USERFAULTFD_H
34*cf84ac9aSAndroid Build Coastguard Worker 
35*cf84ac9aSAndroid Build Coastguard Worker # include <fcntl.h>
36*cf84ac9aSAndroid Build Coastguard Worker # include <inttypes.h>
37*cf84ac9aSAndroid Build Coastguard Worker # include <stdint.h>
38*cf84ac9aSAndroid Build Coastguard Worker # include <stdio.h>
39*cf84ac9aSAndroid Build Coastguard Worker # include <string.h>
40*cf84ac9aSAndroid Build Coastguard Worker # include <unistd.h>
41*cf84ac9aSAndroid Build Coastguard Worker 
42*cf84ac9aSAndroid Build Coastguard Worker # include <sys/ioctl.h>
43*cf84ac9aSAndroid Build Coastguard Worker # include <sys/mman.h>
44*cf84ac9aSAndroid Build Coastguard Worker # include <linux/ioctl.h>
45*cf84ac9aSAndroid Build Coastguard Worker # include <linux/userfaultfd.h>
46*cf84ac9aSAndroid Build Coastguard Worker 
47*cf84ac9aSAndroid Build Coastguard Worker #include "xlat.h"
48*cf84ac9aSAndroid Build Coastguard Worker #include "xlat/uffd_api_features.h"
49*cf84ac9aSAndroid Build Coastguard Worker 
50*cf84ac9aSAndroid Build Coastguard Worker int
main(void)51*cf84ac9aSAndroid Build Coastguard Worker main(void)
52*cf84ac9aSAndroid Build Coastguard Worker {
53*cf84ac9aSAndroid Build Coastguard Worker 	int rc;
54*cf84ac9aSAndroid Build Coastguard Worker 	int fd = syscall(__NR_userfaultfd, O_NONBLOCK);
55*cf84ac9aSAndroid Build Coastguard Worker 	size_t pagesize = getpagesize();
56*cf84ac9aSAndroid Build Coastguard Worker 
57*cf84ac9aSAndroid Build Coastguard Worker 	if (fd < 0)
58*cf84ac9aSAndroid Build Coastguard Worker 		perror_msg_and_skip("userfaultfd");
59*cf84ac9aSAndroid Build Coastguard Worker 
60*cf84ac9aSAndroid Build Coastguard Worker 	/* ---- API ---- */
61*cf84ac9aSAndroid Build Coastguard Worker 	TAIL_ALLOC_OBJECT_CONST_PTR(struct uffdio_api, api_struct);
62*cf84ac9aSAndroid Build Coastguard Worker 
63*cf84ac9aSAndroid Build Coastguard Worker 	/* With a bad fd */
64*cf84ac9aSAndroid Build Coastguard Worker 	memset(api_struct, 0, sizeof(*api_struct));
65*cf84ac9aSAndroid Build Coastguard Worker 	rc = ioctl(-1, UFFDIO_API, api_struct);
66*cf84ac9aSAndroid Build Coastguard Worker 	printf("ioctl(-1, UFFDIO_API, {api=0, features=0}) = %d %s (%m)\n",
67*cf84ac9aSAndroid Build Coastguard Worker 	       rc, errno2name());
68*cf84ac9aSAndroid Build Coastguard Worker 	/* With a bad pointer */
69*cf84ac9aSAndroid Build Coastguard Worker 	rc = ioctl(fd, UFFDIO_API, NULL);
70*cf84ac9aSAndroid Build Coastguard Worker 	printf("ioctl(%d, UFFDIO_API, NULL) = %d %s (%m)\n",
71*cf84ac9aSAndroid Build Coastguard Worker 		fd, rc, errno2name());
72*cf84ac9aSAndroid Build Coastguard Worker 	/* Normal call */
73*cf84ac9aSAndroid Build Coastguard Worker 	api_struct->api = UFFD_API;
74*cf84ac9aSAndroid Build Coastguard Worker 	api_struct->features = 0;
75*cf84ac9aSAndroid Build Coastguard Worker 	rc = ioctl(fd, UFFDIO_API, api_struct);
76*cf84ac9aSAndroid Build Coastguard Worker 	printf("ioctl(%d, UFFDIO_API, {api=0xaa, features=0", fd);
77*cf84ac9aSAndroid Build Coastguard Worker 	if (api_struct->features) {
78*cf84ac9aSAndroid Build Coastguard Worker 		printf(" => features=");
79*cf84ac9aSAndroid Build Coastguard Worker 		printflags(uffd_api_features, api_struct->features,
80*cf84ac9aSAndroid Build Coastguard Worker 			   "UFFD_FEATURE_???");
81*cf84ac9aSAndroid Build Coastguard Worker 	}
82*cf84ac9aSAndroid Build Coastguard Worker 	printf(", ioctls=1<<_UFFDIO_REGISTER|"
83*cf84ac9aSAndroid Build Coastguard Worker 	       "1<<_UFFDIO_UNREGISTER|1<<_UFFDIO_API");
84*cf84ac9aSAndroid Build Coastguard Worker 	api_struct->ioctls &= ~(1ull<<_UFFDIO_REGISTER|
85*cf84ac9aSAndroid Build Coastguard Worker 				1ull<<_UFFDIO_UNREGISTER|
86*cf84ac9aSAndroid Build Coastguard Worker 				1ull<<_UFFDIO_API);
87*cf84ac9aSAndroid Build Coastguard Worker 	if (api_struct->ioctls)
88*cf84ac9aSAndroid Build Coastguard Worker 		printf("|%#" PRIx64, (uint64_t)api_struct->ioctls);
89*cf84ac9aSAndroid Build Coastguard Worker 	printf("}) = %d\n", rc);
90*cf84ac9aSAndroid Build Coastguard Worker 
91*cf84ac9aSAndroid Build Coastguard Worker 	/* For the rest of the tests we need some anonymous memory */
92*cf84ac9aSAndroid Build Coastguard Worker 	void *area1 = mmap(NULL, pagesize, PROT_READ|PROT_WRITE,
93*cf84ac9aSAndroid Build Coastguard Worker 			   MAP_PRIVATE|MAP_ANONYMOUS,
94*cf84ac9aSAndroid Build Coastguard Worker 			   -1, 0);
95*cf84ac9aSAndroid Build Coastguard Worker 	if (area1 == MAP_FAILED)
96*cf84ac9aSAndroid Build Coastguard Worker 		perror_msg_and_fail("mmap area1");
97*cf84ac9aSAndroid Build Coastguard Worker 	void *area2 = mmap(NULL, pagesize, PROT_READ|PROT_WRITE,
98*cf84ac9aSAndroid Build Coastguard Worker 			   MAP_PRIVATE|MAP_ANONYMOUS,
99*cf84ac9aSAndroid Build Coastguard Worker 			   -1, 0);
100*cf84ac9aSAndroid Build Coastguard Worker 	if (area2 == MAP_FAILED)
101*cf84ac9aSAndroid Build Coastguard Worker 		perror_msg_and_fail("mmap area2");
102*cf84ac9aSAndroid Build Coastguard Worker 	madvise(area2, pagesize, MADV_DONTNEED);
103*cf84ac9aSAndroid Build Coastguard Worker 	*(char *)area1 = 42;
104*cf84ac9aSAndroid Build Coastguard Worker 
105*cf84ac9aSAndroid Build Coastguard Worker 	/* ---- REGISTER ---- */
106*cf84ac9aSAndroid Build Coastguard Worker 	struct uffdio_register *register_struct =
107*cf84ac9aSAndroid Build Coastguard Worker 					 tail_alloc(sizeof(*register_struct));
108*cf84ac9aSAndroid Build Coastguard Worker 	memset(register_struct, 0, sizeof(*register_struct));
109*cf84ac9aSAndroid Build Coastguard Worker 
110*cf84ac9aSAndroid Build Coastguard Worker 	rc = ioctl(-1, UFFDIO_REGISTER, register_struct);
111*cf84ac9aSAndroid Build Coastguard Worker 	printf("ioctl(-1, UFFDIO_REGISTER, {range={start=0, len=0}, "
112*cf84ac9aSAndroid Build Coastguard Worker 	       "mode=0}) = %d %s (%m)\n", rc, errno2name());
113*cf84ac9aSAndroid Build Coastguard Worker 
114*cf84ac9aSAndroid Build Coastguard Worker 	rc = ioctl(fd, UFFDIO_REGISTER, NULL);
115*cf84ac9aSAndroid Build Coastguard Worker 	printf("ioctl(%d, UFFDIO_REGISTER, NULL) = %d %s (%m)\n",
116*cf84ac9aSAndroid Build Coastguard Worker 	       fd, rc, errno2name());
117*cf84ac9aSAndroid Build Coastguard Worker 
118*cf84ac9aSAndroid Build Coastguard Worker 	register_struct->range.start = (uint64_t)(uintptr_t)area2;
119*cf84ac9aSAndroid Build Coastguard Worker 	register_struct->range.len = pagesize;
120*cf84ac9aSAndroid Build Coastguard Worker 	register_struct->mode = UFFDIO_REGISTER_MODE_MISSING;
121*cf84ac9aSAndroid Build Coastguard Worker 	rc = ioctl(fd, UFFDIO_REGISTER, register_struct);
122*cf84ac9aSAndroid Build Coastguard Worker 	printf("ioctl(%d, UFFDIO_REGISTER, {range={start=%p, len=%#zx}, "
123*cf84ac9aSAndroid Build Coastguard Worker 	       "mode=UFFDIO_REGISTER_MODE_MISSING, ioctls="
124*cf84ac9aSAndroid Build Coastguard Worker 	       "1<<_UFFDIO_WAKE|1<<_UFFDIO_COPY|1<<_UFFDIO_ZEROPAGE",
125*cf84ac9aSAndroid Build Coastguard Worker 	       fd, area2, pagesize);
126*cf84ac9aSAndroid Build Coastguard Worker 	register_struct->ioctls &= ~(1ull<<_UFFDIO_WAKE|
127*cf84ac9aSAndroid Build Coastguard Worker 				    1ull<<_UFFDIO_COPY|
128*cf84ac9aSAndroid Build Coastguard Worker 				    1ull<<_UFFDIO_ZEROPAGE);
129*cf84ac9aSAndroid Build Coastguard Worker 	if (register_struct->ioctls)
130*cf84ac9aSAndroid Build Coastguard Worker 		printf("|%#" PRIx64, (uint64_t)register_struct->ioctls);
131*cf84ac9aSAndroid Build Coastguard Worker 	printf("}) = %d\n", rc);
132*cf84ac9aSAndroid Build Coastguard Worker 
133*cf84ac9aSAndroid Build Coastguard Worker 	/* With area2 registered we can now do the atomic copies onto it
134*cf84ac9aSAndroid Build Coastguard Worker 	 * but be careful not to access it in any other way otherwise
135*cf84ac9aSAndroid Build Coastguard Worker 	 * userfaultfd will cause us to stall.
136*cf84ac9aSAndroid Build Coastguard Worker 	 */
137*cf84ac9aSAndroid Build Coastguard Worker 	/* ---- COPY ---- */
138*cf84ac9aSAndroid Build Coastguard Worker 	TAIL_ALLOC_OBJECT_CONST_PTR(struct uffdio_copy, copy_struct);
139*cf84ac9aSAndroid Build Coastguard Worker 
140*cf84ac9aSAndroid Build Coastguard Worker 	memset(copy_struct, 0, sizeof(*copy_struct));
141*cf84ac9aSAndroid Build Coastguard Worker 	rc = ioctl(-1, UFFDIO_COPY, copy_struct);
142*cf84ac9aSAndroid Build Coastguard Worker 	printf("ioctl(-1, UFFDIO_COPY, {dst=0, src=0, len=0, mode=0"
143*cf84ac9aSAndroid Build Coastguard Worker 	       "}) = %d %s (%m)\n", rc, errno2name());
144*cf84ac9aSAndroid Build Coastguard Worker 
145*cf84ac9aSAndroid Build Coastguard Worker 	rc = ioctl(fd, UFFDIO_COPY, NULL);
146*cf84ac9aSAndroid Build Coastguard Worker 	printf("ioctl(%d, UFFDIO_COPY, NULL) = %d %s (%m)\n",
147*cf84ac9aSAndroid Build Coastguard Worker 	       fd, rc, errno2name());
148*cf84ac9aSAndroid Build Coastguard Worker 
149*cf84ac9aSAndroid Build Coastguard Worker 	copy_struct->dst = (uint64_t)(uintptr_t)area2;
150*cf84ac9aSAndroid Build Coastguard Worker 	copy_struct->src = (uint64_t)(uintptr_t)area1;
151*cf84ac9aSAndroid Build Coastguard Worker 	copy_struct->len = pagesize;
152*cf84ac9aSAndroid Build Coastguard Worker 	copy_struct->mode = UFFDIO_COPY_MODE_DONTWAKE;
153*cf84ac9aSAndroid Build Coastguard Worker 	rc = ioctl(fd, UFFDIO_COPY, copy_struct);
154*cf84ac9aSAndroid Build Coastguard Worker 	printf("ioctl(%d, UFFDIO_COPY, {dst=%p, src=%p, len=%#zx,"
155*cf84ac9aSAndroid Build Coastguard Worker 	       " mode=UFFDIO_COPY_MODE_DONTWAKE, copy=%#zx}) = %d\n",
156*cf84ac9aSAndroid Build Coastguard Worker 	       fd, area2, area1, pagesize, pagesize, rc);
157*cf84ac9aSAndroid Build Coastguard Worker 
158*cf84ac9aSAndroid Build Coastguard Worker 	/* ---- ZEROPAGE ---- */
159*cf84ac9aSAndroid Build Coastguard Worker 	TAIL_ALLOC_OBJECT_CONST_PTR(struct uffdio_zeropage, zero_struct);
160*cf84ac9aSAndroid Build Coastguard Worker 	madvise(area2, pagesize, MADV_DONTNEED);
161*cf84ac9aSAndroid Build Coastguard Worker 
162*cf84ac9aSAndroid Build Coastguard Worker 	memset(zero_struct, 0, sizeof(*zero_struct));
163*cf84ac9aSAndroid Build Coastguard Worker 	rc = ioctl(-1, UFFDIO_ZEROPAGE, zero_struct);
164*cf84ac9aSAndroid Build Coastguard Worker 	printf("ioctl(-1, UFFDIO_ZEROPAGE, {range={start=0, len=0}, mode=0"
165*cf84ac9aSAndroid Build Coastguard Worker 	       "}) = %d %s (%m)\n", rc, errno2name());
166*cf84ac9aSAndroid Build Coastguard Worker 
167*cf84ac9aSAndroid Build Coastguard Worker 	rc = ioctl(fd, UFFDIO_ZEROPAGE, NULL);
168*cf84ac9aSAndroid Build Coastguard Worker 	printf("ioctl(%d, UFFDIO_ZEROPAGE, NULL) = %d %s (%m)\n",
169*cf84ac9aSAndroid Build Coastguard Worker 	       fd, rc, errno2name());
170*cf84ac9aSAndroid Build Coastguard Worker 
171*cf84ac9aSAndroid Build Coastguard Worker 	zero_struct->range.start = (uint64_t)(uintptr_t)area2;
172*cf84ac9aSAndroid Build Coastguard Worker 	zero_struct->range.len = pagesize;
173*cf84ac9aSAndroid Build Coastguard Worker 	zero_struct->mode = UFFDIO_ZEROPAGE_MODE_DONTWAKE;
174*cf84ac9aSAndroid Build Coastguard Worker 	rc = ioctl(fd, UFFDIO_ZEROPAGE, zero_struct);
175*cf84ac9aSAndroid Build Coastguard Worker 	printf("ioctl(%d, UFFDIO_ZEROPAGE, {range={start=%p, len=%#zx},"
176*cf84ac9aSAndroid Build Coastguard Worker 	       " mode=UFFDIO_ZEROPAGE_MODE_DONTWAKE, zeropage=%#zx}) = %d\n",
177*cf84ac9aSAndroid Build Coastguard Worker 	       fd, area2, pagesize, pagesize, rc);
178*cf84ac9aSAndroid Build Coastguard Worker 
179*cf84ac9aSAndroid Build Coastguard Worker 	/* ---- WAKE ---- */
180*cf84ac9aSAndroid Build Coastguard Worker 	TAIL_ALLOC_OBJECT_CONST_PTR(struct uffdio_range, range_struct);
181*cf84ac9aSAndroid Build Coastguard Worker 	memset(range_struct, 0, sizeof(*range_struct));
182*cf84ac9aSAndroid Build Coastguard Worker 
183*cf84ac9aSAndroid Build Coastguard Worker 	rc = ioctl(-1, UFFDIO_WAKE, range_struct);
184*cf84ac9aSAndroid Build Coastguard Worker 	printf("ioctl(-1, UFFDIO_WAKE, {start=0, len=0}) = %d %s (%m)\n",
185*cf84ac9aSAndroid Build Coastguard Worker 	       rc, errno2name());
186*cf84ac9aSAndroid Build Coastguard Worker 
187*cf84ac9aSAndroid Build Coastguard Worker 	rc = ioctl(fd, UFFDIO_WAKE, NULL);
188*cf84ac9aSAndroid Build Coastguard Worker 	printf("ioctl(%d, UFFDIO_WAKE, NULL) = %d %s (%m)\n",
189*cf84ac9aSAndroid Build Coastguard Worker 	       fd, rc, errno2name());
190*cf84ac9aSAndroid Build Coastguard Worker 
191*cf84ac9aSAndroid Build Coastguard Worker 	range_struct->start = (uint64_t)(uintptr_t)area2;
192*cf84ac9aSAndroid Build Coastguard Worker 	range_struct->len = pagesize;
193*cf84ac9aSAndroid Build Coastguard Worker 	rc = ioctl(fd, UFFDIO_WAKE, range_struct);
194*cf84ac9aSAndroid Build Coastguard Worker 	printf("ioctl(%d, UFFDIO_WAKE, {start=%p, len=%#zx}) = %d\n",
195*cf84ac9aSAndroid Build Coastguard Worker 	       fd, area2, pagesize, rc);
196*cf84ac9aSAndroid Build Coastguard Worker 
197*cf84ac9aSAndroid Build Coastguard Worker 	/* ---- UNREGISTER ---- */
198*cf84ac9aSAndroid Build Coastguard Worker 	memset(range_struct, 0, sizeof(*range_struct));
199*cf84ac9aSAndroid Build Coastguard Worker 
200*cf84ac9aSAndroid Build Coastguard Worker 	rc = ioctl(-1, UFFDIO_UNREGISTER, range_struct);
201*cf84ac9aSAndroid Build Coastguard Worker 	printf("ioctl(-1, UFFDIO_UNREGISTER, {start=0, len=0}) = %d %s (%m)\n",
202*cf84ac9aSAndroid Build Coastguard Worker 	       rc, errno2name());
203*cf84ac9aSAndroid Build Coastguard Worker 
204*cf84ac9aSAndroid Build Coastguard Worker 	rc = ioctl(fd, UFFDIO_UNREGISTER, NULL);
205*cf84ac9aSAndroid Build Coastguard Worker 	printf("ioctl(%d, UFFDIO_UNREGISTER, NULL) = %d %s (%m)\n",
206*cf84ac9aSAndroid Build Coastguard Worker 	       fd, rc, errno2name());
207*cf84ac9aSAndroid Build Coastguard Worker 
208*cf84ac9aSAndroid Build Coastguard Worker 	range_struct->start = (uint64_t)(uintptr_t)area2;
209*cf84ac9aSAndroid Build Coastguard Worker 	range_struct->len = pagesize;
210*cf84ac9aSAndroid Build Coastguard Worker 	rc = ioctl(fd, UFFDIO_UNREGISTER, range_struct);
211*cf84ac9aSAndroid Build Coastguard Worker 	printf("ioctl(%d, UFFDIO_UNREGISTER, {start=%p, len=%#zx}) = %d\n",
212*cf84ac9aSAndroid Build Coastguard Worker 	       fd, area2, pagesize, rc);
213*cf84ac9aSAndroid Build Coastguard Worker 	puts("+++ exited with 0 +++");
214*cf84ac9aSAndroid Build Coastguard Worker 	return 0;
215*cf84ac9aSAndroid Build Coastguard Worker }
216*cf84ac9aSAndroid Build Coastguard Worker 
217*cf84ac9aSAndroid Build Coastguard Worker #else
218*cf84ac9aSAndroid Build Coastguard Worker 
219*cf84ac9aSAndroid Build Coastguard Worker SKIP_MAIN_UNDEFINED("__NR_userfaultfd && HAVE_LINUX_USERFAULTFD_H")
220*cf84ac9aSAndroid Build Coastguard Worker 
221*cf84ac9aSAndroid Build Coastguard Worker #endif
222