From patchwork Mon Aug 31 21:11:25 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Adhemerval Zanella X-Patchwork-Id: 52905 Return-Path: X-Original-To: linaro@patches.linaro.org Delivered-To: linaro@patches.linaro.org Received: from mail-lb0-f198.google.com (mail-lb0-f198.google.com [209.85.217.198]) by patches.linaro.org (Postfix) with ESMTPS id 943472127E for ; Mon, 31 Aug 2015 21:12:11 +0000 (UTC) Received: by lbcue2 with SMTP id ue2sf42338485lbc.1 for ; Mon, 31 Aug 2015 14:12:10 -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=tyda5/BMkExsBfnQGosPF7au0YXFTID4oEeeW0nwZWY=; b=mCVBq4e3xqktPfuXmmUGyDzZHJ3inV8X94vZ6M+Che5L9S0OtYDeJFbHzn/8Z89vHO 0IEyYpboycAt2++uiUSBKjhZAmD7bT7fhupUb+K2hj+6+d2+BrIL2Z3lFI2DHc+aTaCY 5gtWKM0veokfobyIIgg9dFB2oe7NqX0UGqh4VvVFlBHR+9QFg5GNMOhJ/XaQugiH3xYg BRhD8K6LSB8gAFcYQs0/crLwE/8j4q1JZZeRNYb+/0V2axL3vEwoafu224HcXfG0DWFZ G9ZYeDLTZRrM1gbbkVRsgbOjPVLZNFTQto4TM+VlW1KVFShDnMG7MyT0I/OfGx5owVqL d+GQ== X-Gm-Message-State: ALoCoQnnZoKCgXZRhMmlaxq35Msd3/RFbDkLFRe49y3J+6OR0IuqC1I/dkNKE++EEkeB2KV0xN0I X-Received: by 10.180.96.226 with SMTP id dv2mr152517wib.2.1441055530466; Mon, 31 Aug 2015 14:12:10 -0700 (PDT) X-BeenThere: patchwork-forward@linaro.org Received: by 10.152.170.197 with SMTP id ao5ls276137lac.53.gmail; Mon, 31 Aug 2015 14:12:10 -0700 (PDT) X-Received: by 10.152.37.227 with SMTP id b3mr11073978lak.91.1441055530185; Mon, 31 Aug 2015 14:12:10 -0700 (PDT) Received: from mail-lb0-x22a.google.com (mail-lb0-x22a.google.com. [2a00:1450:4010:c04::22a]) by mx.google.com with ESMTPS id x5si4115997lal.70.2015.08.31.14.12.10 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 31 Aug 2015 14:12:10 -0700 (PDT) Received-SPF: pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 2a00:1450:4010:c04::22a as permitted sender) client-ip=2a00:1450:4010:c04::22a; Received: by lbbtg9 with SMTP id tg9so67952957lbb.1 for ; Mon, 31 Aug 2015 14:12:10 -0700 (PDT) X-Received: by 10.152.198.140 with SMTP id jc12mr2322936lac.19.1441055530023; Mon, 31 Aug 2015 14:12:10 -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.164.42 with SMTP id yn10csp92071lbb; Mon, 31 Aug 2015 14:12:08 -0700 (PDT) X-Received: by 10.66.140.70 with SMTP id re6mr41608478pab.31.1441055528823; Mon, 31 Aug 2015 14:12:08 -0700 (PDT) Received: from sourceware.org (server1.sourceware.org. [209.132.180.131]) by mx.google.com with ESMTPS id tt2si26036537pbc.54.2015.08.31.14.12.07 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 31 Aug 2015 14:12:08 -0700 (PDT) Received-SPF: pass (google.com: domain of libc-alpha-return-62843-patch=linaro.org@sourceware.org designates 209.132.180.131 as permitted sender) client-ip=209.132.180.131; Received: (qmail 55967 invoked by alias); 31 Aug 2015 21:11:47 -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 55916 invoked by uid 89); 31 Aug 2015 21:11:47 -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-qk0-f173.google.com X-Received: by 10.129.74.196 with SMTP id x187mr24838748ywa.105.1441055487606; Mon, 31 Aug 2015 14:11:27 -0700 (PDT) From: Adhemerval Zanella Subject: [PATCH 07/08] nptl: aarch64: Fix Race conditions in pthread cancellation (BZ#12683) To: GNU C Library Message-ID: <55E4C2FD.5050407@linaro.org> Date: Mon, 31 Aug 2015 18:11:25 -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:c04::22a 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 aarch64 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. --- * sysdeps/unix/sysv/linux/aarch64/syscall_cancel.S: New file. * sysdeps/unix/sysv/linux/aarch64/sysdep-cancel.h (PSEUDO): Redefine to call __syscall_cancel function for cancellable syscalls. (__pthread_get_ip): Add implementation. * sysdeps/unix/sysv/linux/aarch64/sysdep.h (SYSCALL_CANCEL_ERROR): Add definition. (SYSCALL_CANCEL_ERRNO): Likewise. -- diff --git a/sysdeps/unix/sysv/linux/aarch64/syscall_cancel.S b/sysdeps/unix/sysv/linux/aarch64/syscall_cancel.S new file mode 100644 index 0000000..56ede8e --- /dev/null +++ b/sysdeps/unix/sysv/linux/aarch64/syscall_cancel.S @@ -0,0 +1,61 @@ +/* Cancellable syscall wrapper - aarch64 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 [r0] __syscall_cancel_arch (int *cancelhandling [x0], + long int nr [x1], + long int arg1 [x2], + long int arg2 [x3], + long int arg3 [x4], + long int arg4 [x5], + long int arg5 [x6], + long int arg6 [x7]) */ + +ENTRY (__syscall_cancel_arch) + + .globl __syscall_cancel_arch_start + .type __syscall_cancel_arch_start,@function +__syscall_cancel_arch_start: + + /* if (*cancelhandling & CANCELED_BITMASK) + __syscall_do_cancel() */ + ldr w0, [x0] + tbnz w0, 2, 1f + + /* Issue a 6 argument syscall, the nr [x1] being the syscall + number. */ + mov x8, x1 + mov x0, x2 + mov x1, x3 + mov x2, x4 + mov x3, x5 + mov x4, x6 + mov x5, x7 + svc 0x0 + + .globl __syscall_cancel_arch_end + .type __syscall_cancel_arch_end,@function +__syscall_cancel_arch_end: + ret + +1: + b __syscall_do_cancel + +END (__syscall_cancel_arch) +libc_hidden_def (__syscall_cancel_arch) diff --git a/sysdeps/unix/sysv/linux/aarch64/sysdep-cancel.h b/sysdeps/unix/sysv/linux/aarch64/sysdep-cancel.h index 36e8e39..71207b3 100644 --- a/sysdeps/unix/sysv/linux/aarch64/sysdep-cancel.h +++ b/sysdeps/unix/sysv/linux/aarch64/sysdep-cancel.h @@ -20,80 +20,57 @@ #include #ifndef __ASSEMBLER__ # include +# include #endif #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 +# endif + # undef PSEUDO # define PSEUDO(name, syscall_name, args) \ - .section ".text"; \ -ENTRY (__##syscall_name##_nocancel); \ -.Lpseudo_nocancel: \ - DO_CALL (syscall_name, args); \ -.Lpseudo_finish: \ - cmn x0, 4095; \ - b.cs .Lsyscall_error; \ - .subsection 2; \ - .size __##syscall_name##_nocancel,.-__##syscall_name##_nocancel; \ ENTRY (name); \ SINGLE_THREAD_P(16); \ - cbz w16, .Lpseudo_nocancel; \ - /* Setup common stack frame no matter the number of args. \ - Also save the first arg, since it's basically free. */ \ - stp x30, x0, [sp, -64]!; \ - cfi_adjust_cfa_offset (64); \ - cfi_rel_offset (x30, 0); \ - DOCARGS_##args; /* save syscall args around CENABLE. */ \ - CENABLE; \ - mov x16, x0; /* save mask around syscall. */ \ - UNDOCARGS_##args; /* restore syscall args. */ \ + cbnz w16, L(pseudo_cancel); \ DO_CALL (syscall_name, args); \ - str x0, [sp, 8]; /* save result around CDISABLE. */ \ - mov x0, x16; /* restore mask for CDISABLE. */ \ - CDISABLE; \ - /* Break down the stack frame, restoring result at once. */ \ - ldp x30, x0, [sp], 64; \ - cfi_adjust_cfa_offset (-64); \ - cfi_restore (x30); \ - b .Lpseudo_finish; \ - cfi_endproc; \ - .size name, .-name; \ - .previous + b L(pseudo_finish); \ +L(pseudo_cancel): \ + stp x29, x30, [sp, -16]!; \ + cfi_def_cfa_offset (16); \ + cfi_offset (29, -16); \ + cfi_offset (30, -8); \ + add x29, sp, 0; \ + cfi_def_cfa_register (29); \ + mov x6, x5; \ + mov x5, x4; \ + mov x4, x3; \ + mov x3, x2; \ + mov x2, x1; \ + mov x1, x0; \ + mov x0, SYS_ify (syscall_name); \ + bl JMP_SYSCALL_CANCEL; \ + ldp x29, x30, [sp], 16; \ + cfi_restore (30); \ + cfi_restore (29); \ + cfi_def_cfa (31, 0); \ +L(pseudo_finish): \ + cmn x0, 4095; \ + b.cs L(syscall_error); # undef PSEUDO_END # define PSEUDO_END(name) \ SYSCALL_ERROR_HANDLER; \ - cfi_endproc - -# define DOCARGS_0 -# define DOCARGS_1 -# define DOCARGS_2 str x1, [sp, 16] -# define DOCARGS_3 stp x1, x2, [sp, 16] -# define DOCARGS_4 DOCARGS_3; str x3, [sp, 32] -# define DOCARGS_5 DOCARGS_3; stp x3, x4, [sp, 32] -# define DOCARGS_6 DOCARGS_5; str x5, [sp, 48] - -# define UNDOCARGS_0 -# define UNDOCARGS_1 ldr x0, [sp, 8] -# define UNDOCARGS_2 ldp x0, x1, [sp, 8] -# define UNDOCARGS_3 UNDOCARGS_1; ldp x1, x2, [sp, 16] -# define UNDOCARGS_4 UNDOCARGS_2; ldp x2, x3, [sp, 24] -# define UNDOCARGS_5 UNDOCARGS_3; ldp x3, x4, [sp, 32] -# define UNDOCARGS_6 UNDOCARGS_4; ldp x4, x5, [sp, 40] + cfi_endproc; \ + .size name, .-name; # if IS_IN (libpthread) -# define CENABLE bl __pthread_enable_asynccancel -# define CDISABLE bl __pthread_disable_asynccancel # define __local_multiple_threads __pthread_multiple_threads # elif IS_IN (libc) -# define CENABLE bl __libc_enable_asynccancel -# define CDISABLE bl __libc_disable_asynccancel # define __local_multiple_threads __libc_multiple_threads -# elif IS_IN (librt) -# define CENABLE bl __librt_enable_asynccancel -# define CDISABLE bl __librt_disable_asynccancel -# else -# error Unsupported library # endif # if IS_IN (libpthread) || IS_IN (libc) @@ -131,4 +108,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.pc; +} #endif diff --git a/sysdeps/unix/sysv/linux/aarch64/sysdep.h b/sysdeps/unix/sysv/linux/aarch64/sysdep.h index fe94a50..5f73b9e 100644 --- a/sysdeps/unix/sysv/linux/aarch64/sysdep.h +++ b/sysdeps/unix/sysv/linux/aarch64/sysdep.h @@ -199,6 +199,14 @@ # undef INTERNAL_SYSCALL_ERRNO # define INTERNAL_SYSCALL_ERRNO(val, err) (-(val)) +#undef SYSCALL_CANCEL_ERROR +#define SYSCALL_CANCEL_ERROR(__val) \ + ((unsigned long) (__val) >= (unsigned long) -4095) + +#undef SYSCALL_CANCEL_ERRNO +#define SYSCALL_CANCEL_ERRNO(__val) \ + (-(__val)) + # define LOAD_ARGS_0() \ register long _x0 asm ("x0"); # define LOAD_ARGS_1(x0) \