linux-api.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
To: Peter Zijlstra <peterz@infradead.org>
Cc: linux-kernel@vger.kernel.org,
	Thomas Gleixner <tglx@linutronix.de>,
	"Paul E . McKenney" <paulmck@kernel.org>,
	Boqun Feng <boqun.feng@gmail.com>,
	"H . Peter Anvin" <hpa@zytor.com>, Paul Turner <pjt@google.com>,
	linux-api@vger.kernel.org, Christian Brauner <brauner@kernel.org>,
	Florian Weimer <fw@deneb.enyo.de>,
	David.Laight@ACULAB.COM, carlos@redhat.com,
	Peter Oskolkov <posk@posk.io>,
	Alexander Mikhalitsyn <alexander@mihalicyn.com>,
	Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
Subject: [PATCH v4 04/25] selftests/rseq: Use ELF auxiliary vector for extensible rseq
Date: Thu, 22 Sep 2022 06:59:19 -0400	[thread overview]
Message-ID: <20220922105941.237830-5-mathieu.desnoyers@efficios.com> (raw)
In-Reply-To: <20220922105941.237830-1-mathieu.desnoyers@efficios.com>

Use the ELF auxiliary vector AT_RSEQ_FEATURE_SIZE to detect the RSEQ
features supported by the kernel.

Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
---
 tools/testing/selftests/rseq/rseq-abi.h |  5 ++
 tools/testing/selftests/rseq/rseq.c     | 68 ++++++++++++++++++++++---
 tools/testing/selftests/rseq/rseq.h     | 18 +++++--
 3 files changed, 79 insertions(+), 12 deletions(-)

diff --git a/tools/testing/selftests/rseq/rseq-abi.h b/tools/testing/selftests/rseq/rseq-abi.h
index a8c44d9af71f..00ac846d85b0 100644
--- a/tools/testing/selftests/rseq/rseq-abi.h
+++ b/tools/testing/selftests/rseq/rseq-abi.h
@@ -146,6 +146,11 @@ struct rseq_abi {
 	 *     this thread.
 	 */
 	__u32 flags;
+
+	/*
+	 * Flexible array member at end of structure, after last feature field.
+	 */
+	char end[];
 } __attribute__((aligned(4 * sizeof(__u64))));
 
 #endif /* _RSEQ_ABI_H */
diff --git a/tools/testing/selftests/rseq/rseq.c b/tools/testing/selftests/rseq/rseq.c
index 986b9458efb2..20ea536d1012 100644
--- a/tools/testing/selftests/rseq/rseq.c
+++ b/tools/testing/selftests/rseq/rseq.c
@@ -28,6 +28,8 @@
 #include <limits.h>
 #include <dlfcn.h>
 #include <stddef.h>
+#include <sys/auxv.h>
+#include <linux/auxvec.h>
 
 #include "../kselftest.h"
 #include "rseq.h"
@@ -36,20 +38,38 @@ static const ptrdiff_t *libc_rseq_offset_p;
 static const unsigned int *libc_rseq_size_p;
 static const unsigned int *libc_rseq_flags_p;
 
-/* Offset from the thread pointer to the rseq area.  */
+/* Offset from the thread pointer to the rseq area. */
 ptrdiff_t rseq_offset;
 
-/* Size of the registered rseq area.  0 if the registration was
-   unsuccessful.  */
+/*
+ * Size of the registered rseq area. 0 if the registration was
+ * unsuccessful.
+ */
 unsigned int rseq_size = -1U;
 
 /* Flags used during rseq registration.  */
 unsigned int rseq_flags;
 
+/*
+ * rseq feature size supported by the kernel. 0 if the registration was
+ * unsuccessful.
+ */
+unsigned int rseq_feature_size = -1U;
+
 static int rseq_ownership;
+static int rseq_reg_success;	/* At least one rseq registration has succeded. */
+
+/* Allocate a large area for the TLS. */
+#define RSEQ_THREAD_AREA_ALLOC_SIZE	1024
+
+/* Original struct rseq feature size is 20 bytes. */
+#define ORIG_RSEQ_FEATURE_SIZE		20
+
+/* Orignal struct rseq allocation size is 32 bytes. */
+#define ORIG_RSEQ_ALLOC_SIZE		32
 
 static
-__thread struct rseq_abi __rseq_abi __attribute__((tls_model("initial-exec"))) = {
+__thread struct rseq_abi __rseq_abi __attribute__((tls_model("initial-exec"), aligned(RSEQ_THREAD_AREA_ALLOC_SIZE))) = {
 	.cpu_id = RSEQ_ABI_CPU_ID_UNINITIALIZED,
 };
 
@@ -84,10 +104,18 @@ int rseq_register_current_thread(void)
 		/* Treat libc's ownership as a successful registration. */
 		return 0;
 	}
-	rc = sys_rseq(&__rseq_abi, sizeof(struct rseq_abi), 0, RSEQ_SIG);
-	if (rc)
+	rc = sys_rseq(&__rseq_abi, rseq_size, 0, RSEQ_SIG);
+	if (rc) {
+		if (RSEQ_READ_ONCE(rseq_reg_success)) {
+			/* Incoherent success/failure within process. */
+			abort();
+		}
+		rseq_size = 0;
+		rseq_feature_size = 0;
 		return -1;
+	}
 	assert(rseq_current_cpu_raw() >= 0);
+	RSEQ_WRITE_ONCE(rseq_reg_success, 1);
 	return 0;
 }
 
@@ -99,12 +127,28 @@ int rseq_unregister_current_thread(void)
 		/* Treat libc's ownership as a successful unregistration. */
 		return 0;
 	}
-	rc = sys_rseq(&__rseq_abi, sizeof(struct rseq_abi), RSEQ_ABI_FLAG_UNREGISTER, RSEQ_SIG);
+	rc = sys_rseq(&__rseq_abi, rseq_size, RSEQ_ABI_FLAG_UNREGISTER, RSEQ_SIG);
 	if (rc)
 		return -1;
 	return 0;
 }
 
+static
+unsigned int get_rseq_feature_size(void)
+{
+	unsigned long auxv_rseq_feature_size, auxv_rseq_align;
+
+	auxv_rseq_align = getauxval(AT_RSEQ_ALIGN);
+	assert(!auxv_rseq_align || auxv_rseq_align <= RSEQ_THREAD_AREA_ALLOC_SIZE);
+
+	auxv_rseq_feature_size = getauxval(AT_RSEQ_FEATURE_SIZE);
+	assert(!auxv_rseq_feature_size || auxv_rseq_feature_size <= RSEQ_THREAD_AREA_ALLOC_SIZE);
+	if (auxv_rseq_feature_size)
+		return auxv_rseq_feature_size;
+	else
+		return ORIG_RSEQ_FEATURE_SIZE;
+}
+
 static __attribute__((constructor))
 void rseq_init(void)
 {
@@ -116,14 +160,21 @@ void rseq_init(void)
 		rseq_offset = *libc_rseq_offset_p;
 		rseq_size = *libc_rseq_size_p;
 		rseq_flags = *libc_rseq_flags_p;
+		rseq_feature_size = get_rseq_feature_size();
+		if (rseq_feature_size > rseq_size)
+			rseq_feature_size = rseq_size;
 		return;
 	}
 	if (!rseq_available())
 		return;
 	rseq_ownership = 1;
 	rseq_offset = (void *)&__rseq_abi - rseq_thread_pointer();
-	rseq_size = sizeof(struct rseq_abi);
 	rseq_flags = 0;
+	rseq_feature_size = get_rseq_feature_size();
+	if (rseq_feature_size == ORIG_RSEQ_FEATURE_SIZE)
+		rseq_size = ORIG_RSEQ_ALLOC_SIZE;
+	else
+		rseq_size = RSEQ_THREAD_AREA_ALLOC_SIZE;
 }
 
 static __attribute__((destructor))
@@ -133,6 +184,7 @@ void rseq_exit(void)
 		return;
 	rseq_offset = 0;
 	rseq_size = -1U;
+	rseq_feature_size = -1U;
 	rseq_ownership = 0;
 }
 
diff --git a/tools/testing/selftests/rseq/rseq.h b/tools/testing/selftests/rseq/rseq.h
index 6f7513384bf5..95adc1e1b0db 100644
--- a/tools/testing/selftests/rseq/rseq.h
+++ b/tools/testing/selftests/rseq/rseq.h
@@ -47,14 +47,24 @@
 
 #include "rseq-thread-pointer.h"
 
-/* Offset from the thread pointer to the rseq area.  */
+/* Offset from the thread pointer to the rseq area. */
 extern ptrdiff_t rseq_offset;
-/* Size of the registered rseq area.  0 if the registration was
-   unsuccessful.  */
+
+/*
+ * Size of the registered rseq area. 0 if the registration was
+ * unsuccessful.
+ */
 extern unsigned int rseq_size;
-/* Flags used during rseq registration.  */
+
+/* Flags used during rseq registration. */
 extern unsigned int rseq_flags;
 
+/*
+ * rseq feature size supported by the kernel. 0 if the registration was
+ * unsuccessful.
+ */
+extern unsigned int rseq_feature_size;
+
 static inline struct rseq_abi *rseq_get_abi(void)
 {
 	return (struct rseq_abi *) ((uintptr_t) rseq_thread_pointer() + rseq_offset);
-- 
2.25.1


  parent reply	other threads:[~2022-09-22 11:05 UTC|newest]

Thread overview: 42+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-09-22 10:59 [PATCH v4 00/25] RSEQ node id and virtual cpu id extensions Mathieu Desnoyers
2022-09-22 10:59 ` [PATCH v4 01/25] rseq: Introduce feature size and alignment ELF auxiliary vector entries Mathieu Desnoyers
2022-10-10 12:42   ` Florian Weimer
2022-10-17 16:09     ` Mathieu Desnoyers
2022-10-17 17:32       ` Mathieu Desnoyers
2022-10-18 15:34         ` Florian Weimer
2022-10-18 19:00           ` Mathieu Desnoyers
2022-09-22 10:59 ` [PATCH v4 02/25] rseq: Introduce extensible rseq ABI Mathieu Desnoyers
2022-09-22 10:59 ` [PATCH v4 03/25] rseq: Extend struct rseq with numa node id Mathieu Desnoyers
2022-09-23 11:13   ` Peter Zijlstra
2022-09-23 13:00     ` Mathieu Desnoyers
2022-09-23 13:09     ` [PATCH v4.1 03/25 1/1] " Mathieu Desnoyers
2022-09-22 10:59 ` Mathieu Desnoyers [this message]
2022-09-22 10:59 ` [PATCH v4 05/25] selftests/rseq: Implement rseq numa node id field selftest Mathieu Desnoyers
2022-09-22 10:59 ` [PATCH v4 06/25] lib: Invert _find_next_bit source arguments Mathieu Desnoyers
2022-09-27  8:04   ` kernel test robot
2022-09-22 10:59 ` [PATCH v4 07/25] lib: Implement find_{first,next}_{zero,one}_and_zero_bit Mathieu Desnoyers
2022-09-22 10:59 ` [PATCH v4 08/25] cpumask: Implement cpumask_{first,next}_{zero,one}_and_zero Mathieu Desnoyers
2022-09-22 10:59 ` [PATCH v4 09/25] sched: Introduce per memory space current virtual cpu id Mathieu Desnoyers
2022-09-27 13:43   ` [PATCH v4.1 " Mathieu Desnoyers
2022-09-22 10:59 ` [PATCH v4 10/25] rseq: Extend struct rseq with per memory space vcpu id Mathieu Desnoyers
2022-09-22 10:59 ` [PATCH v4 11/25] selftests/rseq: Remove RSEQ_SKIP_FASTPATH code Mathieu Desnoyers
2022-09-22 10:59 ` [PATCH v4 12/25] selftests/rseq: Implement rseq vm_vcpu_id field support Mathieu Desnoyers
2022-09-22 10:59 ` [PATCH v4 13/25] selftests/rseq: x86: Template memory ordering and percpu access mode Mathieu Desnoyers
2022-09-22 10:59 ` [PATCH v4 14/25] selftests/rseq: arm: " Mathieu Desnoyers
2022-09-22 10:59 ` [PATCH v4 15/25] selftests/rseq: arm64: " Mathieu Desnoyers
2022-09-22 10:59 ` [PATCH v4 16/25] selftests/rseq: mips: " Mathieu Desnoyers
2022-09-22 10:59 ` [PATCH v4 17/25] selftests/rseq: ppc: " Mathieu Desnoyers
2022-09-22 10:59 ` [PATCH v4 18/25] selftests/rseq: s390: " Mathieu Desnoyers
2022-09-22 10:59 ` [PATCH v4 19/25] selftests/rseq: riscv: " Mathieu Desnoyers
2022-09-22 10:59 ` [PATCH v4 20/25] selftests/rseq: Implement basic percpu ops vm_vcpu_id test Mathieu Desnoyers
2022-09-22 10:59 ` [PATCH v4 21/25] selftests/rseq: Implement parametrized " Mathieu Desnoyers
2022-09-22 10:59 ` [PATCH v4 22/25] selftests/rseq: x86: Implement rseq_load_u32_u32 Mathieu Desnoyers
2022-09-22 10:59 ` [PATCH v4 23/25] selftests/rseq: Implement numa node id vs vm_vcpu_id invariant test Mathieu Desnoyers
2022-09-22 10:59 ` [PATCH v4 24/25] selftests/rseq: parametrized test: Report/abort on negative cpu id Mathieu Desnoyers
2022-09-22 10:59 ` [PATCH v4 25/25] tracing/rseq: Add mm_vcpu_id field to rseq_update Mathieu Desnoyers
2022-09-22 15:14   ` kernel test robot
2022-09-22 15:33     ` [PATCH v4.1 " Mathieu Desnoyers
2022-09-23  9:55   ` [PATCH v4 " kernel test robot
     [not found] ` <e753568d-599c-d81a-8456-085bbbb0264d@efficios.com>
     [not found]   ` <CAEE+ybnLUHjU5-dWcWgcWiq-AM4ocquSbZ=PWiuexEsPB8P5Gw@mail.gmail.com>
2022-09-23 13:46     ` [PATCH v4 00/25] RSEQ node id and virtual cpu id extensions Mathieu Desnoyers
2022-10-10 13:04 ` Florian Weimer
2022-10-17 16:05   ` Mathieu Desnoyers

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20220922105941.237830-5-mathieu.desnoyers@efficios.com \
    --to=mathieu.desnoyers@efficios.com \
    --cc=David.Laight@ACULAB.COM \
    --cc=alexander@mihalicyn.com \
    --cc=boqun.feng@gmail.com \
    --cc=brauner@kernel.org \
    --cc=carlos@redhat.com \
    --cc=fw@deneb.enyo.de \
    --cc=hpa@zytor.com \
    --cc=linux-api@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=paulmck@kernel.org \
    --cc=peterz@infradead.org \
    --cc=pjt@google.com \
    --cc=posk@posk.io \
    --cc=tglx@linutronix.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).