Skip to content

Commit

Permalink
selftests/x86/syscall: Simplify message reporting in syscall_numbering
Browse files Browse the repository at this point in the history
Reduce some boiler plate in printing and indenting messages.
This makes it easier to produce clean status output.

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Link: https://lore.kernel.org/r/20210518191303.4135296-3-hpa@zytor.com
  • Loading branch information
H. Peter Anvin (Intel) authored and Thomas Gleixner committed May 20, 2021
1 parent 15c82d9 commit c5c3948
Showing 1 changed file with 72 additions and 31 deletions.
103 changes: 72 additions & 31 deletions tools/testing/selftests/x86/syscall_numbering.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
#include <string.h>
#include <fcntl.h>
#include <limits.h>
#include <sysexits.h>

/* Common system call numbers */
#define SYS_READ 0
Expand All @@ -34,6 +35,33 @@

static unsigned int nerr = 0; /* Cumulative error count */
static int nullfd = -1; /* File descriptor for /dev/null */
static int indent = 0;

static inline unsigned int offset(void)
{
return 8 + indent * 4;
}

#define msg(lvl, fmt, ...) printf("%-*s" fmt, offset(), "[" #lvl "]", \
## __VA_ARGS__)

#define run(fmt, ...) msg(RUN, fmt, ## __VA_ARGS__)
#define info(fmt, ...) msg(INFO, fmt, ## __VA_ARGS__)
#define ok(fmt, ...) msg(OK, fmt, ## __VA_ARGS__)

#define fail(fmt, ...) \
do { \
msg(FAIL, fmt, ## __VA_ARGS__); \
nerr++; \
} while (0)

#define crit(fmt, ...) \
do { \
indent = 0; \
msg(FAIL, fmt, ## __VA_ARGS__); \
msg(SKIP, "Unable to run test\n"); \
exit(EX_OSERR);
} while (0)

/*
* Directly invokes the given syscall with nullfd as the first argument
Expand Down Expand Up @@ -91,28 +119,37 @@ static unsigned int _check_for(int msb, int start, int end, long long expect,
{
unsigned int err = 0;

indent++;
if (start != end)
indent++;

for (int nr = start; nr <= end; nr++) {
long long ret = probe_syscall(msb, nr);

if (ret != expect) {
printf("[FAIL]\t %s returned %lld, but it should have returned %s\n",
fail("%s returned %lld, but it should have returned %s\n",
syscall_str(msb, nr, nr),
ret, expect_str);
err++;
}
}

if (start != end)
indent--;

if (err) {
nerr += err;
if (start != end)
printf("[FAIL]\t %s had %u failure%s\n",
fail("%s had %u failure%s\n",
syscall_str(msb, start, end),
err, (err == 1) ? "s" : "");
err, err == 1 ? "s" : "");
} else {
printf("[OK]\t %s returned %s as expected\n",
syscall_str(msb, start, end), expect_str);
ok("%s returned %s as expected\n",
syscall_str(msb, start, end), expect_str);
}

indent--;

return err;
}

Expand All @@ -137,35 +174,38 @@ static bool check_enosys(int msb, int nr)
static bool test_x32(void)
{
long long ret;
long long mypid = getpid();
pid_t mypid = getpid();
bool with_x32;

printf("[RUN]\tChecking for x32 by calling x32 getpid()\n");
run("Checking for x32 by calling x32 getpid()\n");
ret = probe_syscall(0, SYS_GETPID | X32_BIT);

indent++;
if (ret == mypid) {
printf("[INFO]\t x32 is supported\n");
return true;
info("x32 is supported\n");
with_x32 = true;
} else if (ret == -ENOSYS) {
printf("[INFO]\t x32 is not supported\n");
return false;
info("x32 is not supported\n");
with_x32 = false;
} else {
printf("[FAIL]\t x32 getpid() returned %lld, but it should have returned either %lld or -ENOSYS\n", ret, mypid);
nerr++;
return true; /* Proceed as if... */
fail("x32 getpid() returned %lld, but it should have returned either %lld or -ENOSYS\n", ret, mypid);
with_x32 = false;
}
indent--;
return with_x32;
}

static void test_syscalls_common(int msb)
{
printf("[RUN]\t Checking some common syscalls as 64 bit\n");
run("Checking some common syscalls as 64 bit\n");
check_zero(msb, SYS_READ);
check_zero(msb, SYS_WRITE);

printf("[RUN]\t Checking some 64-bit only syscalls as 64 bit\n");
run("Checking some 64-bit only syscalls as 64 bit\n");
check_zero(msb, X64_READV);
check_zero(msb, X64_WRITEV);

printf("[RUN]\t Checking out of range system calls\n");
run("Checking out of range system calls\n");
check_for(msb, -64, -1, -ENOSYS);
check_for(msb, X32_BIT-64, X32_BIT-1, -ENOSYS);
check_for(msb, -64-X32_BIT, -1-X32_BIT, -ENOSYS);
Expand All @@ -180,26 +220,26 @@ static void test_syscalls_with_x32(int msb)
* set. Calling them without the x32 bit set is
* nonsense and should not work.
*/
printf("[RUN]\t Checking x32 syscalls as 64 bit\n");
run("Checking x32 syscalls as 64 bit\n");
check_for(msb, 512, 547, -ENOSYS);

printf("[RUN]\t Checking some common syscalls as x32\n");
run("Checking some common syscalls as x32\n");
check_zero(msb, SYS_READ | X32_BIT);
check_zero(msb, SYS_WRITE | X32_BIT);

printf("[RUN]\t Checking some x32 syscalls as x32\n");
run("Checking some x32 syscalls as x32\n");
check_zero(msb, X32_READV | X32_BIT);
check_zero(msb, X32_WRITEV | X32_BIT);

printf("[RUN]\t Checking some 64-bit syscalls as x32\n");
run("Checking some 64-bit syscalls as x32\n");
check_enosys(msb, X64_IOCTL | X32_BIT);
check_enosys(msb, X64_READV | X32_BIT);
check_enosys(msb, X64_WRITEV | X32_BIT);
}

static void test_syscalls_without_x32(int msb)
{
printf("[RUN]\t Checking for absence of x32 system calls\n");
run("Checking for absence of x32 system calls\n");
check_for(msb, 0 | X32_BIT, 999 | X32_BIT, -ENOSYS);
}

Expand All @@ -217,14 +257,18 @@ static void test_syscall_numbering(void)
*/
for (size_t i = 0; i < sizeof(msbs)/sizeof(msbs[0]); i++) {
int msb = msbs[i];
printf("[RUN]\tChecking system calls with msb = %d (0x%x)\n",
msb, msb);
run("Checking system calls with msb = %d (0x%x)\n",
msb, msb);

indent++;

test_syscalls_common(msb);
if (with_x32)
test_syscalls_with_x32(msb);
else
test_syscalls_without_x32(msb);

indent--;
}
}

Expand All @@ -241,19 +285,16 @@ int main(void)
*/
nullfd = open("/dev/null", O_RDWR);
if (nullfd < 0) {
printf("[FAIL]\tUnable to open /dev/null: %s\n",
strerror(errno));
printf("[SKIP]\tCannot execute test\n");
return 71; /* EX_OSERR */
crit("Unable to open /dev/null: %s\n", strerror(errno));
}

test_syscall_numbering();
if (!nerr) {
printf("[OK]\tAll system calls succeeded or failed as expected\n");
ok("All system calls succeeded or failed as expected\n");
return 0;
} else {
printf("[FAIL]\tA total of %u system call%s had incorrect behavior\n",
nerr, nerr != 1 ? "s" : "");
fail("A total of %u system call%s had incorrect behavior\n",
nerr, nerr != 1 ? "s" : "");
return 1;
}
}

0 comments on commit c5c3948

Please sign in to comment.