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

fdarray.c (4296B)


      1// SPDX-License-Identifier: GPL-2.0
      2#include <api/fd/array.h>
      3#include <poll.h>
      4#include "util/debug.h"
      5#include "tests/tests.h"
      6
      7static void fdarray__init_revents(struct fdarray *fda, short revents)
      8{
      9	int fd;
     10
     11	fda->nr = fda->nr_alloc;
     12
     13	for (fd = 0; fd < fda->nr; ++fd) {
     14		fda->entries[fd].fd	 = fda->nr - fd;
     15		fda->entries[fd].events  = revents;
     16		fda->entries[fd].revents = revents;
     17	}
     18}
     19
     20static int fdarray__fprintf_prefix(struct fdarray *fda, const char *prefix, FILE *fp)
     21{
     22	int printed = 0;
     23
     24	if (verbose <= 0)
     25		return 0;
     26
     27	printed += fprintf(fp, "\n%s: ", prefix);
     28	return printed + fdarray__fprintf(fda, fp);
     29}
     30
     31static int test__fdarray__filter(struct test_suite *test __maybe_unused, int subtest __maybe_unused)
     32{
     33	int nr_fds, err = TEST_FAIL;
     34	struct fdarray *fda = fdarray__new(5, 5);
     35
     36	if (fda == NULL) {
     37		pr_debug("\nfdarray__new() failed!");
     38		goto out;
     39	}
     40
     41	fdarray__init_revents(fda, POLLIN);
     42	nr_fds = fdarray__filter(fda, POLLHUP, NULL, NULL);
     43	if (nr_fds != fda->nr_alloc) {
     44		pr_debug("\nfdarray__filter()=%d != %d shouldn't have filtered anything",
     45			 nr_fds, fda->nr_alloc);
     46		goto out_delete;
     47	}
     48
     49	fdarray__init_revents(fda, POLLHUP);
     50	nr_fds = fdarray__filter(fda, POLLHUP, NULL, NULL);
     51	if (nr_fds != 0) {
     52		pr_debug("\nfdarray__filter()=%d != %d, should have filtered all fds",
     53			 nr_fds, fda->nr_alloc);
     54		goto out_delete;
     55	}
     56
     57	fdarray__init_revents(fda, POLLHUP);
     58	fda->entries[2].revents = POLLIN;
     59
     60	pr_debug("\nfiltering all but fda->entries[2]:");
     61	fdarray__fprintf_prefix(fda, "before", stderr);
     62	nr_fds = fdarray__filter(fda, POLLHUP, NULL, NULL);
     63	fdarray__fprintf_prefix(fda, " after", stderr);
     64	if (nr_fds != 1) {
     65		pr_debug("\nfdarray__filter()=%d != 1, should have left just one event", nr_fds);
     66		goto out_delete;
     67	}
     68
     69	fdarray__init_revents(fda, POLLHUP);
     70	fda->entries[0].revents = POLLIN;
     71	fda->entries[3].revents = POLLIN;
     72
     73	pr_debug("\nfiltering all but (fda->entries[0], fda->entries[3]):");
     74	fdarray__fprintf_prefix(fda, "before", stderr);
     75	nr_fds = fdarray__filter(fda, POLLHUP, NULL, NULL);
     76	fdarray__fprintf_prefix(fda, " after", stderr);
     77	if (nr_fds != 2) {
     78		pr_debug("\nfdarray__filter()=%d != 2, should have left just two events",
     79			 nr_fds);
     80		goto out_delete;
     81	}
     82
     83	pr_debug("\n");
     84
     85	err = 0;
     86out_delete:
     87	fdarray__delete(fda);
     88out:
     89	return err;
     90}
     91
     92static int test__fdarray__add(struct test_suite *test __maybe_unused, int subtest __maybe_unused)
     93{
     94	int err = TEST_FAIL;
     95	struct fdarray *fda = fdarray__new(2, 2);
     96
     97	if (fda == NULL) {
     98		pr_debug("\nfdarray__new() failed!");
     99		goto out;
    100	}
    101
    102#define FDA_CHECK(_idx, _fd, _revents)					   \
    103	if (fda->entries[_idx].fd != _fd) {				   \
    104		pr_debug("\n%d: fda->entries[%d](%d) != %d!",		   \
    105			 __LINE__, _idx, fda->entries[1].fd, _fd);	   \
    106		goto out_delete;					   \
    107	}								   \
    108	if (fda->entries[_idx].events != (_revents)) {			   \
    109		pr_debug("\n%d: fda->entries[%d].revents(%d) != %d!",	   \
    110			 __LINE__, _idx, fda->entries[_idx].fd, _revents); \
    111		goto out_delete;					   \
    112	}
    113
    114#define FDA_ADD(_idx, _fd, _revents, _nr)				   \
    115	if (fdarray__add(fda, _fd, _revents, fdarray_flag__default) < 0) { \
    116		pr_debug("\n%d: fdarray__add(fda, %d, %d) failed!",	   \
    117			 __LINE__,_fd, _revents);			   \
    118		goto out_delete;					   \
    119	}								   \
    120	if (fda->nr != _nr) {						   \
    121		pr_debug("\n%d: fdarray__add(fda, %d, %d)=%d != %d",	   \
    122			 __LINE__,_fd, _revents, fda->nr, _nr);		   \
    123		goto out_delete;					   \
    124	}								   \
    125	FDA_CHECK(_idx, _fd, _revents)
    126
    127	FDA_ADD(0, 1, POLLIN, 1);
    128	FDA_ADD(1, 2, POLLERR, 2);
    129
    130	fdarray__fprintf_prefix(fda, "before growing array", stderr);
    131
    132	FDA_ADD(2, 35, POLLHUP, 3);
    133
    134	if (fda->entries == NULL) {
    135		pr_debug("\nfdarray__add(fda, 35, POLLHUP) should have allocated fda->pollfd!");
    136		goto out_delete;
    137	}
    138
    139	fdarray__fprintf_prefix(fda, "after 3rd add", stderr);
    140
    141	FDA_ADD(3, 88, POLLIN | POLLOUT, 4);
    142
    143	fdarray__fprintf_prefix(fda, "after 4th add", stderr);
    144
    145	FDA_CHECK(0, 1, POLLIN);
    146	FDA_CHECK(1, 2, POLLERR);
    147	FDA_CHECK(2, 35, POLLHUP);
    148	FDA_CHECK(3, 88, POLLIN | POLLOUT);
    149
    150#undef FDA_ADD
    151#undef FDA_CHECK
    152
    153	pr_debug("\n");
    154
    155	err = 0;
    156out_delete:
    157	fdarray__delete(fda);
    158out:
    159	return err;
    160}
    161
    162DEFINE_SUITE("Filter fds with revents mask in a fdarray", fdarray__filter);
    163DEFINE_SUITE("Add fd to a fdarray, making it autogrow", fdarray__add);