From patchwork Thu Sep 17 20:04:27 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Adhemerval Zanella X-Patchwork-Id: 53848 Return-Path: X-Original-To: linaro@patches.linaro.org Delivered-To: linaro@patches.linaro.org Received: from mail-wi0-f197.google.com (mail-wi0-f197.google.com [209.85.212.197]) by patches.linaro.org (Postfix) with ESMTPS id 8215222E57 for ; Thu, 17 Sep 2015 20:05:25 +0000 (UTC) Received: by wisv5 with SMTP id v5sf1435053wis.0 for ; Thu, 17 Sep 2015 13:05:24 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:delivered-to:mailing-list:precedence:list-id :list-unsubscribe:list-subscribe:list-archive:list-post:list-help :sender:delivered-to:from:subject:to:message-id:date:user-agent :mime-version:content-type:content-transfer-encoding :x-original-sender:x-original-authentication-results; bh=mRR36RRnuRLZ1cOE2ocJVqDCTNs7txaanDxzd540GJg=; b=DPP+ebNLQLU6GF2DhyDmKI6u1m/1n4c+wByvjyWOhWmm7NGCtDJfEwu59OSEEynY2c tSMOkaTrieaDzRAmuVsxPkt+QjUZ8oIKnVGtdKhND2nIEGAgOxiMR922tmGoTy5t9iEc Mz4eJADUNuDAomOPIJYMOOUiQXetMNSPlUZLP9+koWB2HZnOJUflVPYdTiY95ccfA/xp 2vIfk1GhAtiuy7JAp/ocaQZEHTC6bMUyY4y3MuVWr9pKPnxWxMcCr20Kq+M2np9F2q1Y ChpBAWmqXS6XSiwmvAAod3pbJW551/nkOZDKobcEV/XyXePus4T375d6qQ74nzm0ZqJs PjHw== X-Gm-Message-State: ALoCoQmm2ysQKgjc2TUF+VIQsTKZQ2qTaVbsFT66uJCNNwW4ljYyv3JED08nSEJH5gE6c2azXcar X-Received: by 10.112.170.67 with SMTP id ak3mr177525lbc.6.1442520324748; Thu, 17 Sep 2015 13:05:24 -0700 (PDT) X-BeenThere: patchwork-forward@linaro.org Received: by 10.152.20.229 with SMTP id q5ls132397lae.17.gmail; Thu, 17 Sep 2015 13:05:24 -0700 (PDT) X-Received: by 10.112.77.68 with SMTP id q4mr1188043lbw.77.1442520324591; Thu, 17 Sep 2015 13:05:24 -0700 (PDT) Received: from mail-la0-x235.google.com (mail-la0-x235.google.com. [2a00:1450:4010:c03::235]) by mx.google.com with ESMTPS id z15si3320431lbn.158.2015.09.17.13.05.24 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 17 Sep 2015 13:05:24 -0700 (PDT) Received-SPF: pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 2a00:1450:4010:c03::235 as permitted sender) client-ip=2a00:1450:4010:c03::235; Received: by lanb10 with SMTP id b10so18108465lan.3 for ; Thu, 17 Sep 2015 13:05:24 -0700 (PDT) X-Received: by 10.112.129.202 with SMTP id ny10mr1201616lbb.112.1442520324132; Thu, 17 Sep 2015 13:05:24 -0700 (PDT) X-Forwarded-To: patchwork-forward@linaro.org X-Forwarded-For: patch@linaro.org patchwork-forward@linaro.org Delivered-To: patch@linaro.org Received: by 10.112.59.35 with SMTP id w3csp3265189lbq; Thu, 17 Sep 2015 13:05:23 -0700 (PDT) X-Received: by 10.68.194.170 with SMTP id hx10mr1928242pbc.64.1442520322986; Thu, 17 Sep 2015 13:05:22 -0700 (PDT) Received: from sourceware.org (server1.sourceware.org. [209.132.180.131]) by mx.google.com with ESMTPS id yv10si7573950pab.172.2015.09.17.13.05.22 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 17 Sep 2015 13:05:22 -0700 (PDT) Received-SPF: pass (google.com: domain of libc-alpha-return-63265-patch=linaro.org@sourceware.org designates 209.132.180.131 as permitted sender) client-ip=209.132.180.131; Received: (qmail 108731 invoked by alias); 17 Sep 2015 20:04:40 -0000 Mailing-List: list patchwork-forward@linaro.org; contact patchwork-forward+owners@linaro.org Precedence: list 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 108661 invoked by uid 89); 17 Sep 2015 20:04:40 -0000 X-Virus-Found: No X-Spam-SWARE-Status: No, score=-2.3 required=5.0 tests=AWL, BAYES_00, RCVD_IN_DNSWL_LOW, SPF_PASS autolearn=ham version=3.3.2 X-HELO: mail-yk0-f181.google.com X-Received: by 10.129.145.214 with SMTP id i205mr1191635ywg.64.1442520267742; Thu, 17 Sep 2015 13:04:27 -0700 (PDT) From: Adhemerval Zanella Subject: [PATCH 10/10] nptl: s390x: Fix Race conditions in pthread cancellation (BZ#12683) To: GNU C Library Message-ID: <55FB1CCB.2070204@linaro.org> Date: Thu, 17 Sep 2015 17:04:27 -0300 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:38.0) Gecko/20100101 Thunderbird/38.2.0 MIME-Version: 1.0 X-Original-Sender: adhemerval.zanella@linaro.org X-Original-Authentication-Results: mx.google.com; spf=pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 2a00:1450:4010:c03::235 as permitted sender) smtp.mailfrom=patch+caf_=patchwork-forward=linaro.org@linaro.org; dkim=pass header.i=@sourceware.org X-Google-Group-Id: 836684582541 This patch adds the s390x modifications required for the BZ#12683 fix. It basically removes the enable_asynccancel/disable_asynccancel function usage on code, provide a arch-specific symbol that contains global markers to be used in SIGCANCEL handler. --- 2015-09-16 Adhemerval Zanella Stefan Liebler * sysdeps/unix/sysv/linux/s390/s390-64/syscall_cancel.S: New file. * sysdeps/unix/sysv/linux/s390/s390-64/sysdep-cancel.h (PSEUDO): Redefine to call __syscall_cancel function for cancellable syscalls. (__pthread_get_ip): Add implementation. * sysdeps/unix/sysv/linux/s390/s390-64/sysdep.h (SYSCALL_CANCEL_ERROR): Add definition. (SYSCALL_CANCEL_ERRNO): Likewise. -- diff --git a/sysdeps/unix/sysv/linux/s390/s390-64/syscall_cancel.S b/sysdeps/unix/sysv/linux/s390/s390-64/syscall_cancel.S new file mode 100644 index 0000000..2da44a5 --- /dev/null +++ b/sysdeps/unix/sysv/linux/s390/s390-64/syscall_cancel.S @@ -0,0 +1,87 @@ +/* Cancellable syscall wrapper - s390x version. + Copyright (C) 2015 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 + +/* long int [r2] __syscall_cancel_arch (int *cancelhandling [r2], + long int nr [r3], + long int arg1 [r4], + long int arg2 [r5], + long int arg3 [r6], + long int arg4 [SP+160], + long int arg5 [SP+168], + long int arg6 [SP+176]) */ + +ENTRY (__syscall_cancel_arch) + + /* Save registers and setup stack. */ + stmg %r6,%r15,48(%r15) /* Save registers. */ + cfi_offset (%r15,-40) + cfi_offset (%r14,-48) + cfi_offset (%r13,-56) + cfi_offset (%r12,-64) + cfi_offset (%r11,-72) + cfi_offset (%r10,-80) + cfi_offset (%r9,-88) + cfi_offset (%r8,-96) + cfi_offset (%r7,-104) + cfi_offset (%r6,-112) + lgr %r1,%r15 + lg %r0,8(%r15) /* Load eos. */ + aghi %r15,-160 /* Buy stack space. */ + cfi_adjust_cfa_offset (160) + stg %r1,0(%r15) /* Store back chain. */ + stg %r0,8(%r15) /* Store eos. */ + + .globl __syscall_cancel_arch_start + .type __syscall_cancel_arch_start,@function +__syscall_cancel_arch_start: + + /* if (*cancelhandling & CANCELED_BITMASK) + __syscall_do_cancel() */ + tm 3(%r2),4 + jne 1f + + /* Issue a 6 argument syscall */ + lgr %r1,%r3 /* Move syscall number. */ + lgr %r2,%r4 /* First parameter. */ + lgr %r3,%r5 /* Second parameter. */ + lgr %r4,%r6 /* Third parameter. */ + lg %r5,320(%r15) /* Fourth parameter. */ + lg %r6,328(%r15) /* Fifth parameter. */ + lg %r7,336(%r15) /* Sixth parameter. */ + + svc 0 /* svc number is always in r1. */ + + .globl __syscall_cancel_arch_end + .type __syscall_cancel_arch_end,@function +__syscall_cancel_arch_end: + lg %r15,0(%r15) /* load back chain */ + cfi_adjust_cfa_offset (-160) + lmg %r6,%r15,48(%r15) /* Load registers. */ + + br %r14 + + /* Branch to __syscall_do_cancel */ +1: + lg %r15,0(%r15) /* load back chain */ + cfi_adjust_cfa_offset (-160) + lmg %r6,%r15,48(%r15) /* Load registers. */ + jg __syscall_do_cancel +END (__syscall_cancel_arch) +libc_hidden_def (__syscall_cancel_arch) diff --git a/sysdeps/unix/sysv/linux/s390/s390-64/sysdep-cancel.h b/sysdeps/unix/sysv/linux/s390/s390-64/sysdep-cancel.h index e054dc9..d8da8c2 100644 --- a/sysdeps/unix/sysv/linux/s390/s390-64/sysdep-cancel.h +++ b/sysdeps/unix/sysv/linux/s390/s390-64/sysdep-cancel.h @@ -24,93 +24,85 @@ #if IS_IN (libc) || IS_IN (libpthread) || IS_IN (librt) +# if IS_IN (libc) +# define JMP_SYSCALL_CANCEL HIDDEN_JUMPTARGET(__syscall_cancel) +# else +# define JMP_SYSCALL_CANCEL __syscall_cancel@plt +# endif + +# define STORE_0 /* Nothing */ +# define STORE_1 /* Nothing */ +# define STORE_2 /* Nothing */ +# define STORE_3 /* Nothing */ +# define STORE_4 stg %r6,48(%r15); \ + cfi_offset (%r6,-112); +# define STORE_5 STORE_4 +# define STORE_6 STORE_4 + +# define LOAD_0 /* Nothing */ +# define LOAD_1 /* Nothing */ +# define LOAD_2 /* Nothing */ +# define LOAD_3 /* Nothing */ +# define LOAD_4 lg %r6,48(%r15); +# define LOAD_5 LOAD_4 +# define LOAD_6 LOAD_4 + +# define MOVE_ARGS_0 +# define MOVE_ARGS_1 lgr %r3,%r2; \ + MOVE_ARGS_0 +# define MOVE_ARGS_2 lgr %r4,%r3; \ + MOVE_ARGS_1 +# define MOVE_ARGS_3 lgr %r5,%r4; \ + MOVE_ARGS_2 +# define MOVE_ARGS_4 lgr %r6,%r5; \ + MOVE_ARGS_3 +# define MOVE_ARGS_5 stg %r6,160(%r15); \ + MOVE_ARGS_4 +# define MOVE_ARGS_6 lg %r14,160(%r14); \ + stg %r14,168(%r15); \ + MOVE_ARGS_5 + + # undef PSEUDO # define PSEUDO(name, syscall_name, args) \ .text; \ L(pseudo_cancel): \ cfi_startproc; \ - STM_##args \ - stmg %r13,%r15,104(%r15); \ + stmg %r14,%r15,112(%r15); \ cfi_offset (%r15,-40); \ cfi_offset (%r14,-48); \ - cfi_offset (%r13,-56); \ + STORE_##args \ lgr %r14,%r15; \ - aghi %r15,-160; \ - cfi_adjust_cfa_offset (160); \ + aghi %r15,-176; \ + cfi_adjust_cfa_offset (176); \ stg %r14,0(%r15); \ - brasl %r14,CENABLE; \ - lgr %r0,%r2; \ - LM_##args \ - .if SYS_ify (syscall_name) < 256; \ - svc SYS_ify (syscall_name); \ - .else; \ - lghi %r1,SYS_ify (syscall_name); \ - svc 0; \ - .endif; \ - LR7_##args \ - lgr %r13,%r2; \ - lgr %r2,%r0; \ - brasl %r14,CDISABLE; \ - lgr %r2,%r13; \ - lmg %r13,%r15,104+160(%r15); \ + MOVE_ARGS_##args \ + lghi %r2,SYS_ify (syscall_name); \ + brasl %r14,JMP_SYSCALL_CANCEL; \ + lmg %r14,%r15,112+176(%r15); \ + cfi_restore (%r14); \ + cfi_restore (%r15); \ + LOAD_##args \ cfi_endproc; \ j L(pseudo_check); \ ENTRY(name) \ SINGLE_THREAD_P \ jne L(pseudo_cancel); \ -.type __##syscall_name##_nocancel,@function; \ -.globl __##syscall_name##_nocancel; \ -__##syscall_name##_nocancel: \ DO_CALL(syscall_name, args); \ L(pseudo_check): \ lghi %r4,-4095; \ clgr %r2,%r4; \ jgnl SYSCALL_ERROR_LABEL; \ -.size __##syscall_name##_nocancel,.-__##syscall_name##_nocancel; \ L(pseudo_end): # if IS_IN (libpthread) -# define CENABLE __pthread_enable_asynccancel -# define CDISABLE __pthread_disable_asynccancel # define __local_multiple_threads __pthread_multiple_threads # elif IS_IN (libc) -# define CENABLE __libc_enable_asynccancel -# define CDISABLE __libc_disable_asynccancel # define __local_multiple_threads __libc_multiple_threads -# elif IS_IN (librt) -# define CENABLE __librt_enable_asynccancel -# define CDISABLE __librt_disable_asynccancel -# else +# elif !IS_IN (librt) # error Unsupported library # endif -#define STM_0 /* Nothing */ -#define STM_1 stg %r2,16(%r15); -#define STM_2 stmg %r2,%r3,16(%r15); -#define STM_3 stmg %r2,%r4,16(%r15); -#define STM_4 stmg %r2,%r5,16(%r15); -#define STM_5 stmg %r2,%r5,16(%r15); -#define STM_6 stmg %r2,%r7,16(%r15); - -#define LM_0 /* Nothing */ -#define LM_1 lg %r2,16+160(%r15); -#define LM_2 lmg %r2,%r3,16+160(%r15); -#define LM_3 lmg %r2,%r4,16+160(%r15); -#define LM_4 lmg %r2,%r5,16+160(%r15); -#define LM_5 lmg %r2,%r5,16+160(%r15); -#define LM_6 lmg %r2,%r5,16+160(%r15); \ - cfi_offset (%r7, -104); \ - lg %r7,160+160(%r15); - -#define LR7_0 /* Nothing */ -#define LR7_1 /* Nothing */ -#define LR7_2 /* Nothing */ -#define LR7_3 /* Nothing */ -#define LR7_4 /* Nothing */ -#define LR7_5 /* Nothing */ -#define LR7_6 lg %r7,56+160(%r15); \ - cfi_restore (%r7); - # if IS_IN (libpthread) || IS_IN (libc) # ifndef __ASSEMBLER__ extern int __local_multiple_threads attribute_hidden; @@ -149,4 +141,10 @@ extern int __local_multiple_threads attribute_hidden; # define RTLD_SINGLE_THREAD_P \ __builtin_expect (THREAD_GETMEM (THREAD_SELF, \ header.multiple_threads) == 0, 1) + +static inline +long int __pthread_get_ip (const struct ucontext *uc) +{ + return uc->uc_mcontext.psw.addr; +} #endif diff --git a/sysdeps/unix/sysv/linux/s390/s390-64/sysdep.h b/sysdeps/unix/sysv/linux/s390/s390-64/sysdep.h index c041153..4be051e 100644 --- a/sysdeps/unix/sysv/linux/s390/s390-64/sysdep.h +++ b/sysdeps/unix/sysv/linux/s390/s390-64/sysdep.h @@ -249,6 +249,14 @@ #undef INTERNAL_SYSCALL_ERRNO #define INTERNAL_SYSCALL_ERRNO(val, err) (-(val)) +#undef SYSCALL_CANCEL_ERROR +#define SYSCALL_CANCEL_ERROR(__val) \ + ((unsigned long) (__val) >= -4095UL) + +#undef SYSCALL_CANCEL_ERRNO +#define SYSCALL_CANCEL_ERRNO(__val) \ + (-(__val)) + #define DECLARGS_0() #define DECLARGS_1(arg1) \ register unsigned long gpr2 asm ("2") = (unsigned long)(arg1);