2 * Check decoding of move_pages syscall.
4 * Copyright (c) 2016 Dmitry V. Levin <ldv@altlinux.org>
5 * Copyright (c) 2016-2017 The strace developers.
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. The name of the author may not be used to endorse or promote products
17 * derived from this software without specific prior written permission.
19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
20 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
21 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
22 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
23 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
24 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
28 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 #include <asm/unistd.h>
34 #ifdef __NR_move_pages
43 print_page_array(const void **const pages,
44 const unsigned long count,
45 const unsigned int offset)
48 printf("%s", pages ? "[]" : "NULL");
51 if (count <= offset) {
57 for (i = 0; i < count; ++i) {
60 if (i + offset < count) {
61 if (i >= MAX_STRLEN) {
66 printf("... /* %p */", pages + i);
69 const void *const addr = pages[i];
79 print_node_array(const int *const nodes,
80 const unsigned long count,
81 const unsigned int offset)
84 printf("%s", nodes ? "[]" : "NULL");
87 if (count <= offset) {
93 for (i = 0; i < count; ++i) {
96 if (i + offset < count) {
97 if (i >= MAX_STRLEN) {
102 printf("... /* %p */", nodes + i);
105 printf("%d", nodes[i]);
111 print_status_array(const int *const status, const unsigned long count)
114 printf("%s", status ? "[]" : "NULL");
119 for (i = 0; i < count; ++i) {
122 if (i >= MAX_STRLEN) {
126 if (status[i] >= 0) {
127 printf("%d", status[i]);
130 printf("-%s", errno2name());
137 print_stat_pages(const unsigned long pid, const unsigned long count,
138 const void **const pages, int *const status)
140 const unsigned long flags = (unsigned long) 0xfacefeed00000002ULL;
142 long rc = syscall(__NR_move_pages,
143 pid, count, pages, NULL, status, flags);
144 const char *errstr = sprintrc(rc);
145 printf("move_pages(%d, %lu, ", (int) pid, count);
146 print_page_array(pages, count, 0);
150 printf("%p", status);
154 print_status_array(status, count);
156 printf(", MPOL_MF_MOVE) = %s\n", errstr);
160 print_move_pages(const unsigned long pid,
162 const unsigned int offset,
163 const void **const pages,
167 const unsigned long flags = (unsigned long) 0xfacefeed00000004ULL;
170 long rc = syscall(__NR_move_pages,
171 pid, count, pages, nodes, status, flags);
172 const char *errstr = sprintrc(rc);
173 printf("move_pages(%d, %lu, ", (int) pid, count);
174 print_page_array(pages, count, offset);
176 print_node_array(nodes, count, offset);
179 printf("%p", status);
182 printf(", MPOL_MF_MOVE_ALL) = %s\n", errstr);
188 const unsigned long pid =
189 (unsigned long) 0xfacefeed00000000ULL | getpid();
190 unsigned long count = 1;
191 const unsigned page_size = get_page_size();
192 const void *const page = tail_alloc(page_size);
193 const void *const efault = page + page_size;
194 TAIL_ALLOC_OBJECT_VAR_PTR(const void *, pages);
195 TAIL_ALLOC_OBJECT_VAR_PTR(int, nodes);
196 TAIL_ALLOC_OBJECT_VAR_PTR(int, status);
198 print_stat_pages(pid, 0, pages, status);
199 print_move_pages(pid, 0, 0, pages, nodes, status);
200 print_move_pages(pid, 0, 1, pages + 1, nodes + 1, status + 1);
203 print_stat_pages(pid, count, pages, status);
205 print_move_pages(pid, count, 0, pages, nodes, status);
206 print_move_pages(pid, count, 1, pages, nodes, status);
211 print_stat_pages(pid, count, pages, status);
212 *(--nodes) = 0xdeadbee2;
213 print_move_pages(pid, count, 0, pages, nodes, status);
214 print_move_pages(pid, count, 1, pages, nodes, status);
219 print_stat_pages(pid, count, pages, status);
220 *(--nodes) = 0xdeadbee3;
221 print_move_pages(pid, count, 0, pages, nodes, status);
222 print_move_pages(pid, count, 1, pages, nodes, status);
227 print_stat_pages(pid, count, pages, status);
228 *(--nodes) = 0xdeadbee4;
229 print_move_pages(pid, count, 0, pages, nodes, status);
230 print_move_pages(pid, count, 1, pages, nodes, status);
232 puts("+++ exited with 0 +++");
238 SKIP_MAIN_UNDEFINED("__NR_move_pages")