cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

membarrier_test_impl.h (8218B)


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