Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/tools/testing/selftests/kvm/include/test_util.h
38235 views
1
/* SPDX-License-Identifier: GPL-2.0-only */
2
/*
3
* tools/testing/selftests/kvm/include/test_util.h
4
*
5
* Copyright (C) 2018, Google LLC.
6
*/
7
8
#ifndef SELFTEST_KVM_TEST_UTIL_H
9
#define SELFTEST_KVM_TEST_UTIL_H
10
11
#include <setjmp.h>
12
#include <signal.h>
13
#include <stdlib.h>
14
#include <stdarg.h>
15
#include <stdbool.h>
16
#include <stdio.h>
17
#include <string.h>
18
#include <inttypes.h>
19
#include <errno.h>
20
#include <unistd.h>
21
#include <fcntl.h>
22
#include <sys/mman.h>
23
#include "kselftest.h"
24
25
#define msecs_to_usecs(msec) ((msec) * 1000ULL)
26
27
static inline __printf(1, 2) int _no_printf(const char *format, ...) { return 0; }
28
29
#ifdef DEBUG
30
#define pr_debug(...) printf(__VA_ARGS__)
31
#else
32
#define pr_debug(...) _no_printf(__VA_ARGS__)
33
#endif
34
#ifndef QUIET
35
#define pr_info(...) printf(__VA_ARGS__)
36
#else
37
#define pr_info(...) _no_printf(__VA_ARGS__)
38
#endif
39
40
void __printf(1, 2) print_skip(const char *fmt, ...);
41
#define __TEST_REQUIRE(f, fmt, ...) \
42
do { \
43
if (!(f)) \
44
ksft_exit_skip("- " fmt "\n", ##__VA_ARGS__); \
45
} while (0)
46
47
#define TEST_REQUIRE(f) __TEST_REQUIRE(f, "Requirement not met: %s", #f)
48
49
ssize_t test_write(int fd, const void *buf, size_t count);
50
ssize_t test_read(int fd, void *buf, size_t count);
51
int test_seq_read(const char *path, char **bufp, size_t *sizep);
52
53
void __printf(5, 6) test_assert(bool exp, const char *exp_str,
54
const char *file, unsigned int line,
55
const char *fmt, ...);
56
57
#define TEST_ASSERT(e, fmt, ...) \
58
test_assert((e), #e, __FILE__, __LINE__, fmt, ##__VA_ARGS__)
59
60
#define TEST_ASSERT_EQ(a, b) \
61
do { \
62
typeof(a) __a = (a); \
63
typeof(b) __b = (b); \
64
test_assert(__a == __b, #a " == " #b, __FILE__, __LINE__, \
65
"%#lx != %#lx (%s != %s)", \
66
(unsigned long)(__a), (unsigned long)(__b), #a, #b);\
67
} while (0)
68
69
#define TEST_ASSERT_KVM_EXIT_REASON(vcpu, expected) do { \
70
__u32 exit_reason = (vcpu)->run->exit_reason; \
71
\
72
TEST_ASSERT(exit_reason == (expected), \
73
"Wanted KVM exit reason: %u (%s), got: %u (%s)", \
74
(expected), exit_reason_str((expected)), \
75
exit_reason, exit_reason_str(exit_reason)); \
76
} while (0)
77
78
#define TEST_FAIL(fmt, ...) do { \
79
TEST_ASSERT(false, fmt, ##__VA_ARGS__); \
80
__builtin_unreachable(); \
81
} while (0)
82
83
extern sigjmp_buf expect_sigbus_jmpbuf;
84
void expect_sigbus_handler(int signum);
85
86
#define TEST_EXPECT_SIGBUS(action) \
87
do { \
88
struct sigaction sa_old, sa_new = { \
89
.sa_handler = expect_sigbus_handler, \
90
}; \
91
\
92
sigaction(SIGBUS, &sa_new, &sa_old); \
93
if (sigsetjmp(expect_sigbus_jmpbuf, 1) == 0) { \
94
action; \
95
TEST_FAIL("'%s' should have triggered SIGBUS", #action); \
96
} \
97
sigaction(SIGBUS, &sa_old, NULL); \
98
} while (0)
99
100
size_t parse_size(const char *size);
101
102
int64_t timespec_to_ns(struct timespec ts);
103
struct timespec timespec_add_ns(struct timespec ts, int64_t ns);
104
struct timespec timespec_add(struct timespec ts1, struct timespec ts2);
105
struct timespec timespec_sub(struct timespec ts1, struct timespec ts2);
106
struct timespec timespec_elapsed(struct timespec start);
107
struct timespec timespec_div(struct timespec ts, int divisor);
108
109
struct guest_random_state {
110
uint32_t seed;
111
};
112
113
extern uint32_t guest_random_seed;
114
extern struct guest_random_state guest_rng;
115
116
struct guest_random_state new_guest_random_state(uint32_t seed);
117
uint32_t guest_random_u32(struct guest_random_state *state);
118
119
static inline bool __guest_random_bool(struct guest_random_state *state,
120
uint8_t percent)
121
{
122
return (guest_random_u32(state) % 100) < percent;
123
}
124
125
static inline bool guest_random_bool(struct guest_random_state *state)
126
{
127
return __guest_random_bool(state, 50);
128
}
129
130
static inline uint64_t guest_random_u64(struct guest_random_state *state)
131
{
132
return ((uint64_t)guest_random_u32(state) << 32) | guest_random_u32(state);
133
}
134
135
enum vm_mem_backing_src_type {
136
VM_MEM_SRC_ANONYMOUS,
137
VM_MEM_SRC_ANONYMOUS_THP,
138
VM_MEM_SRC_ANONYMOUS_HUGETLB,
139
VM_MEM_SRC_ANONYMOUS_HUGETLB_16KB,
140
VM_MEM_SRC_ANONYMOUS_HUGETLB_64KB,
141
VM_MEM_SRC_ANONYMOUS_HUGETLB_512KB,
142
VM_MEM_SRC_ANONYMOUS_HUGETLB_1MB,
143
VM_MEM_SRC_ANONYMOUS_HUGETLB_2MB,
144
VM_MEM_SRC_ANONYMOUS_HUGETLB_8MB,
145
VM_MEM_SRC_ANONYMOUS_HUGETLB_16MB,
146
VM_MEM_SRC_ANONYMOUS_HUGETLB_32MB,
147
VM_MEM_SRC_ANONYMOUS_HUGETLB_256MB,
148
VM_MEM_SRC_ANONYMOUS_HUGETLB_512MB,
149
VM_MEM_SRC_ANONYMOUS_HUGETLB_1GB,
150
VM_MEM_SRC_ANONYMOUS_HUGETLB_2GB,
151
VM_MEM_SRC_ANONYMOUS_HUGETLB_16GB,
152
VM_MEM_SRC_SHMEM,
153
VM_MEM_SRC_SHARED_HUGETLB,
154
NUM_SRC_TYPES,
155
};
156
157
#define DEFAULT_VM_MEM_SRC VM_MEM_SRC_ANONYMOUS
158
159
struct vm_mem_backing_src_alias {
160
const char *name;
161
uint32_t flag;
162
};
163
164
#define MIN_RUN_DELAY_NS 200000UL
165
166
bool thp_configured(void);
167
size_t get_trans_hugepagesz(void);
168
size_t get_def_hugetlb_pagesz(void);
169
const struct vm_mem_backing_src_alias *vm_mem_backing_src_alias(uint32_t i);
170
size_t get_backing_src_pagesz(uint32_t i);
171
bool is_backing_src_hugetlb(uint32_t i);
172
void backing_src_help(const char *flag);
173
enum vm_mem_backing_src_type parse_backing_src_type(const char *type_name);
174
long get_run_delay(void);
175
bool is_numa_balancing_enabled(void);
176
177
/*
178
* Whether or not the given source type is shared memory (as opposed to
179
* anonymous).
180
*/
181
static inline bool backing_src_is_shared(enum vm_mem_backing_src_type t)
182
{
183
return vm_mem_backing_src_alias(t)->flag & MAP_SHARED;
184
}
185
186
static inline bool backing_src_can_be_huge(enum vm_mem_backing_src_type t)
187
{
188
return t != VM_MEM_SRC_ANONYMOUS && t != VM_MEM_SRC_SHMEM;
189
}
190
191
/* Aligns x up to the next multiple of size. Size must be a power of 2. */
192
static inline uint64_t align_up(uint64_t x, uint64_t size)
193
{
194
uint64_t mask = size - 1;
195
196
TEST_ASSERT(size != 0 && !(size & (size - 1)),
197
"size not a power of 2: %lu", size);
198
return ((x + mask) & ~mask);
199
}
200
201
static inline uint64_t align_down(uint64_t x, uint64_t size)
202
{
203
uint64_t x_aligned_up = align_up(x, size);
204
205
if (x == x_aligned_up)
206
return x;
207
else
208
return x_aligned_up - size;
209
}
210
211
static inline void *align_ptr_up(void *x, size_t size)
212
{
213
return (void *)align_up((unsigned long)x, size);
214
}
215
216
int atoi_paranoid(const char *num_str);
217
218
static inline uint32_t atoi_positive(const char *name, const char *num_str)
219
{
220
int num = atoi_paranoid(num_str);
221
222
TEST_ASSERT(num > 0, "%s must be greater than 0, got '%s'", name, num_str);
223
return num;
224
}
225
226
static inline uint32_t atoi_non_negative(const char *name, const char *num_str)
227
{
228
int num = atoi_paranoid(num_str);
229
230
TEST_ASSERT(num >= 0, "%s must be non-negative, got '%s'", name, num_str);
231
return num;
232
}
233
234
int guest_vsnprintf(char *buf, int n, const char *fmt, va_list args);
235
__printf(3, 4) int guest_snprintf(char *buf, int n, const char *fmt, ...);
236
237
char *strdup_printf(const char *fmt, ...) __attribute__((format(printf, 1, 2), nonnull(1)));
238
239
char *sys_get_cur_clocksource(void);
240
241
#endif /* SELFTEST_KVM_TEST_UTIL_H */
242
243