Skip to content

Commit 44c5d7a

Browse files
author
Frantisek Hrbata
committed
Merge: Rebase selftests/rseq to v6.0
MR: https://gitlab.com/redhat/centos-stream/src/kernel/centos-stream-9/-/merge_requests/1694 Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=2107034 Brew: https://brewweb.engineering.redhat.com/brew/taskinfo?taskID=49263850 Upstream Status: v6.0 and RHEL-only to enable kvm/selftests/rseq_test Tested: Passed selftests/rseq and kvm/selftests/rseq_test This series rebases selftests/rseq to v6.0 so that it's compatible with glibc-2.35. RHEL9.2 has glibc-2.34, plus features backported from glibc-2.35. With glibc-2.35 supported by selftests/rseq, kvm/selftests/rseq_test can be enabled in the last RHEL-only patch. Note that there are two relevant bugs: bug2107034 and bug2116492. The former depends on the later one. The plan is to post only one MR for them, which is associated with bug2107034. It means bug2116492 becomes 'Test-Only' after the MR is merged. Changelog: v2: Improved cover letter to explain the relationship between bug2107034 and bug2116492 (Connie) Dropped 3 Risc-V related commits (Connie/Eric) Signed-off-by: Gavin Shan <gshan@redhat.com> Approved-by: Cornelia Huck <cohuck@redhat.com> Approved-by: Donald Dutile <ddutile@redhat.com> Signed-off-by: Frantisek Hrbata <fhrbata@redhat.com>
2 parents c385e83 + 203da7f commit 44c5d7a

19 files changed

+796
-361
lines changed

tools/testing/selftests/kvm/Makefile

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,7 @@ TEST_GEN_PROGS_x86_64 += kvm_page_table_test
129129
TEST_GEN_PROGS_x86_64 += max_guest_memory_test
130130
TEST_GEN_PROGS_x86_64 += memslot_modification_stress_test
131131
TEST_GEN_PROGS_x86_64 += memslot_perf_test
132-
# TEST_GEN_PROGS_x86_64 += rseq_test
132+
TEST_GEN_PROGS_x86_64 += rseq_test
133133
TEST_GEN_PROGS_x86_64 += set_memory_region_test
134134
TEST_GEN_PROGS_x86_64 += steal_time
135135
TEST_GEN_PROGS_x86_64 += kvm_binary_stats_test
@@ -153,7 +153,7 @@ TEST_GEN_PROGS_aarch64 += kvm_create_max_vcpus
153153
TEST_GEN_PROGS_aarch64 += kvm_page_table_test
154154
TEST_GEN_PROGS_aarch64 += memslot_modification_stress_test
155155
TEST_GEN_PROGS_aarch64 += memslot_perf_test
156-
# TEST_GEN_PROGS_aarch64 += rseq_test
156+
TEST_GEN_PROGS_aarch64 += rseq_test
157157
TEST_GEN_PROGS_aarch64 += set_memory_region_test
158158
TEST_GEN_PROGS_aarch64 += steal_time
159159
TEST_GEN_PROGS_aarch64 += kvm_binary_stats_test
@@ -166,7 +166,7 @@ TEST_GEN_PROGS_s390x += demand_paging_test
166166
TEST_GEN_PROGS_s390x += dirty_log_test
167167
TEST_GEN_PROGS_s390x += kvm_create_max_vcpus
168168
TEST_GEN_PROGS_s390x += kvm_page_table_test
169-
# TEST_GEN_PROGS_s390x += rseq_test
169+
TEST_GEN_PROGS_s390x += rseq_test
170170
TEST_GEN_PROGS_s390x += set_memory_region_test
171171
TEST_GEN_PROGS_s390x += kvm_binary_stats_test
172172

tools/testing/selftests/rseq/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ endif
66

77
CFLAGS += -O2 -Wall -g -I./ -I../../../../usr/include/ -L$(OUTPUT) -Wl,-rpath=./ \
88
$(CLANG_FLAGS)
9-
LDLIBS += -lpthread
9+
LDLIBS += -lpthread -ldl
1010

1111
# Own dependencies because we only want to build against 1st prerequisite, but
1212
# still track changes to header files and depend on shared object.

tools/testing/selftests/rseq/basic_percpu_ops_test.c

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,9 @@
99
#include <string.h>
1010
#include <stddef.h>
1111

12+
#include "../kselftest.h"
1213
#include "rseq.h"
1314

14-
#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
15-
1615
struct percpu_lock_entry {
1716
intptr_t v;
1817
} __attribute__((aligned(128)));
@@ -168,7 +167,7 @@ struct percpu_list_node *this_cpu_list_pop(struct percpu_list *list,
168167
for (;;) {
169168
struct percpu_list_node *head;
170169
intptr_t *targetptr, expectnot, *load;
171-
off_t offset;
170+
long offset;
172171
int ret, cpu;
173172

174173
cpu = rseq_cpu_start();
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
/* SPDX-License-Identifier: LGPL-2.1-only OR MIT */
2+
/*
3+
* rseq/compiler.h
4+
*
5+
* Work-around asm goto compiler bugs.
6+
*
7+
* (C) Copyright 2021 - Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
8+
*/
9+
10+
#ifndef RSEQ_COMPILER_H
11+
#define RSEQ_COMPILER_H
12+
13+
/*
14+
* gcc prior to 4.8.2 miscompiles asm goto.
15+
* https://gcc.gnu.org/bugzilla/show_bug.cgi?id=58670
16+
*
17+
* gcc prior to 8.1.0 miscompiles asm goto at O1.
18+
* https://gcc.gnu.org/bugzilla/show_bug.cgi?id=103908
19+
*
20+
* clang prior to version 13.0.1 miscompiles asm goto at O2.
21+
* https://github.com/llvm/llvm-project/issues/52735
22+
*
23+
* Work around these issues by adding a volatile inline asm with
24+
* memory clobber in the fallthrough after the asm goto and at each
25+
* label target. Emit this for all compilers in case other similar
26+
* issues are found in the future.
27+
*/
28+
#define rseq_after_asm_goto() asm volatile ("" : : : "memory")
29+
30+
#endif /* RSEQ_COMPILER_H_ */

tools/testing/selftests/rseq/param_test.c

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -161,7 +161,7 @@ unsigned int yield_mod_cnt, nr_abort;
161161
" cbnz " INJECT_ASM_REG ", 222b\n" \
162162
"333:\n"
163163

164-
#elif __PPC__
164+
#elif defined(__PPC__)
165165

166166
#define RSEQ_INJECT_INPUT \
167167
, [loop_cnt_1]"m"(loop_cnt[1]) \
@@ -368,9 +368,7 @@ void *test_percpu_spinlock_thread(void *arg)
368368
abort();
369369
reps = thread_data->reps;
370370
for (i = 0; i < reps; i++) {
371-
int cpu = rseq_cpu_start();
372-
373-
cpu = rseq_this_cpu_lock(&data->lock);
371+
int cpu = rseq_this_cpu_lock(&data->lock);
374372
data->c[cpu].count++;
375373
rseq_percpu_unlock(&data->lock, cpu);
376374
#ifndef BENCHMARK
@@ -551,7 +549,7 @@ struct percpu_list_node *this_cpu_list_pop(struct percpu_list *list,
551549
for (;;) {
552550
struct percpu_list_node *head;
553551
intptr_t *targetptr, expectnot, *load;
554-
off_t offset;
552+
long offset;
555553
int ret;
556554

557555
cpu = rseq_cpu_start();
Lines changed: 151 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,151 @@
1+
/* SPDX-License-Identifier: GPL-2.0+ WITH Linux-syscall-note */
2+
#ifndef _RSEQ_ABI_H
3+
#define _RSEQ_ABI_H
4+
5+
/*
6+
* rseq-abi.h
7+
*
8+
* Restartable sequences system call API
9+
*
10+
* Copyright (c) 2015-2022 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
11+
*/
12+
13+
#include <linux/types.h>
14+
#include <asm/byteorder.h>
15+
16+
enum rseq_abi_cpu_id_state {
17+
RSEQ_ABI_CPU_ID_UNINITIALIZED = -1,
18+
RSEQ_ABI_CPU_ID_REGISTRATION_FAILED = -2,
19+
};
20+
21+
enum rseq_abi_flags {
22+
RSEQ_ABI_FLAG_UNREGISTER = (1 << 0),
23+
};
24+
25+
enum rseq_abi_cs_flags_bit {
26+
RSEQ_ABI_CS_FLAG_NO_RESTART_ON_PREEMPT_BIT = 0,
27+
RSEQ_ABI_CS_FLAG_NO_RESTART_ON_SIGNAL_BIT = 1,
28+
RSEQ_ABI_CS_FLAG_NO_RESTART_ON_MIGRATE_BIT = 2,
29+
};
30+
31+
enum rseq_abi_cs_flags {
32+
RSEQ_ABI_CS_FLAG_NO_RESTART_ON_PREEMPT =
33+
(1U << RSEQ_ABI_CS_FLAG_NO_RESTART_ON_PREEMPT_BIT),
34+
RSEQ_ABI_CS_FLAG_NO_RESTART_ON_SIGNAL =
35+
(1U << RSEQ_ABI_CS_FLAG_NO_RESTART_ON_SIGNAL_BIT),
36+
RSEQ_ABI_CS_FLAG_NO_RESTART_ON_MIGRATE =
37+
(1U << RSEQ_ABI_CS_FLAG_NO_RESTART_ON_MIGRATE_BIT),
38+
};
39+
40+
/*
41+
* struct rseq_abi_cs is aligned on 4 * 8 bytes to ensure it is always
42+
* contained within a single cache-line. It is usually declared as
43+
* link-time constant data.
44+
*/
45+
struct rseq_abi_cs {
46+
/* Version of this structure. */
47+
__u32 version;
48+
/* enum rseq_abi_cs_flags */
49+
__u32 flags;
50+
__u64 start_ip;
51+
/* Offset from start_ip. */
52+
__u64 post_commit_offset;
53+
__u64 abort_ip;
54+
} __attribute__((aligned(4 * sizeof(__u64))));
55+
56+
/*
57+
* struct rseq_abi is aligned on 4 * 8 bytes to ensure it is always
58+
* contained within a single cache-line.
59+
*
60+
* A single struct rseq_abi per thread is allowed.
61+
*/
62+
struct rseq_abi {
63+
/*
64+
* Restartable sequences cpu_id_start field. Updated by the
65+
* kernel. Read by user-space with single-copy atomicity
66+
* semantics. This field should only be read by the thread which
67+
* registered this data structure. Aligned on 32-bit. Always
68+
* contains a value in the range of possible CPUs, although the
69+
* value may not be the actual current CPU (e.g. if rseq is not
70+
* initialized). This CPU number value should always be compared
71+
* against the value of the cpu_id field before performing a rseq
72+
* commit or returning a value read from a data structure indexed
73+
* using the cpu_id_start value.
74+
*/
75+
__u32 cpu_id_start;
76+
/*
77+
* Restartable sequences cpu_id field. Updated by the kernel.
78+
* Read by user-space with single-copy atomicity semantics. This
79+
* field should only be read by the thread which registered this
80+
* data structure. Aligned on 32-bit. Values
81+
* RSEQ_CPU_ID_UNINITIALIZED and RSEQ_CPU_ID_REGISTRATION_FAILED
82+
* have a special semantic: the former means "rseq uninitialized",
83+
* and latter means "rseq initialization failed". This value is
84+
* meant to be read within rseq critical sections and compared
85+
* with the cpu_id_start value previously read, before performing
86+
* the commit instruction, or read and compared with the
87+
* cpu_id_start value before returning a value loaded from a data
88+
* structure indexed using the cpu_id_start value.
89+
*/
90+
__u32 cpu_id;
91+
/*
92+
* Restartable sequences rseq_cs field.
93+
*
94+
* Contains NULL when no critical section is active for the current
95+
* thread, or holds a pointer to the currently active struct rseq_cs.
96+
*
97+
* Updated by user-space, which sets the address of the currently
98+
* active rseq_cs at the beginning of assembly instruction sequence
99+
* block, and set to NULL by the kernel when it restarts an assembly
100+
* instruction sequence block, as well as when the kernel detects that
101+
* it is preempting or delivering a signal outside of the range
102+
* targeted by the rseq_cs. Also needs to be set to NULL by user-space
103+
* before reclaiming memory that contains the targeted struct rseq_cs.
104+
*
105+
* Read and set by the kernel. Set by user-space with single-copy
106+
* atomicity semantics. This field should only be updated by the
107+
* thread which registered this data structure. Aligned on 64-bit.
108+
*/
109+
union {
110+
__u64 ptr64;
111+
112+
/*
113+
* The "arch" field provides architecture accessor for
114+
* the ptr field based on architecture pointer size and
115+
* endianness.
116+
*/
117+
struct {
118+
#ifdef __LP64__
119+
__u64 ptr;
120+
#elif defined(__BYTE_ORDER) ? (__BYTE_ORDER == __BIG_ENDIAN) : defined(__BIG_ENDIAN)
121+
__u32 padding; /* Initialized to zero. */
122+
__u32 ptr;
123+
#else
124+
__u32 ptr;
125+
__u32 padding; /* Initialized to zero. */
126+
#endif
127+
} arch;
128+
} rseq_cs;
129+
130+
/*
131+
* Restartable sequences flags field.
132+
*
133+
* This field should only be updated by the thread which
134+
* registered this data structure. Read by the kernel.
135+
* Mainly used for single-stepping through rseq critical sections
136+
* with debuggers.
137+
*
138+
* - RSEQ_ABI_CS_FLAG_NO_RESTART_ON_PREEMPT
139+
* Inhibit instruction sequence block restart on preemption
140+
* for this thread.
141+
* - RSEQ_ABI_CS_FLAG_NO_RESTART_ON_SIGNAL
142+
* Inhibit instruction sequence block restart on signal
143+
* delivery for this thread.
144+
* - RSEQ_ABI_CS_FLAG_NO_RESTART_ON_MIGRATE
145+
* Inhibit instruction sequence block restart on migration for
146+
* this thread.
147+
*/
148+
__u32 flags;
149+
} __attribute__((aligned(4 * sizeof(__u64))));
150+
151+
#endif /* _RSEQ_ABI_H */

0 commit comments

Comments
 (0)