1 /*
2 * Check decoding of mbind syscall.
3 *
4 * Copyright (c) 2016-2021 Dmitry V. Levin <ldv@strace.io>
5 * All rights reserved.
6 *
7 * SPDX-License-Identifier: GPL-2.0-or-later
8 */
9
10 #include "tests.h"
11 #include "scno.h"
12
13 #include <stdio.h>
14 #include <unistd.h>
15
16 static const char *errstr;
17
18 static long
19 k_mbind(const unsigned long start,
20 const unsigned long len,
21 const unsigned long mode,
22 const unsigned long nmask,
23 const unsigned long maxnode,
24 const unsigned int flags)
25 {
26 const kernel_ulong_t fill = (kernel_ulong_t) 0xdefaced00000000ULL;
27 const kernel_ulong_t arg1 = start;
28 const kernel_ulong_t arg2 = len;
29 const kernel_ulong_t arg3 = mode;
30 const kernel_ulong_t arg4 = nmask;
31 const kernel_ulong_t arg5 = maxnode;
32 const kernel_ulong_t arg6 = fill | flags;
33 const long rc = syscall(__NR_mbind, arg1, arg2, arg3, arg4, arg5, arg6);
34 errstr = sprintrc(rc);
35 return rc;
36 }
37
38 #if XLAT_RAW
39 # define out_str raw
40 # define flags_str "0xffffffff"
41 #elif XLAT_VERBOSE
42 # define out_str verbose
43 # define flags_str "0xffffffff /* MPOL_MF_STRICT|MPOL_MF_MOVE" \
44 "|MPOL_MF_MOVE_ALL|0xfffffff8 */"
45 #else
46 # define out_str abbrev
47 # define flags_str "MPOL_MF_STRICT|MPOL_MF_MOVE|MPOL_MF_MOVE_ALL|0xfffffff8"
48 #endif
49
50 static struct {
51 unsigned long val;
52 const char *raw;
53 const char *verbose;
54 const char *abbrev;
55 } mpol_modes[] = {
56 { ARG_STR(0),
57 "0 /* MPOL_DEFAULT */",
58 "MPOL_DEFAULT" },
59 { ARG_STR(0x1),
60 "0x1 /* MPOL_PREFERRED */",
61 "MPOL_PREFERRED" },
62 { ARG_STR(0x2),
63 "0x2 /* MPOL_BIND */",
64 "MPOL_BIND" },
65 { ARG_STR(0x3),
66 "0x3 /* MPOL_INTERLEAVE */",
67 "MPOL_INTERLEAVE" },
68 { ARG_STR(0x4),
69 "0x4 /* MPOL_LOCAL */",
70 "MPOL_LOCAL" },
71 { ARG_STR(0x5),
72 "0x5 /* MPOL_PREFERRED_MANY */",
73 "MPOL_PREFERRED_MANY" },
74 { ARG_STR(0x8000),
75 "0x8000 /* MPOL_DEFAULT|MPOL_F_STATIC_NODES */",
76 "MPOL_DEFAULT|MPOL_F_STATIC_NODES" },
77 { ARG_STR(0x4001),
78 "0x4001 /* MPOL_PREFERRED|MPOL_F_RELATIVE_NODES */",
79 "MPOL_PREFERRED|MPOL_F_RELATIVE_NODES" },
80 { ARG_STR(0x2002),
81 "0x2002 /* MPOL_BIND|MPOL_F_NUMA_BALANCING */",
82 "MPOL_BIND|MPOL_F_NUMA_BALANCING" },
83 { ARG_STR(0xe003),
84 "0xe003 /* MPOL_INTERLEAVE|MPOL_F_STATIC_NODES|MPOL_F_RELATIVE_NODES"
85 "|MPOL_F_NUMA_BALANCING */",
86 "MPOL_INTERLEAVE|MPOL_F_STATIC_NODES|MPOL_F_RELATIVE_NODES"
87 "|MPOL_F_NUMA_BALANCING" },
88 { ARG_STR(0x6),
89 "0x6 /* MPOL_??? */",
90 "0x6 /* MPOL_??? */" },
91 { ARG_STR(0xffff1fff),
92 "0xffff1fff /* MPOL_??? */",
93 "0xffff1fff /* MPOL_??? */" },
94 { ARG_STR(0xffffffff),
95 "0xffffffff /* MPOL_F_STATIC_NODES|MPOL_F_RELATIVE_NODES"
96 "|MPOL_F_NUMA_BALANCING|0xffff1fff */",
97 "MPOL_F_STATIC_NODES|MPOL_F_RELATIVE_NODES|MPOL_F_NUMA_BALANCING"
98 "|0xffff1fff" },
99 #if SIZEOF_LONG > 4
100 { 0xffffffff00000000UL,
101 "0xffffffff00000000",
102 "0xffffffff00000000 /* MPOL_??? */",
103 "0xffffffff00000000 /* MPOL_??? */" },
104 { 0xffffffffffff1fffUL,
105 "0xffffffffffff1fff",
106 "0xffffffffffff1fff /* MPOL_??? */",
107 "0xffffffffffff1fff /* MPOL_??? */" },
108 { -1UL,
109 "0xffffffffffffffff",
110 "0xffffffffffffffff /* MPOL_F_STATIC_NODES|MPOL_F_RELATIVE_NODES"
111 "|MPOL_F_NUMA_BALANCING|0xffffffffffff1fff */",
112 "MPOL_F_STATIC_NODES|MPOL_F_RELATIVE_NODES|MPOL_F_NUMA_BALANCING"
113 "|0xffffffffffff1fff" },
114 #endif
115 };
116
117 int
118 main(void)
119 {
120 const unsigned long size = get_page_size();
121 unsigned long *const addr = tail_alloc(size);
122 const unsigned long start = (unsigned long) 0xfffffff1fffffff2ULL;
123 const unsigned long len = (unsigned long) 0xfffffff4fffffff4ULL;
124 const unsigned long nodemask = (unsigned long) 0xfffffff5fffffff6ULL;
125 const unsigned long maxnode = (unsigned long) 0xfffffff7fffffff8ULL;
126
127 if (k_mbind((unsigned long) addr, size, mpol_modes[0].val, 0, 0, 0))
128 perror_msg_and_skip("mbind");
129 printf("mbind(%p, %lu, %s, NULL, 0, 0) = 0\n",
130 addr, size, mpol_modes[0].out_str);
131
132 for (unsigned int i = 0; i < ARRAY_SIZE(mpol_modes); ++i) {
133 if (i) {
134 k_mbind((unsigned long) addr, size, mpol_modes[i].val,
135 0, 0, 0);
136 printf("mbind(%p, %lu, %s, NULL, 0, 0) = %s\n",
137 addr, size, mpol_modes[i].out_str, errstr);
138 }
139
140 k_mbind(start, len, mpol_modes[i].val,
141 nodemask, maxnode, -1U);
142 printf("mbind(%#lx, %lu, %s, %#lx, %lu, %s) = %s\n",
143 start, len, mpol_modes[i].out_str,
144 nodemask, maxnode, flags_str, errstr);
145 }
146
147 puts("+++ exited with 0 +++");
148 return 0;
149 }