0001
0002 #define _GNU_SOURCE
0003 #include <linux/membarrier.h>
0004 #include <syscall.h>
0005 #include <stdio.h>
0006 #include <errno.h>
0007 #include <string.h>
0008 #include <pthread.h>
0009
0010 #include "../kselftest.h"
0011
0012 static int sys_membarrier(int cmd, int flags)
0013 {
0014 return syscall(__NR_membarrier, cmd, flags);
0015 }
0016
0017 static int test_membarrier_cmd_fail(void)
0018 {
0019 int cmd = -1, flags = 0;
0020 const char *test_name = "sys membarrier invalid command";
0021
0022 if (sys_membarrier(cmd, flags) != -1) {
0023 ksft_exit_fail_msg(
0024 "%s test: command = %d, flags = %d. Should fail, but passed\n",
0025 test_name, cmd, flags);
0026 }
0027 if (errno != EINVAL) {
0028 ksft_exit_fail_msg(
0029 "%s test: flags = %d. Should return (%d: \"%s\"), but returned (%d: \"%s\").\n",
0030 test_name, flags, EINVAL, strerror(EINVAL),
0031 errno, strerror(errno));
0032 }
0033
0034 ksft_test_result_pass(
0035 "%s test: command = %d, flags = %d, errno = %d. Failed as expected\n",
0036 test_name, cmd, flags, errno);
0037 return 0;
0038 }
0039
0040 static int test_membarrier_flags_fail(void)
0041 {
0042 int cmd = MEMBARRIER_CMD_QUERY, flags = 1;
0043 const char *test_name = "sys membarrier MEMBARRIER_CMD_QUERY invalid flags";
0044
0045 if (sys_membarrier(cmd, flags) != -1) {
0046 ksft_exit_fail_msg(
0047 "%s test: flags = %d. Should fail, but passed\n",
0048 test_name, flags);
0049 }
0050 if (errno != EINVAL) {
0051 ksft_exit_fail_msg(
0052 "%s test: flags = %d. Should return (%d: \"%s\"), but returned (%d: \"%s\").\n",
0053 test_name, flags, EINVAL, strerror(EINVAL),
0054 errno, strerror(errno));
0055 }
0056
0057 ksft_test_result_pass(
0058 "%s test: flags = %d, errno = %d. Failed as expected\n",
0059 test_name, flags, errno);
0060 return 0;
0061 }
0062
0063 static int test_membarrier_global_success(void)
0064 {
0065 int cmd = MEMBARRIER_CMD_GLOBAL, flags = 0;
0066 const char *test_name = "sys membarrier MEMBARRIER_CMD_GLOBAL";
0067
0068 if (sys_membarrier(cmd, flags) != 0) {
0069 ksft_exit_fail_msg(
0070 "%s test: flags = %d, errno = %d\n",
0071 test_name, flags, errno);
0072 }
0073
0074 ksft_test_result_pass(
0075 "%s test: flags = %d\n", test_name, flags);
0076 return 0;
0077 }
0078
0079 static int test_membarrier_private_expedited_fail(void)
0080 {
0081 int cmd = MEMBARRIER_CMD_PRIVATE_EXPEDITED, flags = 0;
0082 const char *test_name = "sys membarrier MEMBARRIER_CMD_PRIVATE_EXPEDITED not registered failure";
0083
0084 if (sys_membarrier(cmd, flags) != -1) {
0085 ksft_exit_fail_msg(
0086 "%s test: flags = %d. Should fail, but passed\n",
0087 test_name, flags);
0088 }
0089 if (errno != EPERM) {
0090 ksft_exit_fail_msg(
0091 "%s test: flags = %d. Should return (%d: \"%s\"), but returned (%d: \"%s\").\n",
0092 test_name, flags, EPERM, strerror(EPERM),
0093 errno, strerror(errno));
0094 }
0095
0096 ksft_test_result_pass(
0097 "%s test: flags = %d, errno = %d\n",
0098 test_name, flags, errno);
0099 return 0;
0100 }
0101
0102 static int test_membarrier_register_private_expedited_success(void)
0103 {
0104 int cmd = MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED, flags = 0;
0105 const char *test_name = "sys membarrier MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED";
0106
0107 if (sys_membarrier(cmd, flags) != 0) {
0108 ksft_exit_fail_msg(
0109 "%s test: flags = %d, errno = %d\n",
0110 test_name, flags, errno);
0111 }
0112
0113 ksft_test_result_pass(
0114 "%s test: flags = %d\n",
0115 test_name, flags);
0116 return 0;
0117 }
0118
0119 static int test_membarrier_private_expedited_success(void)
0120 {
0121 int cmd = MEMBARRIER_CMD_PRIVATE_EXPEDITED, flags = 0;
0122 const char *test_name = "sys membarrier MEMBARRIER_CMD_PRIVATE_EXPEDITED";
0123
0124 if (sys_membarrier(cmd, flags) != 0) {
0125 ksft_exit_fail_msg(
0126 "%s test: flags = %d, errno = %d\n",
0127 test_name, flags, errno);
0128 }
0129
0130 ksft_test_result_pass(
0131 "%s test: flags = %d\n",
0132 test_name, flags);
0133 return 0;
0134 }
0135
0136 static int test_membarrier_private_expedited_sync_core_fail(void)
0137 {
0138 int cmd = MEMBARRIER_CMD_PRIVATE_EXPEDITED_SYNC_CORE, flags = 0;
0139 const char *test_name = "sys membarrier MEMBARRIER_CMD_PRIVATE_EXPEDITED_SYNC_CORE not registered failure";
0140
0141 if (sys_membarrier(cmd, flags) != -1) {
0142 ksft_exit_fail_msg(
0143 "%s test: flags = %d. Should fail, but passed\n",
0144 test_name, flags);
0145 }
0146 if (errno != EPERM) {
0147 ksft_exit_fail_msg(
0148 "%s test: flags = %d. Should return (%d: \"%s\"), but returned (%d: \"%s\").\n",
0149 test_name, flags, EPERM, strerror(EPERM),
0150 errno, strerror(errno));
0151 }
0152
0153 ksft_test_result_pass(
0154 "%s test: flags = %d, errno = %d\n",
0155 test_name, flags, errno);
0156 return 0;
0157 }
0158
0159 static int test_membarrier_register_private_expedited_sync_core_success(void)
0160 {
0161 int cmd = MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED_SYNC_CORE, flags = 0;
0162 const char *test_name = "sys membarrier MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED_SYNC_CORE";
0163
0164 if (sys_membarrier(cmd, flags) != 0) {
0165 ksft_exit_fail_msg(
0166 "%s test: flags = %d, errno = %d\n",
0167 test_name, flags, errno);
0168 }
0169
0170 ksft_test_result_pass(
0171 "%s test: flags = %d\n",
0172 test_name, flags);
0173 return 0;
0174 }
0175
0176 static int test_membarrier_private_expedited_sync_core_success(void)
0177 {
0178 int cmd = MEMBARRIER_CMD_PRIVATE_EXPEDITED, flags = 0;
0179 const char *test_name = "sys membarrier MEMBARRIER_CMD_PRIVATE_EXPEDITED_SYNC_CORE";
0180
0181 if (sys_membarrier(cmd, flags) != 0) {
0182 ksft_exit_fail_msg(
0183 "%s test: flags = %d, errno = %d\n",
0184 test_name, flags, errno);
0185 }
0186
0187 ksft_test_result_pass(
0188 "%s test: flags = %d\n",
0189 test_name, flags);
0190 return 0;
0191 }
0192
0193 static int test_membarrier_register_global_expedited_success(void)
0194 {
0195 int cmd = MEMBARRIER_CMD_REGISTER_GLOBAL_EXPEDITED, flags = 0;
0196 const char *test_name = "sys membarrier MEMBARRIER_CMD_REGISTER_GLOBAL_EXPEDITED";
0197
0198 if (sys_membarrier(cmd, flags) != 0) {
0199 ksft_exit_fail_msg(
0200 "%s test: flags = %d, errno = %d\n",
0201 test_name, flags, errno);
0202 }
0203
0204 ksft_test_result_pass(
0205 "%s test: flags = %d\n",
0206 test_name, flags);
0207 return 0;
0208 }
0209
0210 static int test_membarrier_global_expedited_success(void)
0211 {
0212 int cmd = MEMBARRIER_CMD_GLOBAL_EXPEDITED, flags = 0;
0213 const char *test_name = "sys membarrier MEMBARRIER_CMD_GLOBAL_EXPEDITED";
0214
0215 if (sys_membarrier(cmd, flags) != 0) {
0216 ksft_exit_fail_msg(
0217 "%s test: flags = %d, errno = %d\n",
0218 test_name, flags, errno);
0219 }
0220
0221 ksft_test_result_pass(
0222 "%s test: flags = %d\n",
0223 test_name, flags);
0224 return 0;
0225 }
0226
0227 static int test_membarrier_fail(void)
0228 {
0229 int status;
0230
0231 status = test_membarrier_cmd_fail();
0232 if (status)
0233 return status;
0234 status = test_membarrier_flags_fail();
0235 if (status)
0236 return status;
0237 status = test_membarrier_private_expedited_fail();
0238 if (status)
0239 return status;
0240 status = sys_membarrier(MEMBARRIER_CMD_QUERY, 0);
0241 if (status < 0) {
0242 ksft_test_result_fail("sys_membarrier() failed\n");
0243 return status;
0244 }
0245 if (status & MEMBARRIER_CMD_PRIVATE_EXPEDITED_SYNC_CORE) {
0246 status = test_membarrier_private_expedited_sync_core_fail();
0247 if (status)
0248 return status;
0249 }
0250 return 0;
0251 }
0252
0253 static int test_membarrier_success(void)
0254 {
0255 int status;
0256
0257 status = test_membarrier_global_success();
0258 if (status)
0259 return status;
0260 status = test_membarrier_register_private_expedited_success();
0261 if (status)
0262 return status;
0263 status = test_membarrier_private_expedited_success();
0264 if (status)
0265 return status;
0266 status = sys_membarrier(MEMBARRIER_CMD_QUERY, 0);
0267 if (status < 0) {
0268 ksft_test_result_fail("sys_membarrier() failed\n");
0269 return status;
0270 }
0271 if (status & MEMBARRIER_CMD_PRIVATE_EXPEDITED_SYNC_CORE) {
0272 status = test_membarrier_register_private_expedited_sync_core_success();
0273 if (status)
0274 return status;
0275 status = test_membarrier_private_expedited_sync_core_success();
0276 if (status)
0277 return status;
0278 }
0279
0280
0281
0282
0283 status = test_membarrier_global_expedited_success();
0284 if (status)
0285 return status;
0286 status = test_membarrier_register_global_expedited_success();
0287 if (status)
0288 return status;
0289 status = test_membarrier_global_expedited_success();
0290 if (status)
0291 return status;
0292 return 0;
0293 }
0294
0295 static int test_membarrier_query(void)
0296 {
0297 int flags = 0, ret;
0298
0299 ret = sys_membarrier(MEMBARRIER_CMD_QUERY, flags);
0300 if (ret < 0) {
0301 if (errno == ENOSYS) {
0302
0303
0304
0305
0306 ksft_exit_skip(
0307 "sys membarrier (CONFIG_MEMBARRIER) is disabled.\n");
0308 }
0309 ksft_exit_fail_msg("sys_membarrier() failed\n");
0310 }
0311 if (!(ret & MEMBARRIER_CMD_GLOBAL))
0312 ksft_exit_skip(
0313 "sys_membarrier unsupported: CMD_GLOBAL not found.\n");
0314
0315 ksft_test_result_pass("sys_membarrier available\n");
0316 return 0;
0317 }