Commit 66d42ac7 authored by Gavin Shan's avatar Gavin Shan Committed by Paolo Bonzini

KVM: selftests: Make rseq compatible with glibc-2.35

The rseq information is registered by TLS, starting from glibc-2.35.
In this case, the test always fails due to syscall(__NR_rseq). For
example, on RHEL9.1 where upstream glibc-2.35 features are enabled
on downstream glibc-2.34, the test fails like below.

  # ./rseq_test
  ==== Test Assertion Failure ====
    rseq_test.c:60: !r
    pid=112043 tid=112043 errno=22 - Invalid argument
       1        0x0000000000401973: main at rseq_test.c:226
       2        0x0000ffff84b6c79b: ?? ??:0
       3        0x0000ffff84b6c86b: ?? ??:0
       4        0x0000000000401b6f: _start at ??:?
    rseq failed, errno = 22 (Invalid argument)
  # rpm -aq | grep glibc-2
  glibc-2.34-39.el9.aarch64

Fix the issue by using "../rseq/rseq.c" to fetch the rseq information,
registred by TLS if it exists. Otherwise, we're going to register our
own rseq information as before.
Reported-by: default avatarYihuang Yu <yihyu@redhat.com>
Suggested-by: default avatarFlorian Weimer <fweimer@redhat.com>
Suggested-by: default avatarMathieu Desnoyers <mathieu.desnoyers@efficios.com>
Suggested-by: default avatarPaolo Bonzini <pbonzini@redhat.com>
Signed-off-by: default avatarGavin Shan <gshan@redhat.com>
Message-Id: <20220810104114.6838-2-gshan@redhat.com>
Signed-off-by: default avatarPaolo Bonzini <pbonzini@redhat.com>
parent b74ed7a6
...@@ -199,7 +199,8 @@ endif ...@@ -199,7 +199,8 @@ endif
CFLAGS += -Wall -Wstrict-prototypes -Wuninitialized -O2 -g -std=gnu99 \ CFLAGS += -Wall -Wstrict-prototypes -Wuninitialized -O2 -g -std=gnu99 \
-fno-stack-protector -fno-PIE -I$(LINUX_TOOL_INCLUDE) \ -fno-stack-protector -fno-PIE -I$(LINUX_TOOL_INCLUDE) \
-I$(LINUX_TOOL_ARCH_INCLUDE) -I$(LINUX_HDR_PATH) -Iinclude \ -I$(LINUX_TOOL_ARCH_INCLUDE) -I$(LINUX_HDR_PATH) -Iinclude \
-I$(<D) -Iinclude/$(UNAME_M) -I.. $(EXTRA_CFLAGS) $(KHDR_INCLUDES) -I$(<D) -Iinclude/$(UNAME_M) -I ../rseq -I.. $(EXTRA_CFLAGS) \
$(KHDR_INCLUDES)
no-pie-option := $(call try-run, echo 'int main() { return 0; }' | \ no-pie-option := $(call try-run, echo 'int main() { return 0; }' | \
$(CC) -Werror -no-pie -x c - -o "$$TMP", -no-pie) $(CC) -Werror -no-pie -x c - -o "$$TMP", -no-pie)
...@@ -208,7 +209,7 @@ no-pie-option := $(call try-run, echo 'int main() { return 0; }' | \ ...@@ -208,7 +209,7 @@ no-pie-option := $(call try-run, echo 'int main() { return 0; }' | \
pgste-option = $(call try-run, echo 'int main() { return 0; }' | \ pgste-option = $(call try-run, echo 'int main() { return 0; }' | \
$(CC) -Werror -Wl$(comma)--s390-pgste -x c - -o "$$TMP",-Wl$(comma)--s390-pgste) $(CC) -Werror -Wl$(comma)--s390-pgste -x c - -o "$$TMP",-Wl$(comma)--s390-pgste)
LDLIBS += -ldl
LDFLAGS += -pthread $(no-pie-option) $(pgste-option) LDFLAGS += -pthread $(no-pie-option) $(pgste-option)
# After inclusion, $(OUTPUT) is defined and # After inclusion, $(OUTPUT) is defined and
......
...@@ -20,15 +20,7 @@ ...@@ -20,15 +20,7 @@
#include "processor.h" #include "processor.h"
#include "test_util.h" #include "test_util.h"
static __thread volatile struct rseq __rseq = { #include "../rseq/rseq.c"
.cpu_id = RSEQ_CPU_ID_UNINITIALIZED,
};
/*
* Use an arbitrary, bogus signature for configuring rseq, this test does not
* actually enter an rseq critical section.
*/
#define RSEQ_SIG 0xdeadbeef
/* /*
* Any bug related to task migration is likely to be timing-dependent; perform * Any bug related to task migration is likely to be timing-dependent; perform
...@@ -49,14 +41,6 @@ static void guest_code(void) ...@@ -49,14 +41,6 @@ static void guest_code(void)
GUEST_SYNC(0); GUEST_SYNC(0);
} }
static void sys_rseq(int flags)
{
int r;
r = syscall(__NR_rseq, &__rseq, sizeof(__rseq), flags, RSEQ_SIG);
TEST_ASSERT(!r, "rseq failed, errno = %d (%s)", errno, strerror(errno));
}
static int next_cpu(int cpu) static int next_cpu(int cpu)
{ {
/* /*
...@@ -218,7 +202,9 @@ int main(int argc, char *argv[]) ...@@ -218,7 +202,9 @@ int main(int argc, char *argv[])
calc_min_max_cpu(); calc_min_max_cpu();
sys_rseq(0); r = rseq_register_current_thread();
TEST_ASSERT(!r, "rseq_register_current_thread failed, errno = %d (%s)",
errno, strerror(errno));
/* /*
* Create and run a dummy VM that immediately exits to userspace via * Create and run a dummy VM that immediately exits to userspace via
...@@ -256,7 +242,7 @@ int main(int argc, char *argv[]) ...@@ -256,7 +242,7 @@ int main(int argc, char *argv[])
*/ */
smp_rmb(); smp_rmb();
cpu = sched_getcpu(); cpu = sched_getcpu();
rseq_cpu = READ_ONCE(__rseq.cpu_id); rseq_cpu = rseq_current_cpu_raw();
smp_rmb(); smp_rmb();
} while (snapshot != atomic_read(&seq_cnt)); } while (snapshot != atomic_read(&seq_cnt));
...@@ -278,7 +264,7 @@ int main(int argc, char *argv[]) ...@@ -278,7 +264,7 @@ int main(int argc, char *argv[])
kvm_vm_free(vm); kvm_vm_free(vm);
sys_rseq(RSEQ_FLAG_UNREGISTER); rseq_unregister_current_thread();
return 0; return 0;
} }
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment