From patchwork Mon Dec 11 19:06:47 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Adhemerval Zanella Netto X-Patchwork-Id: 121440 Delivered-To: patch@linaro.org Received: by 10.140.22.227 with SMTP id 90csp3167606qgn; Mon, 11 Dec 2017 11:08:17 -0800 (PST) X-Google-Smtp-Source: ACJfBosy8Lauiqsd34FRrkhTAkDDBbWJF5ZwV7GFaTmgeY82I+/nuUchUE4QaVVZTr3FOJs0GOUJ X-Received: by 10.159.214.148 with SMTP id n20mr1272580plp.101.1513019297243; Mon, 11 Dec 2017 11:08:17 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1513019297; cv=none; d=google.com; s=arc-20160816; b=EKPz7uwPEXCwPWIkvGbvE4qYaVbdJSYPf7R/pMgcBB+FwQNbSOSuFDOMXTVycISwAs Gvuxchnbry7Rrl2AhWgsq6PPBQSXmdlDXM4xqHNAl7AR7etFV1kKOns7XQvRjx3ZhzbL zaDDNE+dh74CjfhnG+0yfzz8mI/Hc06Vla58NpKSaFQHNdIh/d3BuK9jXo3iFW6RkKi2 Eo9dRvrlzi/7VvhkF5VHXfPOFtVuKopvQypFO6NjyOMvoH8F/Xmu/u/deOI8GVDD6INx b2ivUFiM2J3dGPyrTTSKynGq1AN8grHiRC5RwPAAT9xmWulCCIYqvoLRc8TlgTl3w1eV 7rmw== 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=7Ye/+cXRyMK2m2IbkWy1/+PbxiiIRwoJvLzJGFfJ0LY=; b=DnuzKRDBw+q0JWMp0XVAHkDozUkKMcJbFdnWCxcLIGK3vd7lF9wK1tcQCGVVbjz+iD vu8HJNMA97hDarqA6CJRJHqObkwx+7LZAwq27JyODt2TG2dQfY8bm9yzn7PqIO3TyESA vcJpQJrC6N/NaqX4oT2b7LYg1cnkzBYd+I3o+CvbEt7lobRHRa+Ib/g7b81mWdo9sd0k pSbRcox8oi7CdCrsCIz/oyx74EyjvqzAGfLpk4gTAxxBRpHPu5IfnNI5ftAtL56yCmCR 5dL+pS0cXlGvLPnWWwZTdO7pF8YfOA0V/BCbtIZFFjAfznpzGo5y8q7rsdo0fglpC+Jk ghBA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@sourceware.org header.s=default header.b=mP48nJic; spf=pass (google.com: domain of libc-alpha-return-88017-patch=linaro.org@sourceware.org designates 209.132.180.131 as permitted sender) smtp.mailfrom=libc-alpha-return-88017-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 q3si1346429pll.254.2017.12.11.11.08.16 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 11 Dec 2017 11:08:17 -0800 (PST) Received-SPF: pass (google.com: domain of libc-alpha-return-88017-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=mP48nJic; spf=pass (google.com: domain of libc-alpha-return-88017-patch=linaro.org@sourceware.org designates 209.132.180.131 as permitted sender) smtp.mailfrom=libc-alpha-return-88017-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=yrbM8ZDUO6ZKSNOCDGydVdKkYEMyvEb LsND3I3sdZjdtcy5s8oG6JnMZ7nhtDLFS1F5GOEDrmhsdUKdi7ZhX36Xw7kHudkh SLIILQvcl3jCahemKXqyfRys6v4KIL4HG2r+2GADbrpiRvZAaYmNeE1h6nQ3eJ5Y 0K7qE71cFFHc= 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=XzuSU6prTyqkulWVTcDOWy0Gocg=; b=mP48n JicTe/RcxJztbSApXU+SVSxnE4Q7BulJjKl47iQoZy/RmPbGv5SzU19l2FJ145DZ 7Hu3w1mEqRB0YJMB+eg1DvHPYrPwyRVs5ZWQ+tszFQLXy3ImWmB3yfSewyVxMbwP MIGuVmA8x9IObqYkEynkEZpKxf59LQwevRk3b8= Received: (qmail 40894 invoked by alias); 11 Dec 2017 19:07:20 -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 40836 invoked by uid 89); 11 Dec 2017 19:07:20 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-25.8 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=proves, crucial, H*RU:209.85.216.196, 2009-2017 X-HELO: mail-qt0-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=7Ye/+cXRyMK2m2IbkWy1/+PbxiiIRwoJvLzJGFfJ0LY=; b=cfxFBdZKzG6+90JAslUau6tI+IZb3dRZqQQcb+oSYjSWvZAh1uOH87kT/fx7Yv0S1Z 8QOkpso99mvWCJMPbrNLvmc946w+8hyq4XlC3u/r0xuMccDYVa29LTlA7Vz+ODwrgXL7 eNA0hNRNq3S9CERCm0/Q2WtjsUG3HyOIHPl3C7/gfmpJhqWWkZePdWZj9mcsXySKcj3N EZVzuO1PzNtgvWFR/qjIyw6cD61nwUB6kc/gCikjmTBMsjNuuZEv39Jw4LG9H+S7Zgs7 2fxRfqYbECbhOS0cy6AE7nbuagxWiw76hKQYzkY21JaYhe8WpQ/O5RRBy1dMx5Syv5GR nhsg== X-Gm-Message-State: AKGB3mLYvpaBXKqRbmXRppGOAIQ4JNvcYCUjdfYTILDaScKv3PtGghs4 2CYk0vpUC6RchG4E0QxzqlFdjIybfmA= X-Received: by 10.55.16.80 with SMTP id a77mr1982288qkh.250.1513019234955; Mon, 11 Dec 2017 11:07:14 -0800 (PST) From: Adhemerval Zanella To: libc-alpha@sourceware.org Subject: [PATCH 03/19] nptl: x86_64: Fix Race conditions in pthread cancellation (BZ#12683) Date: Mon, 11 Dec 2017 17:06:47 -0200 Message-Id: <1513019223-7603-4-git-send-email-adhemerval.zanella@linaro.org> In-Reply-To: <1513019223-7603-1-git-send-email-adhemerval.zanella@linaro.org> References: <1513019223-7603-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. * 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. Signed-off-by: Adhemerval Zanella --- ChangeLog | 12 +++ 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, 27 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 ed804df..0000000 --- a/sysdeps/unix/sysv/linux/x86_64/cancellation.S +++ /dev/null @@ -1,115 +0,0 @@ -/* Copyright (C) 2009-2017 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 dc9d822..0000000 --- a/sysdeps/unix/sysv/linux/x86_64/libc-cancellation.S +++ /dev/null @@ -1,21 +0,0 @@ -/* Copyright (C) 2009-2017 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 8422939..0000000 --- a/sysdeps/unix/sysv/linux/x86_64/librt-cancellation.S +++ /dev/null @@ -1,21 +0,0 @@ -/* Copyright (C) 2009-2017 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 cbf6597..bb6d9ee 100644 --- a/sysdeps/unix/sysv/linux/x86_64/lowlevellock.h +++ b/sysdeps/unix/sysv/linux/x86_64/lowlevellock.h @@ -232,10 +232,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 131f96b..d9a44e1 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 9b8ad82..4594fe9 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)