xref: /aosp_15_r20/external/ltp/testcases/kernel/syscalls/membarrier/membarrier01.c (revision 49cdfc7efb34551c7342be41a7384b9c40d7cab7)
1*49cdfc7eSAndroid Build Coastguard Worker // SPDX-License-Identifier: GPL-2.0-or-later
2*49cdfc7eSAndroid Build Coastguard Worker /*
3*49cdfc7eSAndroid Build Coastguard Worker  * Copyright (c) 2018 Linaro Limited. All rights reserved.
4*49cdfc7eSAndroid Build Coastguard Worker  * Author: Rafael David Tinoco <[email protected]>
5*49cdfc7eSAndroid Build Coastguard Worker  */
6*49cdfc7eSAndroid Build Coastguard Worker /*
7*49cdfc7eSAndroid Build Coastguard Worker  * Basic tests for membarrier(2) syscall. Tests below are responsible for
8*49cdfc7eSAndroid Build Coastguard Worker  * testing the membarrier(2) interface only, without checking if the barrier
9*49cdfc7eSAndroid Build Coastguard Worker  * was successful or not. Check test_case structure for each test description.
10*49cdfc7eSAndroid Build Coastguard Worker  */
11*49cdfc7eSAndroid Build Coastguard Worker 
12*49cdfc7eSAndroid Build Coastguard Worker #include "config.h"
13*49cdfc7eSAndroid Build Coastguard Worker #include <sys/types.h>
14*49cdfc7eSAndroid Build Coastguard Worker #include <sys/stat.h>
15*49cdfc7eSAndroid Build Coastguard Worker #include <sys/wait.h>
16*49cdfc7eSAndroid Build Coastguard Worker #include <syscall.h>
17*49cdfc7eSAndroid Build Coastguard Worker #include <errno.h>
18*49cdfc7eSAndroid Build Coastguard Worker #include <fcntl.h>
19*49cdfc7eSAndroid Build Coastguard Worker #include <unistd.h>
20*49cdfc7eSAndroid Build Coastguard Worker #include <signal.h>
21*49cdfc7eSAndroid Build Coastguard Worker #include <stdio.h>
22*49cdfc7eSAndroid Build Coastguard Worker #include <stdlib.h>
23*49cdfc7eSAndroid Build Coastguard Worker #include <string.h>
24*49cdfc7eSAndroid Build Coastguard Worker #include "tst_test.h"
25*49cdfc7eSAndroid Build Coastguard Worker #include "lapi/syscalls.h"
26*49cdfc7eSAndroid Build Coastguard Worker #include "lapi/membarrier.h"
27*49cdfc7eSAndroid Build Coastguard Worker 
28*49cdfc7eSAndroid Build Coastguard Worker struct test_case {
29*49cdfc7eSAndroid Build Coastguard Worker 	char testname[80];
30*49cdfc7eSAndroid Build Coastguard Worker 	int command;		/* membarrier cmd                            */
31*49cdfc7eSAndroid Build Coastguard Worker 	int needregister;	/* membarrier cmd needs register cmd	     */
32*49cdfc7eSAndroid Build Coastguard Worker 	int flags;		/* flags for given membarrier cmd	     */
33*49cdfc7eSAndroid Build Coastguard Worker 	long exp_ret;		/* expected return code for given cmd        */
34*49cdfc7eSAndroid Build Coastguard Worker 	int exp_errno;		/* expected errno for given cmd failure      */
35*49cdfc7eSAndroid Build Coastguard Worker 	int enabled;		/* enabled, despite results from CMD_QUERY   */
36*49cdfc7eSAndroid Build Coastguard Worker 	int always;		/* CMD_QUERY should always enable this test  */
37*49cdfc7eSAndroid Build Coastguard Worker 	int force;		/* force if CMD_QUERY reports not enabled    */
38*49cdfc7eSAndroid Build Coastguard Worker 	int force_exp_errno;	/* expected errno after forced cmd           */
39*49cdfc7eSAndroid Build Coastguard Worker 	int change_exp_errno;	/* previous kernels forced errno result      */
40*49cdfc7eSAndroid Build Coastguard Worker 	int change_kernver[3];	/* kernel version having diff expected errno */
41*49cdfc7eSAndroid Build Coastguard Worker };
42*49cdfc7eSAndroid Build Coastguard Worker 
43*49cdfc7eSAndroid Build Coastguard Worker struct test_case tc[] = {
44*49cdfc7eSAndroid Build Coastguard Worker 	{
45*49cdfc7eSAndroid Build Coastguard Worker 	 /*
46*49cdfc7eSAndroid Build Coastguard Worker 	  * case 00) invalid cmd
47*49cdfc7eSAndroid Build Coastguard Worker 	  *     - enabled by default
48*49cdfc7eSAndroid Build Coastguard Worker 	  *     - should always fail with EINVAL
49*49cdfc7eSAndroid Build Coastguard Worker 	  */
50*49cdfc7eSAndroid Build Coastguard Worker 	 .testname = "cmd_fail",
51*49cdfc7eSAndroid Build Coastguard Worker 	 .command = -1,
52*49cdfc7eSAndroid Build Coastguard Worker 	 .exp_ret = -1,
53*49cdfc7eSAndroid Build Coastguard Worker 	 .exp_errno = EINVAL,
54*49cdfc7eSAndroid Build Coastguard Worker 	 .enabled = 1,
55*49cdfc7eSAndroid Build Coastguard Worker 	 },
56*49cdfc7eSAndroid Build Coastguard Worker 	{
57*49cdfc7eSAndroid Build Coastguard Worker 	 /*
58*49cdfc7eSAndroid Build Coastguard Worker 	  * case 01) invalid flags
59*49cdfc7eSAndroid Build Coastguard Worker 	  *     - enabled by default
60*49cdfc7eSAndroid Build Coastguard Worker 	  *     - should always fail with EINVAL
61*49cdfc7eSAndroid Build Coastguard Worker 	  */
62*49cdfc7eSAndroid Build Coastguard Worker 	 .testname = "cmd_flags_fail",
63*49cdfc7eSAndroid Build Coastguard Worker 	 .command = MEMBARRIER_CMD_QUERY,
64*49cdfc7eSAndroid Build Coastguard Worker 	 .flags = 1,
65*49cdfc7eSAndroid Build Coastguard Worker 	 .exp_ret = -1,
66*49cdfc7eSAndroid Build Coastguard Worker 	 .exp_errno = EINVAL,
67*49cdfc7eSAndroid Build Coastguard Worker 	 .enabled = 1,
68*49cdfc7eSAndroid Build Coastguard Worker 	 },
69*49cdfc7eSAndroid Build Coastguard Worker 	{
70*49cdfc7eSAndroid Build Coastguard Worker 	 /*
71*49cdfc7eSAndroid Build Coastguard Worker 	  * case 02) global barrier
72*49cdfc7eSAndroid Build Coastguard Worker 	  *     - should ALWAYS be enabled by CMD_QUERY
73*49cdfc7eSAndroid Build Coastguard Worker 	  *     - should always succeed
74*49cdfc7eSAndroid Build Coastguard Worker 	  */
75*49cdfc7eSAndroid Build Coastguard Worker 	 .testname = "cmd_global_success",
76*49cdfc7eSAndroid Build Coastguard Worker 	 .command = MEMBARRIER_CMD_GLOBAL,
77*49cdfc7eSAndroid Build Coastguard Worker 	 .flags = 0,
78*49cdfc7eSAndroid Build Coastguard Worker 	 .exp_ret = 0,
79*49cdfc7eSAndroid Build Coastguard Worker 	 .always = 1,
80*49cdfc7eSAndroid Build Coastguard Worker 	 },
81*49cdfc7eSAndroid Build Coastguard Worker 	 /*
82*49cdfc7eSAndroid Build Coastguard Worker 	  * commit 22e4ebb975 (v4.14-rc1) added cases 03, 04 and 05 features:
83*49cdfc7eSAndroid Build Coastguard Worker 	  */
84*49cdfc7eSAndroid Build Coastguard Worker 	{
85*49cdfc7eSAndroid Build Coastguard Worker 	 /*
86*49cdfc7eSAndroid Build Coastguard Worker 	  * case 03) private expedited barrier with no registrations
87*49cdfc7eSAndroid Build Coastguard Worker 	  *     - should fail with errno=EPERM due to no registrations
88*49cdfc7eSAndroid Build Coastguard Worker 	  *     - or be skipped if unsupported by running kernel
89*49cdfc7eSAndroid Build Coastguard Worker 	  */
90*49cdfc7eSAndroid Build Coastguard Worker 	 .testname = "cmd_private_expedited_fail",
91*49cdfc7eSAndroid Build Coastguard Worker 	 .command = MEMBARRIER_CMD_PRIVATE_EXPEDITED,
92*49cdfc7eSAndroid Build Coastguard Worker 	 .flags = 0,
93*49cdfc7eSAndroid Build Coastguard Worker 	 .exp_ret = -1,
94*49cdfc7eSAndroid Build Coastguard Worker 	 .exp_errno = EPERM,
95*49cdfc7eSAndroid Build Coastguard Worker 	 },
96*49cdfc7eSAndroid Build Coastguard Worker 	{
97*49cdfc7eSAndroid Build Coastguard Worker 	 /*
98*49cdfc7eSAndroid Build Coastguard Worker 	  * case 04) register private expedited
99*49cdfc7eSAndroid Build Coastguard Worker 	  *     - should succeed when supported by running kernel
100*49cdfc7eSAndroid Build Coastguard Worker 	  *     - or fail with errno=EINVAL if unsupported and forced
101*49cdfc7eSAndroid Build Coastguard Worker 	  */
102*49cdfc7eSAndroid Build Coastguard Worker 	 .testname = "cmd_private_expedited_register_success",
103*49cdfc7eSAndroid Build Coastguard Worker 	 .command = MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED,
104*49cdfc7eSAndroid Build Coastguard Worker 	 .flags = 0,
105*49cdfc7eSAndroid Build Coastguard Worker 	 .exp_ret = 0,
106*49cdfc7eSAndroid Build Coastguard Worker 	 .force = 1,
107*49cdfc7eSAndroid Build Coastguard Worker 	 .force_exp_errno = EINVAL,
108*49cdfc7eSAndroid Build Coastguard Worker 	 },
109*49cdfc7eSAndroid Build Coastguard Worker 	{
110*49cdfc7eSAndroid Build Coastguard Worker 	 /*
111*49cdfc7eSAndroid Build Coastguard Worker 	  * case 05) private expedited barrier with registration
112*49cdfc7eSAndroid Build Coastguard Worker 	  *     - should succeed due to existing registration
113*49cdfc7eSAndroid Build Coastguard Worker 	  *     - or fail with errno=EINVAL if unsupported and forced
114*49cdfc7eSAndroid Build Coastguard Worker 	  *     - NOTE: commit 70216e18e5 (v4.16-rc1) changed behavior:
115*49cdfc7eSAndroid Build Coastguard Worker 	  *     -       (a) if unsupported, and forced, < 4.16 , errno is EINVAL
116*49cdfc7eSAndroid Build Coastguard Worker 	  *     -       (b) if unsupported, and forced, >= 4.16, errno is EPERM
117*49cdfc7eSAndroid Build Coastguard Worker 	  */
118*49cdfc7eSAndroid Build Coastguard Worker 	 .testname = "cmd_private_expedited_success",
119*49cdfc7eSAndroid Build Coastguard Worker 	 .needregister = MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED,
120*49cdfc7eSAndroid Build Coastguard Worker 	 .command = MEMBARRIER_CMD_PRIVATE_EXPEDITED,
121*49cdfc7eSAndroid Build Coastguard Worker 	 .flags = 0,
122*49cdfc7eSAndroid Build Coastguard Worker 	 .exp_ret = 0,
123*49cdfc7eSAndroid Build Coastguard Worker 	 .force = 1,
124*49cdfc7eSAndroid Build Coastguard Worker 	 .force_exp_errno = EPERM,
125*49cdfc7eSAndroid Build Coastguard Worker 	 .change_exp_errno = EINVAL,
126*49cdfc7eSAndroid Build Coastguard Worker 	 .change_kernver = { 4, 16, 0 },
127*49cdfc7eSAndroid Build Coastguard Worker 	 },
128*49cdfc7eSAndroid Build Coastguard Worker 	 /*
129*49cdfc7eSAndroid Build Coastguard Worker 	  * commit 70216e18e5 (v4.16-rc1) added cases 06, 07 and 08 features:
130*49cdfc7eSAndroid Build Coastguard Worker 	  */
131*49cdfc7eSAndroid Build Coastguard Worker 	{
132*49cdfc7eSAndroid Build Coastguard Worker 	 /*
133*49cdfc7eSAndroid Build Coastguard Worker 	  * case 06) private expedited sync core barrier with no registrations
134*49cdfc7eSAndroid Build Coastguard Worker 	  *     - should fail with errno=EPERM due to no registrations
135*49cdfc7eSAndroid Build Coastguard Worker 	  *     - or be skipped if unsupported by running kernel
136*49cdfc7eSAndroid Build Coastguard Worker 	  */
137*49cdfc7eSAndroid Build Coastguard Worker 	 .testname = "cmd_private_expedited_sync_core_fail",
138*49cdfc7eSAndroid Build Coastguard Worker 	 .command = MEMBARRIER_CMD_PRIVATE_EXPEDITED_SYNC_CORE,
139*49cdfc7eSAndroid Build Coastguard Worker 	 .flags = 0,
140*49cdfc7eSAndroid Build Coastguard Worker 	 .exp_ret = -1,
141*49cdfc7eSAndroid Build Coastguard Worker 	 .exp_errno = EPERM,
142*49cdfc7eSAndroid Build Coastguard Worker 	 },
143*49cdfc7eSAndroid Build Coastguard Worker 	{
144*49cdfc7eSAndroid Build Coastguard Worker 	 /*
145*49cdfc7eSAndroid Build Coastguard Worker 	  * case 07) register private expedited sync core
146*49cdfc7eSAndroid Build Coastguard Worker 	  *     - should succeed when supported by running kernel
147*49cdfc7eSAndroid Build Coastguard Worker 	  *     - or fail with errno=EINVAL if unsupported and forced
148*49cdfc7eSAndroid Build Coastguard Worker 	  */
149*49cdfc7eSAndroid Build Coastguard Worker 	 .testname = "cmd_private_expedited_sync_core_register_success",
150*49cdfc7eSAndroid Build Coastguard Worker 	 .command = MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED_SYNC_CORE,
151*49cdfc7eSAndroid Build Coastguard Worker 	 .flags = 0,
152*49cdfc7eSAndroid Build Coastguard Worker 	 .exp_ret = 0,
153*49cdfc7eSAndroid Build Coastguard Worker 	 .force = 1,
154*49cdfc7eSAndroid Build Coastguard Worker 	 .force_exp_errno = EINVAL,
155*49cdfc7eSAndroid Build Coastguard Worker 	 },
156*49cdfc7eSAndroid Build Coastguard Worker 	{
157*49cdfc7eSAndroid Build Coastguard Worker 	 /*
158*49cdfc7eSAndroid Build Coastguard Worker 	  * case 08) private expedited sync core barrier with registration
159*49cdfc7eSAndroid Build Coastguard Worker 	  *     - should succeed due to existing registration
160*49cdfc7eSAndroid Build Coastguard Worker 	  *     - or fail with errno=EINVAL if unsupported and forced
161*49cdfc7eSAndroid Build Coastguard Worker 	  */
162*49cdfc7eSAndroid Build Coastguard Worker 	 .testname = "cmd_private_expedited_sync_core_success",
163*49cdfc7eSAndroid Build Coastguard Worker 	 .needregister = MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED_SYNC_CORE,
164*49cdfc7eSAndroid Build Coastguard Worker 	 .command = MEMBARRIER_CMD_PRIVATE_EXPEDITED_SYNC_CORE,
165*49cdfc7eSAndroid Build Coastguard Worker 	 .flags = 0,
166*49cdfc7eSAndroid Build Coastguard Worker 	 .exp_ret = 0,
167*49cdfc7eSAndroid Build Coastguard Worker 	 .force = 1,
168*49cdfc7eSAndroid Build Coastguard Worker 	 .force_exp_errno = EINVAL,
169*49cdfc7eSAndroid Build Coastguard Worker 	 },
170*49cdfc7eSAndroid Build Coastguard Worker 	 /*
171*49cdfc7eSAndroid Build Coastguard Worker 	  * commit c5f58bd58f4 (v4.16-rc1) added cases 09, 10 and 11 features:
172*49cdfc7eSAndroid Build Coastguard Worker 	  */
173*49cdfc7eSAndroid Build Coastguard Worker 	{
174*49cdfc7eSAndroid Build Coastguard Worker 	 /*
175*49cdfc7eSAndroid Build Coastguard Worker 	  * case 09) global expedited barrier with no registrations
176*49cdfc7eSAndroid Build Coastguard Worker 	  *     - should never fail due to no registrations
177*49cdfc7eSAndroid Build Coastguard Worker 	  *     - or be skipped if unsupported by running kernel
178*49cdfc7eSAndroid Build Coastguard Worker 	  */
179*49cdfc7eSAndroid Build Coastguard Worker 	 .testname = "cmd_global_expedited_success",
180*49cdfc7eSAndroid Build Coastguard Worker 	 .command = MEMBARRIER_CMD_GLOBAL_EXPEDITED,
181*49cdfc7eSAndroid Build Coastguard Worker 	 .flags = 0,
182*49cdfc7eSAndroid Build Coastguard Worker 	 .exp_ret = 0,
183*49cdfc7eSAndroid Build Coastguard Worker 	 },
184*49cdfc7eSAndroid Build Coastguard Worker 	{
185*49cdfc7eSAndroid Build Coastguard Worker 	 /*
186*49cdfc7eSAndroid Build Coastguard Worker 	  * case 10) register global expedited
187*49cdfc7eSAndroid Build Coastguard Worker 	  *     - should succeed when supported by running kernel
188*49cdfc7eSAndroid Build Coastguard Worker 	  *     - or fail with errno=EINVAL if unsupported and forced
189*49cdfc7eSAndroid Build Coastguard Worker 	  */
190*49cdfc7eSAndroid Build Coastguard Worker 	 .testname = "cmd_global_expedited_register_success",
191*49cdfc7eSAndroid Build Coastguard Worker 	 .command = MEMBARRIER_CMD_REGISTER_GLOBAL_EXPEDITED,
192*49cdfc7eSAndroid Build Coastguard Worker 	 .flags = 0,
193*49cdfc7eSAndroid Build Coastguard Worker 	 .exp_ret = 0,
194*49cdfc7eSAndroid Build Coastguard Worker 	 .force = 1,
195*49cdfc7eSAndroid Build Coastguard Worker 	 .force_exp_errno = EINVAL,
196*49cdfc7eSAndroid Build Coastguard Worker 	 },
197*49cdfc7eSAndroid Build Coastguard Worker 	{
198*49cdfc7eSAndroid Build Coastguard Worker 	 /*
199*49cdfc7eSAndroid Build Coastguard Worker 	  * case 11) global expedited barrier with registration
200*49cdfc7eSAndroid Build Coastguard Worker 	  *     - should also succeed with registrations
201*49cdfc7eSAndroid Build Coastguard Worker 	  *     - or fail with errno=EINVAL if unsupported and forced
202*49cdfc7eSAndroid Build Coastguard Worker 	  */
203*49cdfc7eSAndroid Build Coastguard Worker 	 .testname = "cmd_global_expedited_success",
204*49cdfc7eSAndroid Build Coastguard Worker 	 .needregister = MEMBARRIER_CMD_REGISTER_GLOBAL_EXPEDITED,
205*49cdfc7eSAndroid Build Coastguard Worker 	 .command = MEMBARRIER_CMD_GLOBAL_EXPEDITED,
206*49cdfc7eSAndroid Build Coastguard Worker 	 .flags = 0,
207*49cdfc7eSAndroid Build Coastguard Worker 	 .exp_ret = 0,
208*49cdfc7eSAndroid Build Coastguard Worker 	 .force = 1,
209*49cdfc7eSAndroid Build Coastguard Worker 	 .force_exp_errno = EINVAL,
210*49cdfc7eSAndroid Build Coastguard Worker 	 },
211*49cdfc7eSAndroid Build Coastguard Worker };
212*49cdfc7eSAndroid Build Coastguard Worker 
213*49cdfc7eSAndroid Build Coastguard Worker #define passed_ok(_test)						       \
214*49cdfc7eSAndroid Build Coastguard Worker 	do {								       \
215*49cdfc7eSAndroid Build Coastguard Worker 		tst_res(TPASS, "membarrier(2): %s passed", _test.testname);    \
216*49cdfc7eSAndroid Build Coastguard Worker 		return;							       \
217*49cdfc7eSAndroid Build Coastguard Worker 	} while (0)
218*49cdfc7eSAndroid Build Coastguard Worker 
219*49cdfc7eSAndroid Build Coastguard Worker #define passed_unexpec(_test)						       \
220*49cdfc7eSAndroid Build Coastguard Worker 	do {								       \
221*49cdfc7eSAndroid Build Coastguard Worker 		tst_res(TFAIL, "membarrier(2): %s passed unexpectedly. "       \
222*49cdfc7eSAndroid Build Coastguard Worker 			"ret = %ld with errno %d were expected. (force: %d)",  \
223*49cdfc7eSAndroid Build Coastguard Worker 			_test.testname, _test.exp_ret, _test.exp_errno,        \
224*49cdfc7eSAndroid Build Coastguard Worker 			_test.force);					       \
225*49cdfc7eSAndroid Build Coastguard Worker 		return;							       \
226*49cdfc7eSAndroid Build Coastguard Worker 	} while (0)
227*49cdfc7eSAndroid Build Coastguard Worker 
228*49cdfc7eSAndroid Build Coastguard Worker #define failed_ok(_test)						       \
229*49cdfc7eSAndroid Build Coastguard Worker 	do {								       \
230*49cdfc7eSAndroid Build Coastguard Worker 		tst_res(TPASS, "membarrier(2): %s failed as expected",	       \
231*49cdfc7eSAndroid Build Coastguard Worker 			_test.testname);				       \
232*49cdfc7eSAndroid Build Coastguard Worker 		return;							       \
233*49cdfc7eSAndroid Build Coastguard Worker 	} while (0)
234*49cdfc7eSAndroid Build Coastguard Worker 
235*49cdfc7eSAndroid Build Coastguard Worker #define failed_ok_unsupported(_test)					       \
236*49cdfc7eSAndroid Build Coastguard Worker 	do {								       \
237*49cdfc7eSAndroid Build Coastguard Worker 		tst_res(TPASS, "membarrier(2): %s failed as expected "	       \
238*49cdfc7eSAndroid Build Coastguard Worker 			"(unsupported)", _test.testname);		       \
239*49cdfc7eSAndroid Build Coastguard Worker 		return;							       \
240*49cdfc7eSAndroid Build Coastguard Worker 	} while (0)
241*49cdfc7eSAndroid Build Coastguard Worker 
242*49cdfc7eSAndroid Build Coastguard Worker #define failed_not_ok(_test, _gotret, _goterr)				       \
243*49cdfc7eSAndroid Build Coastguard Worker 	do {								       \
244*49cdfc7eSAndroid Build Coastguard Worker 		tst_res(TFAIL, "membarrier(2): %s failed. "		       \
245*49cdfc7eSAndroid Build Coastguard Worker 			"ret = %ld when expected was %ld. "		       \
246*49cdfc7eSAndroid Build Coastguard Worker 			"errno = %d when expected was %d. (force: %d)",        \
247*49cdfc7eSAndroid Build Coastguard Worker 			_test.testname, _gotret, _test.exp_ret, _goterr,       \
248*49cdfc7eSAndroid Build Coastguard Worker 			_test.exp_errno, _test.force);			       \
249*49cdfc7eSAndroid Build Coastguard Worker 		return;							       \
250*49cdfc7eSAndroid Build Coastguard Worker 	} while (0)
251*49cdfc7eSAndroid Build Coastguard Worker 
252*49cdfc7eSAndroid Build Coastguard Worker #define failed_unexpec(_test, _gotret, _goterr) 			       \
253*49cdfc7eSAndroid Build Coastguard Worker 	do {								       \
254*49cdfc7eSAndroid Build Coastguard Worker 		tst_res(TFAIL, "membarrier(2): %s failed unexpectedly. "       \
255*49cdfc7eSAndroid Build Coastguard Worker 			"Got ret = %ld with errno %d. (force: %d)",	       \
256*49cdfc7eSAndroid Build Coastguard Worker 			_test.testname, _gotret, _goterr, _test.force);	       \
257*49cdfc7eSAndroid Build Coastguard Worker 		return;							       \
258*49cdfc7eSAndroid Build Coastguard Worker 	} while (0)
259*49cdfc7eSAndroid Build Coastguard Worker 
260*49cdfc7eSAndroid Build Coastguard Worker #define skipped(_test)							       \
261*49cdfc7eSAndroid Build Coastguard Worker 	do {								       \
262*49cdfc7eSAndroid Build Coastguard Worker 		tst_res(TPASS, "membarrier(2): %s skipped (unsupported)",      \
263*49cdfc7eSAndroid Build Coastguard Worker 			_test.testname);				       \
264*49cdfc7eSAndroid Build Coastguard Worker 		return;							       \
265*49cdfc7eSAndroid Build Coastguard Worker 	} while (0)
266*49cdfc7eSAndroid Build Coastguard Worker 
267*49cdfc7eSAndroid Build Coastguard Worker #define skipped_fail(_test)						       \
268*49cdfc7eSAndroid Build Coastguard Worker 	do {								       \
269*49cdfc7eSAndroid Build Coastguard Worker 		tst_res(TFAIL, "membarrier(2): %s reported as not supported",  \
270*49cdfc7eSAndroid Build Coastguard Worker 			_test.testname);				       \
271*49cdfc7eSAndroid Build Coastguard Worker 		return;							       \
272*49cdfc7eSAndroid Build Coastguard Worker 	} while (0)
273*49cdfc7eSAndroid Build Coastguard Worker 
sys_membarrier(int cmd,int flags)274*49cdfc7eSAndroid Build Coastguard Worker static int sys_membarrier(int cmd, int flags)
275*49cdfc7eSAndroid Build Coastguard Worker {
276*49cdfc7eSAndroid Build Coastguard Worker 	return tst_syscall(__NR_membarrier, cmd, flags);
277*49cdfc7eSAndroid Build Coastguard Worker }
278*49cdfc7eSAndroid Build Coastguard Worker 
verify_membarrier(unsigned int i)279*49cdfc7eSAndroid Build Coastguard Worker static void verify_membarrier(unsigned int i)
280*49cdfc7eSAndroid Build Coastguard Worker {
281*49cdfc7eSAndroid Build Coastguard Worker 	int ret;
282*49cdfc7eSAndroid Build Coastguard Worker 
283*49cdfc7eSAndroid Build Coastguard Worker 	/* not enabled and not enforced: test is skipped */
284*49cdfc7eSAndroid Build Coastguard Worker 
285*49cdfc7eSAndroid Build Coastguard Worker 	if (!tc[i].enabled && !tc[i].force) {
286*49cdfc7eSAndroid Build Coastguard Worker 
287*49cdfc7eSAndroid Build Coastguard Worker 		if (tc[i].always == 0)
288*49cdfc7eSAndroid Build Coastguard Worker 			skipped(tc[i]);
289*49cdfc7eSAndroid Build Coastguard Worker 
290*49cdfc7eSAndroid Build Coastguard Worker 		skipped_fail(tc[i]);
291*49cdfc7eSAndroid Build Coastguard Worker 	}
292*49cdfc7eSAndroid Build Coastguard Worker 
293*49cdfc7eSAndroid Build Coastguard Worker 	/* iterations: registration needed for some cases */
294*49cdfc7eSAndroid Build Coastguard Worker 
295*49cdfc7eSAndroid Build Coastguard Worker 	if (tc[i].needregister && tc[i].enabled) {
296*49cdfc7eSAndroid Build Coastguard Worker 		ret = sys_membarrier(tc[i].needregister, 0);
297*49cdfc7eSAndroid Build Coastguard Worker 		if (ret < 0) {
298*49cdfc7eSAndroid Build Coastguard Worker 			tst_brk(TBROK, "membarrier(2): %s could not register",
299*49cdfc7eSAndroid Build Coastguard Worker 					tc[i].testname);
300*49cdfc7eSAndroid Build Coastguard Worker 		}
301*49cdfc7eSAndroid Build Coastguard Worker 	}
302*49cdfc7eSAndroid Build Coastguard Worker 
303*49cdfc7eSAndroid Build Coastguard Worker 	TEST(sys_membarrier(tc[i].command, tc[i].flags));
304*49cdfc7eSAndroid Build Coastguard Worker 
305*49cdfc7eSAndroid Build Coastguard Worker 	/* enabled and not enforced: regular expected results only */
306*49cdfc7eSAndroid Build Coastguard Worker 
307*49cdfc7eSAndroid Build Coastguard Worker 	if (tc[i].enabled && !tc[i].force) {
308*49cdfc7eSAndroid Build Coastguard Worker 
309*49cdfc7eSAndroid Build Coastguard Worker 		if (TST_RET >= 0 && tc[i].exp_ret == TST_RET)
310*49cdfc7eSAndroid Build Coastguard Worker 			passed_ok(tc[i]);
311*49cdfc7eSAndroid Build Coastguard Worker 
312*49cdfc7eSAndroid Build Coastguard Worker 		if (TST_RET < 0) {
313*49cdfc7eSAndroid Build Coastguard Worker 			if (tc[i].exp_ret == TST_RET)
314*49cdfc7eSAndroid Build Coastguard Worker 				failed_ok(tc[i]);
315*49cdfc7eSAndroid Build Coastguard Worker 			else
316*49cdfc7eSAndroid Build Coastguard Worker 				failed_not_ok(tc[i], TST_RET, TST_ERR);
317*49cdfc7eSAndroid Build Coastguard Worker 		}
318*49cdfc7eSAndroid Build Coastguard Worker 	}
319*49cdfc7eSAndroid Build Coastguard Worker 
320*49cdfc7eSAndroid Build Coastguard Worker 	/* not enabled and enforced: failure and expected errors */
321*49cdfc7eSAndroid Build Coastguard Worker 
322*49cdfc7eSAndroid Build Coastguard Worker 	if (!tc[i].enabled && tc[i].force) {
323*49cdfc7eSAndroid Build Coastguard Worker 
324*49cdfc7eSAndroid Build Coastguard Worker 		if (TST_RET >= 0)
325*49cdfc7eSAndroid Build Coastguard Worker 			passed_unexpec(tc[i]);
326*49cdfc7eSAndroid Build Coastguard Worker 
327*49cdfc7eSAndroid Build Coastguard Worker 		if (TST_RET < 0) {
328*49cdfc7eSAndroid Build Coastguard Worker 			if (tc[i].force_exp_errno == TST_ERR)
329*49cdfc7eSAndroid Build Coastguard Worker 				failed_ok_unsupported(tc[i]);
330*49cdfc7eSAndroid Build Coastguard Worker 			else
331*49cdfc7eSAndroid Build Coastguard Worker 				failed_unexpec(tc[i], TST_RET, TST_ERR);
332*49cdfc7eSAndroid Build Coastguard Worker 		}
333*49cdfc7eSAndroid Build Coastguard Worker 	}
334*49cdfc7eSAndroid Build Coastguard Worker 
335*49cdfc7eSAndroid Build Coastguard Worker 	/* enabled and enforced: tricky */
336*49cdfc7eSAndroid Build Coastguard Worker 
337*49cdfc7eSAndroid Build Coastguard Worker 	if (tc[i].enabled && tc[i].force) {
338*49cdfc7eSAndroid Build Coastguard Worker 
339*49cdfc7eSAndroid Build Coastguard Worker 		if (TST_RET >= 0) {
340*49cdfc7eSAndroid Build Coastguard Worker 			if (tc[i].exp_ret == TST_RET)
341*49cdfc7eSAndroid Build Coastguard Worker 				passed_ok(tc[i]);
342*49cdfc7eSAndroid Build Coastguard Worker 			else
343*49cdfc7eSAndroid Build Coastguard Worker 				passed_unexpec(tc[i]);
344*49cdfc7eSAndroid Build Coastguard Worker 		}
345*49cdfc7eSAndroid Build Coastguard Worker 
346*49cdfc7eSAndroid Build Coastguard Worker 		if (TST_RET < 0) {
347*49cdfc7eSAndroid Build Coastguard Worker 
348*49cdfc7eSAndroid Build Coastguard Worker 			if (tc[i].exp_ret == TST_RET) {
349*49cdfc7eSAndroid Build Coastguard Worker 
350*49cdfc7eSAndroid Build Coastguard Worker 				if (tc[i].exp_errno == TST_ERR)
351*49cdfc7eSAndroid Build Coastguard Worker 					failed_ok(tc[i]);
352*49cdfc7eSAndroid Build Coastguard Worker 				else
353*49cdfc7eSAndroid Build Coastguard Worker 					failed_unexpec(tc[i], TST_RET, TST_ERR);
354*49cdfc7eSAndroid Build Coastguard Worker 			}
355*49cdfc7eSAndroid Build Coastguard Worker 
356*49cdfc7eSAndroid Build Coastguard Worker 			/* unknown on force failure if enabled and forced */
357*49cdfc7eSAndroid Build Coastguard Worker 			failed_unexpec(tc[i], TST_RET, TST_ERR);
358*49cdfc7eSAndroid Build Coastguard Worker 		}
359*49cdfc7eSAndroid Build Coastguard Worker 	}
360*49cdfc7eSAndroid Build Coastguard Worker }
361*49cdfc7eSAndroid Build Coastguard Worker 
wrap_verify_membarrier(unsigned int i)362*49cdfc7eSAndroid Build Coastguard Worker static void wrap_verify_membarrier(unsigned int i)
363*49cdfc7eSAndroid Build Coastguard Worker {
364*49cdfc7eSAndroid Build Coastguard Worker 	pid_t pid;
365*49cdfc7eSAndroid Build Coastguard Worker 
366*49cdfc7eSAndroid Build Coastguard Worker 	/*
367*49cdfc7eSAndroid Build Coastguard Worker 	 * The Linux kernel does not provide a way to unregister the process
368*49cdfc7eSAndroid Build Coastguard Worker 	 * (mm->membarrier_state) intent of being affected by the membarrier(2)
369*49cdfc7eSAndroid Build Coastguard Worker 	 * system call, thus the need of having a wrapper to fork() a child.
370*49cdfc7eSAndroid Build Coastguard Worker 	 */
371*49cdfc7eSAndroid Build Coastguard Worker 
372*49cdfc7eSAndroid Build Coastguard Worker 	pid = SAFE_FORK();
373*49cdfc7eSAndroid Build Coastguard Worker 
374*49cdfc7eSAndroid Build Coastguard Worker 	if (pid)
375*49cdfc7eSAndroid Build Coastguard Worker 		SAFE_WAITPID(pid, NULL, 0);
376*49cdfc7eSAndroid Build Coastguard Worker 	else
377*49cdfc7eSAndroid Build Coastguard Worker 		verify_membarrier(i);
378*49cdfc7eSAndroid Build Coastguard Worker }
379*49cdfc7eSAndroid Build Coastguard Worker 
setup(void)380*49cdfc7eSAndroid Build Coastguard Worker static void setup(void)
381*49cdfc7eSAndroid Build Coastguard Worker {
382*49cdfc7eSAndroid Build Coastguard Worker 	size_t i;
383*49cdfc7eSAndroid Build Coastguard Worker 	int ret;
384*49cdfc7eSAndroid Build Coastguard Worker 
385*49cdfc7eSAndroid Build Coastguard Worker 	ret = sys_membarrier(MEMBARRIER_CMD_QUERY, 0);
386*49cdfc7eSAndroid Build Coastguard Worker 	if (ret < 0) {
387*49cdfc7eSAndroid Build Coastguard Worker 		if (errno == ENOSYS)
388*49cdfc7eSAndroid Build Coastguard Worker 			tst_brk(TBROK, "membarrier(2): not supported");
389*49cdfc7eSAndroid Build Coastguard Worker 	}
390*49cdfc7eSAndroid Build Coastguard Worker 
391*49cdfc7eSAndroid Build Coastguard Worker 	for (i = 0; i < ARRAY_SIZE(tc); i++) {
392*49cdfc7eSAndroid Build Coastguard Worker 		if ((tc[i].command > 0) && (ret & tc[i].command))
393*49cdfc7eSAndroid Build Coastguard Worker 			tc[i].enabled = 1;
394*49cdfc7eSAndroid Build Coastguard Worker 
395*49cdfc7eSAndroid Build Coastguard Worker 		/* forcing unsupported command might have different errno */
396*49cdfc7eSAndroid Build Coastguard Worker 
397*49cdfc7eSAndroid Build Coastguard Worker 		if (tc[i].change_exp_errno && tc[i].enabled == 0) {
398*49cdfc7eSAndroid Build Coastguard Worker 			if (tst_kvercmp(tc[i].change_kernver[0],
399*49cdfc7eSAndroid Build Coastguard Worker 					tc[i].change_kernver[1],
400*49cdfc7eSAndroid Build Coastguard Worker 					tc[i].change_kernver[2]) < 0)
401*49cdfc7eSAndroid Build Coastguard Worker 				tc[i].force_exp_errno = tc[i].change_exp_errno;
402*49cdfc7eSAndroid Build Coastguard Worker 		}
403*49cdfc7eSAndroid Build Coastguard Worker 	}
404*49cdfc7eSAndroid Build Coastguard Worker }
405*49cdfc7eSAndroid Build Coastguard Worker 
406*49cdfc7eSAndroid Build Coastguard Worker static struct tst_test test = {
407*49cdfc7eSAndroid Build Coastguard Worker 	.setup = setup,
408*49cdfc7eSAndroid Build Coastguard Worker 	.test = wrap_verify_membarrier,
409*49cdfc7eSAndroid Build Coastguard Worker 	.tcnt = ARRAY_SIZE(tc),
410*49cdfc7eSAndroid Build Coastguard Worker 	.min_kver = "4.3.0",	/* commit: 5b25b13ab0 (sys_membarrier(): ...) */
411*49cdfc7eSAndroid Build Coastguard Worker 	.forks_child = 1,
412*49cdfc7eSAndroid Build Coastguard Worker };
413