The rseq selftests should discover whether the kernel implements the RSEQ_FLAG_RELIABLE_CPU_ID flag, which indicates that the __rseq_abi.cpu_id field is reliable. Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@xxxxxxxxxxxx> Cc: Shuah Khan <skhan@xxxxxxxxxxxxxxxxxxx> Cc: Peter Zijlstra (Intel) <peterz@xxxxxxxxxxxxx> Cc: Thomas Gleixner <tglx@xxxxxxxxxxxxx> Cc: Florian Weimer <fw@xxxxxxxxxxxxx> Cc: "Paul E. McKenney" <paulmck@xxxxxxxxxxxxx> Cc: Boqun Feng <boqun.feng@xxxxxxxxx> Cc: "H . Peter Anvin" <hpa@xxxxxxxxx> Cc: Paul Turner <pjt@xxxxxxxxxx> Cc: Dmitry Vyukov <dvyukov@xxxxxxxxxx> Cc: Neel Natu <neelnatu@xxxxxxxxxx> Cc: linux-api@xxxxxxxxxxxxxxx Cc: linux-kselftest@xxxxxxxxxxxxxxx --- tools/testing/selftests/rseq/rseq.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/tools/testing/selftests/rseq/rseq.c b/tools/testing/selftests/rseq/rseq.c index 7159eb777fd3..55f1edb0649c 100644 --- a/tools/testing/selftests/rseq/rseq.c +++ b/tools/testing/selftests/rseq/rseq.c @@ -73,6 +73,11 @@ static int sys_rseq(volatile struct rseq *rseq_abi, uint32_t rseq_len, return syscall(__NR_rseq, rseq_abi, rseq_len, flags, sig); } +static bool rseq_reliable_cpu_id(void) +{ + return sys_rseq(NULL, 0, RSEQ_FLAG_RELIABLE_CPU_ID, 0) == 0; +} + int rseq_register_current_thread(void) { int rc, ret = 0; @@ -87,7 +92,8 @@ int rseq_register_current_thread(void) } if (__rseq_refcount++) goto end; - rc = sys_rseq(&__rseq_abi, sizeof(struct rseq), 0, RSEQ_SIG); + rc = sys_rseq(&__rseq_abi, sizeof(struct rseq), + RSEQ_FLAG_REGISTER | RSEQ_FLAG_RELIABLE_CPU_ID, RSEQ_SIG); if (!rc) { assert(rseq_current_cpu_raw() >= 0); goto end; @@ -96,6 +102,8 @@ int rseq_register_current_thread(void) __rseq_abi.cpu_id = RSEQ_CPU_ID_REGISTRATION_FAILED; ret = -1; __rseq_refcount--; + if (errno == EINVAL && !rseq_reliable_cpu_id()) + fprintf(stderr, "Error: rseq does not provide a reliable cpu_id field.\n"); end: signal_restore(oldset); return ret; -- 2.17.1