x86/syscalls: Split the x32 syscalls into their own table
[sfrench/cifs-2.6.git] / tools / testing / selftests / x86 / syscall_numbering.c
1 /* SPDX-License-Identifier: GPL-2.0 */
2 /*
3  * syscall_arg_fault.c - tests faults 32-bit fast syscall stack args
4  * Copyright (c) 2018 Andrew Lutomirski
5  */
6
7 #define _GNU_SOURCE
8
9 #include <stdlib.h>
10 #include <stdio.h>
11 #include <stdbool.h>
12 #include <errno.h>
13 #include <unistd.h>
14 #include <syscall.h>
15
16 static int nerrs;
17
18 #define X32_BIT 0x40000000UL
19
20 static void check_enosys(unsigned long nr, bool *ok)
21 {
22         /* If this fails, a segfault is reasonably likely. */
23         fflush(stdout);
24
25         long ret = syscall(nr, 0, 0, 0, 0, 0, 0);
26         if (ret == 0) {
27                 printf("[FAIL]\tsyscall %lu succeeded, but it should have failed\n", nr);
28                 *ok = false;
29         } else if (errno != ENOSYS) {
30                 printf("[FAIL]\tsyscall %lu had error code %d, but it should have reported ENOSYS\n", nr, errno);
31                 *ok = false;
32         }
33 }
34
35 static void test_x32_without_x32_bit(void)
36 {
37         bool ok = true;
38
39         /*
40          * Syscalls 512-547 are "x32" syscalls.  They are intended to be
41          * called with the x32 (0x40000000) bit set.  Calling them without
42          * the x32 bit set is nonsense and should not work.
43          */
44         printf("[RUN]\tChecking syscalls 512-547\n");
45         for (int i = 512; i <= 547; i++)
46                 check_enosys(i, &ok);
47
48         /*
49          * Check that a handful of 64-bit-only syscalls are rejected if the x32
50          * bit is set.
51          */
52         printf("[RUN]\tChecking some 64-bit syscalls in x32 range\n");
53         check_enosys(16 | X32_BIT, &ok);        /* ioctl */
54         check_enosys(19 | X32_BIT, &ok);        /* readv */
55         check_enosys(20 | X32_BIT, &ok);        /* writev */
56
57         /*
58          * Check some syscalls with high bits set.
59          */
60         printf("[RUN]\tChecking numbers above 2^32-1\n");
61         check_enosys((1UL << 32), &ok);
62         check_enosys(X32_BIT | (1UL << 32), &ok);
63
64         if (!ok)
65                 nerrs++;
66         else
67                 printf("[OK]\tThey all returned -ENOSYS\n");
68 }
69
70 int main()
71 {
72         /*
73          * Anyone diagnosing a failure will want to know whether the kernel
74          * supports x32.  Tell them.
75          */
76         printf("\tChecking for x32...");
77         fflush(stdout);
78         if (syscall(39 | X32_BIT, 0, 0, 0, 0, 0, 0) >= 0) {
79                 printf(" supported\n");
80         } else if (errno == ENOSYS) {
81                 printf(" not supported\n");
82         } else {
83                 printf(" confused\n");
84         }
85
86         test_x32_without_x32_bit();
87
88         return nerrs ? 1 : 0;
89 }