Received: by 2002:ac0:a582:0:0:0:0:0 with SMTP id m2-v6csp1305987imm; Wed, 10 Oct 2018 12:20:55 -0700 (PDT) X-Google-Smtp-Source: ACcGV633aYqF0qHaaS5Il+e42qntc4NAu7VJjovwaFblUOdbrVSAqEiSz6qWfOc6Mqd+sKJRdosB X-Received: by 2002:a63:f314:: with SMTP id l20-v6mr30198809pgh.407.1539199255516; Wed, 10 Oct 2018 12:20:55 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1539199255; cv=none; d=google.com; s=arc-20160816; b=faMbJ3WDMzSDEIHdn6hTaLOhj7LwjZ0kOmjonfbjIUNAuSiTOzXjOJVNdvyubaZuA1 S6fOETe1luIUg88B5N5DhoLBRAgskP2oHQfD+7dc9seqkjshRvDOmUyzxOJcTON3qJlz mRUgcWdsmHWtKvKmBj1JCGA6VYGTffn6pvRV9+ot7h83q+otNiIeJg50pCPvsmWhT5Fk scA/aQVNFGfbq1LRUipXu7rnq66SUYK+OSRp9OEMsFX1QFpNVnlZ89Z3Jg4K6ELAIgNs 8AP8PV9VsomNx7SWATRowmmGVfXmKQAIYJ8Ini28Jc58R6QgRikZ8Jepit58AoFWXFiA MQjQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:message-id:date :subject:cc:to:from:dkim-signature:dkim-filter; bh=W9+7YUDhhfJN0h5lP3hptKUVRtrFuDrfUHKAQiTlV2Y=; b=ODATF+bABmXnFr72g1yhHomn4kkkWAV6i23A8jXthS2cIE/KtZfli6eC9N92tMoLzz x2EB81O/4vum1hO+QQZIEH2SzRpoAohtMzlj9mHB8BhwPymYCycqpdDOSSRqp6AIEMkQ Pklo21kFft9JMi04waLjd21NqrXFq4QM7vg4KIa7KgHa2x9q7gcHQQU84KZuYFxonjpP tBlGz5tcJN09Vk9bY13v58OIYAz3Nr3did6eJAqiUyxTMztUwi+40+5cUfaA7hE4ohKc QDifoTk/0abyvqyXun9lYalDb7AzSKM2Os2BxCvjewfSldWbK8cE9uZ/j6reX1w+z7ck edMw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@efficios.com header.s=default header.b=kHk8BaUt; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=efficios.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id z1-v6si25283232plb.131.2018.10.10.12.20.39; Wed, 10 Oct 2018 12:20:55 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@efficios.com header.s=default header.b=kHk8BaUt; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=efficios.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727546AbeJKCng (ORCPT + 99 others); Wed, 10 Oct 2018 22:43:36 -0400 Received: from mail.efficios.com ([167.114.142.138]:60960 "EHLO mail.efficios.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727268AbeJKCng (ORCPT ); Wed, 10 Oct 2018 22:43:36 -0400 Received: from localhost (ip6-localhost [IPv6:::1]) by mail.efficios.com (Postfix) with ESMTP id EBCF4183B3F; Wed, 10 Oct 2018 15:20:02 -0400 (EDT) Received: from mail.efficios.com ([IPv6:::1]) by localhost (mail02.efficios.com [IPv6:::1]) (amavisd-new, port 10032) with ESMTP id ZarWOQeCeu7k; Wed, 10 Oct 2018 15:20:01 -0400 (EDT) Received: from localhost (ip6-localhost [IPv6:::1]) by mail.efficios.com (Postfix) with ESMTP id B935A183B28; Wed, 10 Oct 2018 15:20:01 -0400 (EDT) DKIM-Filter: OpenDKIM Filter v2.10.3 mail.efficios.com B935A183B28 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=efficios.com; s=default; t=1539199201; bh=W9+7YUDhhfJN0h5lP3hptKUVRtrFuDrfUHKAQiTlV2Y=; h=From:To:Date:Message-Id; b=kHk8BaUtgcpzWncfzeMvw/MKwjHPUtweBGpZ3m9wWnu0emUK9OYAmv+Rx36f+g/10 oNYJfhjmNhcr0cxccT0purUjbk0HU1Y9gPjx/2CHdzQNdiTVXBZ/OIk79I4sEdtgHg mLcbkD/VK/frVRiIWFsiDddaB6CR1Fa7XRphP5n28QhwOFXZn26ijdKD98dI8+eFwu 8aPPhasSiM3mwgjyW1+NOLXFFpWZXB+RJmQtf+3YC6kymNX8jHDaFvtp7GTQudRVwl i/z967v3O+k6YvxYXOIP6nI/+MHOPaFcj/hWR5Yz+JV3JoNKnyFuR0nT3x4Baj4Hbr rnZap3bC4G1RA== X-Virus-Scanned: amavisd-new at efficios.com Received: from mail.efficios.com ([IPv6:::1]) by localhost (mail02.efficios.com [IPv6:::1]) (amavisd-new, port 10026) with ESMTP id BICCTx2yh6d3; Wed, 10 Oct 2018 15:20:01 -0400 (EDT) Received: from thinkos.internal.efficios.com (192-222-157-41.qc.cable.ebox.net [192.222.157.41]) by mail.efficios.com (Postfix) with ESMTPSA id A1258183B05; Wed, 10 Oct 2018 15:19:57 -0400 (EDT) From: Mathieu Desnoyers To: Peter Zijlstra , "Paul E . McKenney" , Boqun Feng Cc: linux-kernel@vger.kernel.org, linux-api@vger.kernel.org, Thomas Gleixner , Andy Lutomirski , Dave Watson , Paul Turner , Andrew Morton , Russell King , Ingo Molnar , "H . Peter Anvin" , Andi Kleen , Chris Lameter , Ben Maurer , Steven Rostedt , Josh Triplett , Linus Torvalds , Catalin Marinas , Will Deacon , Michael Kerrisk , Joel Fernandes , Mathieu Desnoyers , Shuah Khan , Carlos O'Donell , Florian Weimer , Joseph Myers , Szabolcs Nagy Subject: [RFC PATCH for 4.21 01/16] rseq/selftests: Add reference counter to coexist with glibc Date: Wed, 10 Oct 2018 15:19:21 -0400 Message-Id: <20181010191936.7495-2-mathieu.desnoyers@efficios.com> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20181010191936.7495-1-mathieu.desnoyers@efficios.com> References: <20181010191936.7495-1-mathieu.desnoyers@efficios.com> Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org In order to integrate rseq into user-space applications, add a reference counter field after the struct rseq TLS ABI so many rseq users can be linked into the same application (e.g. librseq and glibc). The reference count ensures that rseq syscall registration/unregistration happens only for the most early/late user for each thread, thus ensuring that rseq is registered across the lifetime of all rseq users for a given thread. Therefore, struct rseq contains the fields shared between kernel and user-space, and represents the ABI between kernel and user-space. The extra field added after struct rseq is an ABI between user-space executable and libraries, but the kernel does not care about that field, so it is not part of the Linux uapi. Signed-off-by: Mathieu Desnoyers CC: Shuah Khan CC: Carlos O'Donell CC: Florian Weimer CC: Joseph Myers CC: Szabolcs Nagy CC: Thomas Gleixner CC: Ben Maurer CC: Peter Zijlstra CC: "Paul E. McKenney" CC: Boqun Feng CC: Will Deacon CC: Dave Watson CC: Paul Turner CC: linux-api@vger.kernel.org --- tools/testing/selftests/rseq/rseq.c | 32 ++++++++++++++++++++++++-------- 1 file changed, 24 insertions(+), 8 deletions(-) diff --git a/tools/testing/selftests/rseq/rseq.c b/tools/testing/selftests/rseq/rseq.c index 4847e97ed049..7e9ae973f786 100644 --- a/tools/testing/selftests/rseq/rseq.c +++ b/tools/testing/selftests/rseq/rseq.c @@ -30,13 +30,29 @@ #define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0])) -__attribute__((tls_model("initial-exec"))) __thread -volatile struct rseq __rseq_abi = { +/* + * linux/rseq.h defines struct rseq as aligned on 32 bytes. The kernel ABI + * size is 20 bytes. For support of multiple rseq users within a process, + * user-space defines an extra 4 bytes field as a reference count, for a + * total of 24 bytes. + */ +struct libc_rseq { + /* kernel-userspace ABI. */ + __u32 cpu_id_start; + __u32 cpu_id; + __u64 rseq_cs; + __u32 flags; + /* user-space ABI. */ + __u32 refcount; +} __attribute__((aligned(4 * sizeof(__u64)))); + +__attribute__((visibility("hidden"))) __thread +volatile struct libc_rseq __lib_rseq_abi = { .cpu_id = RSEQ_CPU_ID_UNINITIALIZED, }; -static __attribute__((tls_model("initial-exec"))) __thread -volatile int refcount; +extern __attribute__((weak, alias("__lib_rseq_abi"))) __thread +volatile struct rseq __rseq_abi; static void signal_off_save(sigset_t *oldset) { @@ -70,7 +86,7 @@ int rseq_register_current_thread(void) sigset_t oldset; signal_off_save(&oldset); - if (refcount++) + if (__lib_rseq_abi.refcount++) goto end; rc = sys_rseq(&__rseq_abi, sizeof(struct rseq), 0, RSEQ_SIG); if (!rc) { @@ -78,9 +94,9 @@ int rseq_register_current_thread(void) goto end; } if (errno != EBUSY) - __rseq_abi.cpu_id = -2; + __rseq_abi.cpu_id = RSEQ_CPU_ID_REGISTRATION_FAILED; ret = -1; - refcount--; + __lib_rseq_abi.refcount--; end: signal_restore(oldset); return ret; @@ -92,7 +108,7 @@ int rseq_unregister_current_thread(void) sigset_t oldset; signal_off_save(&oldset); - if (--refcount) + if (--__lib_rseq_abi.refcount) goto end; rc = sys_rseq(&__rseq_abi, sizeof(struct rseq), RSEQ_FLAG_UNREGISTER, RSEQ_SIG); -- 2.11.0