From patchwork Thu Nov 21 19:08:51 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Michael Jeanson X-Patchwork-Id: 101690 X-Patchwork-Delegate: fweimer@redhat.com Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 2A57A3857346 for ; Thu, 21 Nov 2024 19:12:52 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 2A57A3857346 Authentication-Results: sourceware.org; dkim=pass (2048-bit key, unprotected) header.d=efficios.com header.i=@efficios.com header.a=rsa-sha256 header.s=smtpout1 header.b=P9QqdHts X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from smtpout.efficios.com (smtpout.efficios.com [167.114.26.122]) by sourceware.org (Postfix) with ESMTPS id B81A43857BA2 for ; Thu, 21 Nov 2024 19:09:36 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org B81A43857BA2 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=efficios.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=efficios.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org B81A43857BA2 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=167.114.26.122 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1732216176; cv=none; b=mewTjZpKu7SpXGuqQwF8zBmhx4fQ+Kh9EX2BSkZWJYOS9CMz7I5ptQQyrl+j5hWvVbk/kJWP90EGj1N+0jh1oU9PMGjHmh/0oEx3kQ+jYU9/vSO1bElZLTtpc1q4ucpzsGQNlghCrGDDgSx0QJnAcPgki1Bjr6X5A49xJwVqroY= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1732216176; c=relaxed/simple; bh=IaF8z8+yU+zEyyKiHb0wn6NGeDU4PCoWOEaZHkNCUv0=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=JtmG1ZXnCDznVrNA3cJsjjiYBXFgu1QL2dO9LviaXmAX8zJdmBTksHdX2eCy/3GuXqfzgBAiP2UXYPicDwQAxYgpNzHCDk7jTIrZDa3QEvLnDA4RO8Ct3XMjnsbu8tmyTpEMV0HmgMBniV/HAPVVfMQcGsKG0d7USXGPCC1Sq4w= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org B81A43857BA2 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=efficios.com; s=smtpout1; t=1732216176; bh=IaF8z8+yU+zEyyKiHb0wn6NGeDU4PCoWOEaZHkNCUv0=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=P9QqdHts3zEPxQNBZDNLaYoGTgjpTPcOEvDi6Y8fZ2nk5ZT8z23krqo3ApmTtfkA1 KQQHNUQIRBpSmn7p2knwMljzWBoWj86pr7OVZcY5x2dun65UZl8r7MvSbOEks6atzB 7YYdEiPOUkpRHD7RGUNEJcXKmbKwA+sRJ43X2TmQwLU0Y+L7Vx/TkM0etnQpTITZ2r rEOm24s/R7vGZ1OSWabyL4BrNH0JY+dByUtoASWSRtgLkjHCwrH6jTHh47PspUurbe rr6XIcISUdT25jovdFEPMWht8CmLOpn40ETGGbJq5nMw6SHuEG6/7jCdwIKfUF6Aox qb1JTqrXrgdAA== Received: from laptop-mjeanson.internal.efficios.com (96-127-217-162.qc.cable.ebox.net [96.127.217.162]) by smtpout.efficios.com (Postfix) with ESMTPSA id 4XvSTX21pZz14Sf; Thu, 21 Nov 2024 14:09:36 -0500 (EST) From: Michael Jeanson To: libc-alpha@sourceware.org Cc: Michael Jeanson , Florian Weimer , Carlos O'Donell , DJ Delorie , Mathieu Desnoyers Subject: [PATCH v14 1/9] nptl: initialize cpu_id_start prior to rseq registration Date: Thu, 21 Nov 2024 14:08:51 -0500 Message-ID: <20241121190924.837446-2-mjeanson@efficios.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20241121190924.837446-1-mjeanson@efficios.com> References: <20241121190924.837446-1-mjeanson@efficios.com> MIME-Version: 1.0 X-Spam-Status: No, score=-12.2 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: libc-alpha@sourceware.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Libc-alpha mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: libc-alpha-bounces~patchwork=sourceware.org@sourceware.org When adding explicit initialization of rseq fields prior to registration, I glossed over the fact that 'cpu_id_start' is also documented as initialized by user-space. While current kernels don't validate the content of this field on registration, future ones could. Signed-off-by: Michael Jeanson Reviewed-by: Mathieu Desnoyers --- sysdeps/unix/sysv/linux/rseq-internal.h | 1 + 1 file changed, 1 insertion(+) diff --git a/sysdeps/unix/sysv/linux/rseq-internal.h b/sysdeps/unix/sysv/linux/rseq-internal.h index 37a8f630b6..ef3eab1fef 100644 --- a/sysdeps/unix/sysv/linux/rseq-internal.h +++ b/sysdeps/unix/sysv/linux/rseq-internal.h @@ -56,6 +56,7 @@ rseq_register_current_thread (struct pthread *self, bool do_rseq) registration, there is no guarantee that struct pthread is cleared on all architectures. */ THREAD_SETMEM (self, rseq_area.cpu_id, RSEQ_CPU_ID_UNINITIALIZED); + THREAD_SETMEM (self, rseq_area.cpu_id_start, 0); THREAD_SETMEM (self, rseq_area.rseq_cs, 0); THREAD_SETMEM (self, rseq_area.flags, 0); From patchwork Thu Nov 21 19:08:52 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Michael Jeanson X-Patchwork-Id: 101688 X-Patchwork-Delegate: fweimer@redhat.com Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 0BD78385772C for ; Thu, 21 Nov 2024 19:12:46 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 0BD78385772C Authentication-Results: sourceware.org; dkim=pass (2048-bit key, unprotected) header.d=efficios.com header.i=@efficios.com header.a=rsa-sha256 header.s=smtpout1 header.b=MBJtXwDU X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from smtpout.efficios.com (smtpout.efficios.com [IPv6:2607:5300:203:b2ee::31e5]) by sourceware.org (Postfix) with ESMTPS id 92E813857BA5 for ; Thu, 21 Nov 2024 19:09:37 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 92E813857BA5 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=efficios.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=efficios.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 92E813857BA5 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=2607:5300:203:b2ee::31e5 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1732216177; cv=none; b=gGqal2kRiLsiWougfjjOphbvnuYFVQd+zay0+un2j6gI4CA18c4U9b2w8H7r7tiMtO4pxxs6EzDMq0ONrRbFZUprTL3kdbucDYMvsx5H5TidmNBmFBy2Jal6Rhoel71jHRT1g85F8zvOzxDJEMWj/syjvf9l25sPzyeuQaEgWtU= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1732216177; c=relaxed/simple; bh=Q+lwGZhhnt7LApo4Yv4AjD2YMKnGyAy1pzrP70TLz+w=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=r+Oe3PiQLWm8C+3m/y6ds+5P077eSS+hTcOHvCCshP8LH6eFnmp6gLxVQwiOxPt1FmDO5xP838DWeW6In9jRiPVc2oZoZSu7BbijVLLbphmT9L1KYl3P6+Jjp6RW9FzDpHiERMMv6CBMd73Wps7Nr5qoDmzd85gz4+61TZlNAbQ= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 92E813857BA5 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=efficios.com; s=smtpout1; t=1732216177; bh=Q+lwGZhhnt7LApo4Yv4AjD2YMKnGyAy1pzrP70TLz+w=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=MBJtXwDUGd9ftlFtsM/mtyHPKL0jPox8RdqYM8oOjnqAj9IA0AX4k3hlCqVbUeIUr XX7+fAi8/py65tkXvuphxM1kWxxhNLCNYGYewWp9qJZVWjNU8oY4Iwz2hb0F5y1hXD aC8SchRlbdHmB3t4uW5XatnkX3DwRKwtMm9O8Af/S0U7JvPNVVSSkWfp9b8GA1t+Xk jAFcTpMsdRXSDmfUyd0kAY1AXW3v2oY7BW2NseMOBp/1DW/Qg+4I9hacFtewylCog0 J9/a701/7V9JGNw6l4VSUhUG4I/Numty98b9o8DFNsV4GPz5yTxHcu93l/zqC6ljjE q3tnUD6eFKg2g== Received: from laptop-mjeanson.internal.efficios.com (96-127-217-162.qc.cable.ebox.net [96.127.217.162]) by smtpout.efficios.com (Postfix) with ESMTPSA id 4XvSTY1D8Xz14Sg; Thu, 21 Nov 2024 14:09:37 -0500 (EST) From: Michael Jeanson To: libc-alpha@sourceware.org Cc: Michael Jeanson , Florian Weimer , Carlos O'Donell , DJ Delorie , Mathieu Desnoyers Subject: [PATCH v14 2/9] nptl: Add rseq auxvals Date: Thu, 21 Nov 2024 14:08:52 -0500 Message-ID: <20241121190924.837446-3-mjeanson@efficios.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20241121190924.837446-1-mjeanson@efficios.com> References: <20241121190924.837446-1-mjeanson@efficios.com> MIME-Version: 1.0 X-Spam-Status: No, score=-12.2 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: libc-alpha@sourceware.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Libc-alpha mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: libc-alpha-bounces~patchwork=sourceware.org@sourceware.org Get the rseq feature size and alignment requirement from the auxiliary vector for use inside the dynamic loader. Use '__rseq_size' directly to store the feature size. If the main thread registration fails or is disabled by tunable, reset the value to 0. This will be used in the TLS block allocator to compute the size and alignment of the rseq area block for the extended ABI support. Signed-off-by: Michael Jeanson Reviewed-by: Mathieu Desnoyers --- Changes since v13: - Fix nits and typos in comments and commit message Changes since v12: - Set _rseq_size to 0 on registration failure Changes since v11: - Removed _dl_rseq_feature_size, use __rseq_size instead - Replace GLRO(dl_rseq_align) with a hidden global variable _rseq_align --- sysdeps/nptl/dl-tls_init_tp.c | 14 ++++++++++---- sysdeps/unix/sysv/linux/dl-parse_auxv.h | 13 +++++++++++++ sysdeps/unix/sysv/linux/rseq-internal.h | 24 +++++++++++++++++++++--- sysdeps/unix/sysv/linux/tst-rseq.c | 6 ++++-- sysdeps/unix/sysv/linux/tst-rseq.h | 1 + 5 files changed, 49 insertions(+), 9 deletions(-) diff --git a/sysdeps/nptl/dl-tls_init_tp.c b/sysdeps/nptl/dl-tls_init_tp.c index 7803e19fd1..801b993000 100644 --- a/sysdeps/nptl/dl-tls_init_tp.c +++ b/sysdeps/nptl/dl-tls_init_tp.c @@ -46,6 +46,8 @@ rtld_mutex_dummy (pthread_mutex_t *lock) const unsigned int __rseq_flags; +size_t _rseq_align attribute_hidden; + void __tls_pre_init_tp (void) { @@ -99,10 +101,14 @@ __tls_init_tp (void) } { - bool do_rseq = true; - do_rseq = TUNABLE_GET (rseq, int, NULL); - if (rseq_register_current_thread (pd, do_rseq)) - _rseq_size = RSEQ_AREA_SIZE_INITIAL_USED; + /* If the registration fails or is disabled by tunable, the public + '__rseq_size' will be set to '0' regardless of the feature size of the + allocated rseq area. An rseq area of at least 32 bytes is always + allocated since application code is allowed to check the status of the + rseq registration by reading the content of the 'cpu_id' field. */ + bool do_rseq = TUNABLE_GET (rseq, int, NULL); + if (!rseq_register_current_thread (pd, do_rseq)) + _rseq_size = 0; #ifdef RSEQ_SIG /* This should be a compile-time constant, but the current diff --git a/sysdeps/unix/sysv/linux/dl-parse_auxv.h b/sysdeps/unix/sysv/linux/dl-parse_auxv.h index ea2a58ecb1..5a0ef0ae2a 100644 --- a/sysdeps/unix/sysv/linux/dl-parse_auxv.h +++ b/sysdeps/unix/sysv/linux/dl-parse_auxv.h @@ -21,6 +21,7 @@ #include #include #include +#include typedef ElfW(Addr) dl_parse_auxv_t[AT_MINSIGSTKSZ + 1]; @@ -59,5 +60,17 @@ void _dl_parse_auxv (ElfW(auxv_t) *av, dl_parse_auxv_t auxv_values) GLRO(dl_sysinfo) = auxv_values[AT_SYSINFO]; #endif + /* Get the rseq feature size, with a minimum of RSEQ_AREA_SIZE_INITIAL_USED + (20) for kernels that don't have AT_RSEQ_FEATURE_SIZE. Limit the feature + size to RSEQ_AREA_SIZE_MAX_USED (28) which fits the rseq area in 'struct + pthread' and represents the maximum feature size of currently released + kernels. Since no kernels currently cross the 32 bytes of the original + ABI, the semantics of a feature size of 32 or more are still undetermined. + */ + _rseq_size = MIN (MAX (auxv_values[AT_RSEQ_FEATURE_SIZE], + RSEQ_AREA_SIZE_INITIAL_USED), + RSEQ_AREA_SIZE_MAX_USED); + _rseq_align = MAX (auxv_values[AT_RSEQ_ALIGN], RSEQ_MIN_ALIGN); + DL_PLATFORM_AUXV } diff --git a/sysdeps/unix/sysv/linux/rseq-internal.h b/sysdeps/unix/sysv/linux/rseq-internal.h index ef3eab1fef..7e0804ec52 100644 --- a/sysdeps/unix/sysv/linux/rseq-internal.h +++ b/sysdeps/unix/sysv/linux/rseq-internal.h @@ -25,13 +25,31 @@ #include #include -/* 32 is the initially required value for the area size. The - actually used rseq size may be less (20 bytes initially). */ +/* Minimum size of the rseq area allocation required by the syscall. The + actually used rseq feature size may be less (20 bytes initially). */ #define RSEQ_AREA_SIZE_INITIAL 32 + +/* Minimum used feature size of the rseq area. */ #define RSEQ_AREA_SIZE_INITIAL_USED 20 -/* The variables are in .data.relro but are not yet write-protected. */ +/* Maximum currently used feature size of the rseq area. */ +#define RSEQ_AREA_SIZE_MAX_USED 28 + +/* Minimum alignment of the rseq area. */ +#define RSEQ_MIN_ALIGN 32 + +/* Alignment requirement of the rseq area. + Populated from the auxiliary vector with a minimum of '32'. + In .data.relro but not yet write-protected. */ +extern size_t _rseq_align attribute_hidden; + +/* Size of the active features in the rseq area. + Populated from the auxiliary vector with a minimum of '20'. + In .data.relro but not yet write-protected. */ extern unsigned int _rseq_size attribute_hidden; + +/* Offset from the thread pointer to the rseq area. + In .data.relro but not yet write-protected. */ extern ptrdiff_t _rseq_offset attribute_hidden; #ifdef RSEQ_SIG diff --git a/sysdeps/unix/sysv/linux/tst-rseq.c b/sysdeps/unix/sysv/linux/tst-rseq.c index 08a9533130..d1ae16b953 100644 --- a/sysdeps/unix/sysv/linux/tst-rseq.c +++ b/sysdeps/unix/sysv/linux/tst-rseq.c @@ -38,13 +38,15 @@ static void do_rseq_main_test (void) { struct pthread *pd = THREAD_SELF; + size_t rseq_feature_size = MIN (MAX (getauxval (AT_RSEQ_FEATURE_SIZE), + RSEQ_AREA_SIZE_INITIAL_USED), + RSEQ_AREA_SIZE_MAX_USED); TEST_VERIFY_EXIT (rseq_thread_registered ()); TEST_COMPARE (__rseq_flags, 0); TEST_VERIFY ((char *) __thread_pointer () + __rseq_offset == (char *) &pd->rseq_area); - /* The current implementation only supports the initial size. */ - TEST_COMPARE (__rseq_size, 20); + TEST_COMPARE (__rseq_size, rseq_feature_size); } static void diff --git a/sysdeps/unix/sysv/linux/tst-rseq.h b/sysdeps/unix/sysv/linux/tst-rseq.h index dc603327d3..7f82554e83 100644 --- a/sysdeps/unix/sysv/linux/tst-rseq.h +++ b/sysdeps/unix/sysv/linux/tst-rseq.h @@ -23,6 +23,7 @@ #include #include #include +#include static inline bool rseq_thread_registered (void) From patchwork Thu Nov 21 19:08:53 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Michael Jeanson X-Patchwork-Id: 101691 X-Patchwork-Delegate: fweimer@redhat.com Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id A27E9385780C for ; Thu, 21 Nov 2024 19:16:45 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org A27E9385780C Authentication-Results: sourceware.org; dkim=pass (2048-bit key, unprotected) header.d=efficios.com header.i=@efficios.com header.a=rsa-sha256 header.s=smtpout1 header.b=ishrcNZx X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from smtpout.efficios.com (smtpout.efficios.com [167.114.26.122]) by sourceware.org (Postfix) with ESMTPS id 721BC3857BB6 for ; Thu, 21 Nov 2024 19:09:38 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 721BC3857BB6 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=efficios.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=efficios.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 721BC3857BB6 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=167.114.26.122 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1732216178; cv=none; b=ddCATchoIEyq36bWHb/UivrdqlcegcucZr7+F4FzBD8gMsYXN88fFQGkUT6Mt2bCue2mXeKXwC93NI3eTQ1XRQCUeXPbonez+ilFNIz24KTOMcr5c1dnj8oLERrO+UtyAe6E57aclkCdkjAC2fzozNNH6Q96+VRHlHWhsaz08SE= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1732216178; c=relaxed/simple; bh=x6De0FD/bqTvhc0uZAK/V478ska3UPG0HKpAqX2Tzbs=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=hd5WcbWmVaEJANCZzzitwpsXyMlLd4z8F04Bv7RxP1d5f+USnrRAEEPMQGW31tjdM7NYE8cVRyX+wUsCAdVbqMHfLLfGHb6n3bjJ8hO7wKY7a2mP/JdsYDQnIeBIllxKsP5LiM7zQ5BjTqkkiU1JfYgRuK6Iu8BouF7sIoTBfEU= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 721BC3857BB6 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=efficios.com; s=smtpout1; t=1732216178; bh=x6De0FD/bqTvhc0uZAK/V478ska3UPG0HKpAqX2Tzbs=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=ishrcNZxJGJN7dpLd5R/EEm+E0/rkI6IAdwvj3WmI04hptNDK2Q+WbmXd34WW4yJE CqEt4IcXNmzY1W5+SwKs4Ul/4UhVCAeF7p3AT4nAIu7SBwx/xSYf2v8nIXU6YTNjuM Y9H0O0XCzj+/esx1h8VjBFTAIIV9NkXYFshOY9Y5gHaMNj08W8BoZ7Y80FRjIATahU uMfgWa1rtLg3h5ZgNWmdw7gslgjTqVYtZboRwJMx/aTNl3GfAbC8tbUY7zpTdMCJKi MPFf/PwHF2/D6wwD8LOlkrkh5Xv4VL3vHhBImPUlyUCgf1sWVt0tOlNMLcurzoZFo3 QS3IBIi5AbpJQ== Received: from laptop-mjeanson.internal.efficios.com (96-127-217-162.qc.cable.ebox.net [96.127.217.162]) by smtpout.efficios.com (Postfix) with ESMTPSA id 4XvSTZ01d4z14Sh; Thu, 21 Nov 2024 14:09:37 -0500 (EST) From: Michael Jeanson To: libc-alpha@sourceware.org Cc: Michael Jeanson , Florian Weimer , Carlos O'Donell , DJ Delorie , Mathieu Desnoyers Subject: [PATCH v14 3/9] Add generic 'extra TLS' Date: Thu, 21 Nov 2024 14:08:53 -0500 Message-ID: <20241121190924.837446-4-mjeanson@efficios.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20241121190924.837446-1-mjeanson@efficios.com> References: <20241121190924.837446-1-mjeanson@efficios.com> MIME-Version: 1.0 X-Spam-Status: No, score=-12.2 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, KAM_SHORT, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: libc-alpha@sourceware.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Libc-alpha mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: libc-alpha-bounces~patchwork=sourceware.org@sourceware.org Add the logic to append an 'extra TLS' block in the TLS block allocator with a generic stub implementation. The duplicated code in 'csu/libc-tls.c' and 'elf/dl-tls.c' is to handle both statically linked applications and the ELF dynamic loader. Signed-off-by: Michael Jeanson Reviewed-by: Mathieu Desnoyers --- Changes since v13: - Improve commit message --- csu/libc-tls.c | 59 ++++++++++++++++++++++++++++------ elf/dl-tls.c | 59 ++++++++++++++++++++++++++++++++++ sysdeps/generic/dl-extra_tls.h | 45 ++++++++++++++++++++++++++ 3 files changed, 154 insertions(+), 9 deletions(-) create mode 100644 sysdeps/generic/dl-extra_tls.h diff --git a/csu/libc-tls.c b/csu/libc-tls.c index b7682bdf43..03a000c499 100644 --- a/csu/libc-tls.c +++ b/csu/libc-tls.c @@ -26,6 +26,7 @@ #include #include #include +#include #ifdef SHARED #error makefile bug, this file is for static only @@ -110,6 +111,7 @@ __libc_setup_tls (void) size_t filesz = 0; void *initimage = NULL; size_t align = 0; + size_t tls_blocks_size = 0; size_t max_align = TCB_ALIGNMENT; size_t tcb_offset; const ElfW(Phdr) *phdr; @@ -135,22 +137,67 @@ __libc_setup_tls (void) /* Calculate the size of the static TLS surplus, with 0 auditors. */ _dl_tls_static_surplus_init (0); + /* Extra TLS block for internal usage to append at the end of the TLS blocks + (in allocation order). On Linux systems this is where the rseq area will + be allocated. On other systems it is currently unused and both values will + be '0'. */ + size_t extra_tls_size = _dl_extra_tls_get_size(); + size_t extra_tls_align = _dl_extra_tls_get_align(); + + /* Increase the maximum alignment with the extra TLS alignment requirements + if necessary. */ + max_align = MAX (max_align, extra_tls_align); + /* We have to set up the TCB block which also (possibly) contains 'errno'. Therefore we avoid 'malloc' which might touch 'errno'. Instead we use 'sbrk' which would only uses 'errno' if it fails. In this case we are right away out of memory and the user gets what she/he deserves. */ #if TLS_TCB_AT_TP + /* Before the the thread pointer, add the aligned tls block size and then + align the extra tls block on top. */ + tls_blocks_size = roundup (roundup (memsz, align ?: 1) + extra_tls_size, + extra_tls_align); + + /* Record the extra TLS block offset from the thread pointer. + + With TLS_TCB_AT_TP the TLS blocks are allocated before the thread pointer + in reverse order. Our block is added last which results in it being the + first in the static TLS block, thus record the most negative offset. + + The alignment requirements of the pointer resulting from this offset and + the thread pointer are enforced by 'max_align' which is used to align the + tcb_offset. */ + _dl_extra_tls_set_offset(-tls_blocks_size); + /* Align the TCB offset to the maximum alignment, as _dl_allocate_tls_storage (in elf/dl-tls.c) does using __libc_memalign and dl_tls_static_align. */ - tcb_offset = roundup (memsz + GLRO(dl_tls_static_surplus), max_align); + tcb_offset = roundup (tls_blocks_size + GLRO(dl_tls_static_surplus), max_align); tlsblock = _dl_early_allocate (tcb_offset + TLS_INIT_TCB_SIZE + max_align); if (tlsblock == NULL) _startup_fatal_tls_error (); #elif TLS_DTV_AT_TP + /* Align memsz on top of the initial tcb. */ tcb_offset = roundup (TLS_INIT_TCB_SIZE, align ?: 1); - tlsblock = _dl_early_allocate (tcb_offset + memsz + max_align + + /* After the thread pointer, add the initial tcb plus the tls block size and + then align the extra TLS block on top. */ + tls_blocks_size = roundup (tcb_offset + memsz + extra_tls_size, extra_tls_align); + + /* Record the extra TLS block offset from the thread pointer. + + With TLS_DTV_AT_TP the TLS blocks are allocated after the thread pointer in + order. Our block is added last which results in it being the last in the + static TLS block, thus record the offset as the size of the static TLS + block minus the size of our block. The resulting offset will be positive. + + The alignment requirements of the pointer resulting from this offset and + the thread pointer are enforced by 'max_align' which is used to align the + tcb_offset. */ + _dl_extra_tls_set_offset(tls_blocks_size - extra_tls_size); + + tlsblock = _dl_early_allocate (tls_blocks_size + max_align + TLS_PRE_TCB_SIZE + GLRO(dl_tls_static_surplus)); if (tlsblock == NULL) @@ -209,11 +256,5 @@ __libc_setup_tls (void) /* static_slotinfo.slotinfo[1].gen = 0; -- Already zero. */ static_slotinfo.slotinfo[1].map = main_map; - memsz = roundup (memsz, align ?: 1); - -#if TLS_DTV_AT_TP - memsz += tcb_offset; -#endif - - init_static_tls (memsz, MAX (TCB_ALIGNMENT, max_align)); + init_static_tls (tls_blocks_size, MAX (TCB_ALIGNMENT, max_align)); } diff --git a/elf/dl-tls.c b/elf/dl-tls.c index 3d529b722c..57e72be4f2 100644 --- a/elf/dl-tls.c +++ b/elf/dl-tls.c @@ -36,6 +36,8 @@ #define TUNABLE_NAMESPACE rtld #include +#include + /* Surplus static TLS, GLRO(dl_tls_static_surplus), is used for - IE TLS in libc.so for all dlmopen namespaces except in the initial @@ -323,6 +325,33 @@ _dl_determine_tlsoffset (void) slotinfo[cnt].map->l_tls_offset = off; } + /* Insert the extra TLS block after the last TLS block. */ + + /* Extra TLS block for internal usage to append at the end of the TLS blocks + (in allocation order). On Linux systems this is where the rseq area will + be allocated. On other systems it is currently unused and both values will + be '0'. */ + size_t extra_tls_size = _dl_extra_tls_get_size(); + size_t extra_tls_align = _dl_extra_tls_get_align(); + + /* Align and add the extra TLS block to the global offset. */ + offset = roundup (offset, extra_tls_align) + extra_tls_size; + + /* Increase the maximum alignment with the extra TLS alignment requirements + if necessary. */ + max_align = MAX (max_align, extra_tls_align); + + /* Record the extra TLS offset. + + With TLS_TCB_AT_TP the TLS blocks are allocated before the thread pointer + in reverse order. Our block is added last which results in it being the + first in the static TLS block, thus record the most negative offset. + + The alignment requirements of the pointer resulting from this offset and + the thread pointer are enforced by 'max_align' which is used to align the + tcb_offset. */ + _dl_extra_tls_set_offset(-offset); + GL(dl_tls_static_used) = offset; GLRO (dl_tls_static_size) = (roundup (offset + GLRO(dl_tls_static_surplus), max_align) @@ -368,6 +397,36 @@ _dl_determine_tlsoffset (void) offset = off + slotinfo[cnt].map->l_tls_blocksize - firstbyte; } + /* Insert the extra TLS block after the last TLS block. */ + + /* Extra TLS block for internal usage to append at the end of the TLS blocks + (in allocation order). On Linux systems this is where the rseq area will + be allocated. On other systems it is currently unused and both values will + be '0'. */ + size_t extra_tls_size = _dl_extra_tls_get_size(); + size_t extra_tls_align = _dl_extra_tls_get_align(); + + /* Align the global offset to the beginning of the extra TLS block. */ + offset = roundup (offset, extra_tls_align); + + /* Record the extra TLS offset. + + With TLS_DTV_AT_TP the TLS blocks are allocated after the thread pointer in + order. Our block is added last which results in it being the last in the + static TLS block, thus record the offset as the size of the static TLS + block minus the size of our block. The resulting offset will be positive. + + The alignment requirements of the pointer resulting from this offset and + the thread pointer are enforced by 'max_align' which is used to align the + tcb_offset. */ + _dl_extra_tls_set_offset(offset); + + /* Add the extra TLS block to the global offset. */ + offset += extra_tls_size; + + /* Increase the max_align if necessary. */ + max_align = MAX (max_align, extra_tls_align); + GL(dl_tls_static_used) = offset; GLRO (dl_tls_static_size) = roundup (offset + GLRO(dl_tls_static_surplus), TCB_ALIGNMENT); diff --git a/sysdeps/generic/dl-extra_tls.h b/sysdeps/generic/dl-extra_tls.h new file mode 100644 index 0000000000..c699e88e85 --- /dev/null +++ b/sysdeps/generic/dl-extra_tls.h @@ -0,0 +1,45 @@ +/* extra tls utils for the dynamic linker. Generic stub version. + Copyright (C) 2024 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +#ifndef _DL_EXTRA_TLS_H +#define _DL_EXTRA_TLS_H 1 +#include + +/* In this generic version, the extra TLS block is unused. */ + +/* Returns the size of the extra TLS block. */ +static inline size_t +_dl_extra_tls_get_size (void) +{ + return 0; +} + +/* Returns the alignment requirements of the extra TLS block. */ +static inline size_t +_dl_extra_tls_get_align (void) +{ + return 0; +} + +/* Record the offset of the extra TLS block from the thread pointer. */ +static inline void +_dl_extra_tls_set_offset (ptrdiff_t tls_offset __attribute__ ((unused))) +{ +} + +#endif From patchwork Thu Nov 21 19:08:54 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Michael Jeanson X-Patchwork-Id: 101687 X-Patchwork-Delegate: fweimer@redhat.com Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 3D44A3857BA0 for ; Thu, 21 Nov 2024 19:12:24 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 3D44A3857BA0 Authentication-Results: sourceware.org; dkim=pass (2048-bit key, unprotected) header.d=efficios.com header.i=@efficios.com header.a=rsa-sha256 header.s=smtpout1 header.b=Y1NEsvrF X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from smtpout.efficios.com (smtpout.efficios.com [IPv6:2607:5300:203:b2ee::31e5]) by sourceware.org (Postfix) with ESMTPS id 409C43857BBA for ; Thu, 21 Nov 2024 19:09:39 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 409C43857BBA Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=efficios.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=efficios.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 409C43857BBA Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=2607:5300:203:b2ee::31e5 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1732216179; cv=none; b=qr9VF+u2sp+QZvGel1TdL+20H5iNIqfCT6nTno8BPWHI1SyIUryhc/stbWFTe5H8vpPAXBt8ssKAdZFSl+l/wsPZp5q2//wjw26FkR6P/ZfPQu6IUCOzYtpwzDz9mvOSOYZOGXG7O1OOmVYq4Ec53uX6Y/o/QS09ROwMHX50KxA= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1732216179; c=relaxed/simple; bh=d6d3ueq/0/CMrgatJRVZLYZfnYLeDHA822+lpyKA3Q4=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=gAUaxr8/CHkCKiCiRkqmg9SUN32sln0SsxNrF4qr0WUmoq9mOWLCVFEPPzZBBSlxssaqbpwcLyvSAVvfPCujAiqDS6yFXT/ZdGH1wAaFSTAfH9psYqkWj9dMN26tSPyLocgHCRqA8uMWCZmVMQgE2DuocMFJXZU497aK5LN3neU= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 409C43857BBA DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=efficios.com; s=smtpout1; t=1732216178; bh=d6d3ueq/0/CMrgatJRVZLYZfnYLeDHA822+lpyKA3Q4=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=Y1NEsvrFJ2radvXrIESlRHCr8pkBiHKE5pWZIK/sYwL3lRk7dYcBmkHPs3dVKPe0/ jViJ0iTmbioZSkTEa6bj4q0MAdHaSYMEFS2vCZVIIMVmxP2NRE7Hd3blhyfOJOLeOG lfvS8RWDPsjIB6dT7oOZGXSNzCtJ3ITfZux2jaA+sZZlNRjF6fPhPJZQUSzKrSAfJX oG0hiqo++5gGYbVLBOQ2Gw24mDTPYRwYg2xFWgOjilo5Ow97Ib9wVXcGmXsRVvs00l rwb/r6JaKWHA11ITDHIvN+SCe3/iY2sDv20PDr0+4h5JpUmkTODedoKCP+yiO3+aq2 H/aRgS8wOhw4w== Received: from laptop-mjeanson.internal.efficios.com (96-127-217-162.qc.cable.ebox.net [96.127.217.162]) by smtpout.efficios.com (Postfix) with ESMTPSA id 4XvSTZ5k83z13GF; Thu, 21 Nov 2024 14:09:38 -0500 (EST) From: Michael Jeanson To: libc-alpha@sourceware.org Cc: Michael Jeanson , Florian Weimer , Carlos O'Donell , DJ Delorie , Mathieu Desnoyers Subject: [PATCH v14 4/9] Add Linux 'extra TLS' Date: Thu, 21 Nov 2024 14:08:54 -0500 Message-ID: <20241121190924.837446-5-mjeanson@efficios.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20241121190924.837446-1-mjeanson@efficios.com> References: <20241121190924.837446-1-mjeanson@efficios.com> MIME-Version: 1.0 X-Spam-Status: No, score=-12.2 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, KAM_SHORT, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: libc-alpha@sourceware.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Libc-alpha mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: libc-alpha-bounces~patchwork=sourceware.org@sourceware.org Add the Linux implementation of 'extra TLS' which will allocate space for the rseq area at the end of the TLS blocks in allocation order. Signed-off-by: Michael Jeanson Reviewed-by: Mathieu Desnoyers --- sysdeps/unix/sysv/linux/dl-extra_tls.h | 70 ++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) create mode 100644 sysdeps/unix/sysv/linux/dl-extra_tls.h diff --git a/sysdeps/unix/sysv/linux/dl-extra_tls.h b/sysdeps/unix/sysv/linux/dl-extra_tls.h new file mode 100644 index 0000000000..52208f0407 --- /dev/null +++ b/sysdeps/unix/sysv/linux/dl-extra_tls.h @@ -0,0 +1,70 @@ +/* extra tls block utils for the dynamic linker. Linux version. + Copyright (C) 2024 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +#ifndef _DL_EXTRA_TLS_H +#define _DL_EXTRA_TLS_H 1 + +#include +#include +#include +#include + +/* Returns the size of the extra TLS block. */ +static inline size_t +_dl_extra_tls_get_size (void) +{ + bool do_rseq = TUNABLE_GET_FULL (glibc, pthread, rseq, int, NULL); + if (do_rseq) + { + /* Make sure the rseq area size is at least the minimum ABI size and a + multiple of the requested aligment. */ + return roundup (MAX (_rseq_size, RSEQ_AREA_SIZE_INITIAL), _rseq_align); + } + + /* Even when disabled by tunable, an rseq area will be allocated to allow + application code to test the registration status with 'rseq->cpu_id >= 0'. + Default to the rseq ABI minimum size, this will ensure we don't use more + TLS than necessary. */ + return RSEQ_AREA_SIZE_INITIAL; +} + +/* Returns the alignment requirements of the extra TLS block. */ +static inline size_t +_dl_extra_tls_get_align (void) +{ + bool do_rseq = TUNABLE_GET_FULL (glibc, pthread, rseq, int, NULL); + if (do_rseq) + { + return _rseq_align; + } + + /* Even when disabled by tunable, an rseq area will be allocated to allow + application code to test the registration status with 'rseq->cpu_id >= 0'. + Default to the rseq ABI minimum alignment, this will ensure we don't use + more TLS than necessary. */ + return RSEQ_MIN_ALIGN; +} + +/* Record the offset of the extra TLS block from the thread pointer. */ +static inline void +_dl_extra_tls_set_offset (ptrdiff_t tls_offset) +{ + _rseq_offset = tls_offset; +} + +#endif From patchwork Thu Nov 21 19:08:55 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Michael Jeanson X-Patchwork-Id: 101692 X-Patchwork-Delegate: fweimer@redhat.com Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id B81D0385771E for ; Thu, 21 Nov 2024 19:17:27 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org B81D0385771E Authentication-Results: sourceware.org; dkim=pass (2048-bit key, unprotected) header.d=efficios.com header.i=@efficios.com header.a=rsa-sha256 header.s=smtpout1 header.b=RXpF3P+g X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from smtpout.efficios.com (smtpout.efficios.com [167.114.26.122]) by sourceware.org (Postfix) with ESMTPS id 99963385781B for ; Thu, 21 Nov 2024 19:09:47 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 99963385781B Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=efficios.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=efficios.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 99963385781B Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=167.114.26.122 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1732216187; cv=none; b=I1A03kKB7diF/QrKHVKElhgDTkRmb4okUFfVTPTc3Xex6a6R1KOPeLc7C+cqh0WBP8Tfp8KNPSjkKqvnATI0+yCdiatCsPNYBpPbwO4/qYmDB5VEQ3QRqHadflCgkMkQceEYLk9Z+vwEokPOVlB+pw+DNMMA/JGTUxw0nVOgzHs= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1732216187; c=relaxed/simple; bh=zRR5npomnPJm3yN8G47LKmRIVDVV4qRma9Fv6NLBP6g=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=TWuBXYTl94BrBPXlMVIPiYTFeYFVZDhvTUkwTJjr2JqSP+93+G7wyyWtEL7VFUei3/riH5QgyXrS0Zoj/XPWVbQJjzo2EMSEOUxslg/695QMgKHUTww/3smK6qLZRxhoXlsIan0gdSeeQrpzJRkSpQGaKMJRiBdGHwHfm62KCeE= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 99963385781B DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=efficios.com; s=smtpout1; t=1732216179; bh=zRR5npomnPJm3yN8G47LKmRIVDVV4qRma9Fv6NLBP6g=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=RXpF3P+g3hTb1GiHzYYFqJR84LqSCRJiY3s276a5PYt0CcU6apbPTUON6vPUsoI6b 32IlIWFmWeh1h26U5EMBl+RxWWmX864VCIsbr7vm0+Llhv22pNQq30o6rcg6HHSkgV tQlshXb2nbZiegLLnQlgk45PB7U4COC12l/IktdCiPRpl60YzsSr6x+g9cz1AYwiVu hePAFyn7x19Thi33mMBpiGhfB4mPQiiO9LvUO3/nwvd4FGObY2rDw13AiXwovBqAzE zgG3/SmQgdtoliC+8AGLBncDGkWkTdsFpBtln0JCdHek/5NWUYYurQK1abOj3Rriax k++0XHKmdkhdg== Received: from laptop-mjeanson.internal.efficios.com (96-127-217-162.qc.cable.ebox.net [96.127.217.162]) by smtpout.efficios.com (Postfix) with ESMTPSA id 4XvSTb4MrQz13GG; Thu, 21 Nov 2024 14:09:39 -0500 (EST) From: Michael Jeanson To: libc-alpha@sourceware.org Cc: Michael Jeanson , Florian Weimer , Carlos O'Donell , DJ Delorie , Mathieu Desnoyers Subject: [PATCH v14 5/9] nptl: add rtld_hidden_proto to __rseq_size and __rseq_offset Date: Thu, 21 Nov 2024 14:08:55 -0500 Message-ID: <20241121190924.837446-6-mjeanson@efficios.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20241121190924.837446-1-mjeanson@efficios.com> References: <20241121190924.837446-1-mjeanson@efficios.com> MIME-Version: 1.0 X-Spam-Status: No, score=-12.2 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: libc-alpha@sourceware.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Libc-alpha mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: libc-alpha-bounces~patchwork=sourceware.org@sourceware.org This allows accessing the internal aliases of __rseq_size and __rseq_offset from ld.so without ifdefs and avoids a PLT entry in ld.so for both variables. Signed-off-by: Michael Jeanson Reviewed-by: Mathieu Desnoyers --- sysdeps/unix/sysv/linux/dl-rseq-symbols.S | 27 ++++++++++++++++------- sysdeps/unix/sysv/linux/rseq-internal.h | 16 ++++++++------ 2 files changed, 28 insertions(+), 15 deletions(-) diff --git a/sysdeps/unix/sysv/linux/dl-rseq-symbols.S b/sysdeps/unix/sysv/linux/dl-rseq-symbols.S index b4bba06a99..66b33c1096 100644 --- a/sysdeps/unix/sysv/linux/dl-rseq-symbols.S +++ b/sysdeps/unix/sysv/linux/dl-rseq-symbols.S @@ -27,14 +27,18 @@ /* Some targets define a macro to denote the zero register. */ #undef zero -/* Define 2 symbols: '__rseq_size' is public const and '_rseq_size' (an - alias of '__rseq_size') is hidden and writable for internal use by the - dynamic linker which will initialize the value both symbols point to - before copy relocations take place. */ +/* Define 3 symbols: '__rseq_size' is public const and then '_rseq_size' and + '__GI___rseq_size' (both aliases of '__rseq_size') are hidden, '_rseq_size' + is writable for internal use by the dynamic linker which will initialize + the value the symbols point to before copy relocations take place. */ .globl __rseq_size .type __rseq_size, %object .size __rseq_size, 4 + .hidden __GI___rseq_size + .globl __GI___rseq_size + .type __GI___rseq_size, %object + .size __GI___rseq_size, 4 .hidden _rseq_size .globl _rseq_size .type _rseq_size, %object @@ -42,17 +46,23 @@ .section .data.rel.ro .balign 4 __rseq_size: +__GI___rseq_size: _rseq_size: .zero 4 -/* Define 2 symbols: '__rseq_offset' is public const and '_rseq_offset' (an - alias of '__rseq_offset') is hidden and writable for internal use by the - dynamic linker which will initialize the value both symbols point to - before copy relocations take place. */ +/* Define 3 symbols: '__rseq_offset' is public const and then '_rseq_offset' + and '__GI___rseq_offset' (both aliases of '__rseq_offset') are hidden, + '_rseq_offset' is writable for internal use by the dynamic linker which will + initialize the value the symbols point to before copy relocations take + place. */ .globl __rseq_offset .type __rseq_offset, %object .size __rseq_offset, RSEQ_OFFSET_SIZE + .hidden __GI___rseq_offset + .globl __GI___rseq_offset + .type __GI___rseq_offset, %object + .size __GI___rseq_offset, RSEQ_OFFSET_SIZE .hidden _rseq_offset .globl _rseq_offset .type _rseq_offset, %object @@ -60,5 +70,6 @@ _rseq_size: .section .data.rel.ro .balign RSEQ_OFFSET_SIZE __rseq_offset: +__GI___rseq_offset: _rseq_offset: .zero RSEQ_OFFSET_SIZE diff --git a/sysdeps/unix/sysv/linux/rseq-internal.h b/sysdeps/unix/sysv/linux/rseq-internal.h index 7e0804ec52..30b3d5bb19 100644 --- a/sysdeps/unix/sysv/linux/rseq-internal.h +++ b/sysdeps/unix/sysv/linux/rseq-internal.h @@ -24,6 +24,7 @@ #include #include #include +#include /* Minimum size of the rseq area allocation required by the syscall. The actually used rseq feature size may be less (20 bytes initially). */ @@ -52,19 +53,20 @@ extern unsigned int _rseq_size attribute_hidden; In .data.relro but not yet write-protected. */ extern ptrdiff_t _rseq_offset attribute_hidden; +/* We want to use rtld_hidden_proto in order to call the internal aliases + of __rseq_size and __rseq_offset from ld.so. This avoids a PLT entry in + ld.so for both variables. */ +rtld_hidden_proto (__rseq_size) +rtld_hidden_proto (__rseq_offset) + #ifdef RSEQ_SIG static inline bool rseq_register_current_thread (struct pthread *self, bool do_rseq) { if (do_rseq) { - unsigned int size; -#if IS_IN (rtld) - /* Use the hidden symbol in ld.so. */ - size = _rseq_size; -#else - size = __rseq_size; -#endif + unsigned int size = __rseq_size; + if (size < RSEQ_AREA_SIZE_INITIAL) /* The initial implementation used only 20 bytes out of 32, but still expected size 32. */ From patchwork Thu Nov 21 19:08:56 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Michael Jeanson X-Patchwork-Id: 101695 X-Patchwork-Delegate: fweimer@redhat.com Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 6B0D53857BBA for ; Thu, 21 Nov 2024 19:22:34 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 6B0D53857BBA Authentication-Results: sourceware.org; dkim=pass (2048-bit key, unprotected) header.d=efficios.com header.i=@efficios.com header.a=rsa-sha256 header.s=smtpout1 header.b=X1m8OQeH X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from smtpout.efficios.com (smtpout.efficios.com [167.114.26.122]) by sourceware.org (Postfix) with ESMTPS id 94D193857BA0 for ; Thu, 21 Nov 2024 19:09:47 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 94D193857BA0 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=efficios.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=efficios.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 94D193857BA0 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=167.114.26.122 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1732216187; cv=none; b=F09uOVtm5MREKNfqqJhtnQhhTjMS+gz0VUohNwtqz9bBeW3oL/b/SdbbVTowa/fCy+nHTC4r6x04MnJRFWwMB9Rhh4s13QsGHxNMBufiTMfBxkf/2Y/w9jeDnLsHqCPnYfd6M/KksKcuYNkIjrs/NKBpAcjCO0cznfjtONSbsao= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1732216187; c=relaxed/simple; bh=5Y/pQYgurNSxVPLw5/I2FbdfbGCi+Z0KpoX1/zcFSak=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=R9ECwC9fDHm1TEPMxMuAae7rR5mYGAqLolgqg8Bj+1fABaHsLCCqQVwf5zNSOq26owF90g31rbBNaBzGP5n45GPkVhUZOzAc1wOxYEWzKDTZIRHvtLPjCiHeNR0V+Ps+4NMCHqECsMy4l0+zTqjLRdK2t6Mr7QiMEthNiBmPGWo= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 94D193857BA0 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=efficios.com; s=smtpout1; t=1732216180; bh=5Y/pQYgurNSxVPLw5/I2FbdfbGCi+Z0KpoX1/zcFSak=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=X1m8OQeHQOxnngcPxB/pkoXItG2ntzCYwXQ8PYEPeXxTxmdafWG7L0+RHN0gfYVrk vpbGJD3SOVO5+M5xT0mVea1MJKf/S5eOgAI4sGzuSPGrsgyCb4kqEEhrVHLrKhGRcb nbXNGzH6sxXbmfduZ272xUVgTqPb4rJ4J/qi17t9d0izpxayIDxTjlj3mmaHM/aJTL ElIlw9jWJShTO/cu4AfmE2ymROyxFrnOIIyTsNBQ6nKBFxPRx2fKEokoH+f4Owf8sf L5Pd2i8CLie6urmqa4Oc6CQ1jhAtECnQx2JAHmHKgXx6GABcFpPsb6kJNvbBd39CF9 l0TeA92kWzZoQ== Received: from laptop-mjeanson.internal.efficios.com (96-127-217-162.qc.cable.ebox.net [96.127.217.162]) by smtpout.efficios.com (Postfix) with ESMTPSA id 4XvSTc3Wy1z141Y; Thu, 21 Nov 2024 14:09:40 -0500 (EST) From: Michael Jeanson To: libc-alpha@sourceware.org Cc: Michael Jeanson , Florian Weimer , Carlos O'Donell , DJ Delorie , Mathieu Desnoyers Subject: [PATCH v14 6/9] nptl: Introduce for RSEQ_* accessors Date: Thu, 21 Nov 2024 14:08:56 -0500 Message-ID: <20241121190924.837446-7-mjeanson@efficios.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20241121190924.837446-1-mjeanson@efficios.com> References: <20241121190924.837446-1-mjeanson@efficios.com> MIME-Version: 1.0 X-Spam-Status: No, score=-12.2 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, KAM_SHORT, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: libc-alpha@sourceware.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Libc-alpha mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: libc-alpha-bounces~patchwork=sourceware.org@sourceware.org In preparation to move the rseq area to the 'extra TLS' block, we need accessors based on the thread pointer and the rseq offset. The VOLATILE variant of the accessors ensures single-copy atomicity for loads and stores which is required for all fields once the registration is active. A separate header is required to allow including which results in an include loop when added to . Signed-off-by: Michael Jeanson Reviewed-by: Mathieu Desnoyers --- Changes since v13: - Ensure that the VOLATILE variant static assert on 64bit types on 32bit architectures - Split to separate header to allow including 'atomic.h' without an include loop - Move rtld_hidden_proto rseq symbols to a separate patch Changes since v12: - Split RSEQ_SET/GETMEM from THREAD_SET/GETMEM - Rename rseq_get_area() to RSEQ_SELF() - Add rtld_hidden_proto to __rseq_size and __rseq_offset --- sysdeps/i386/nptl/rseq-access.h | 98 +++++++++++++++++++++++++ sysdeps/nptl/rseq-access.h | 58 +++++++++++++++ sysdeps/unix/sysv/linux/rseq-internal.h | 8 ++ sysdeps/x86_64/nptl/rseq-access.h | 79 ++++++++++++++++++++ 4 files changed, 243 insertions(+) create mode 100644 sysdeps/i386/nptl/rseq-access.h create mode 100644 sysdeps/nptl/rseq-access.h create mode 100644 sysdeps/x86_64/nptl/rseq-access.h diff --git a/sysdeps/i386/nptl/rseq-access.h b/sysdeps/i386/nptl/rseq-access.h new file mode 100644 index 0000000000..1ddb0219c0 --- /dev/null +++ b/sysdeps/i386/nptl/rseq-access.h @@ -0,0 +1,98 @@ +/* RSEQ_* accessors. i386 version. + Copyright (C) 2002-2024 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +#define __RSEQ_GETMEM(member) \ + ({ __typeof (RSEQ_SELF()->member) __value; \ + if (sizeof (__value) == 1) \ + asm volatile ("movb %%gs:%P2(%3),%b0" \ + : "=q" (__value) \ + : "0" (0), "i" (offsetof (struct rseq_area, member)), \ + "r" (__rseq_offset)); \ + else if (sizeof (__value) == 4) \ + asm volatile ("movl %%gs:%P1(%2),%0" \ + : "=r" (__value) \ + : "i" (offsetof (struct rseq_area, member)), \ + "r" (__rseq_offset)); \ + else /* 8 */ \ + { \ + asm volatile ("movl %%gs:%P1(%2),%%eax\n\t" \ + "movl %%gs:4+%P1(%2),%%edx" \ + : "=&A" (__value) \ + : "i" (offsetof (struct rseq_area, member)), \ + "r" (__rseq_offset)); \ + } \ + __value; }) + +/* Read member of the RSEQ area directly. */ +#define RSEQ_GETMEM(member) \ + ({ \ + _Static_assert (sizeof (RSEQ_SELF()->member) == 1 \ + || sizeof (RSEQ_SELF()->member) == 4 \ + || sizeof (RSEQ_SELF()->member) == 8, \ + "size of rseq data"); \ + __RSEQ_GETMEM(member); }) + +/* Read member of the RSEQ area directly, with single-copy atomicity semantics, + hence the 'volatile'. Static assert for types >= 64 bits since they can't be + loaded atomically on x86-32. */ +#define RSEQ_GETMEM_VOLATILE(member) \ + ({ \ + _Static_assert (sizeof (RSEQ_SELF()->member) == 1 \ + || sizeof (RSEQ_SELF()->member) == 4, \ + "size of rseq data"); \ + __RSEQ_GETMEM(member); }) + +#define __RSEQ_SETMEM(member, value) \ + ({ \ + if (sizeof (RSEQ_SELF()->member) == 1) \ + asm volatile ("movb %b0,%%gs:%P1(%2)" : \ + : "iq" (value), \ + "i" (offsetof (struct rseq_area, member)), \ + "r" (__rseq_offset)); \ + else if (sizeof (RSEQ_SELF()->member) == 4) \ + asm volatile ("movl %0,%%gs:%P1(%2)" : \ + : "ir" (value), \ + "i" (offsetof (struct rseq_area, member)), \ + "r" (__rseq_offset)); \ + else /* 8 */ \ + { \ + asm volatile ("movl %%eax,%%gs:%P1(%2)\n\t" \ + "movl %%edx,%%gs:4+%P1(%2)" : \ + : "A" ((uint64_t) cast_to_integer (value)), \ + "i" (offsetof (struct rseq_area, member)), \ + "r" (__rseq_offset)); \ + }}) + +/* Set member of the RSEQ area directly. */ +#define RSEQ_SETMEM(member, value) \ + ({ \ + _Static_assert (sizeof (RSEQ_SELF()->member) == 1 \ + || sizeof (RSEQ_SELF()->member) == 4 \ + || sizeof (RSEQ_SELF()->member) == 8, \ + "size of rseq data"); \ + __RSEQ_SETMEM(member, value); }) + +/* Set member of the RSEQ area directly, with single-copy atomicity semantics, + hence the 'volatile'. Static assert for types >= 64 bits since they can't be + stored atomically on x86-32. */ +#define RSEQ_SETMEM_VOLATILE(member, value) \ + ({ \ + _Static_assert (sizeof (RSEQ_SELF()->member) == 1 \ + || sizeof (RSEQ_SELF()->member) == 4, \ + "size of rseq data"); \ + __RSEQ_SETMEM(member, value); }) diff --git a/sysdeps/nptl/rseq-access.h b/sysdeps/nptl/rseq-access.h new file mode 100644 index 0000000000..1681a53ebf --- /dev/null +++ b/sysdeps/nptl/rseq-access.h @@ -0,0 +1,58 @@ +/* RSEQ_* accessors. Generic version. + Copyright (C) 2002-2024 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +#include + +/* Read member of the RSEQ area directly. */ +#define RSEQ_GETMEM(member) \ + RSEQ_SELF()->member + +/* Set member of the RSEQ area directly. */ +#define RSEQ_SETMEM(member, value) \ + RSEQ_SELF()->member = (value) + +/* Static assert for types that can't be loaded/stored atomically on the + current architecture. */ +#if __HAVE_64B_ATOMICS +#define __RSEQ_ASSERT_ATOMIC(member) \ + _Static_assert (sizeof (RSEQ_SELF()->member) == 1 \ + || sizeof (RSEQ_SELF()->member) == 4 \ + || sizeof (RSEQ_SELF()->member) == 8, \ + "size of rseq data") +#else +#define __RSEQ_ASSERT_ATOMIC(member) \ + _Static_assert (sizeof (RSEQ_SELF()->member) == 1 \ + || sizeof (RSEQ_SELF()->member) == 4, \ + "size of rseq data") +#endif + +/* Read member of the RSEQ area directly, with single-copy atomicity semantics, + hence the 'volatile'. */ +#define RSEQ_GETMEM_VOLATILE(member) \ + ({ \ + __RSEQ_ASSERT_ATOMIC(member); \ + (*(volatile __typeof (RSEQ_SELF()->member) *)&RSEQ_SELF()->member); \ + }) + +/* Set member of the RSEQ area directly, with single-copy atomicity semantics, + hence the 'volatile'. */ +#define RSEQ_SETMEM_VOLATILE(member, value) \ + ({ \ + __RSEQ_ASSERT_ATOMIC(member); \ + (*(volatile __typeof (RSEQ_SELF()->member) *)&RSEQ_SELF()->member = (value)); \ + }) diff --git a/sysdeps/unix/sysv/linux/rseq-internal.h b/sysdeps/unix/sysv/linux/rseq-internal.h index 30b3d5bb19..8e4a292ffc 100644 --- a/sysdeps/unix/sysv/linux/rseq-internal.h +++ b/sysdeps/unix/sysv/linux/rseq-internal.h @@ -25,6 +25,7 @@ #include #include #include +#include /* Minimum size of the rseq area allocation required by the syscall. The actually used rseq feature size may be less (20 bytes initially). */ @@ -59,6 +60,13 @@ extern ptrdiff_t _rseq_offset attribute_hidden; rtld_hidden_proto (__rseq_size) rtld_hidden_proto (__rseq_offset) +/* Returns a pointer to the current thread rseq area. */ +static inline struct rseq_area * +RSEQ_SELF (void) +{ + return (struct rseq_area *) ((char *) __thread_pointer () + __rseq_offset); +} + #ifdef RSEQ_SIG static inline bool rseq_register_current_thread (struct pthread *self, bool do_rseq) diff --git a/sysdeps/x86_64/nptl/rseq-access.h b/sysdeps/x86_64/nptl/rseq-access.h new file mode 100644 index 0000000000..fad215bccf --- /dev/null +++ b/sysdeps/x86_64/nptl/rseq-access.h @@ -0,0 +1,79 @@ +/* RSEQ_* accessors. x86_64 version. + Copyright (C) 2002-2024 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +/* Read member of the RSEQ area directly, with single-copy atomicity semantics, + hence the 'volatile'. */ +#define RSEQ_GETMEM_VOLATILE(member) \ + ({ __typeof (RSEQ_SELF()->member) __value; \ + _Static_assert (sizeof (__value) == 1 \ + || sizeof (__value) == 4 \ + || sizeof (__value) == 8, \ + "size of rseq data"); \ + if (sizeof (__value) == 1) \ + asm volatile ("movb %%fs:%P2(%q3),%b0" \ + : "=q" (__value) \ + : "0" (0), "i" (offsetof (struct rseq_area, member)), \ + "r" (__rseq_offset)); \ + else if (sizeof (__value) == 4) \ + asm volatile ("movl %%fs:%P1(%q2),%0" \ + : "=r" (__value) \ + : "i" (offsetof (struct rseq_area, member)), \ + "r" (__rseq_offset)); \ + else /* 8 */ \ + { \ + asm volatile ("movq %%fs:%P1(%q2),%q0" \ + : "=r" (__value) \ + : "i" (offsetof (struct rseq_area, member)), \ + "r" (__rseq_offset)); \ + } \ + __value; }) + +/* Read member of the RSEQ area directly. */ +#define RSEQ_GETMEM(member) RSEQ_GETMEM_VOLATILE(member) + +/* Set member of the RSEQ area directly, with single-copy atomicity semantics, + hence the 'volatile'. */ +#define RSEQ_SETMEM_VOLATILE(member, value) \ + ({ \ + _Static_assert (sizeof (RSEQ_SELF()->member) == 1 \ + || sizeof (RSEQ_SELF()->member) == 4 \ + || sizeof (RSEQ_SELF()->member) == 8, \ + "size of rseq data"); \ + if (sizeof (RSEQ_SELF()->member) == 1) \ + asm volatile ("movb %b0,%%fs:%P1(%q2)" : \ + : "iq" (value), \ + "i" (offsetof (struct rseq_area, member)), \ + "r" (__rseq_offset)); \ + else if (sizeof (RSEQ_SELF()->member) == 4) \ + asm volatile ("movl %0,%%fs:%P1(%q2)" : \ + : IMM_MODE (value), \ + "i" (offsetof (struct rseq_area, member)), \ + "r" (__rseq_offset)); \ + else /* 8 */ \ + { \ + /* Since movq takes a signed 32-bit immediate or a register source \ + operand, use "er" constraint for 32-bit signed integer constant \ + or register. */ \ + asm volatile ("movq %q0,%%fs:%P1(%q2)" : \ + : "er" ((uint64_t) cast_to_integer (value)), \ + "i" (offsetof (struct rseq_area, member)), \ + "r" (__rseq_offset)); \ + }}) + +/* Set member of the RSEQ area directly. */ +#define RSEQ_SETMEM(member, value) RSEQ_SETMEM_VOLATILE(member, value) From patchwork Thu Nov 21 19:08:57 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Michael Jeanson X-Patchwork-Id: 101694 X-Patchwork-Delegate: fweimer@redhat.com Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 79F383857350 for ; Thu, 21 Nov 2024 19:22:20 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 79F383857350 Authentication-Results: sourceware.org; dkim=pass (2048-bit key, unprotected) header.d=efficios.com header.i=@efficios.com header.a=rsa-sha256 header.s=smtpout1 header.b=Gg0nhLP7 X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from smtpout.efficios.com (smtpout.efficios.com [IPv6:2607:5300:203:b2ee::31e5]) by sourceware.org (Postfix) with ESMTPS id DA6843857820 for ; Thu, 21 Nov 2024 19:09:47 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org DA6843857820 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=efficios.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=efficios.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org DA6843857820 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=2607:5300:203:b2ee::31e5 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1732216187; cv=none; b=QGkzlMYLPso1BVA8RUWlWHz+2K7lhmLA1KOGszNmoc7EoueHpaAEZ71AQEryu4bkBkSqi5q0euFeHREjNNcLInSK9reUPq04e7VAAbvaDNiXnxIapm/xapkbf7CxSSGUA3fVuIURx+u1mbsBNHFG3kFmoSLH2vbCU+qqz9e0Ovs= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1732216187; c=relaxed/simple; bh=wt9q+m3iDdudZxKvOX3xC6fd70bRDXtcMHONpooeNck=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=TyDLjLKggKaLXtFNBU5BOAgomO9arcIOHX0QehlWqvMzsUr68g3rEUz4TbQ3NXIObw5Sk9BDhmlkTNSEVR0kDbWo+KDvxL1n9dw5YsqFX5yinKGNuLwkfHLGmfF7J3DN5d/xxHAh5RAOYSCxROQH4T94DHe84QsVMMX4SNppyYk= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org DA6843857820 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=efficios.com; s=smtpout1; t=1732216181; bh=wt9q+m3iDdudZxKvOX3xC6fd70bRDXtcMHONpooeNck=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=Gg0nhLP7A9S1AA4lPwAc5D187/XGq39qso6eQcdJNtY1+FdWjD/AJHlG5ldQXmAHe RTrZjIXTI3OsUjE6gACGWc1xtszOuw8t49xwQSFP77u+1+7LKgRHUsE/aG+hxz7lz0 Cs58qpj+kmvmXaRQFv3LZnE3xR1KU+wh/MAfpIdovAGVmIIOJVbxM5MFx/IYVX+kSJ 2ddgCtBs+sJTcPNtBW99bNoRPk0IlzVu/ayWShztSf83zpgzjCpXZltMK64EQSAPUF zvjz7hB1YmF6Honw81jnx7gbi0dEVjqRNhL/B5xXUfCuu/oXLh8w9vQkNPxsVxFsXj 14fWlMZZ/Jodg== Received: from laptop-mjeanson.internal.efficios.com (96-127-217-162.qc.cable.ebox.net [96.127.217.162]) by smtpout.efficios.com (Postfix) with ESMTPSA id 4XvSTd2PS3z143L; Thu, 21 Nov 2024 14:09:41 -0500 (EST) From: Michael Jeanson To: libc-alpha@sourceware.org Cc: Michael Jeanson , Florian Weimer , Carlos O'Donell , DJ Delorie , Mathieu Desnoyers Subject: [PATCH v14 7/9] nptl: Move the rseq area to the 'extra TLS' block Date: Thu, 21 Nov 2024 14:08:57 -0500 Message-ID: <20241121190924.837446-8-mjeanson@efficios.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20241121190924.837446-1-mjeanson@efficios.com> References: <20241121190924.837446-1-mjeanson@efficios.com> MIME-Version: 1.0 X-Spam-Status: No, score=-12.3 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: libc-alpha@sourceware.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Libc-alpha mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: libc-alpha-bounces~patchwork=sourceware.org@sourceware.org Move the rseq area to the newly added 'extra TLS' block, this is the last step in adding support for the rseq extended ABI. The size of the rseq area is now dynamic and depends on the rseq features reported by the kernel through the elf auxiliary vector. This will allow applications to use rseq features past the 32 bytes of the original rseq ABI as they become available in future kernels. Signed-off-by: Michael Jeanson Reviewed-by: Mathieu Desnoyers --- Changes since v12: - Style nits, missing spaces before '(' in function macro/calls - Add comment and variable array member to 'struct rseq_area' - Comment and style nits in tst-rseq-disable.c Changes since v11: - __rseq_size is now set directly in _dl_parse_auxv, set it to 0 when the main thread registration fails or is disabled by tunable --- nptl/pthread_create.c | 2 +- sysdeps/nptl/dl-tls_init_tp.c | 9 -- sysdeps/unix/sysv/linux/Makefile | 10 +++ sysdeps/unix/sysv/linux/dl-parse_auxv.h | 12 +-- sysdeps/unix/sysv/linux/rseq-internal.h | 49 ++++++++--- sysdeps/unix/sysv/linux/sched_getcpu.c | 3 +- .../unix/sysv/linux/tst-rseq-disable-static.c | 1 + sysdeps/unix/sysv/linux/tst-rseq-disable.c | 64 +++++++++++--- .../unix/sysv/linux/tst-rseq-nptl-static.c | 1 + sysdeps/unix/sysv/linux/tst-rseq-static.c | 1 + sysdeps/unix/sysv/linux/tst-rseq.c | 84 +++++++++++++++---- sysdeps/unix/sysv/linux/tst-rseq.h | 2 +- 12 files changed, 180 insertions(+), 58 deletions(-) create mode 100644 sysdeps/unix/sysv/linux/tst-rseq-disable-static.c create mode 100644 sysdeps/unix/sysv/linux/tst-rseq-nptl-static.c create mode 100644 sysdeps/unix/sysv/linux/tst-rseq-static.c diff --git a/nptl/pthread_create.c b/nptl/pthread_create.c index ef3ec33290..dd11a9fa46 100644 --- a/nptl/pthread_create.c +++ b/nptl/pthread_create.c @@ -696,7 +696,7 @@ __pthread_create_2_1 (pthread_t *newthread, const pthread_attr_t *attr, /* Inherit rseq registration state. Without seccomp filters, rseq registration will either always fail or always succeed. */ - if ((int) THREAD_GETMEM_VOLATILE (self, rseq_area.cpu_id) >= 0) + if ((int) RSEQ_GETMEM_VOLATILE (cpu_id) >= 0) pd->flags |= ATTR_FLAG_DO_RSEQ; /* Initialize the field for the ID of the thread which is waiting diff --git a/sysdeps/nptl/dl-tls_init_tp.c b/sysdeps/nptl/dl-tls_init_tp.c index 801b993000..7265e8768d 100644 --- a/sysdeps/nptl/dl-tls_init_tp.c +++ b/sysdeps/nptl/dl-tls_init_tp.c @@ -109,15 +109,6 @@ __tls_init_tp (void) bool do_rseq = TUNABLE_GET (rseq, int, NULL); if (!rseq_register_current_thread (pd, do_rseq)) _rseq_size = 0; - -#ifdef RSEQ_SIG - /* This should be a compile-time constant, but the current - infrastructure makes it difficult to determine its value. Not - all targets support __thread_pointer, so set __rseq_offset only - if the rseq registration may have happened because RSEQ_SIG is - defined. */ - _rseq_offset = (char *) &pd->rseq_area - (char *) __thread_pointer (); -#endif } /* Set initial thread's stack block from 0 up to __libc_stack_end. diff --git a/sysdeps/unix/sysv/linux/Makefile b/sysdeps/unix/sysv/linux/Makefile index 527c7a5ae8..ea0e712011 100644 --- a/sysdeps/unix/sysv/linux/Makefile +++ b/sysdeps/unix/sysv/linux/Makefile @@ -267,6 +267,11 @@ tests-internal += \ tst-rseq-disable \ # tests-internal +tests-static += \ + tst-rseq-disable-static \ + tst-rseq-static \ + # tests-static + tests-time64 += \ tst-adjtimex-time64 \ tst-clock_adjtime-time64 \ @@ -410,6 +415,7 @@ $(objpfx)tst-sched-consts.out: ../sysdeps/unix/sysv/linux/tst-sched-consts.py $(objpfx)tst-sched-consts.out: $(sysdeps-linux-python-deps) tst-rseq-disable-ENV = GLIBC_TUNABLES=glibc.pthread.rseq=0 +tst-rseq-disable-static-ENV = GLIBC_TUNABLES=glibc.pthread.rseq=0 endif # $(subdir) == misc @@ -675,4 +681,8 @@ tests += \ tests-internal += \ tst-rseq-nptl \ # tests-internal + +tests-static += \ + tst-rseq-nptl-static \ + # tests-static endif diff --git a/sysdeps/unix/sysv/linux/dl-parse_auxv.h b/sysdeps/unix/sysv/linux/dl-parse_auxv.h index 5a0ef0ae2a..8657cf7b2f 100644 --- a/sysdeps/unix/sysv/linux/dl-parse_auxv.h +++ b/sysdeps/unix/sysv/linux/dl-parse_auxv.h @@ -61,15 +61,9 @@ void _dl_parse_auxv (ElfW(auxv_t) *av, dl_parse_auxv_t auxv_values) #endif /* Get the rseq feature size, with a minimum of RSEQ_AREA_SIZE_INITIAL_USED - (20) for kernels that don't have AT_RSEQ_FEATURE_SIZE. Limit the feature - size to RSEQ_AREA_SIZE_MAX_USED (28) which fits the rseq area in 'struct - pthread' and represents the maximum feature size of currently released - kernels. Since no kernels currently cross the 32 bytes of the original - ABI, the semantics of a feature size of 32 or more are still undetermined. - */ - _rseq_size = MIN (MAX (auxv_values[AT_RSEQ_FEATURE_SIZE], - RSEQ_AREA_SIZE_INITIAL_USED), - RSEQ_AREA_SIZE_MAX_USED); + (20) for kernels that don't have AT_RSEQ_FEATURE_SIZE. */ + _rseq_size = MAX (auxv_values[AT_RSEQ_FEATURE_SIZE], + RSEQ_AREA_SIZE_INITIAL_USED); _rseq_align = MAX (auxv_values[AT_RSEQ_ALIGN], RSEQ_MIN_ALIGN); DL_PLATFORM_AUXV diff --git a/sysdeps/unix/sysv/linux/rseq-internal.h b/sysdeps/unix/sysv/linux/rseq-internal.h index 8e4a292ffc..eaa065e27b 100644 --- a/sysdeps/unix/sysv/linux/rseq-internal.h +++ b/sysdeps/unix/sysv/linux/rseq-internal.h @@ -26,6 +26,30 @@ #include #include #include +#include + +/* rseq area registered with the kernel. Use a custom definition here to + isolate from the system provided header which could lack some fields of the + Extended ABI. + + This is only used to get the field offsets and sizes, it should never be + used for direct object allocations. + + Access to fields of the Extended ABI beyond the 20 bytes of the original ABI + (after 'flags') must be gated by a check of the feature size. */ +struct rseq_area +{ + /* Original ABI. */ + uint32_t cpu_id_start; + uint32_t cpu_id; + uint64_t rseq_cs; + uint32_t flags; + /* Extended ABI. */ + uint32_t node_id; + uint32_t mm_cid; + /* Flexible array member to discourage direct object allocations. */ + char end[]; +}; /* Minimum size of the rseq area allocation required by the syscall. The actually used rseq feature size may be less (20 bytes initially). */ @@ -47,10 +71,12 @@ extern size_t _rseq_align attribute_hidden; /* Size of the active features in the rseq area. Populated from the auxiliary vector with a minimum of '20'. + Set to '0' on registration failure of the main thread. In .data.relro but not yet write-protected. */ extern unsigned int _rseq_size attribute_hidden; -/* Offset from the thread pointer to the rseq area. +/* Offset from the thread pointer to the rseq area, always set to allow + checking the registration status by reading the 'cpu_id' field. In .data.relro but not yet write-protected. */ extern ptrdiff_t _rseq_offset attribute_hidden; @@ -75,34 +101,35 @@ rseq_register_current_thread (struct pthread *self, bool do_rseq) { unsigned int size = __rseq_size; + /* The feature size can be smaller than the minimum rseq area size of 32 + bytes accepted by the syscall, if this is the case, bump the size of + the registration to the minimum. The 'extra TLS' block is always at + least 32 bytes. */ if (size < RSEQ_AREA_SIZE_INITIAL) - /* The initial implementation used only 20 bytes out of 32, - but still expected size 32. */ size = RSEQ_AREA_SIZE_INITIAL; /* Initialize the rseq fields that are read by the kernel on registration, there is no guarantee that struct pthread is cleared on all architectures. */ - THREAD_SETMEM (self, rseq_area.cpu_id, RSEQ_CPU_ID_UNINITIALIZED); - THREAD_SETMEM (self, rseq_area.cpu_id_start, 0); - THREAD_SETMEM (self, rseq_area.rseq_cs, 0); - THREAD_SETMEM (self, rseq_area.flags, 0); + RSEQ_SETMEM (cpu_id, RSEQ_CPU_ID_UNINITIALIZED); + RSEQ_SETMEM (cpu_id_start, 0); + RSEQ_SETMEM (rseq_cs, 0); + RSEQ_SETMEM (flags, 0); - int ret = INTERNAL_SYSCALL_CALL (rseq, &self->rseq_area, - size, 0, RSEQ_SIG); + int ret = INTERNAL_SYSCALL_CALL (rseq, RSEQ_SELF (), size, 0, RSEQ_SIG); if (!INTERNAL_SYSCALL_ERROR_P (ret)) return true; } /* When rseq is disabled by tunables or the registration fails, inform userspace by setting 'cpu_id' to RSEQ_CPU_ID_REGISTRATION_FAILED. */ - THREAD_SETMEM (self, rseq_area.cpu_id, RSEQ_CPU_ID_REGISTRATION_FAILED); + RSEQ_SETMEM (cpu_id, RSEQ_CPU_ID_REGISTRATION_FAILED); return false; } #else /* RSEQ_SIG */ static inline bool rseq_register_current_thread (struct pthread *self, bool do_rseq) { - THREAD_SETMEM (self, rseq_area.cpu_id, RSEQ_CPU_ID_REGISTRATION_FAILED); + RSEQ_SETMEM (cpu_id, RSEQ_CPU_ID_REGISTRATION_FAILED); return false; } #endif /* RSEQ_SIG */ diff --git a/sysdeps/unix/sysv/linux/sched_getcpu.c b/sysdeps/unix/sysv/linux/sched_getcpu.c index 72a3360550..18a7817148 100644 --- a/sysdeps/unix/sysv/linux/sched_getcpu.c +++ b/sysdeps/unix/sysv/linux/sched_getcpu.c @@ -19,6 +19,7 @@ #include #include #include +#include static int vsyscall_sched_getcpu (void) @@ -36,6 +37,6 @@ vsyscall_sched_getcpu (void) int sched_getcpu (void) { - int cpu_id = THREAD_GETMEM_VOLATILE (THREAD_SELF, rseq_area.cpu_id); + int cpu_id = RSEQ_GETMEM_VOLATILE (cpu_id); return __glibc_likely (cpu_id >= 0) ? cpu_id : vsyscall_sched_getcpu (); } diff --git a/sysdeps/unix/sysv/linux/tst-rseq-disable-static.c b/sysdeps/unix/sysv/linux/tst-rseq-disable-static.c new file mode 100644 index 0000000000..2687d13d3d --- /dev/null +++ b/sysdeps/unix/sysv/linux/tst-rseq-disable-static.c @@ -0,0 +1 @@ +#include "tst-rseq-disable.c" diff --git a/sysdeps/unix/sysv/linux/tst-rseq-disable.c b/sysdeps/unix/sysv/linux/tst-rseq-disable.c index bbc655bec4..31b3444e11 100644 --- a/sysdeps/unix/sysv/linux/tst-rseq-disable.c +++ b/sysdeps/unix/sysv/linux/tst-rseq-disable.c @@ -26,32 +26,69 @@ #include #ifdef RSEQ_SIG +# include +# include "tst-rseq.h" + +/* Used to test private registration with the rseq system call because glibc + rseq is disabled. */ +static __thread struct rseq local_rseq = { + .cpu_id = RSEQ_CPU_ID_REGISTRATION_FAILED, +}; /* Check that rseq can be registered and has not been taken by glibc. */ static void check_rseq_disabled (void) { - struct pthread *pd = THREAD_SELF; + struct rseq *rseq_abi = (struct rseq *) ((char *) __thread_pointer () + + __rseq_offset); + +#if TLS_TCB_AT_TP + /* The rseq area block should come before the thread pointer and be at least + 32 bytes. */ + TEST_VERIFY (__rseq_offset <= -RSEQ_AREA_SIZE_INITIAL); +#elif TLS_DTV_AT_TP + /* The rseq area block should come after the thread pointer. */ + TEST_VERIFY (__rseq_offset >= 0); +#else +# error "Either TLS_TCB_AT_TP or TLS_DTV_AT_TP must be defined" +#endif + /* __rseq_flags is unused and should always be '0'. */ TEST_COMPARE (__rseq_flags, 0); - TEST_VERIFY ((char *) __thread_pointer () + __rseq_offset - == (char *) &pd->rseq_area); + + /* When rseq is not registered, __rseq_size should always be '0'. */ TEST_COMPARE (__rseq_size, 0); - TEST_COMPARE ((int) pd->rseq_area.cpu_id, RSEQ_CPU_ID_REGISTRATION_FAILED); - int ret = syscall (__NR_rseq, &pd->rseq_area, sizeof (pd->rseq_area), - 0, RSEQ_SIG); + /* When rseq is not registered, the 'cpu_id' field should be set to + RSEQ_CPU_ID_REGISTRATION_FAILED. */ + TEST_COMPARE ((int) rseq_abi->cpu_id, RSEQ_CPU_ID_REGISTRATION_FAILED); + + /* Test a rseq registration which should succeed since the internal + registration is disabled. */ + int ret = syscall (__NR_rseq, &local_rseq, RSEQ_AREA_SIZE_INITIAL, 0, RSEQ_SIG); if (ret == 0) { - ret = syscall (__NR_rseq, &pd->rseq_area, sizeof (pd->rseq_area), + /* A successful registration should set the cpu id. */ + TEST_VERIFY (local_rseq.cpu_id >= 0); + + /* Test we can also unregister rseq. */ + ret = syscall (__NR_rseq, &local_rseq, RSEQ_AREA_SIZE_INITIAL, RSEQ_FLAG_UNREGISTER, RSEQ_SIG); TEST_COMPARE (ret, 0); - pd->rseq_area.cpu_id = RSEQ_CPU_ID_REGISTRATION_FAILED; } else { - TEST_VERIFY (errno != -EINVAL); - TEST_VERIFY (errno != -EBUSY); + /* Check if we failed with EINVAL which would mean an invalid rseq flags, + a mis-aligned rseq area address or an incorrect rseq size. */ + TEST_VERIFY (errno != EINVAL); + + /* Check if we failed with EBUSY which means an existing rseq + registration. */ + TEST_VERIFY (errno != EBUSY); + + /* Check if we failed with EFAULT which means an invalid rseq area + address. */ + TEST_VERIFY (errno != EFAULT); } } @@ -71,6 +108,13 @@ proc_func (void *ignored) static int do_test (void) { + printf ("info: __rseq_size: %u\n", __rseq_size); + printf ("info: __rseq_offset: %td\n", __rseq_offset); + printf ("info: __rseq_flags: %u\n", __rseq_flags); + printf ("info: getauxval (AT_RSEQ_FEATURE_SIZE): %ld\n", + getauxval (AT_RSEQ_FEATURE_SIZE)); + printf ("info: getauxval (AT_RSEQ_ALIGN): %ld\n", getauxval (AT_RSEQ_ALIGN)); + puts ("info: checking main thread"); check_rseq_disabled (); diff --git a/sysdeps/unix/sysv/linux/tst-rseq-nptl-static.c b/sysdeps/unix/sysv/linux/tst-rseq-nptl-static.c new file mode 100644 index 0000000000..6e2c923bb9 --- /dev/null +++ b/sysdeps/unix/sysv/linux/tst-rseq-nptl-static.c @@ -0,0 +1 @@ +#include "tst-rseq-nptl.c" diff --git a/sysdeps/unix/sysv/linux/tst-rseq-static.c b/sysdeps/unix/sysv/linux/tst-rseq-static.c new file mode 100644 index 0000000000..1d97f3bd3d --- /dev/null +++ b/sysdeps/unix/sysv/linux/tst-rseq-static.c @@ -0,0 +1 @@ +#include "tst-rseq.c" diff --git a/sysdeps/unix/sysv/linux/tst-rseq.c b/sysdeps/unix/sysv/linux/tst-rseq.c index d1ae16b953..7bdda17feb 100644 --- a/sysdeps/unix/sysv/linux/tst-rseq.c +++ b/sysdeps/unix/sysv/linux/tst-rseq.c @@ -19,6 +19,8 @@ not linked against libpthread. */ #include +#include +#include #include #include #include @@ -32,25 +34,69 @@ # include # include # include +# include # include "tst-rseq.h" static void do_rseq_main_test (void) { - struct pthread *pd = THREAD_SELF; - size_t rseq_feature_size = MIN (MAX (getauxval (AT_RSEQ_FEATURE_SIZE), - RSEQ_AREA_SIZE_INITIAL_USED), - RSEQ_AREA_SIZE_MAX_USED); + size_t rseq_align = MAX (getauxval (AT_RSEQ_ALIGN), RSEQ_MIN_ALIGN); + size_t rseq_feature_size = MAX (getauxval (AT_RSEQ_FEATURE_SIZE), + RSEQ_AREA_SIZE_INITIAL_USED); + size_t rseq_alloc_size = roundup (MAX (rseq_feature_size, + RSEQ_AREA_SIZE_INITIAL_USED), rseq_align); + struct rseq *rseq_abi = __thread_pointer () + __rseq_offset; TEST_VERIFY_EXIT (rseq_thread_registered ()); + + /* __rseq_flags is unused and should always be '0'. */ TEST_COMPARE (__rseq_flags, 0); - TEST_VERIFY ((char *) __thread_pointer () + __rseq_offset - == (char *) &pd->rseq_area); + + /* When rseq is registered, __rseq_size should report the feature size. */ TEST_COMPARE (__rseq_size, rseq_feature_size); + + /* When rseq is registered, the 'cpu_id' field should be set to a valid cpu + * number. */ + TEST_VERIFY ((int32_t) rseq_abi->cpu_id >= 0); + + /* The rseq area address must be aligned. */ + TEST_VERIFY (((unsigned long) rseq_abi % rseq_align) == 0); + +#if TLS_TCB_AT_TP + /* The rseq area block should come before the thread pointer and be at least + 32 bytes. */ + TEST_VERIFY (__rseq_offset <= -RSEQ_AREA_SIZE_INITIAL); +#elif TLS_DTV_AT_TP + /* The rseq area block should come after the thread pointer. */ + TEST_VERIFY (__rseq_offset >= 0); +#else +# error "Either TLS_TCB_AT_TP or TLS_DTV_AT_TP must be defined" +#endif + + /* Test a rseq registration with the same arguments as the internal + registration which should fail with errno == EBUSY. */ + TEST_VERIFY (((unsigned long) rseq_abi % rseq_align) == 0); + TEST_VERIFY (__rseq_size <= rseq_alloc_size); + int ret = syscall (__NR_rseq, rseq_abi, rseq_alloc_size, 0, RSEQ_SIG); + TEST_VERIFY (ret != 0); + TEST_COMPARE (errno, EBUSY); +} + +static void * +thread_func (void *ignored) +{ + do_rseq_main_test (); + return NULL; } static void -do_rseq_test (void) +proc_func (void *ignored) +{ + do_rseq_main_test (); +} + +static int +do_test (void) { if (!rseq_available ()) { @@ -62,21 +108,27 @@ do_rseq_test (void) printf ("info: getauxval (AT_RSEQ_FEATURE_SIZE): %ld\n", getauxval (AT_RSEQ_FEATURE_SIZE)); printf ("info: getauxval (AT_RSEQ_ALIGN): %ld\n", getauxval (AT_RSEQ_ALIGN)); + + puts ("info: checking main thread"); + do_rseq_main_test (); + + puts ("info: checking main thread (2)"); do_rseq_main_test (); + + puts ("info: checking new thread"); + xpthread_join (xpthread_create (NULL, thread_func, NULL)); + + puts ("info: checking subprocess"); + support_isolate_in_subprocess (proc_func, NULL); + + return 0; } #else /* RSEQ_SIG */ -static void -do_rseq_test (void) -{ - FAIL_UNSUPPORTED ("glibc does not define RSEQ_SIG, skipping test"); -} -#endif /* RSEQ_SIG */ - static int do_test (void) { - do_rseq_test (); - return 0; + FAIL_UNSUPPORTED ("glibc does not define RSEQ_SIG, skipping test"); } +#endif /* RSEQ_SIG */ #include diff --git a/sysdeps/unix/sysv/linux/tst-rseq.h b/sysdeps/unix/sysv/linux/tst-rseq.h index 7f82554e83..75dd8efb2e 100644 --- a/sysdeps/unix/sysv/linux/tst-rseq.h +++ b/sysdeps/unix/sysv/linux/tst-rseq.h @@ -28,7 +28,7 @@ static inline bool rseq_thread_registered (void) { - return THREAD_GETMEM_VOLATILE (THREAD_SELF, rseq_area.cpu_id) >= 0; + return RSEQ_GETMEM_VOLATILE (cpu_id) >= 0; } static inline int From patchwork Thu Nov 21 19:08:58 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Michael Jeanson X-Patchwork-Id: 101689 X-Patchwork-Delegate: fweimer@redhat.com Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 712843857BB6 for ; Thu, 21 Nov 2024 19:12:51 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 712843857BB6 Authentication-Results: sourceware.org; dkim=pass (2048-bit key, unprotected) header.d=efficios.com header.i=@efficios.com header.a=rsa-sha256 header.s=smtpout1 header.b=kcFWX0T9 X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from smtpout.efficios.com (smtpout.efficios.com [IPv6:2607:5300:203:b2ee::31e5]) by sourceware.org (Postfix) with ESMTPS id DC9FC3857831 for ; Thu, 21 Nov 2024 19:09:47 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org DC9FC3857831 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=efficios.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=efficios.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org DC9FC3857831 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=2607:5300:203:b2ee::31e5 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1732216187; cv=none; b=A4sbUIrdhzPPD/7aO2wD88ijnqY1z/XVZ0MYSnxnzUBIYgK6sLIYuCRA8nQvFgKo/0dSKjHTEEa/KJrQAmKSgm5dnICP9TiTWJ+7YWKUWnPfcvjWG361pl8rAiJ//g02vc0Vj5HQBCbtnRwhvRG7wcIoiQGzjYcRsGmNi0RraKE= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1732216187; c=relaxed/simple; bh=uvttmjMr544h7PQVTlijYC3Jj6PfHc9sq5NmulOkKsk=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=DSsKJ5DB9LhIpqK2riM+ysGYELwWUpeM6LH1zMOYeDX1uhyQv4PaSPMTJMi/nA32pauqr8IwaTzfXI48+aI2Tg0ex7hc3kUf/nOw6QTB3y77oS4j6h8JplBoIO6214RuMvwF/W04FxqysnmB3Xzhs9ZEWF+pDh8HBIIflB55iUs= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org DC9FC3857831 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=efficios.com; s=smtpout1; t=1732216182; bh=uvttmjMr544h7PQVTlijYC3Jj6PfHc9sq5NmulOkKsk=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=kcFWX0T9EX5k7udE2QgHGiCzYhzy6y03m/9ZCatKmulN7wuVXA1SCo8bpU9j57J+I wzJGDG67pas+6vAt41Xn32VoMlL97a+ST3U5JhzVnxoFo0fAf4HdWSXGs8ap8+ooft 5mekbpMjRL3RGykPqLXaevtIVEJIakicAjkh56gO85Ohi7mNJ4RInMEn07tFqRgfyq TilZh/CXg3IkcEOzg6FAvN2nBdYIRwwxpCg6tOmzzQl4ZINAgKiBliB5TCwC8yg1Zx bI/AE44B/keaWV3CPIcPhZq52SJlUIcUNW9TqvVB0PcXMf4/1qycnekMQgubRLOBO3 dW4Uvbg2B3o6w== Received: from laptop-mjeanson.internal.efficios.com (96-127-217-162.qc.cable.ebox.net [96.127.217.162]) by smtpout.efficios.com (Postfix) with ESMTPSA id 4XvSTf0hSJz14S9; Thu, 21 Nov 2024 14:09:42 -0500 (EST) From: Michael Jeanson To: libc-alpha@sourceware.org Cc: Michael Jeanson , Florian Weimer , Carlos O'Donell , DJ Delorie , Mathieu Desnoyers Subject: [PATCH v14 8/9] nptl: Remove the rseq area from 'struct pthread' Date: Thu, 21 Nov 2024 14:08:58 -0500 Message-ID: <20241121190924.837446-9-mjeanson@efficios.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20241121190924.837446-1-mjeanson@efficios.com> References: <20241121190924.837446-1-mjeanson@efficios.com> MIME-Version: 1.0 X-Spam-Status: No, score=-12.2 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: libc-alpha@sourceware.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Libc-alpha mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: libc-alpha-bounces~patchwork=sourceware.org@sourceware.org The rseq extensible ABI implementation moved the rseq area to the 'extra TLS' block, remove the unused 'rseq_area' member of 'struct pthread'. Signed-off-by: Michael Jeanson Reviewed-by: Mathieu Desnoyers --- nptl/descr.h | 22 +++------------------- 1 file changed, 3 insertions(+), 19 deletions(-) diff --git a/nptl/descr.h b/nptl/descr.h index a69f5c9697..ed767e4859 100644 --- a/nptl/descr.h +++ b/nptl/descr.h @@ -407,27 +407,11 @@ struct pthread /* getrandom vDSO per-thread opaque state. */ void *getrandom_buf; - /* rseq area registered with the kernel. Use a custom definition - here to isolate from kernel struct rseq changes. The - implementation of sched_getcpu needs acccess to the cpu_id field; - the other fields are unused and not included here. */ - union - { - struct - { - uint32_t cpu_id_start; - uint32_t cpu_id; - uint64_t rseq_cs; - uint32_t flags; - }; - char pad[32]; /* Original rseq area size. */ - } rseq_area __attribute__ ((aligned (32))); - /* Amount of end padding, if any, in this structure. - This definition relies on rseq_area being last. */ + This definition relies on getrandom_buf being last. */ #define PTHREAD_STRUCT_END_PADDING \ - (sizeof (struct pthread) - offsetof (struct pthread, rseq_area) \ - + sizeof ((struct pthread) {}.rseq_area)) + (sizeof (struct pthread) - offsetof (struct pthread, getrandom_buf) \ + + sizeof ((struct pthread) {}.getrandom_buf)) } __attribute ((aligned (TCB_ALIGNMENT))); static inline bool From patchwork Thu Nov 21 19:08:59 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Michael Jeanson X-Patchwork-Id: 101693 X-Patchwork-Delegate: fweimer@redhat.com Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 3CC653857365 for ; Thu, 21 Nov 2024 19:21:36 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 3CC653857365 Authentication-Results: sourceware.org; dkim=pass (2048-bit key, unprotected) header.d=efficios.com header.i=@efficios.com header.a=rsa-sha256 header.s=smtpout1 header.b=HlyKb/15 X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from smtpout.efficios.com (smtpout.efficios.com [167.114.26.122]) by sourceware.org (Postfix) with ESMTPS id 098243857835 for ; Thu, 21 Nov 2024 19:09:48 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 098243857835 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=efficios.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=efficios.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 098243857835 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=167.114.26.122 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1732216188; cv=none; b=uGQDfSAuIAc29SsaFN4vTseaQoeoSs+GxPPNfIGyiEsZPWKMqAbDB0d1aFgpgMWbFl3/S6R//g5dMeD8IWaUAnaQUc+YjvFbX7mp8arku+3NJ7u1CiJLpwlBYQsRMdHEDHaMO0/Y/rH1d2zngMbvdRnAQlTvk7vm3Rjm8SfIT80= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1732216188; c=relaxed/simple; bh=51HQL10PzzL+t/8GAn2TA2sDKB/6WrOMgbqcT2+Al9I=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=W76vtQJEF405Y7cZYTaZl9t1s7ya0MGVNxQeWzYwj1KL4qmWQWCuwZ+lrVlKkMEP9vHyiLwTfj73bqL26R0hvTewIK2HDfQZcf/wvt6qUy6/f6ZyFM4+5ySnTBhAIvahUwsK5QEF0o2J7f1c41GvY+hhRaFB50Y8zSpy8SZ++A4= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 098243857835 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=efficios.com; s=smtpout1; t=1732216183; bh=51HQL10PzzL+t/8GAn2TA2sDKB/6WrOMgbqcT2+Al9I=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=HlyKb/158Rzo40HToUohL9PcQRloAE/EKHVPG/2LSyWMLVPK9Clanttha9FWEmy63 mBIwPAh22Y2W15U0kgeDr1wgeWzhsia/oJ/vpbyrW5KR/k9ZQCRS1pEmmQ7d9/Bt6g 6zQJ4VpXK7cUpA/B8axbNKl2nEtXEqBdtp3pZcKBnqrdvW+r8sxEbMfCW0SeZTJv2k Cz8oQRXrHy0zc/z2ti3xyPPdzGMaS/Am24e4YIbakCzdCFAJlut7ViDJ5YF92uet5W KcvpvAa1lMbL920OYT4dtox9PaMuU8wkFjjlkMEVKIBtMmAqWDYHlVUvI4Jk+oWLDA 20SGwCSmeB+ow== Received: from laptop-mjeanson.internal.efficios.com (96-127-217-162.qc.cable.ebox.net [96.127.217.162]) by smtpout.efficios.com (Postfix) with ESMTPSA id 4XvSTf6KDvz14SB; Thu, 21 Nov 2024 14:09:42 -0500 (EST) From: Michael Jeanson To: libc-alpha@sourceware.org Cc: Michael Jeanson , Florian Weimer , Carlos O'Donell , DJ Delorie , Mathieu Desnoyers Subject: [PATCH v14 9/9] Linux: Update internal copy of '' Date: Thu, 21 Nov 2024 14:08:59 -0500 Message-ID: <20241121190924.837446-10-mjeanson@efficios.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20241121190924.837446-1-mjeanson@efficios.com> References: <20241121190924.837446-1-mjeanson@efficios.com> MIME-Version: 1.0 X-Spam-Status: No, score=-12.2 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: libc-alpha@sourceware.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Libc-alpha mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: libc-alpha-bounces~patchwork=sourceware.org@sourceware.org Sync the internal copy of '' with the latest Linux kernel 'include/uapi/linux/rseq.h'. Signed-off-by: Michael Jeanson Reviewed-by: Mathieu Desnoyers --- sysdeps/unix/sysv/linux/sys/rseq.h | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/sysdeps/unix/sysv/linux/sys/rseq.h b/sysdeps/unix/sysv/linux/sys/rseq.h index b8afab8945..7f0c27fc42 100644 --- a/sysdeps/unix/sysv/linux/sys/rseq.h +++ b/sysdeps/unix/sysv/linux/sys/rseq.h @@ -152,6 +152,17 @@ struct rseq Inhibit instruction sequence block restart on migration for this thread. */ uint32_t flags; + /* Restartable sequences node_id field. Updated by the kernel. Read by + user-space with single-copy atomicity semantics. This field should only + be read by the thread which registered this data structure. Aligned on + 32-bit. Contains the current NUMA node ID. */ + uint32_t node_id; + /* Restartable sequences mm_cid field. Updated by the kernel. Read by + user-space with single-copy atomicity semantics. This field should only + be read by the thread which registered this data structure. Aligned on + 32-bit. Contains the current thread's concurrency ID (allocated + uniquely within a memory map). */ + uint32_t mm_cid; } __attribute__ ((__aligned__ (32))); #endif /* __GLIBC_HAVE_KERNEL_RSEQ */