brintos

brintos / linux-shallow public Read only

0
0
Text · 8.8 KiB · af89855 Raw
351 lines · c
1/* SPDX-License-Identifier: GPL-2.0 */2#define _GNU_SOURCE3#include <linux/membarrier.h>4#include <syscall.h>5#include <stdio.h>6#include <errno.h>7#include <string.h>8#include <pthread.h>9 10#include "../kselftest.h"11 12static int registrations;13 14static int sys_membarrier(int cmd, int flags)15{16	return syscall(__NR_membarrier, cmd, flags);17}18 19static int test_membarrier_get_registrations(int cmd)20{21	int ret, flags = 0;22	const char *test_name =23		"sys membarrier MEMBARRIER_CMD_GET_REGISTRATIONS";24 25	registrations |= cmd;26 27	ret = sys_membarrier(MEMBARRIER_CMD_GET_REGISTRATIONS, 0);28	if (ret < 0) {29		ksft_exit_fail_msg(30			"%s test: flags = %d, errno = %d\n",31			test_name, flags, errno);32	} else if (ret != registrations) {33		ksft_exit_fail_msg(34			"%s test: flags = %d, ret = %d, registrations = %d\n",35			test_name, flags, ret, registrations);36	}37	ksft_test_result_pass(38		"%s test: flags = %d, ret = %d, registrations = %d\n",39		test_name, flags, ret, registrations);40 41	return 0;42}43 44static int test_membarrier_cmd_fail(void)45{46	int cmd = -1, flags = 0;47	const char *test_name = "sys membarrier invalid command";48 49	if (sys_membarrier(cmd, flags) != -1) {50		ksft_exit_fail_msg(51			"%s test: command = %d, flags = %d. Should fail, but passed\n",52			test_name, cmd, flags);53	}54	if (errno != EINVAL) {55		ksft_exit_fail_msg(56			"%s test: flags = %d. Should return (%d: \"%s\"), but returned (%d: \"%s\").\n",57			test_name, flags, EINVAL, strerror(EINVAL),58			errno, strerror(errno));59	}60 61	ksft_test_result_pass(62		"%s test: command = %d, flags = %d, errno = %d. Failed as expected\n",63		test_name, cmd, flags, errno);64	return 0;65}66 67static int test_membarrier_flags_fail(void)68{69	int cmd = MEMBARRIER_CMD_QUERY, flags = 1;70	const char *test_name = "sys membarrier MEMBARRIER_CMD_QUERY invalid flags";71 72	if (sys_membarrier(cmd, flags) != -1) {73		ksft_exit_fail_msg(74			"%s test: flags = %d. Should fail, but passed\n",75			test_name, flags);76	}77	if (errno != EINVAL) {78		ksft_exit_fail_msg(79			"%s test: flags = %d. Should return (%d: \"%s\"), but returned (%d: \"%s\").\n",80			test_name, flags, EINVAL, strerror(EINVAL),81			errno, strerror(errno));82	}83 84	ksft_test_result_pass(85		"%s test: flags = %d, errno = %d. Failed as expected\n",86		test_name, flags, errno);87	return 0;88}89 90static int test_membarrier_global_success(void)91{92	int cmd = MEMBARRIER_CMD_GLOBAL, flags = 0;93	const char *test_name = "sys membarrier MEMBARRIER_CMD_GLOBAL";94 95	if (sys_membarrier(cmd, flags) != 0) {96		ksft_exit_fail_msg(97			"%s test: flags = %d, errno = %d\n",98			test_name, flags, errno);99	}100 101	ksft_test_result_pass(102		"%s test: flags = %d\n", test_name, flags);103	return 0;104}105 106static int test_membarrier_private_expedited_fail(void)107{108	int cmd = MEMBARRIER_CMD_PRIVATE_EXPEDITED, flags = 0;109	const char *test_name = "sys membarrier MEMBARRIER_CMD_PRIVATE_EXPEDITED not registered failure";110 111	if (sys_membarrier(cmd, flags) != -1) {112		ksft_exit_fail_msg(113			"%s test: flags = %d. Should fail, but passed\n",114			test_name, flags);115	}116	if (errno != EPERM) {117		ksft_exit_fail_msg(118			"%s test: flags = %d. Should return (%d: \"%s\"), but returned (%d: \"%s\").\n",119			test_name, flags, EPERM, strerror(EPERM),120			errno, strerror(errno));121	}122 123	ksft_test_result_pass(124		"%s test: flags = %d, errno = %d\n",125		test_name, flags, errno);126	return 0;127}128 129static int test_membarrier_register_private_expedited_success(void)130{131	int cmd = MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED, flags = 0;132	const char *test_name = "sys membarrier MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED";133 134	if (sys_membarrier(cmd, flags) != 0) {135		ksft_exit_fail_msg(136			"%s test: flags = %d, errno = %d\n",137			test_name, flags, errno);138	}139 140	ksft_test_result_pass(141		"%s test: flags = %d\n",142		test_name, flags);143 144	test_membarrier_get_registrations(cmd);145	return 0;146}147 148static int test_membarrier_private_expedited_success(void)149{150	int cmd = MEMBARRIER_CMD_PRIVATE_EXPEDITED, flags = 0;151	const char *test_name = "sys membarrier MEMBARRIER_CMD_PRIVATE_EXPEDITED";152 153	if (sys_membarrier(cmd, flags) != 0) {154		ksft_exit_fail_msg(155			"%s test: flags = %d, errno = %d\n",156			test_name, flags, errno);157	}158 159	ksft_test_result_pass(160		"%s test: flags = %d\n",161		test_name, flags);162	return 0;163}164 165static int test_membarrier_private_expedited_sync_core_fail(void)166{167	int cmd = MEMBARRIER_CMD_PRIVATE_EXPEDITED_SYNC_CORE, flags = 0;168	const char *test_name = "sys membarrier MEMBARRIER_CMD_PRIVATE_EXPEDITED_SYNC_CORE not registered failure";169 170	if (sys_membarrier(cmd, flags) != -1) {171		ksft_exit_fail_msg(172			"%s test: flags = %d. Should fail, but passed\n",173			test_name, flags);174	}175	if (errno != EPERM) {176		ksft_exit_fail_msg(177			"%s test: flags = %d. Should return (%d: \"%s\"), but returned (%d: \"%s\").\n",178			test_name, flags, EPERM, strerror(EPERM),179			errno, strerror(errno));180	}181 182	ksft_test_result_pass(183		"%s test: flags = %d, errno = %d\n",184		test_name, flags, errno);185	return 0;186}187 188static int test_membarrier_register_private_expedited_sync_core_success(void)189{190	int cmd = MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED_SYNC_CORE, flags = 0;191	const char *test_name = "sys membarrier MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED_SYNC_CORE";192 193	if (sys_membarrier(cmd, flags) != 0) {194		ksft_exit_fail_msg(195			"%s test: flags = %d, errno = %d\n",196			test_name, flags, errno);197	}198 199	ksft_test_result_pass(200		"%s test: flags = %d\n",201		test_name, flags);202 203	test_membarrier_get_registrations(cmd);204	return 0;205}206 207static int test_membarrier_private_expedited_sync_core_success(void)208{209	int cmd = MEMBARRIER_CMD_PRIVATE_EXPEDITED, flags = 0;210	const char *test_name = "sys membarrier MEMBARRIER_CMD_PRIVATE_EXPEDITED_SYNC_CORE";211 212	if (sys_membarrier(cmd, flags) != 0) {213		ksft_exit_fail_msg(214			"%s test: flags = %d, errno = %d\n",215			test_name, flags, errno);216	}217 218	ksft_test_result_pass(219		"%s test: flags = %d\n",220		test_name, flags);221	return 0;222}223 224static int test_membarrier_register_global_expedited_success(void)225{226	int cmd = MEMBARRIER_CMD_REGISTER_GLOBAL_EXPEDITED, flags = 0;227	const char *test_name = "sys membarrier MEMBARRIER_CMD_REGISTER_GLOBAL_EXPEDITED";228 229	if (sys_membarrier(cmd, flags) != 0) {230		ksft_exit_fail_msg(231			"%s test: flags = %d, errno = %d\n",232			test_name, flags, errno);233	}234 235	ksft_test_result_pass(236		"%s test: flags = %d\n",237		test_name, flags);238 239	test_membarrier_get_registrations(cmd);240	return 0;241}242 243static int test_membarrier_global_expedited_success(void)244{245	int cmd = MEMBARRIER_CMD_GLOBAL_EXPEDITED, flags = 0;246	const char *test_name = "sys membarrier MEMBARRIER_CMD_GLOBAL_EXPEDITED";247 248	if (sys_membarrier(cmd, flags) != 0) {249		ksft_exit_fail_msg(250			"%s test: flags = %d, errno = %d\n",251			test_name, flags, errno);252	}253 254	ksft_test_result_pass(255		"%s test: flags = %d\n",256		test_name, flags);257	return 0;258}259 260static int test_membarrier_fail(void)261{262	int status;263 264	status = test_membarrier_cmd_fail();265	if (status)266		return status;267	status = test_membarrier_flags_fail();268	if (status)269		return status;270	status = test_membarrier_private_expedited_fail();271	if (status)272		return status;273	status = sys_membarrier(MEMBARRIER_CMD_QUERY, 0);274	if (status < 0) {275		ksft_test_result_fail("sys_membarrier() failed\n");276		return status;277	}278	if (status & MEMBARRIER_CMD_PRIVATE_EXPEDITED_SYNC_CORE) {279		status = test_membarrier_private_expedited_sync_core_fail();280		if (status)281			return status;282	}283	return 0;284}285 286static int test_membarrier_success(void)287{288	int status;289 290	status = test_membarrier_global_success();291	if (status)292		return status;293	status = test_membarrier_register_private_expedited_success();294	if (status)295		return status;296	status = test_membarrier_private_expedited_success();297	if (status)298		return status;299	status = sys_membarrier(MEMBARRIER_CMD_QUERY, 0);300	if (status < 0) {301		ksft_test_result_fail("sys_membarrier() failed\n");302		return status;303	}304	if (status & MEMBARRIER_CMD_PRIVATE_EXPEDITED_SYNC_CORE) {305		status = test_membarrier_register_private_expedited_sync_core_success();306		if (status)307			return status;308		status = test_membarrier_private_expedited_sync_core_success();309		if (status)310			return status;311	}312	/*313	 * It is valid to send a global membarrier from a non-registered314	 * process.315	 */316	status = test_membarrier_global_expedited_success();317	if (status)318		return status;319	status = test_membarrier_register_global_expedited_success();320	if (status)321		return status;322	status = test_membarrier_global_expedited_success();323	if (status)324		return status;325	return 0;326}327 328static int test_membarrier_query(void)329{330	int flags = 0, ret;331 332	ret = sys_membarrier(MEMBARRIER_CMD_QUERY, flags);333	if (ret < 0) {334		if (errno == ENOSYS) {335			/*336			 * It is valid to build a kernel with337			 * CONFIG_MEMBARRIER=n. However, this skips the tests.338			 */339			ksft_exit_skip(340				"sys membarrier (CONFIG_MEMBARRIER) is disabled.\n");341		}342		ksft_exit_fail_msg("sys_membarrier() failed\n");343	}344	if (!(ret & MEMBARRIER_CMD_GLOBAL))345		ksft_exit_skip(346			"sys_membarrier unsupported: CMD_GLOBAL not found.\n");347 348	ksft_test_result_pass("sys_membarrier available\n");349	return 0;350}351