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

api-io.c (5472B)


      1// SPDX-License-Identifier: GPL-2.0-only
      2#include <sys/types.h>
      3#include <sys/stat.h>
      4#include <fcntl.h>
      5#include <limits.h>
      6#include <stdio.h>
      7#include <stdlib.h>
      8#include <string.h>
      9#include <unistd.h>
     10
     11#include "debug.h"
     12#include "tests.h"
     13#include <api/io.h>
     14#include <linux/kernel.h>
     15
     16#define TEMPL "/tmp/perf-test-XXXXXX"
     17
     18#define EXPECT_EQUAL(val, expected)                             \
     19do {								\
     20	if (val != expected) {					\
     21		pr_debug("%s:%d: %d != %d\n",			\
     22			__FILE__, __LINE__, val, expected);	\
     23		ret = -1;					\
     24	}							\
     25} while (0)
     26
     27#define EXPECT_EQUAL64(val, expected)                           \
     28do {								\
     29	if (val != expected) {					\
     30		pr_debug("%s:%d: %lld != %lld\n",		\
     31			__FILE__, __LINE__, val, expected);	\
     32		ret = -1;					\
     33	}							\
     34} while (0)
     35
     36static int make_test_file(char path[PATH_MAX], const char *contents)
     37{
     38	ssize_t contents_len = strlen(contents);
     39	int fd;
     40
     41	strcpy(path, TEMPL);
     42	fd = mkstemp(path);
     43	if (fd < 0) {
     44		pr_debug("mkstemp failed");
     45		return -1;
     46	}
     47	if (write(fd, contents, contents_len) < contents_len) {
     48		pr_debug("short write");
     49		close(fd);
     50		unlink(path);
     51		return -1;
     52	}
     53	close(fd);
     54	return 0;
     55}
     56
     57static int setup_test(char path[PATH_MAX], const char *contents,
     58		      size_t buf_size, struct io *io)
     59{
     60	if (make_test_file(path, contents))
     61		return -1;
     62
     63	io->fd = open(path, O_RDONLY);
     64	if (io->fd < 0) {
     65		pr_debug("Failed to open '%s'\n", path);
     66		unlink(path);
     67		return -1;
     68	}
     69	io->buf = malloc(buf_size);
     70	if (io->buf == NULL) {
     71		pr_debug("Failed to allocate memory");
     72		close(io->fd);
     73		unlink(path);
     74		return -1;
     75	}
     76	io__init(io, io->fd, io->buf, buf_size);
     77	return 0;
     78}
     79
     80static void cleanup_test(char path[PATH_MAX], struct io *io)
     81{
     82	free(io->buf);
     83	close(io->fd);
     84	unlink(path);
     85}
     86
     87static int do_test_get_char(const char *test_string, size_t buf_size)
     88{
     89	char path[PATH_MAX];
     90	struct io io;
     91	int ch, ret = 0;
     92	size_t i;
     93
     94	if (setup_test(path, test_string, buf_size, &io))
     95		return -1;
     96
     97	for (i = 0; i < strlen(test_string); i++) {
     98		ch = io__get_char(&io);
     99
    100		EXPECT_EQUAL(ch, test_string[i]);
    101		EXPECT_EQUAL(io.eof, false);
    102	}
    103	ch = io__get_char(&io);
    104	EXPECT_EQUAL(ch, -1);
    105	EXPECT_EQUAL(io.eof, true);
    106
    107	cleanup_test(path, &io);
    108	return ret;
    109}
    110
    111static int test_get_char(void)
    112{
    113	int i, ret = 0;
    114	size_t j;
    115
    116	static const char *const test_strings[] = {
    117		"12345678abcdef90",
    118		"a\nb\nc\nd\n",
    119		"\a\b\t\v\f\r",
    120	};
    121	for (i = 0; i <= 10; i++) {
    122		for (j = 0; j < ARRAY_SIZE(test_strings); j++) {
    123			if (do_test_get_char(test_strings[j], 1 << i))
    124				ret = -1;
    125		}
    126	}
    127	return ret;
    128}
    129
    130static int do_test_get_hex(const char *test_string,
    131			__u64 val1, int ch1,
    132			__u64 val2, int ch2,
    133			__u64 val3, int ch3,
    134			bool end_eof)
    135{
    136	char path[PATH_MAX];
    137	struct io io;
    138	int ch, ret = 0;
    139	__u64 hex;
    140
    141	if (setup_test(path, test_string, 4, &io))
    142		return -1;
    143
    144	ch = io__get_hex(&io, &hex);
    145	EXPECT_EQUAL64(hex, val1);
    146	EXPECT_EQUAL(ch, ch1);
    147
    148	ch = io__get_hex(&io, &hex);
    149	EXPECT_EQUAL64(hex, val2);
    150	EXPECT_EQUAL(ch, ch2);
    151
    152	ch = io__get_hex(&io, &hex);
    153	EXPECT_EQUAL64(hex, val3);
    154	EXPECT_EQUAL(ch, ch3);
    155
    156	EXPECT_EQUAL(io.eof, end_eof);
    157
    158	cleanup_test(path, &io);
    159	return ret;
    160}
    161
    162static int test_get_hex(void)
    163{
    164	int ret = 0;
    165
    166	if (do_test_get_hex("12345678abcdef90",
    167				0x12345678abcdef90, -1,
    168				0, -1,
    169				0, -1,
    170				true))
    171		ret = -1;
    172
    173	if (do_test_get_hex("1\n2\n3\n",
    174				1, '\n',
    175				2, '\n',
    176				3, '\n',
    177				false))
    178		ret = -1;
    179
    180	if (do_test_get_hex("12345678ABCDEF90;a;b",
    181				0x12345678abcdef90, ';',
    182				0xa, ';',
    183				0xb, -1,
    184				true))
    185		ret = -1;
    186
    187	if (do_test_get_hex("0x1x2x",
    188				0, 'x',
    189				1, 'x',
    190				2, 'x',
    191				false))
    192		ret = -1;
    193
    194	if (do_test_get_hex("x1x",
    195				0, -2,
    196				1, 'x',
    197				0, -1,
    198				true))
    199		ret = -1;
    200
    201	if (do_test_get_hex("10000000000000000000000000000abcdefgh99i",
    202				0xabcdef, 'g',
    203				0, -2,
    204				0x99, 'i',
    205				false))
    206		ret = -1;
    207
    208	return ret;
    209}
    210
    211static int do_test_get_dec(const char *test_string,
    212			__u64 val1, int ch1,
    213			__u64 val2, int ch2,
    214			__u64 val3, int ch3,
    215			bool end_eof)
    216{
    217	char path[PATH_MAX];
    218	struct io io;
    219	int ch, ret = 0;
    220	__u64 dec;
    221
    222	if (setup_test(path, test_string, 4, &io))
    223		return -1;
    224
    225	ch = io__get_dec(&io, &dec);
    226	EXPECT_EQUAL64(dec, val1);
    227	EXPECT_EQUAL(ch, ch1);
    228
    229	ch = io__get_dec(&io, &dec);
    230	EXPECT_EQUAL64(dec, val2);
    231	EXPECT_EQUAL(ch, ch2);
    232
    233	ch = io__get_dec(&io, &dec);
    234	EXPECT_EQUAL64(dec, val3);
    235	EXPECT_EQUAL(ch, ch3);
    236
    237	EXPECT_EQUAL(io.eof, end_eof);
    238
    239	cleanup_test(path, &io);
    240	return ret;
    241}
    242
    243static int test_get_dec(void)
    244{
    245	int ret = 0;
    246
    247	if (do_test_get_dec("12345678abcdef90",
    248				12345678, 'a',
    249				0, -2,
    250				0, -2,
    251				false))
    252		ret = -1;
    253
    254	if (do_test_get_dec("1\n2\n3\n",
    255				1, '\n',
    256				2, '\n',
    257				3, '\n',
    258				false))
    259		ret = -1;
    260
    261	if (do_test_get_dec("12345678;1;2",
    262				12345678, ';',
    263				1, ';',
    264				2, -1,
    265				true))
    266		ret = -1;
    267
    268	if (do_test_get_dec("0x1x2x",
    269				0, 'x',
    270				1, 'x',
    271				2, 'x',
    272				false))
    273		ret = -1;
    274
    275	if (do_test_get_dec("x1x",
    276				0, -2,
    277				1, 'x',
    278				0, -1,
    279				true))
    280		ret = -1;
    281
    282	if (do_test_get_dec("10000000000000000000000000000000000000000000000000000000000123456789ab99c",
    283				123456789, 'a',
    284				0, -2,
    285				99, 'c',
    286				false))
    287		ret = -1;
    288
    289	return ret;
    290}
    291
    292static int test__api_io(struct test_suite *test __maybe_unused,
    293			int subtest __maybe_unused)
    294{
    295	int ret = 0;
    296
    297	if (test_get_char())
    298		ret = TEST_FAIL;
    299	if (test_get_hex())
    300		ret = TEST_FAIL;
    301	if (test_get_dec())
    302		ret = TEST_FAIL;
    303	return ret;
    304}
    305
    306DEFINE_SUITE("Test api io", api_io);