From patchwork Mon Feb 26 21:03:19 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Adhemerval Zanella X-Patchwork-Id: 129706 Delivered-To: patch@linaro.org Received: by 10.80.172.228 with SMTP id x91csp4290278edc; Mon, 26 Feb 2018 13:04:44 -0800 (PST) X-Google-Smtp-Source: AH8x225szdm4yXF8kUAql3HL9AwZIcothzDblllmmSl5eLi8pIFYXKcKrzJ61Fj8DjvoYLADdrLa X-Received: by 2002:a17:902:724a:: with SMTP id c10-v6mr11808138pll.98.1519679084158; Mon, 26 Feb 2018 13:04:44 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1519679084; cv=none; d=google.com; s=arc-20160816; b=nIM8KQp60ANiy3t6+vFefiNxmkIK88OJ4jMRllyVDnN+5cdhLpOajGMxhNThc6mmoI V2IH1O0kczE60v3XZ6j4ELPae5hBJzLjWs6DTkInEVTogGm+Qg5MB6ZtQmv0CsWaEJLx PPS08nXd3koCBaGqjL39r3bA4gZA0G8jpwnd1QqSNAgXn0LDInDfX/GOcb1uyVtEZHnn 7PVQ6at5MITYy8zM3d0+J0OF6L9MVgx7PxdpOP+gIEXSnLt5olsIT5g+WA6inUpxIm3s 5Qa82LuGc1E68lWE+p4800LSEfEEJeCr8xTdYy6mU1PswngSsIsVHVagUCTzrPuILQFP ZH7g== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=references:in-reply-to:message-id:date:subject:to:from:delivered-to :sender:list-help:list-post:list-archive:list-subscribe :list-unsubscribe:list-id:precedence:mailing-list:dkim-signature :domainkey-signature:arc-authentication-results; bh=0OvUE6+pqjeOafyE/ME95EIdFmdPEo1SAGyN3s7voRA=; b=rxNVoWNtaPRqGOhsUYwSACEqzsDKGD7N3OqPkbC5iSRLkGLU6FOH0Ab6e/rLKr5+sf NbHHK7+AapUHALeMu6bI4UJG4sH3/0wC191fL31MCgqho5rc/JN562k+4mmyJwZKacYj P/KY8HSJF8x8LylJqkFBokKW/cCsEo56Ezpz3W4QEenHlm7jG+8FpGBU1w4O4Iswr2O2 8AxgeCE1v1qzQbjgpO42kXvaJEyBMfw6mamyq9moxYSoF8KB+kNAHIKs/D1JhUJ3m6xp J97mfuZH6NwXpgTB4Ag5BKAC6coOGZYDonSXCPdk7CnRYccGAkWDSy+jCpvjEgrg9+RA 8fKA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@sourceware.org header.s=default header.b=gCHgi0/w; spf=pass (google.com: domain of libc-alpha-return-90621-patch=linaro.org@sourceware.org designates 209.132.180.131 as permitted sender) smtp.mailfrom=libc-alpha-return-90621-patch=linaro.org@sourceware.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from sourceware.org (server1.sourceware.org. [209.132.180.131]) by mx.google.com with ESMTPS id s11si6001468pgp.162.2018.02.26.13.04.43 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 26 Feb 2018 13:04:44 -0800 (PST) Received-SPF: pass (google.com: domain of libc-alpha-return-90621-patch=linaro.org@sourceware.org designates 209.132.180.131 as permitted sender) client-ip=209.132.180.131; Authentication-Results: mx.google.com; dkim=pass header.i=@sourceware.org header.s=default header.b=gCHgi0/w; spf=pass (google.com: domain of libc-alpha-return-90621-patch=linaro.org@sourceware.org designates 209.132.180.131 as permitted sender) smtp.mailfrom=libc-alpha-return-90621-patch=linaro.org@sourceware.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org DomainKey-Signature: a=rsa-sha1; c=nofws; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:from:to:subject:date:message-id:in-reply-to :references; q=dns; s=default; b=Sgwxe2cyZJ3xGHDm1NlTjCFo90oAGWr PUQS+l4jQgflQgwb2+Gocr+U+A+IRxLwcuR2ncyHpU7eyY/MY+UjJfiKgb3CcI3m sr2zklDPeoZe34318RIvoGcKstERnkcZ8h6aoXpEIgVlZknFwOJjJ6Om9zKNhaZc ov7L1VrZh2tY= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:from:to:subject:date:message-id:in-reply-to :references; s=default; bh=czAQe8icjjVu6ZnMr8Hyl2WHUxM=; b=gCHgi 0/wp0ofWTLlbP8upbsd4tzyfMANA2upeZXzj7P0fh+cHvVzkI2RrRghcpyA/VA6R jiA1xbJOcSs05Dv0zVpybF3bmIEyxTaGYbidafRhi8cjFxcouXGfsXJ7buciASWk yVm3kh2y827v0RpR48jTt4UZ0vCy2goaAJyHac= Received: (qmail 75113 invoked by alias); 26 Feb 2018 21:03:56 -0000 Mailing-List: contact libc-alpha-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: libc-alpha-owner@sourceware.org Delivered-To: mailing list libc-alpha@sourceware.org Received: (qmail 74980 invoked by uid 89); 26 Feb 2018 21:03:55 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-26.0 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, KAM_SHORT, RCVD_IN_DNSWL_NONE, SPF_PASS autolearn=ham version=3.3.2 spammy=Hx-spam-relays-external:209.85.220.196, H*RU:209.85.220.196 X-HELO: mail-qk0-f196.google.com X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references; bh=0OvUE6+pqjeOafyE/ME95EIdFmdPEo1SAGyN3s7voRA=; b=bVlIBYv1KSo3zFBXEmEjTFBysNvgP3RVlDnOHzdpWfvG/2SIM/qCZ30odib5IknjwD OgRr3VVj9mkoUqjXcwXKVt1DccvssjGjw2lDzBWOxGb+8iNIBYYG73lZSL9Or1o3W/7O 4ScV9RsqUnlb2P1CQJZ14HMeWe85Nh/Vf6tFdCfP3WeO7VDGm3tLJ8kz2QQVIOQ9sQ+8 ggy89CWWTEq0Q4D4fF1A7Pcadpg0Yv7ZZTDGv7OyfRMSJOaD8H/Aeasf3yOVF5jvl1+H NX/AosvtFSQ2Qr/2ptY3FBSJYtXNoI+m6g1CYgnsbJ8AxIQcmKUr6y15TlbHkMqC24W7 C8RA== X-Gm-Message-State: APf1xPC8oJDWI4DgCwgqaEOywJDUaUWn5GnebDaVU9DsEEIzcTbSvXMQ 6REbV4yKXFR6BLKdCNSaBbNboTiJf/I= X-Received: by 10.55.161.134 with SMTP id k128mr18222526qke.295.1519679029483; Mon, 26 Feb 2018 13:03:49 -0800 (PST) From: Adhemerval Zanella To: libc-alpha@sourceware.org Subject: [PATCH v2 04/21] nptl: x86_64: Fix Race conditions in pthread cancellation (BZ#12683) Date: Mon, 26 Feb 2018 18:03:19 -0300 Message-Id: <1519679016-12241-5-git-send-email-adhemerval.zanella@linaro.org> In-Reply-To: <1519679016-12241-1-git-send-email-adhemerval.zanella@linaro.org> References: <1519679016-12241-1-git-send-email-adhemerval.zanella@linaro.org> This patches adds the x86_64 modification required for the BZ#12683. It basically provide the required ucontext_get_pc symbol and remove the arch-specific libc-cancellation implementations. It also remove bogus arch-specific THREAD_ATOMIC_BIT_SET where it always reference to current thread instead of the one referenced by input 'descr' argument. It works as long the input is the self thread pointer, however it creates wrong code is it used along with a description to a different one (as on nptl/pthread_cancel.c). The code generated create an additional load to reference to TLS segment, for instance the code: THREAD_ATOMIC_BIT_SET (THREAD_SELF, cancelhandling, CANCELED_BIT); Compiles to: lock;orl $4, %fs:776 Where with patch changes it now compiles to: mov %fs:16,%rax lock;orl $4, 776(%rax) If some usage indeed proves to be a hotspot we can add an extra macro with a more descriptive name (THREAD_ATOMIC_BIT_SET_SELF for instance) where x86_64 might optimize it. In fact all x86_64 THREAD_ATOMIC_* macros do not respect the input descr and possible will fail when used with a 'descr' difference than THREAD_SELF. Checked on x86_64-linux-gnu. [BZ #12683] * sysdeps/unix/sysv/linux/x86_64/cancellation.S: Remove file. * sysdeps/unix/sysv/linux/x86_64/libc-cancellation.S: Remove file. * sysdeps/unix/sysv/linux/x86_64/librt-cancellation.S: Remove file. * sysdeps/unix/sysv/linux/x86_64/lowlevellock.h (lll_wait_tid): Use cancellable futex wait call. * sysdeps/unix/sysv/linux/x86_64/sigcontextinfo.h (ucontext_get_pc): New function. * sysdeps/x86_64/nptl/tcb-offsets.sym (TCB_CANCELING_BITMASK): Remove. * sysdeps/x86_64/nptl/tls.h (THREAD_ATOMIC_CMPXCHG_VAL, THREAD_ATOMIC_BIT_SET): Remove macros. --- ChangeLog | 13 +++ sysdeps/unix/sysv/linux/x86_64/cancellation.S | 115 --------------------- sysdeps/unix/sysv/linux/x86_64/libc-cancellation.S | 21 ---- .../unix/sysv/linux/x86_64/librt-cancellation.S | 21 ---- sysdeps/unix/sysv/linux/x86_64/lowlevellock.h | 8 +- sysdeps/unix/sysv/linux/x86_64/sigcontextinfo.h | 11 ++ sysdeps/x86_64/nptl/tcb-offsets.sym | 1 - sysdeps/x86_64/nptl/tls.h | 11 -- 8 files changed, 28 insertions(+), 173 deletions(-) delete mode 100644 sysdeps/unix/sysv/linux/x86_64/cancellation.S delete mode 100644 sysdeps/unix/sysv/linux/x86_64/libc-cancellation.S delete mode 100644 sysdeps/unix/sysv/linux/x86_64/librt-cancellation.S -- 2.7.4 diff --git a/sysdeps/unix/sysv/linux/x86_64/cancellation.S b/sysdeps/unix/sysv/linux/x86_64/cancellation.S deleted file mode 100644 index f3fb19d..0000000 --- a/sysdeps/unix/sysv/linux/x86_64/cancellation.S +++ /dev/null @@ -1,115 +0,0 @@ -/* Copyright (C) 2009-2018 Free Software Foundation, Inc. - This file is part of the GNU C Library. - Contributed by Ulrich Drepper , 2009. - - 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 -#include -#include -#include "lowlevellock.h" - -#define PTHREAD_UNWIND JUMPTARGET(__pthread_unwind) -#if IS_IN (libpthread) -# if defined SHARED && !defined NO_HIDDEN -# undef PTHREAD_UNWIND -# define PTHREAD_UNWIND __GI___pthread_unwind -# endif -#else -# ifndef SHARED - .weak __pthread_unwind -# endif -#endif - - -#ifdef __ASSUME_PRIVATE_FUTEX -# define LOAD_PRIVATE_FUTEX_WAIT(reg) \ - movl $(FUTEX_WAIT | FUTEX_PRIVATE_FLAG), reg -#else -# if FUTEX_WAIT == 0 -# define LOAD_PRIVATE_FUTEX_WAIT(reg) \ - movl %fs:PRIVATE_FUTEX, reg -# else -# define LOAD_PRIVATE_FUTEX_WAIT(reg) \ - movl %fs:PRIVATE_FUTEX, reg ; \ - orl $FUTEX_WAIT, reg -# endif -#endif - -/* It is crucial that the functions in this file don't modify registers - other than %rax and %r11. The syscall wrapper code depends on this - because it doesn't explicitly save the other registers which hold - relevant values. */ - .text - - .hidden __pthread_enable_asynccancel -ENTRY(__pthread_enable_asynccancel) - movl %fs:CANCELHANDLING, %eax -2: movl %eax, %r11d - orl $TCB_CANCELTYPE_BITMASK, %r11d - cmpl %eax, %r11d - je 1f - - lock - cmpxchgl %r11d, %fs:CANCELHANDLING - jnz 2b - - andl $(TCB_CANCELSTATE_BITMASK|TCB_CANCELTYPE_BITMASK|TCB_CANCELED_BITMASK|TCB_EXITING_BITMASK|TCB_CANCEL_RESTMASK|TCB_TERMINATED_BITMASK), %r11d - cmpl $(TCB_CANCELTYPE_BITMASK|TCB_CANCELED_BITMASK), %r11d - je 3f - -1: ret - -3: subq $8, %rsp - cfi_adjust_cfa_offset(8) - LP_OP(mov) $TCB_PTHREAD_CANCELED, %fs:RESULT - lock - orl $TCB_EXITING_BITMASK, %fs:CANCELHANDLING - mov %fs:CLEANUP_JMP_BUF, %RDI_LP - call PTHREAD_UNWIND - hlt -END(__pthread_enable_asynccancel) - - - .hidden __pthread_disable_asynccancel -ENTRY(__pthread_disable_asynccancel) - testl $TCB_CANCELTYPE_BITMASK, %edi - jnz 1f - - movl %fs:CANCELHANDLING, %eax -2: movl %eax, %r11d - andl $~TCB_CANCELTYPE_BITMASK, %r11d - lock - cmpxchgl %r11d, %fs:CANCELHANDLING - jnz 2b - - movl %r11d, %eax -3: andl $(TCB_CANCELING_BITMASK|TCB_CANCELED_BITMASK), %eax - cmpl $TCB_CANCELING_BITMASK, %eax - je 4f -1: ret - - /* Performance doesn't matter in this loop. We will - delay until the thread is canceled. And we will unlikely - enter the loop twice. */ -4: mov %fs:0, %RDI_LP - movl $__NR_futex, %eax - xorq %r10, %r10 - addq $CANCELHANDLING, %rdi - LOAD_PRIVATE_FUTEX_WAIT (%esi) - syscall - movl %fs:CANCELHANDLING, %eax - jmp 3b -END(__pthread_disable_asynccancel) diff --git a/sysdeps/unix/sysv/linux/x86_64/libc-cancellation.S b/sysdeps/unix/sysv/linux/x86_64/libc-cancellation.S deleted file mode 100644 index ed7af0d..0000000 --- a/sysdeps/unix/sysv/linux/x86_64/libc-cancellation.S +++ /dev/null @@ -1,21 +0,0 @@ -/* Copyright (C) 2009-2018 Free Software Foundation, Inc. - This file is part of the GNU C Library. - Contributed by Ulrich Drepper , 2009. - - 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 __pthread_enable_asynccancel __libc_enable_asynccancel -#define __pthread_disable_asynccancel __libc_disable_asynccancel -#include "cancellation.S" diff --git a/sysdeps/unix/sysv/linux/x86_64/librt-cancellation.S b/sysdeps/unix/sysv/linux/x86_64/librt-cancellation.S deleted file mode 100644 index d0f0ee4..0000000 --- a/sysdeps/unix/sysv/linux/x86_64/librt-cancellation.S +++ /dev/null @@ -1,21 +0,0 @@ -/* Copyright (C) 2009-2018 Free Software Foundation, Inc. - This file is part of the GNU C Library. - Contributed by Ulrich Drepper , 2009. - - 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 __pthread_enable_asynccancel __librt_enable_asynccancel -#define __pthread_disable_asynccancel __librt_disable_asynccancel -#include "cancellation.S" diff --git a/sysdeps/unix/sysv/linux/x86_64/lowlevellock.h b/sysdeps/unix/sysv/linux/x86_64/lowlevellock.h index eedb6fc..957d4c1 100644 --- a/sysdeps/unix/sysv/linux/x86_64/lowlevellock.h +++ b/sysdeps/unix/sysv/linux/x86_64/lowlevellock.h @@ -231,10 +231,10 @@ extern int __lll_timedlock_elision (int *futex, short *adapt_count, afterwards. The kernel up to version 3.16.3 does not use the private futex operations for futex wake-up when the clone terminates. */ #define lll_wait_tid(tid) \ - do { \ - __typeof (tid) __tid; \ - while ((__tid = (tid)) != 0) \ - lll_futex_wait (&(tid), __tid, LLL_SHARED);\ + do { \ + __typeof (tid) __tid; \ + while ((__tid = (tid)) != 0) \ + lll_futex_wait_cancel (&(tid), __tid, LLL_SHARED); \ } while (0) extern int __lll_timedwait_tid (int *, const struct timespec *) diff --git a/sysdeps/unix/sysv/linux/x86_64/sigcontextinfo.h b/sysdeps/unix/sysv/linux/x86_64/sigcontextinfo.h index 41ace60..3cc7336 100644 --- a/sysdeps/unix/sysv/linux/x86_64/sigcontextinfo.h +++ b/sysdeps/unix/sysv/linux/x86_64/sigcontextinfo.h @@ -15,6 +15,9 @@ License along with the GNU C Library; if not, see . */ +#ifndef _SIGCONTEXTINFO_H +#define _SIGCONTEXTINFO_H + #include #define SIGCONTEXT siginfo_t *_si, ucontext_t * @@ -28,3 +31,11 @@ #define CALL_SIGHANDLER(handler, signo, ctx) \ (handler)((signo), SIGCONTEXT_EXTRA_ARGS (ctx)) + +static inline +uintptr_t ucontext_get_pc (const ucontext_t *uc) +{ + return uc->uc_mcontext.gregs[REG_RIP]; +} + +#endif diff --git a/sysdeps/x86_64/nptl/tcb-offsets.sym b/sysdeps/x86_64/nptl/tcb-offsets.sym index 8a25c48..b225e5b 100644 --- a/sysdeps/x86_64/nptl/tcb-offsets.sym +++ b/sysdeps/x86_64/nptl/tcb-offsets.sym @@ -19,7 +19,6 @@ PRIVATE_FUTEX offsetof (tcbhead_t, private_futex) -- Not strictly offsets, but these values are also used in the TCB. TCB_CANCELSTATE_BITMASK CANCELSTATE_BITMASK TCB_CANCELTYPE_BITMASK CANCELTYPE_BITMASK -TCB_CANCELING_BITMASK CANCELING_BITMASK TCB_CANCELED_BITMASK CANCELED_BITMASK TCB_EXITING_BITMASK EXITING_BITMASK TCB_CANCEL_RESTMASK CANCEL_RESTMASK diff --git a/sysdeps/x86_64/nptl/tls.h b/sysdeps/x86_64/nptl/tls.h index bdd0237..ed0c65b 100644 --- a/sysdeps/x86_64/nptl/tls.h +++ b/sysdeps/x86_64/nptl/tls.h @@ -315,17 +315,6 @@ typedef struct abort (); }) -/* Atomic set bit. */ -# define THREAD_ATOMIC_BIT_SET(descr, member, bit) \ - (void) ({ if (sizeof ((descr)->member) == 4) \ - asm volatile (LOCK_PREFIX "orl %1, %%fs:%P0" \ - :: "i" (offsetof (struct pthread, member)), \ - "ir" (1 << (bit))); \ - else \ - /* Not necessary for other sizes in the moment. */ \ - abort (); }) - - /* Set the stack guard field in TCB head. */ # define THREAD_SET_STACK_GUARD(value) \ THREAD_SETMEM (THREAD_SELF, header.stack_guard, value)