Skip to content

Commit d1d873a

Browse files
committed
Merge tag 'linux_kselftest-fixes-6.8-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/shuah/linux-kselftest
Pull kselftest fixes from Shuah Khan: "Three fixes to livepatch, rseq, and seccomp tests" * tag 'linux_kselftest-fixes-6.8-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/shuah/linux-kselftest: kselftest/seccomp: Report each expectation we assert as a KTAP test kselftest/seccomp: Use kselftest output functions for benchmark selftests/livepatch: fix and refactor new dmesg message code selftests/rseq: Do not skip !allowed_cpus for mm_cid
2 parents 53ed2ac + b54761f commit d1d873a

File tree

4 files changed

+109
-68
lines changed

4 files changed

+109
-68
lines changed

tools/testing/selftests/livepatch/functions.sh

Lines changed: 17 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -42,17 +42,6 @@ function die() {
4242
exit 1
4343
}
4444

45-
# save existing dmesg so we can detect new content
46-
function save_dmesg() {
47-
SAVED_DMESG=$(mktemp --tmpdir -t klp-dmesg-XXXXXX)
48-
dmesg > "$SAVED_DMESG"
49-
}
50-
51-
# cleanup temporary dmesg file from save_dmesg()
52-
function cleanup_dmesg_file() {
53-
rm -f "$SAVED_DMESG"
54-
}
55-
5645
function push_config() {
5746
DYNAMIC_DEBUG=$(grep '^kernel/livepatch' /sys/kernel/debug/dynamic_debug/control | \
5847
awk -F'[: ]' '{print "file " $1 " line " $2 " " $4}')
@@ -99,7 +88,6 @@ function set_ftrace_enabled() {
9988

10089
function cleanup() {
10190
pop_config
102-
cleanup_dmesg_file
10391
}
10492

10593
# setup_config - save the current config and set a script exit trap that
@@ -280,7 +268,15 @@ function set_pre_patch_ret {
280268
function start_test {
281269
local test="$1"
282270

283-
save_dmesg
271+
# Dump something unique into the dmesg log, then stash the entry
272+
# in LAST_DMESG. The check_result() function will use it to
273+
# find new kernel messages since the test started.
274+
local last_dmesg_msg="livepatch kselftest timestamp: $(date --rfc-3339=ns)"
275+
log "$last_dmesg_msg"
276+
loop_until 'dmesg | grep -q "$last_dmesg_msg"' ||
277+
die "buffer busy? can't find canary dmesg message: $last_dmesg_msg"
278+
LAST_DMESG=$(dmesg | grep "$last_dmesg_msg")
279+
284280
echo -n "TEST: $test ... "
285281
log "===== TEST: $test ====="
286282
}
@@ -291,23 +287,24 @@ function check_result {
291287
local expect="$*"
292288
local result
293289

294-
# Note: when comparing dmesg output, the kernel log timestamps
295-
# help differentiate repeated testing runs. Remove them with a
296-
# post-comparison sed filter.
297-
298-
result=$(dmesg | comm --nocheck-order -13 "$SAVED_DMESG" - | \
290+
# Test results include any new dmesg entry since LAST_DMESG, then:
291+
# - include lines matching keywords
292+
# - exclude lines matching keywords
293+
# - filter out dmesg timestamp prefixes
294+
result=$(dmesg | awk -v last_dmesg="$LAST_DMESG" 'p; $0 == last_dmesg { p=1 }' | \
299295
grep -e 'livepatch:' -e 'test_klp' | \
300296
grep -v '\(tainting\|taints\) kernel' | \
301297
sed 's/^\[[ 0-9.]*\] //')
302298

303299
if [[ "$expect" == "$result" ]] ; then
304300
echo "ok"
301+
elif [[ "$result" == "" ]] ; then
302+
echo -e "not ok\n\nbuffer overrun? can't find canary dmesg entry: $LAST_DMESG\n"
303+
die "livepatch kselftest(s) failed"
305304
else
306305
echo -e "not ok\n\n$(diff -upr --label expected --label result <(echo "$expect") <(echo "$result"))\n"
307306
die "livepatch kselftest(s) failed"
308307
fi
309-
310-
cleanup_dmesg_file
311308
}
312309

313310
# check_sysfs_rights(modname, rel_path, expected_rights) - check sysfs

tools/testing/selftests/rseq/basic_percpu_ops_test.c

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,11 @@ bool rseq_validate_cpu_id(void)
2424
{
2525
return rseq_mm_cid_available();
2626
}
27+
static
28+
bool rseq_use_cpu_index(void)
29+
{
30+
return false; /* Use mm_cid */
31+
}
2732
#else
2833
# define RSEQ_PERCPU RSEQ_PERCPU_CPU_ID
2934
static
@@ -36,6 +41,11 @@ bool rseq_validate_cpu_id(void)
3641
{
3742
return rseq_current_cpu_raw() >= 0;
3843
}
44+
static
45+
bool rseq_use_cpu_index(void)
46+
{
47+
return true; /* Use cpu_id as index. */
48+
}
3949
#endif
4050

4151
struct percpu_lock_entry {
@@ -274,7 +284,7 @@ void test_percpu_list(void)
274284
/* Generate list entries for every usable cpu. */
275285
sched_getaffinity(0, sizeof(allowed_cpus), &allowed_cpus);
276286
for (i = 0; i < CPU_SETSIZE; i++) {
277-
if (!CPU_ISSET(i, &allowed_cpus))
287+
if (rseq_use_cpu_index() && !CPU_ISSET(i, &allowed_cpus))
278288
continue;
279289
for (j = 1; j <= 100; j++) {
280290
struct percpu_list_node *node;
@@ -299,7 +309,7 @@ void test_percpu_list(void)
299309
for (i = 0; i < CPU_SETSIZE; i++) {
300310
struct percpu_list_node *node;
301311

302-
if (!CPU_ISSET(i, &allowed_cpus))
312+
if (rseq_use_cpu_index() && !CPU_ISSET(i, &allowed_cpus))
303313
continue;
304314

305315
while ((node = __percpu_list_pop(&list, i))) {

tools/testing/selftests/rseq/param_test.c

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -288,6 +288,11 @@ bool rseq_validate_cpu_id(void)
288288
{
289289
return rseq_mm_cid_available();
290290
}
291+
static
292+
bool rseq_use_cpu_index(void)
293+
{
294+
return false; /* Use mm_cid */
295+
}
291296
# ifdef TEST_MEMBARRIER
292297
/*
293298
* Membarrier does not currently support targeting a mm_cid, so
@@ -312,6 +317,11 @@ bool rseq_validate_cpu_id(void)
312317
{
313318
return rseq_current_cpu_raw() >= 0;
314319
}
320+
static
321+
bool rseq_use_cpu_index(void)
322+
{
323+
return true; /* Use cpu_id as index. */
324+
}
315325
# ifdef TEST_MEMBARRIER
316326
static
317327
int rseq_membarrier_expedited(int cpu)
@@ -715,7 +725,7 @@ void test_percpu_list(void)
715725
/* Generate list entries for every usable cpu. */
716726
sched_getaffinity(0, sizeof(allowed_cpus), &allowed_cpus);
717727
for (i = 0; i < CPU_SETSIZE; i++) {
718-
if (!CPU_ISSET(i, &allowed_cpus))
728+
if (rseq_use_cpu_index() && !CPU_ISSET(i, &allowed_cpus))
719729
continue;
720730
for (j = 1; j <= 100; j++) {
721731
struct percpu_list_node *node;
@@ -752,7 +762,7 @@ void test_percpu_list(void)
752762
for (i = 0; i < CPU_SETSIZE; i++) {
753763
struct percpu_list_node *node;
754764

755-
if (!CPU_ISSET(i, &allowed_cpus))
765+
if (rseq_use_cpu_index() && !CPU_ISSET(i, &allowed_cpus))
756766
continue;
757767

758768
while ((node = __percpu_list_pop(&list, i))) {
@@ -902,7 +912,7 @@ void test_percpu_buffer(void)
902912
/* Generate list entries for every usable cpu. */
903913
sched_getaffinity(0, sizeof(allowed_cpus), &allowed_cpus);
904914
for (i = 0; i < CPU_SETSIZE; i++) {
905-
if (!CPU_ISSET(i, &allowed_cpus))
915+
if (rseq_use_cpu_index() && !CPU_ISSET(i, &allowed_cpus))
906916
continue;
907917
/* Worse-case is every item in same CPU. */
908918
buffer.c[i].array =
@@ -952,7 +962,7 @@ void test_percpu_buffer(void)
952962
for (i = 0; i < CPU_SETSIZE; i++) {
953963
struct percpu_buffer_node *node;
954964

955-
if (!CPU_ISSET(i, &allowed_cpus))
965+
if (rseq_use_cpu_index() && !CPU_ISSET(i, &allowed_cpus))
956966
continue;
957967

958968
while ((node = __percpu_buffer_pop(&buffer, i))) {
@@ -1113,7 +1123,7 @@ void test_percpu_memcpy_buffer(void)
11131123
/* Generate list entries for every usable cpu. */
11141124
sched_getaffinity(0, sizeof(allowed_cpus), &allowed_cpus);
11151125
for (i = 0; i < CPU_SETSIZE; i++) {
1116-
if (!CPU_ISSET(i, &allowed_cpus))
1126+
if (rseq_use_cpu_index() && !CPU_ISSET(i, &allowed_cpus))
11171127
continue;
11181128
/* Worse-case is every item in same CPU. */
11191129
buffer.c[i].array =
@@ -1160,7 +1170,7 @@ void test_percpu_memcpy_buffer(void)
11601170
for (i = 0; i < CPU_SETSIZE; i++) {
11611171
struct percpu_memcpy_buffer_node item;
11621172

1163-
if (!CPU_ISSET(i, &allowed_cpus))
1173+
if (rseq_use_cpu_index() && !CPU_ISSET(i, &allowed_cpus))
11641174
continue;
11651175

11661176
while (__percpu_memcpy_buffer_pop(&buffer, &item, i)) {

tools/testing/selftests/seccomp/seccomp_benchmark.c

Lines changed: 64 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -38,10 +38,10 @@ unsigned long long timing(clockid_t clk_id, unsigned long long samples)
3838
i *= 1000000000ULL;
3939
i += finish.tv_nsec - start.tv_nsec;
4040

41-
printf("%lu.%09lu - %lu.%09lu = %llu (%.1fs)\n",
42-
finish.tv_sec, finish.tv_nsec,
43-
start.tv_sec, start.tv_nsec,
44-
i, (double)i / 1000000000.0);
41+
ksft_print_msg("%lu.%09lu - %lu.%09lu = %llu (%.1fs)\n",
42+
finish.tv_sec, finish.tv_nsec,
43+
start.tv_sec, start.tv_nsec,
44+
i, (double)i / 1000000000.0);
4545

4646
return i;
4747
}
@@ -53,7 +53,7 @@ unsigned long long calibrate(void)
5353
pid_t pid, ret;
5454
int seconds = 15;
5555

56-
printf("Calibrating sample size for %d seconds worth of syscalls ...\n", seconds);
56+
ksft_print_msg("Calibrating sample size for %d seconds worth of syscalls ...\n", seconds);
5757

5858
samples = 0;
5959
pid = getpid();
@@ -98,24 +98,36 @@ bool le(int i_one, int i_two)
9898
}
9999

100100
long compare(const char *name_one, const char *name_eval, const char *name_two,
101-
unsigned long long one, bool (*eval)(int, int), unsigned long long two)
101+
unsigned long long one, bool (*eval)(int, int), unsigned long long two,
102+
bool skip)
102103
{
103104
bool good;
104105

105-
printf("\t%s %s %s (%lld %s %lld): ", name_one, name_eval, name_two,
106-
(long long)one, name_eval, (long long)two);
106+
if (skip) {
107+
ksft_test_result_skip("%s %s %s\n", name_one, name_eval,
108+
name_two);
109+
return 0;
110+
}
111+
112+
ksft_print_msg("\t%s %s %s (%lld %s %lld): ", name_one, name_eval, name_two,
113+
(long long)one, name_eval, (long long)two);
107114
if (one > INT_MAX) {
108-
printf("Miscalculation! Measurement went negative: %lld\n", (long long)one);
109-
return 1;
115+
ksft_print_msg("Miscalculation! Measurement went negative: %lld\n", (long long)one);
116+
good = false;
117+
goto out;
110118
}
111119
if (two > INT_MAX) {
112-
printf("Miscalculation! Measurement went negative: %lld\n", (long long)two);
113-
return 1;
120+
ksft_print_msg("Miscalculation! Measurement went negative: %lld\n", (long long)two);
121+
good = false;
122+
goto out;
114123
}
115124

116125
good = eval(one, two);
117126
printf("%s\n", good ? "✔️" : "❌");
118127

128+
out:
129+
ksft_test_result(good, "%s %s %s\n", name_one, name_eval, name_two);
130+
119131
return good ? 0 : 1;
120132
}
121133

@@ -142,27 +154,34 @@ int main(int argc, char *argv[])
142154
unsigned long long samples, calc;
143155
unsigned long long native, filter1, filter2, bitmap1, bitmap2;
144156
unsigned long long entry, per_filter1, per_filter2;
157+
bool skip = false;
145158

146159
setbuf(stdout, NULL);
147160

148-
printf("Running on:\n");
161+
ksft_print_header();
162+
ksft_set_plan(7);
163+
164+
ksft_print_msg("Running on:\n");
165+
ksft_print_msg("");
149166
system("uname -a");
150167

151-
printf("Current BPF sysctl settings:\n");
168+
ksft_print_msg("Current BPF sysctl settings:\n");
152169
/* Avoid using "sysctl" which may not be installed. */
170+
ksft_print_msg("");
153171
system("grep -H . /proc/sys/net/core/bpf_jit_enable");
172+
ksft_print_msg("");
154173
system("grep -H . /proc/sys/net/core/bpf_jit_harden");
155174

156175
if (argc > 1)
157176
samples = strtoull(argv[1], NULL, 0);
158177
else
159178
samples = calibrate();
160179

161-
printf("Benchmarking %llu syscalls...\n", samples);
180+
ksft_print_msg("Benchmarking %llu syscalls...\n", samples);
162181

163182
/* Native call */
164183
native = timing(CLOCK_PROCESS_CPUTIME_ID, samples) / samples;
165-
printf("getpid native: %llu ns\n", native);
184+
ksft_print_msg("getpid native: %llu ns\n", native);
166185

167186
ret = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);
168187
assert(ret == 0);
@@ -172,35 +191,37 @@ int main(int argc, char *argv[])
172191
assert(ret == 0);
173192

174193
bitmap1 = timing(CLOCK_PROCESS_CPUTIME_ID, samples) / samples;
175-
printf("getpid RET_ALLOW 1 filter (bitmap): %llu ns\n", bitmap1);
194+
ksft_print_msg("getpid RET_ALLOW 1 filter (bitmap): %llu ns\n", bitmap1);
176195

177196
/* Second filter resulting in a bitmap */
178197
ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &bitmap_prog);
179198
assert(ret == 0);
180199

181200
bitmap2 = timing(CLOCK_PROCESS_CPUTIME_ID, samples) / samples;
182-
printf("getpid RET_ALLOW 2 filters (bitmap): %llu ns\n", bitmap2);
201+
ksft_print_msg("getpid RET_ALLOW 2 filters (bitmap): %llu ns\n", bitmap2);
183202

184203
/* Third filter, can no longer be converted to bitmap */
185204
ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog);
186205
assert(ret == 0);
187206

188207
filter1 = timing(CLOCK_PROCESS_CPUTIME_ID, samples) / samples;
189-
printf("getpid RET_ALLOW 3 filters (full): %llu ns\n", filter1);
208+
ksft_print_msg("getpid RET_ALLOW 3 filters (full): %llu ns\n", filter1);
190209

191210
/* Fourth filter, can not be converted to bitmap because of filter 3 */
192211
ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &bitmap_prog);
193212
assert(ret == 0);
194213

195214
filter2 = timing(CLOCK_PROCESS_CPUTIME_ID, samples) / samples;
196-
printf("getpid RET_ALLOW 4 filters (full): %llu ns\n", filter2);
215+
ksft_print_msg("getpid RET_ALLOW 4 filters (full): %llu ns\n", filter2);
197216

198217
/* Estimations */
199218
#define ESTIMATE(fmt, var, what) do { \
200219
var = (what); \
201-
printf("Estimated " fmt ": %llu ns\n", var); \
202-
if (var > INT_MAX) \
203-
goto more_samples; \
220+
ksft_print_msg("Estimated " fmt ": %llu ns\n", var); \
221+
if (var > INT_MAX) { \
222+
skip = true; \
223+
ret |= 1; \
224+
} \
204225
} while (0)
205226

206227
ESTIMATE("total seccomp overhead for 1 bitmapped filter", calc,
@@ -218,31 +239,34 @@ int main(int argc, char *argv[])
218239
ESTIMATE("seccomp per-filter overhead (filters / 4)", per_filter2,
219240
(filter2 - native - entry) / 4);
220241

221-
printf("Expectations:\n");
222-
ret |= compare("native", "≤", "1 bitmap", native, le, bitmap1);
223-
bits = compare("native", "≤", "1 filter", native, le, filter1);
242+
ksft_print_msg("Expectations:\n");
243+
ret |= compare("native", "≤", "1 bitmap", native, le, bitmap1,
244+
skip);
245+
bits = compare("native", "≤", "1 filter", native, le, filter1,
246+
skip);
224247
if (bits)
225-
goto more_samples;
248+
skip = true;
226249

227250
ret |= compare("per-filter (last 2 diff)", "≈", "per-filter (filters / 4)",
228-
per_filter1, approx, per_filter2);
251+
per_filter1, approx, per_filter2, skip);
229252

230253
bits = compare("1 bitmapped", "≈", "2 bitmapped",
231-
bitmap1 - native, approx, bitmap2 - native);
254+
bitmap1 - native, approx, bitmap2 - native, skip);
232255
if (bits) {
233-
printf("Skipping constant action bitmap expectations: they appear unsupported.\n");
234-
goto out;
256+
ksft_print_msg("Skipping constant action bitmap expectations: they appear unsupported.\n");
257+
skip = true;
235258
}
236259

237-
ret |= compare("entry", "≈", "1 bitmapped", entry, approx, bitmap1 - native);
238-
ret |= compare("entry", "≈", "2 bitmapped", entry, approx, bitmap2 - native);
260+
ret |= compare("entry", "≈", "1 bitmapped", entry, approx,
261+
bitmap1 - native, skip);
262+
ret |= compare("entry", "≈", "2 bitmapped", entry, approx,
263+
bitmap2 - native, skip);
239264
ret |= compare("native + entry + (per filter * 4)", "≈", "4 filters total",
240-
entry + (per_filter1 * 4) + native, approx, filter2);
241-
if (ret == 0)
242-
goto out;
265+
entry + (per_filter1 * 4) + native, approx, filter2,
266+
skip);
243267

244-
more_samples:
245-
printf("Saw unexpected benchmark result. Try running again with more samples?\n");
246-
out:
247-
return 0;
268+
if (ret)
269+
ksft_print_msg("Saw unexpected benchmark result. Try running again with more samples?\n");
270+
271+
ksft_finished();
248272
}

0 commit comments

Comments
 (0)