1 /* SPDX-License-Identifier: GPL-2.0-only */
2 #ifndef SELFTEST_KVM_SYSCALLS_H
3 #define SELFTEST_KVM_SYSCALLS_H
4
5 /*
6 * Include both the kernel and libc versions of mman.h. The kernel provides
7 * the most up-to-date flags and definitions, while libc provides the syscall
8 * wrappers tests expect.
9 */
10 #include <linux/mman.h>
11
12 #include <sys/mman.h>
13 #include <sys/syscall.h>
14
15 #include <test_util.h>
16
17 #define MAP_ARGS0(m,...)
18 #define MAP_ARGS1(m,t,a,...) m(t,a)
19 #define MAP_ARGS2(m,t,a,...) m(t,a), MAP_ARGS1(m,__VA_ARGS__)
20 #define MAP_ARGS3(m,t,a,...) m(t,a), MAP_ARGS2(m,__VA_ARGS__)
21 #define MAP_ARGS4(m,t,a,...) m(t,a), MAP_ARGS3(m,__VA_ARGS__)
22 #define MAP_ARGS5(m,t,a,...) m(t,a), MAP_ARGS4(m,__VA_ARGS__)
23 #define MAP_ARGS6(m,t,a,...) m(t,a), MAP_ARGS5(m,__VA_ARGS__)
24 #define MAP_ARGS(n,...) MAP_ARGS##n(__VA_ARGS__)
25
26 #define __DECLARE_ARGS(t, a) t a
27 #define __UNPACK_ARGS(t, a) a
28
29 #define DECLARE_ARGS(nr_args, args...) MAP_ARGS(nr_args, __DECLARE_ARGS, args)
30 #define UNPACK_ARGS(nr_args, args...) MAP_ARGS(nr_args, __UNPACK_ARGS, args)
31
32 #define __KVM_SYSCALL_ERROR(_name, _ret) \
33 "%s failed, rc: %i errno: %i (%s)", (_name), (_ret), errno, strerror(errno)
34
35 /* Define a kvm_<syscall>() API to assert success. */
36 #define __KVM_SYSCALL_DEFINE(name, nr_args, args...) \
37 static inline void kvm_##name(DECLARE_ARGS(nr_args, args)) \
38 { \
39 int r; \
40 \
41 r = name(UNPACK_ARGS(nr_args, args)); \
42 TEST_ASSERT(!r, __KVM_SYSCALL_ERROR(#name, r)); \
43 }
44
45 /*
46 * Macro to define syscall APIs, either because KVM selftests doesn't link to
47 * the standard library, e.g. libnuma, or because there is no library that yet
48 * provides the syscall. These
49 */
50 #define KVM_SYSCALL_DEFINE(name, nr_args, args...) \
51 static inline long name(DECLARE_ARGS(nr_args, args)) \
52 { \
53 return syscall(__NR_##name, UNPACK_ARGS(nr_args, args)); \
54 } \
55 __KVM_SYSCALL_DEFINE(name, nr_args, args)
56
57 /*
58 * Special case mmap(), as KVM selftest rarely/never specific an address,
59 * rarely specify an offset, and because the unique return code requires
60 * special handling anyways.
61 */
__kvm_mmap(size_t size,int prot,int flags,int fd,off_t offset)62 static inline void *__kvm_mmap(size_t size, int prot, int flags, int fd,
63 off_t offset)
64 {
65 void *mem;
66
67 mem = mmap(NULL, size, prot, flags, fd, offset);
68 TEST_ASSERT(mem != MAP_FAILED, __KVM_SYSCALL_ERROR("mmap()",
69 (int)(unsigned long)MAP_FAILED));
70 return mem;
71 }
72
kvm_mmap(size_t size,int prot,int flags,int fd)73 static inline void *kvm_mmap(size_t size, int prot, int flags, int fd)
74 {
75 return __kvm_mmap(size, prot, flags, fd, 0);
76 }
77
kvm_dup(int fd)78 static inline int kvm_dup(int fd)
79 {
80 int new_fd = dup(fd);
81
82 TEST_ASSERT(new_fd >= 0, __KVM_SYSCALL_ERROR("dup()", new_fd));
83 return new_fd;
84 }
85
86 __KVM_SYSCALL_DEFINE(munmap, 2, void *, mem, size_t, size);
87 __KVM_SYSCALL_DEFINE(close, 1, int, fd);
88 __KVM_SYSCALL_DEFINE(fallocate, 4, int, fd, int, mode, loff_t, offset, loff_t, len);
89 __KVM_SYSCALL_DEFINE(ftruncate, 2, unsigned int, fd, off_t, length);
90 __KVM_SYSCALL_DEFINE(madvise, 3, void *, addr, size_t, length, int, advice);
91
92 #endif /* SELFTEST_KVM_SYSCALLS_H */
93