From patchwork Thu Sep 17 20:04:20 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Adhemerval Zanella X-Patchwork-Id: 53846 Return-Path: X-Original-To: linaro@patches.linaro.org Delivered-To: linaro@patches.linaro.org Received: from mail-lb0-f200.google.com (mail-lb0-f200.google.com [209.85.217.200]) by patches.linaro.org (Postfix) with ESMTPS id 2E2F622E57 for ; Thu, 17 Sep 2015 20:04:56 +0000 (UTC) Received: by lbbti1 with SMTP id ti1sf9812623lbb.3 for ; Thu, 17 Sep 2015 13:04:55 -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=Y8M3QXvf+Dwuni1kl5MuthwFOMDw1WLrZA2kSrqgziwqJLGoQnKMkqY7y5oZjjk2tI i2ij2hHF0Qrx08DZ7M4fucbAU3AsZEo3E4owL7MxkwJvqCZ9mq66ePG59a7GM55BakbO tDIa+zOhmB+ngAoZrM2ZnmfsADkKiATlsBNnBeiBPCexjUkHhV7yUL70nUo/iEcCWtns iClEWk3i+VX+Lj7BD+Qz/VQmH1UJtZ6H9Yxhpxc4Un4972/js5zJDoIavLQ1TW+qJivB 55GqjavyjPNFbHzge94fuTOCl5ifJt7hu4i+Nu4URUyrLT9QobP9oD6OiG5SWmfZ4X7D oViw== X-Gm-Message-State: ALoCoQnYDjdHxmjNnCAr63y+W/hekcZmP/cramwUeSYk8fc4L14iY/ICk5TEuE1R6cnlhxl17M+l X-Received: by 10.180.89.104 with SMTP id bn8mr3468506wib.4.1442520295133; Thu, 17 Sep 2015 13:04:55 -0700 (PDT) X-BeenThere: patchwork-forward@linaro.org Received: by 10.152.5.164 with SMTP id t4ls129596lat.84.gmail; Thu, 17 Sep 2015 13:04:54 -0700 (PDT) X-Received: by 10.112.52.168 with SMTP id u8mr1245204lbo.48.1442520294950; Thu, 17 Sep 2015 13:04:54 -0700 (PDT) Received: from mail-lb0-x230.google.com (mail-lb0-x230.google.com. [2a00:1450:4010:c04::230]) by mx.google.com with ESMTPS id jc6si3484528lac.3.2015.09.17.13.04.54 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 17 Sep 2015 13:04:54 -0700 (PDT) Received-SPF: pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 2a00:1450:4010:c04::230 as permitted sender) client-ip=2a00:1450:4010:c04::230; Received: by lbbmp1 with SMTP id mp1so15163344lbb.1 for ; Thu, 17 Sep 2015 13:04:54 -0700 (PDT) X-Received: by 10.112.129.202 with SMTP id ny10mr1199251lbb.112.1442520294845; Thu, 17 Sep 2015 13:04:54 -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 w3csp3264976lbq; Thu, 17 Sep 2015 13:04:53 -0700 (PDT) X-Received: by 10.68.137.35 with SMTP id qf3mr1810138pbb.89.1442520293713; Thu, 17 Sep 2015 13:04:53 -0700 (PDT) Received: from sourceware.org (server1.sourceware.org. [209.132.180.131]) by mx.google.com with ESMTPS id qp7si7613746pbc.93.2015.09.17.13.04.53 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 17 Sep 2015 13:04:53 -0700 (PDT) Received-SPF: pass (google.com: domain of libc-alpha-return-63262-patch=linaro.org@sourceware.org designates 209.132.180.131 as permitted sender) client-ip=209.132.180.131; Received: (qmail 108315 invoked by alias); 17 Sep 2015 20:04:38 -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 107832 invoked by uid 89); 17 Sep 2015 20:04:34 -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-f177.google.com X-Received: by 10.129.116.84 with SMTP id p81mr1140289ywc.1.1442520261090; Thu, 17 Sep 2015 13:04:21 -0700 (PDT) From: Adhemerval Zanella Subject: [PATCH 07/10] nptl: aarch64: Fix Race conditions in pthread cancellation (BZ#12683) To: GNU C Library Message-ID: <55FB1CC4.7090005@linaro.org> Date: Thu, 17 Sep 2015 17:04:20 -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::230 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) \