public inbox for libc-alpha@sourceware.org
 help / color / mirror / Atom feed
* [PATCH v3 07/21] nptl: i386: Fix Race conditions in pthread cancellation (BZ#12683)
  2019-10-14 20:57 [PATCH v3 00/21] nptl: Fix Race conditions in pthread cancellation (BZ#12683) Adhemerval Zanella
                   ` (7 preceding siblings ...)
  2019-10-14 20:57 ` [PATCH v3 15/21] nptl: alpha: " Adhemerval Zanella
@ 2019-10-14 20:57 ` Adhemerval Zanella
  2019-10-14 20:57 ` [PATCH v3 01/21] nptl: Handle EPIPE on tst-cancel2 Adhemerval Zanella
                   ` (11 subsequent siblings)
  20 siblings, 0 replies; 38+ messages in thread
From: Adhemerval Zanella @ 2019-10-14 20:57 UTC (permalink / raw)
  To: libc-alpha

This patch adds the i386 modifications required for the BZ#12683 fix
by adding the arch-specific cancellation syscall bridge.

The syscall bridge uses the old int80 instruction because by using
the optimized vDSO symbol the resulting PC value for an interrupted
syscall points to an adress outside the expected markers in
__syscall_cancel_arch.  It has been discussed in LKML [1] on how
kernel could help userland to accomplish it, but afaik discussion
has stalled.

Also, sysenter should not be used directly by libc since its calling
convention is set by the kernel depending of the underlying x86 chip
(check kernel commit 30bfa7b3488bfb1bb75c9f50a5fcac1832970c60).

Checked on i686-linux-gnu.

[1] https://lkml.org/lkml/2016/3/8/1105
---
 sysdeps/unix/sysv/linux/i386/Makefile         |   2 +-
 sysdeps/unix/sysv/linux/i386/syscall_cancel.S | 105 ++++++++++++++++++
 2 files changed, 106 insertions(+), 1 deletion(-)
 create mode 100644 sysdeps/unix/sysv/linux/i386/syscall_cancel.S

diff --git a/sysdeps/unix/sysv/linux/i386/Makefile b/sysdeps/unix/sysv/linux/i386/Makefile
index da716e2c1b..7928497a35 100644
--- a/sysdeps/unix/sysv/linux/i386/Makefile
+++ b/sysdeps/unix/sysv/linux/i386/Makefile
@@ -9,7 +9,7 @@ $(objpfx)tst-bz21269: $(shared-thread-library)
 endif
 
 ifeq ($(subdir),elf)
-sysdep-dl-routines += libc-do-syscall
+sysdep-rtld_routines += libc-do-syscall
 sysdep-others += lddlibc4
 install-bin += lddlibc4
 endif
diff --git a/sysdeps/unix/sysv/linux/i386/syscall_cancel.S b/sysdeps/unix/sysv/linux/i386/syscall_cancel.S
new file mode 100644
index 0000000000..cc8c43f84d
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/i386/syscall_cancel.S
@@ -0,0 +1,105 @@
+/* Cancellable syscall wrapper.  Linux/i686 version.
+   Copyright (C) 2019 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
+   <http://www.gnu.org/licenses/>.  */
+
+#include <sysdep.h>
+
+/* long int [eax] __syscall_cancel_arch (int *cancelhandling [SP],
+					 long int nr   [SP+4],
+					 long int arg1 [SP+8],
+					 long int arg2 [SP+12],
+					 long int arg3 [SP+16],
+					 long int arg4 [SP+20],
+					 long int arg5 [SP+24],
+					 long int arg6 [SP+28])  */
+
+ENTRY (__syscall_cancel_arch)
+	pushl %ebp
+	cfi_def_cfa_offset (8)
+	cfi_offset (ebp, -8)
+	pushl %edi
+	cfi_def_cfa_offset (12)
+	cfi_offset (edi, -12)
+	pushl %esi
+	cfi_def_cfa_offset (16)
+	cfi_offset (esi, -16)
+	pushl %ebx
+	cfi_def_cfa_offset (20)
+	cfi_offset (ebx, -20)
+
+	.global __syscall_cancel_arch_start
+	.type   __syscall_cancel_arch_start, @function
+__syscall_cancel_arch_start:
+
+	/* if (*cancelhandling & CANCELED_BITMASK)
+	     __syscall_do_cancel()  */
+	testb	$4, (%eax)
+	jne     1f
+
+	/* Issue a 6 argument syscall, the nr [%eax] being the syscall
+	   number.  */
+	movl    24(%esp), %eax
+	movl    28(%esp), %ebx
+	movl    32(%esp), %ecx
+	movl    36(%esp), %edx
+	movl    40(%esp), %esi
+	movl    44(%esp), %edi
+	movl    48(%esp), %ebp
+
+	/* We can not use the vDSO helper for syscall (__kernel_vsyscall)
+	   because the returned PC from kernel will point to the vDSO page
+	   instead of the expected __syscall_cancel_arch_{start,end}
+	   marks.  */
+	int	$128
+
+	.global __syscall_cancel_arch_end
+	.type   __syscall_cancel_arch_end, @function
+__syscall_cancel_arch_end:
+
+	popl %ebx
+	cfi_restore (ebx)
+	cfi_def_cfa_offset (16)
+	popl %esi
+	cfi_restore (esi)
+	cfi_def_cfa_offset (12)
+	popl %edi
+	cfi_restore (edi)
+	cfi_def_cfa_offset (8)
+	popl %ebp
+	cfi_restore (ebp)
+	cfi_def_cfa_offset (4)
+        ret
+
+1:
+	/* Although the __syscall_do_cancel do not return, we need to stack
+	   being set correctly for unwind.  */
+	popl %ebx
+	cfi_restore (ebx)
+	cfi_def_cfa_offset (16)
+	popl %esi
+	cfi_restore (esi)
+	cfi_def_cfa_offset (12)
+	popl %edi
+	cfi_restore (edi)
+	cfi_def_cfa_offset (8)
+	popl %ebp
+	cfi_restore (ebp)
+	cfi_def_cfa_offset (4)
+	jmp __syscall_do_cancel
+
+END (__syscall_cancel_arch)
+libc_hidden_def (__syscall_cancel_arch)
-- 
2.17.1

^ permalink raw reply	[flat|nested] 38+ messages in thread

* [PATCH v3 17/21] nptl: riscv: Fix Race conditions in pthread cancellation (BZ#12683)
  2019-10-14 20:57 [PATCH v3 00/21] nptl: Fix Race conditions in pthread cancellation (BZ#12683) Adhemerval Zanella
                   ` (18 preceding siblings ...)
  2019-10-14 20:57 ` [PATCH v3 11/21] nptl: microblaze: " Adhemerval Zanella
@ 2019-10-14 20:57 ` Adhemerval Zanella
  2019-10-14 23:22   ` Andrew Waterman
  2019-10-14 20:58 ` [PATCH v3 21/21] Remove sysdep-cancel header Adhemerval Zanella
  20 siblings, 1 reply; 38+ messages in thread
From: Adhemerval Zanella @ 2019-10-14 20:57 UTC (permalink / raw)
  To: libc-alpha

This patch adds the riscv modifications required for the BZ#12683 fix
by adding the arch-specific cancellation syscall bridge.
---
 .../unix/sysv/linux/riscv/syscall_cancel.S    | 68 +++++++++++++++++++
 1 file changed, 68 insertions(+)
 create mode 100644 sysdeps/unix/sysv/linux/riscv/syscall_cancel.S

diff --git a/sysdeps/unix/sysv/linux/riscv/syscall_cancel.S b/sysdeps/unix/sysv/linux/riscv/syscall_cancel.S
new file mode 100644
index 0000000000..38fd630c6d
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/riscv/syscall_cancel.S
@@ -0,0 +1,68 @@
+/* Cancellable syscall wrapper.  Linux/riscv version.
+   Copyright (C) 2019 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
+   <http://www.gnu.org/licenses/>.  */
+
+#include <sysdep.h>
+
+/* long int __syscall_cancel_arch (int *cancelhandling,
+				   __syscall_arg_t nr,
+				   __syscall_arg_t arg1,
+				   __syscall_arg_t arg2,
+				   __syscall_arg_t arg3,
+				   __syscall_arg_t arg4,
+				   __syscall_arg_t arg5,
+				   __syscall_arg_t arg6)  */
+
+#ifdef SHARED
+	.option pic
+#else
+	.option nopic
+#endif
+
+ENTRY (__syscall_cancel_arch)
+	mv	t1, a7
+
+	.globl __syscall_cancel_arch_start
+	.type  __syscall_cancel_arch_start,@function
+__syscall_cancel_arch_start:
+	lw	a7, 0(a0)
+	andi	a7, a7, 4	/* if (*ch & CANCELED_BITMASK)  */
+	bnez	a7, 1f
+
+	mv	a7,a1
+	mv	a0,a2
+	mv	a1,a3
+	mv	a2,a4
+	mv	a3,a5
+	mv	a4,a6
+	mv	a5,t1
+	scall
+
+	.globl __syscall_cancel_arch_end
+	.type  __syscall_cancel_arch_end,@function
+__syscall_cancel_arch_end:
+	ret
+
+1:
+	addi	sp, sp, -16
+	cfi_def_cfa_offset (16)
+	sd	ra, 8(sp)
+	cfi_offset (ra, -8)
+	call	__syscall_do_cancel
+
+END (__syscall_cancel_arch)
+libc_hidden_def (__syscall_cancel_arch)
-- 
2.17.1

^ permalink raw reply	[flat|nested] 38+ messages in thread

* [PATCH v3 00/21] nptl: Fix Race conditions in pthread cancellation (BZ#12683)
@ 2019-10-14 20:57 Adhemerval Zanella
  2019-10-14 20:57 ` [PATCH v3 12/21] nptl: sparc: " Adhemerval Zanella
                   ` (20 more replies)
  0 siblings, 21 replies; 38+ messages in thread
From: Adhemerval Zanella @ 2019-10-14 20:57 UTC (permalink / raw)
  To: libc-alpha

This is an updated version of my previous version [1] to fix BZ#12683.
All the required internal changes not related to fix itself were
already pushed, so the patchset contains only the changes to fix
the issue itself.

The changes from previous version [1] are:

  - Add a syscall_cancel.S implementation for every port, as suggested
    by Zack Weinberg.  I agree with him that the reference C
    implementation is somewhat fragile to generate the correct markers,
    so I keep it only to use as reference for future ports to which
    semantic it should implement.

  - Fixed issues on ia64 regarding architecture instruction bundle
    and how kernel returned a syscall with side-effects.

  - Rework the SIGCANCEL handler so architectures that uses a different
    signature other than ucontext_t as third argument can override the
    required fields.

I also extended the architectures I fully tested with a make check
on real hardware:

	aarch64			no regresssions
	alpha			no regresssions
	arm			no regresssions
	csky			no coverage
	hppa			no regresssions
	i386			no regresssions
	ia64			1 regression *
	m68k			basic tests on simulator
	microblaze		no coverage
	mips64			no regresssions
	mips64n32		no regresssions
	mips			no regresssions
	nios2			no coverage
	powerpc			no regresssions
	powerpc64		no regresssions
	powerpc64le		no regresssions
	riscv64			no coverage
	s390x			no regresssions
	s390			no regresssions
	sh4			no regresssions
	sparc64			1 regression **
	sparcv9			no regresssions
	x86_64			no regresssions
	x86_64-32		no regresssions

*  On ia64 I am seeing nptl/tst-cancel21{-static} failure on libunwind stack
   unwind on third internal test (for SA_SIGINFO).  It only happens also for
   exception based unwind (-fexceptions), so I presume it might be related to
   the arch-specific syscall_cancel.S implementation.

** on sparc64 I am seeing intermitent nptl/tst-cond25 failures I can't
   pinpoint exactly what is triggering the SEGFAULT.  I am inclined to
   see it as a codegen issue, I will try with an updated compiler.

[1] https://sourceware.org/ml/libc-alpha/2018-02/msg00782.html

Adhemerval Zanella (21):
  nptl: Handle EPIPE on tst-cancel2
  nptl: Fix Race conditions in pthread cancellation (BZ#12683)
  nptl: x86_64: Fix Race conditions in pthread cancellation (BZ#12683)
  nptl: x32: Fix Race conditions in pthread cancellation (BZ#12683)
  nptl: ia64: Fix Race conditions in pthread cancellation (BZ#12683)
  nptl: mips: Fix Race conditions in pthread cancellation (BZ#12683)
  nptl: i386: Fix Race conditions in pthread cancellation (BZ#12683)
  nptl: aarch64: Fix Race conditions in pthread cancellation (BZ#12683)
  nptl: arm: Fix Race conditions in pthread cancellation (BZ#12683)
  nptl: powerpc: Fix Race conditions in pthread cancellation (BZ#12683)
  nptl: microblaze: Fix Race conditions in pthread cancellation
    (BZ#12683)
  nptl: sparc: Fix Race conditions in pthread cancellation (BZ#12683)
  nptl: hppa: Fix Race conditions in pthread cancellation (BZ#12683)
  nptl: m68k: Fix Race conditions in pthread cancellation (BZ#12683)
  nptl: alpha: Fix Race conditions in pthread cancellation (BZ#12683)
  nptl: sh: Fix Race conditions in pthread cancellation (BZ#12683)
  nptl: riscv: Fix Race conditions in pthread cancellation (BZ#12683)
  nptl: s390: Fix Race conditions in pthread cancellation (BZ#12683)
  nptl: nios2: Fix Race conditions in pthread cancellation (BZ#12683)
  nptl: csky: Fix Race conditions in pthread cancellation (BZ#12683)
  Remove sysdep-cancel header

 elf/dl-close.c                                |   1 -
 elf/dl-lookup.c                               |   1 -
 elf/dl-open.c                                 |   1 -
 elf/dl-runtime.c                              |   1 -
 elf/dl-scope.c                                |   1 -
 elf/dl-sym.c                                  |   1 -
 include/libc-pointer-arith.h                  |  16 ++-
 io/creat.c                                    |   1 -
 io/ppoll.c                                    |   1 -
 malloc/malloc.c                               |   3 -
 manual/llio.texi                              |   4 +-
 misc/pselect.c                                |   1 -
 nptl/Makefile                                 |  12 +-
 nptl/Versions                                 |   3 +
 nptl/cancellation.c                           | 101 -------------
 nptl/descr.h                                  |  15 +-
 nptl/libc-cancellation.c                      |  46 +++++-
 nptl/nptl-init.c                              |  88 ++++++------
 nptl/pthreadP.h                               |  40 +++++-
 nptl/pthread_cancel.c                         |  69 ++-------
 nptl/pthread_create.c                         |   7 +-
 nptl/pthread_exit.c                           |   5 +-
 nptl/pthread_join_common.c                    |   2 +-
 nptl/pthread_kill.c                           |   7 +-
 .../pthread_kill_internal.c                   |  15 +-
 nptl/pthread_setcanceltype.c                  |   2 +-
 nptl/thrd_sleep.c                             |   8 +-
 nptl/tst-cancel2.c                            |   3 -
 nptl/tst-cancel28.c                           | 100 +++++++++++++
 rt/Makefile                                   |   2 +-
 sysdeps/generic/sysdep-cancel.h               |   7 -
 sysdeps/htl/pthreadP.h                        |   1 +
 sysdeps/mach/hurd/sysdep-cancel.h             |   8 --
 sysdeps/mips/dl-trampoline.c                  |   1 -
 sysdeps/mips/nptl/tls.h                       |   2 +-
 sysdeps/nptl/Makefile                         |   3 +-
 sysdeps/nptl/cancellation-pc-check.h          |  40 ++++++
 .../cancellation-sigmask.h}                   |  21 ++-
 sysdeps/posix/open64.c                        |   1 -
 sysdeps/posix/pause.c                         |   1 -
 sysdeps/posix/sigpause.c                      |   1 -
 sysdeps/posix/sigwait.c                       |   1 -
 sysdeps/posix/waitid.c                        |   1 -
 sysdeps/powerpc/powerpc32/sysdep.h            |   3 +
 sysdeps/powerpc/powerpc64/sysdep.h            |  19 +++
 sysdeps/sh/sysdep.h                           |   1 +
 sysdeps/unix/clock_nanosleep.c                |   1 -
 sysdeps/unix/sysdep.h                         | 136 ++++++++++++++----
 .../unix/sysv/linux/aarch64/syscall_cancel.S  |  61 ++++++++
 sysdeps/unix/sysv/linux/accept.c              |   1 -
 sysdeps/unix/sysv/linux/accept4.c             |   1 -
 sysdeps/unix/sysv/linux/access.c              |   2 +-
 sysdeps/unix/sysv/linux/alpha/select.c        |   1 -
 .../unix/sysv/linux/alpha/syscall_cancel.S    |  82 +++++++++++
 sysdeps/unix/sysv/linux/arm/syscall_cancel.S  |  80 +++++++++++
 sysdeps/unix/sysv/linux/clock_nanosleep.c     |   7 +-
 sysdeps/unix/sysv/linux/close.c               |   1 -
 sysdeps/unix/sysv/linux/close_nocancel.c      |   1 -
 sysdeps/unix/sysv/linux/connect.c             |   1 -
 sysdeps/unix/sysv/linux/copy_file_range.c     |   1 -
 sysdeps/unix/sysv/linux/creat.c               |   1 -
 sysdeps/unix/sysv/linux/creat64.c             |   1 -
 sysdeps/unix/sysv/linux/csky/syscall_cancel.S | 116 +++++++++++++++
 sysdeps/unix/sysv/linux/epoll_pwait.c         |   1 -
 sysdeps/unix/sysv/linux/epoll_wait.c          |   1 -
 sysdeps/unix/sysv/linux/fallocate.c           |   1 -
 sysdeps/unix/sysv/linux/fallocate64.c         |   1 -
 sysdeps/unix/sysv/linux/fcntl.c               |   1 -
 sysdeps/unix/sysv/linux/fcntl64.c             |   1 -
 sysdeps/unix/sysv/linux/fcntl_nocancel.c      |   1 -
 sysdeps/unix/sysv/linux/fdatasync.c           |   2 +-
 sysdeps/unix/sysv/linux/fsync.c               |   2 +-
 sysdeps/unix/sysv/linux/futex-internal.h      |  19 +--
 sysdeps/unix/sysv/linux/getrandom.c           |   1 -
 sysdeps/unix/sysv/linux/hppa/syscall_cancel.S |  82 +++++++++++
 sysdeps/unix/sysv/linux/i386/Makefile         |   2 +-
 sysdeps/unix/sysv/linux/i386/syscall_cancel.S | 105 ++++++++++++++
 .../sysv/linux/ia64/cancellation-pc-check.h   |  48 +++++++
 .../sysv/linux/ia64/cancellation-sigmask.h    |  33 +++++
 sysdeps/unix/sysv/linux/ia64/syscall_cancel.S |  83 +++++++++++
 sysdeps/unix/sysv/linux/lowlevellock-futex.h  |  46 ++++--
 sysdeps/unix/sysv/linux/m68k/syscall_cancel.S |  87 +++++++++++
 .../sysv/linux/microblaze/syscall_cancel.S    |  64 +++++++++
 .../sysv/linux/mips/mips32/syscall_cancel.S   | 128 +++++++++++++++++
 sysdeps/unix/sysv/linux/mips/mips32/sysdep.h  |   4 +
 .../sysv/linux/mips/mips64/syscall_cancel.S   | 114 +++++++++++++++
 sysdeps/unix/sysv/linux/mq_timedreceive.c     |   2 +-
 sysdeps/unix/sysv/linux/mq_timedsend.c        |   2 +-
 sysdeps/unix/sysv/linux/msgrcv.c              |   2 +-
 sysdeps/unix/sysv/linux/msgsnd.c              |   2 +-
 sysdeps/unix/sysv/linux/msync.c               |   2 +-
 sysdeps/unix/sysv/linux/nanosleep.c           |   3 +-
 sysdeps/unix/sysv/linux/nanosleep_nocancel.c  |   1 -
 .../unix/sysv/linux/nios2/syscall_cancel.S    |  97 +++++++++++++
 sysdeps/unix/sysv/linux/open.c                |   3 +-
 sysdeps/unix/sysv/linux/open64.c              |   4 +-
 sysdeps/unix/sysv/linux/open_by_handle_at.c   |   2 +-
 sysdeps/unix/sysv/linux/open_nocancel.c       |   1 -
 sysdeps/unix/sysv/linux/openat.c              |   3 +-
 sysdeps/unix/sysv/linux/openat64.c            |   3 +-
 sysdeps/unix/sysv/linux/openat64_nocancel.c   |   1 -
 sysdeps/unix/sysv/linux/openat_nocancel.c     |   1 -
 sysdeps/unix/sysv/linux/pause.c               |   2 +-
 sysdeps/unix/sysv/linux/pause_nocancel.c      |   1 -
 sysdeps/unix/sysv/linux/poll.c                |   1 -
 .../unix/sysv/linux/powerpc/syscall_cancel.S  |  67 +++++++++
 sysdeps/unix/sysv/linux/ppoll.c               |   2 -
 sysdeps/unix/sysv/linux/pread.c               |   2 +-
 sysdeps/unix/sysv/linux/pread64.c             |   2 +-
 sysdeps/unix/sysv/linux/preadv.c              |   2 +-
 sysdeps/unix/sysv/linux/preadv2.c             |   2 +-
 sysdeps/unix/sysv/linux/preadv64.c            |   2 +-
 sysdeps/unix/sysv/linux/preadv64v2.c          |   2 +-
 sysdeps/unix/sysv/linux/pselect.c             |   2 -
 ...pthread_kill.c => pthread_kill_internal.c} |  22 +--
 sysdeps/unix/sysv/linux/pwrite.c              |   2 +-
 sysdeps/unix/sysv/linux/pwrite64.c            |   2 +-
 sysdeps/unix/sysv/linux/pwritev.c             |   2 +-
 sysdeps/unix/sysv/linux/pwritev2.c            |   2 +-
 sysdeps/unix/sysv/linux/pwritev64.c           |   2 +-
 sysdeps/unix/sysv/linux/pwritev64v2.c         |   2 +-
 sysdeps/unix/sysv/linux/read.c                |   2 +-
 sysdeps/unix/sysv/linux/read_nocancel.c       |   1 -
 sysdeps/unix/sysv/linux/readv.c               |   2 +-
 sysdeps/unix/sysv/linux/recv.c                |   1 -
 sysdeps/unix/sysv/linux/recvfrom.c            |   1 -
 sysdeps/unix/sysv/linux/recvmmsg.c            |   1 -
 sysdeps/unix/sysv/linux/recvmsg.c             |   1 -
 .../unix/sysv/linux/riscv/syscall_cancel.S    |  68 +++++++++
 .../sysv/linux/s390/s390-32/syscall_cancel.S  |  83 +++++++++++
 .../sysv/linux/s390/s390-64/syscall_cancel.S  |  83 +++++++++++
 sysdeps/unix/sysv/linux/select.c              |   1 -
 sysdeps/unix/sysv/linux/send.c                |   1 -
 sysdeps/unix/sysv/linux/sendmmsg.c            |   1 -
 sysdeps/unix/sysv/linux/sendmsg.c             |   1 -
 sysdeps/unix/sysv/linux/sendto.c              |   1 -
 sysdeps/unix/sysv/linux/sh/syscall_cancel.S   | 128 +++++++++++++++++
 sysdeps/unix/sysv/linux/sigsuspend.c          |   2 +-
 sysdeps/unix/sysv/linux/sigtimedwait.c        |   1 -
 sysdeps/unix/sysv/linux/sigwait.c             |   1 -
 sysdeps/unix/sysv/linux/sigwaitinfo.c         |   1 -
 sysdeps/unix/sysv/linux/socketcall.h          |  42 ++++--
 .../sysv/linux/sparc/cancellation-sigmask.h   |  39 +++++
 .../sysv/linux/sparc/sparc32/syscall_cancel.S |  76 ++++++++++
 .../sysv/linux/sparc/sparc64/pause.c}         |  17 +--
 .../sysv/linux/sparc/sparc64/syscall_cancel.S |  77 ++++++++++
 sysdeps/unix/sysv/linux/splice.c              |   2 +-
 sysdeps/unix/sysv/linux/sync_file_range.c     |   2 +-
 sysdeps/unix/sysv/linux/syscall_cancel.c      |  64 +++++++++
 sysdeps/unix/sysv/linux/sysdep-cancel.h       |  67 ---------
 sysdeps/unix/sysv/linux/sysdep.h              |  20 +++
 sysdeps/unix/sysv/linux/tcdrain.c             |   1 -
 sysdeps/unix/sysv/linux/tee.c                 |   2 +-
 sysdeps/unix/sysv/linux/timer_routines.c      |   1 -
 sysdeps/unix/sysv/linux/vmsplice.c            |   2 +-
 sysdeps/unix/sysv/linux/wait.c                |   1 -
 sysdeps/unix/sysv/linux/waitid.c              |   1 -
 sysdeps/unix/sysv/linux/waitpid.c             |   1 -
 sysdeps/unix/sysv/linux/waitpid_nocancel.c    |   1 -
 sysdeps/unix/sysv/linux/write.c               |   2 +-
 sysdeps/unix/sysv/linux/write_nocancel.c      |   1 -
 sysdeps/unix/sysv/linux/writev.c              |   2 +-
 sysdeps/unix/sysv/linux/x86_64/cancellation.S | 104 --------------
 .../unix/sysv/linux/x86_64/syscall_cancel.S   |  61 ++++++++
 sysdeps/unix/sysv/linux/x86_64/x32/sysdep.h   |  13 ++
 sysdeps/x86_64/nptl/tcb-offsets.sym           |   1 -
 166 files changed, 2560 insertions(+), 660 deletions(-)
 delete mode 100644 nptl/cancellation.c
 rename sysdeps/unix/sysv/linux/x86_64/libc-cancellation.S => nptl/pthread_kill_internal.c (72%)
 create mode 100644 nptl/tst-cancel28.c
 delete mode 100644 sysdeps/generic/sysdep-cancel.h
 delete mode 100644 sysdeps/mach/hurd/sysdep-cancel.h
 create mode 100644 sysdeps/nptl/cancellation-pc-check.h
 rename sysdeps/{unix/sysv/linux/x86_64/librt-cancellation.S => nptl/cancellation-sigmask.h} (60%)
 create mode 100644 sysdeps/unix/sysv/linux/aarch64/syscall_cancel.S
 create mode 100644 sysdeps/unix/sysv/linux/alpha/syscall_cancel.S
 create mode 100644 sysdeps/unix/sysv/linux/arm/syscall_cancel.S
 create mode 100644 sysdeps/unix/sysv/linux/csky/syscall_cancel.S
 create mode 100644 sysdeps/unix/sysv/linux/hppa/syscall_cancel.S
 create mode 100644 sysdeps/unix/sysv/linux/i386/syscall_cancel.S
 create mode 100644 sysdeps/unix/sysv/linux/ia64/cancellation-pc-check.h
 create mode 100644 sysdeps/unix/sysv/linux/ia64/cancellation-sigmask.h
 create mode 100644 sysdeps/unix/sysv/linux/ia64/syscall_cancel.S
 create mode 100644 sysdeps/unix/sysv/linux/m68k/syscall_cancel.S
 create mode 100644 sysdeps/unix/sysv/linux/microblaze/syscall_cancel.S
 create mode 100644 sysdeps/unix/sysv/linux/mips/mips32/syscall_cancel.S
 create mode 100644 sysdeps/unix/sysv/linux/mips/mips64/syscall_cancel.S
 create mode 100644 sysdeps/unix/sysv/linux/nios2/syscall_cancel.S
 create mode 100644 sysdeps/unix/sysv/linux/powerpc/syscall_cancel.S
 rename sysdeps/unix/sysv/linux/{pthread_kill.c => pthread_kill_internal.c} (75%)
 create mode 100644 sysdeps/unix/sysv/linux/riscv/syscall_cancel.S
 create mode 100644 sysdeps/unix/sysv/linux/s390/s390-32/syscall_cancel.S
 create mode 100644 sysdeps/unix/sysv/linux/s390/s390-64/syscall_cancel.S
 create mode 100644 sysdeps/unix/sysv/linux/sh/syscall_cancel.S
 create mode 100644 sysdeps/unix/sysv/linux/sparc/cancellation-sigmask.h
 create mode 100644 sysdeps/unix/sysv/linux/sparc/sparc32/syscall_cancel.S
 rename sysdeps/{nptl/librt-cancellation.c => unix/sysv/linux/sparc/sparc64/pause.c} (63%)
 create mode 100644 sysdeps/unix/sysv/linux/sparc/sparc64/syscall_cancel.S
 create mode 100644 sysdeps/unix/sysv/linux/syscall_cancel.c
 delete mode 100644 sysdeps/unix/sysv/linux/sysdep-cancel.h
 delete mode 100644 sysdeps/unix/sysv/linux/x86_64/cancellation.S
 create mode 100644 sysdeps/unix/sysv/linux/x86_64/syscall_cancel.S

-- 
2.17.1

^ permalink raw reply	[flat|nested] 38+ messages in thread

* [PATCH v3 18/21] nptl: s390: Fix Race conditions in pthread cancellation (BZ#12683)
  2019-10-14 20:57 [PATCH v3 00/21] nptl: Fix Race conditions in pthread cancellation (BZ#12683) Adhemerval Zanella
                   ` (3 preceding siblings ...)
  2019-10-14 20:57 ` [PATCH v3 20/21] nptl: csky: " Adhemerval Zanella
@ 2019-10-14 20:57 ` Adhemerval Zanella
  2019-10-16 15:46   ` Stefan Liebler
  2019-10-14 20:57 ` [PATCH v3 02/21] nptl: " Adhemerval Zanella
                   ` (15 subsequent siblings)
  20 siblings, 1 reply; 38+ messages in thread
From: Adhemerval Zanella @ 2019-10-14 20:57 UTC (permalink / raw)
  To: libc-alpha

This patch adds the s390 modifications required for the BZ#12683 fix
by adding the arch-specific cancellation syscall bridge.

Checked on s390-linux-gnu and s390x-linux-gnu.
---
 .../sysv/linux/s390/s390-32/syscall_cancel.S  | 83 +++++++++++++++++++
 .../sysv/linux/s390/s390-64/syscall_cancel.S  | 83 +++++++++++++++++++
 2 files changed, 166 insertions(+)
 create mode 100644 sysdeps/unix/sysv/linux/s390/s390-32/syscall_cancel.S
 create mode 100644 sysdeps/unix/sysv/linux/s390/s390-64/syscall_cancel.S

diff --git a/sysdeps/unix/sysv/linux/s390/s390-32/syscall_cancel.S b/sysdeps/unix/sysv/linux/s390/s390-32/syscall_cancel.S
new file mode 100644
index 0000000000..3c934addbd
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/s390/s390-32/syscall_cancel.S
@@ -0,0 +1,83 @@
+/* Cancellable syscall wrapper.  Linux/s390 version.
+   Copyright (C) 2019 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
+   <http://www.gnu.org/licenses/>.  */
+
+#include <sysdep.h>
+
+/* long int __syscall_cancel_arch (int *cancelhandling,
+				   __syscall_arg_t nr,
+				   __syscall_arg_t arg1,
+				   __syscall_arg_t arg2,
+				   __syscall_arg_t arg3,
+				   __syscall_arg_t arg4,
+				   __syscall_arg_t arg5,
+				   __syscall_arg_t arg6)  */
+
+ENTRY (__syscall_cancel_arch)
+	stm	%r6,%r15,24(%r15)
+	cfi_offset (6, -72)
+	cfi_offset (7, -68)
+	cfi_offset (8, -64)
+	cfi_offset (9, -60)
+	cfi_offset (10, -56)
+	cfi_offset (11, -52)
+	cfi_offset (12, -48)
+	cfi_offset (13, -44)
+	cfi_offset (14, -40)
+	cfi_offset (15, -36)
+	ahi	%r15, -96
+	cfi_def_cfa_offset (192)
+
+	.globl __syscall_cancel_arch_start
+	.type  __syscall_cancel_arch_start,@function
+__syscall_cancel_arch_start:
+	l	%r0, 0(%r2)
+	tml	%r0, 4
+	jne	1f
+	lr	%r1, %r3
+	lr	%r2, %r4
+	lr	%r3, %r5
+	lr	%r4, %r6
+	l	%r5, 192(%r15)
+	l	%r6, 196(%r15)
+	l	%r7, 200(%r15)
+	svc	0
+
+	.globl __syscall_cancel_arch_end
+	.type  __syscall_cancel_arch_end,@function
+__syscall_cancel_arch_end:
+	l	%r4, 152(%r15)
+	lm	%r6, %r15, 120(%r15)
+	cfi_remember_state
+	cfi_restore (15)
+	cfi_restore (14)
+	cfi_restore (13)
+	cfi_restore (12)
+	cfi_restore (11)
+	cfi_restore (10)
+	cfi_restore (9)
+	cfi_restore (8)
+	cfi_restore (7)
+	cfi_restore (6)
+	cfi_def_cfa_offset (96)
+	br	%r4
+
+1:
+	cfi_restore_state
+	brasl	%r14, __syscall_do_cancel
+END (__syscall_cancel_arch)
+libc_hidden_def (__syscall_cancel_arch)
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 0000000000..3480020fbb
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/s390/s390-64/syscall_cancel.S
@@ -0,0 +1,83 @@
+/* Cancellable syscall wrapper.  Linux/s390x version.
+   Copyright (C) 2019 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
+   <http://www.gnu.org/licenses/>.  */
+
+#include <sysdep.h>
+
+/* long int __syscall_cancel_arch (int *cancelhandling,
+				   __syscall_arg_t nr,
+				   __syscall_arg_t arg1,
+				   __syscall_arg_t arg2,
+				   __syscall_arg_t arg3,
+				   __syscall_arg_t arg4,
+				   __syscall_arg_t arg5,
+				   __syscall_arg_t arg6)  */
+
+ENTRY (__syscall_cancel_arch)
+	stmg	%r6, %r15, 48(%r15)
+	cfi_offset (6, -112)
+	cfi_offset (7, -104)
+	cfi_offset (8, -96)
+	cfi_offset (9, -88)
+	cfi_offset (10, -80)
+	cfi_offset (11, -72)
+	cfi_offset (12, -64)
+	cfi_offset (13, -56)
+	cfi_offset (14, -48)
+	cfi_offset (15, -40)
+	aghi	%r15,-160
+	cfi_def_cfa_offset (320)
+
+	.globl __syscall_cancel_arch_start
+	.type  __syscall_cancel_arch_start,@function
+__syscall_cancel_arch_start:
+	l	%r0,0(%r2)
+	tmll	%r0,4
+	jne	1f
+	lgr	%r1,%r3
+	lgr	%r2,%r4
+	lgr	%r3,%r5
+	lgr	%r4,%r6
+	lg	%r5,320(%r15)
+	lg	%r6,328(%r15)
+	lg	%r7,336(%r15)
+	svc	0
+
+	.globl __syscall_cancel_arch_end
+	.type  __syscall_cancel_arch_end,@function
+__syscall_cancel_arch_end:
+	lg	%r4,272(%r15)
+	lmg	%r6,%r15,208(%r15)
+	cfi_remember_state
+	cfi_restore (15)
+	cfi_restore (14)
+	cfi_restore (13)
+	cfi_restore (12)
+	cfi_restore (11)
+	cfi_restore (10)
+	cfi_restore (9)
+	cfi_restore (8)
+	cfi_restore (7)
+	cfi_restore (6)
+	cfi_def_cfa_offset (160)
+	br	%r4
+
+1:
+	cfi_restore_state
+	brasl	%r14, __syscall_do_cancel
+END (__syscall_cancel_arch)
+libc_hidden_def (__syscall_cancel_arch)
-- 
2.17.1

^ permalink raw reply	[flat|nested] 38+ messages in thread

* [PATCH v3 06/21] nptl: mips: Fix Race conditions in pthread cancellation (BZ#12683)
  2019-10-14 20:57 [PATCH v3 00/21] nptl: Fix Race conditions in pthread cancellation (BZ#12683) Adhemerval Zanella
                   ` (11 preceding siblings ...)
  2019-10-14 20:57 ` [PATCH v3 13/21] nptl: hppa: " Adhemerval Zanella
@ 2019-10-14 20:57 ` Adhemerval Zanella
  2019-10-14 20:57 ` [PATCH v3 19/21] nptl: nios2: " Adhemerval Zanella
                   ` (7 subsequent siblings)
  20 siblings, 0 replies; 38+ messages in thread
From: Adhemerval Zanella @ 2019-10-14 20:57 UTC (permalink / raw)
  To: libc-alpha

This patch adds the mips modifications required for the BZ#12683.
It adds the arch-specific cancellation syscall bridge and
adjust the cancellable syscall bridge to accept 7 arguments (as
required by mips o32).

To avoid code pessimization and add a requirement on all architectures
to support {INLINE,INTERNAL)_SYSCALL with 7 argument, its support is
added through a flag, HAVE_CANCELABLE_SYSCALL_WITH_7_ARGS, which changes
the signature and prototype of the requires macros and functions
(SYSCALL_CANCEL, __syscall_cancel and __syscall_cancel_arch). As
default 6 arguments cancellable syscalls are use.

Checked on mips-linux-gnu, mips64-linux-gnu, and mips64-n32-linux-gnu.
---
 nptl/libc-cancellation.c                      |   7 +-
 nptl/pthreadP.h                               |   3 +-
 sysdeps/mips/nptl/tls.h                       |   2 +-
 sysdeps/unix/sysdep.h                         |  37 +++--
 .../sysv/linux/mips/mips32/syscall_cancel.S   | 128 ++++++++++++++++++
 sysdeps/unix/sysv/linux/mips/mips32/sysdep.h  |   4 +
 .../sysv/linux/mips/mips64/syscall_cancel.S   | 114 ++++++++++++++++
 sysdeps/unix/sysv/linux/syscall_cancel.c      |   6 +-
 8 files changed, 286 insertions(+), 15 deletions(-)
 create mode 100644 sysdeps/unix/sysv/linux/mips/mips32/syscall_cancel.S
 create mode 100644 sysdeps/unix/sysv/linux/mips/mips64/syscall_cancel.S

diff --git a/nptl/libc-cancellation.c b/nptl/libc-cancellation.c
index 430e0b962e..4dab740b38 100644
--- a/nptl/libc-cancellation.c
+++ b/nptl/libc-cancellation.c
@@ -23,7 +23,7 @@ long int
 __syscall_cancel (__syscall_arg_t nr, __syscall_arg_t a1,
 		  __syscall_arg_t a2, __syscall_arg_t a3,
 		  __syscall_arg_t a4, __syscall_arg_t a5,
-		  __syscall_arg_t a6)
+		  __syscall_arg_t a6 __SYSCALL_CANCEL7_ARG_DEF)
 {
   pthread_t self = (pthread_t) THREAD_SELF;
   struct pthread *pd = (struct pthread *) self;
@@ -33,7 +33,8 @@ __syscall_cancel (__syscall_arg_t nr, __syscall_arg_t a1,
   if (pd->cancelhandling & CANCELSTATE_BITMASK)
     {
       INTERNAL_SYSCALL_DECL (err);
-      result = INTERNAL_SYSCALL_NCS_CALL (nr, err, a1, a2, a3, a4, a5, a6);
+      result = INTERNAL_SYSCALL_NCS_CALL (nr, err, a1, a2, a3, a4, a5, a6
+					  __SYSCALL_CANCEL7_ARG7);
       if (INTERNAL_SYSCALL_ERROR_P (result, err))
 	return -INTERNAL_SYSCALL_ERRNO (result, err);
       return result;
@@ -42,7 +43,7 @@ __syscall_cancel (__syscall_arg_t nr, __syscall_arg_t a1,
   /* Call the arch-specific entry points that contains the globals markers
      to be checked by SIGCANCEL handler.  */
   result = __syscall_cancel_arch (&pd->cancelhandling, nr, a1, a2, a3, a4, a5,
-			          a6);
+			          a6 __SYSCALL_CANCEL7_ARG7);
 
   if ((result == -EINTR)
       && (pd->cancelhandling & CANCELED_BITMASK)
diff --git a/nptl/pthreadP.h b/nptl/pthreadP.h
index cafd14f5af..ac0ad00745 100644
--- a/nptl/pthreadP.h
+++ b/nptl/pthreadP.h
@@ -331,7 +331,8 @@ __do_cancel (void)
 
 extern long int __syscall_cancel_arch (volatile int *, __syscall_arg_t nr,
      __syscall_arg_t arg1, __syscall_arg_t arg2, __syscall_arg_t arg3,
-     __syscall_arg_t arg4, __syscall_arg_t arg5, __syscall_arg_t arg6);
+     __syscall_arg_t arg4, __syscall_arg_t arg5, __syscall_arg_t arg6
+     __SYSCALL_CANCEL7_ARG_DEF);
 libc_hidden_proto (__syscall_cancel_arch);
 
 extern _Noreturn void __syscall_do_cancel (void)
diff --git a/sysdeps/mips/nptl/tls.h b/sysdeps/mips/nptl/tls.h
index e0364d46a8..3f53e53efb 100644
--- a/sysdeps/mips/nptl/tls.h
+++ b/sysdeps/mips/nptl/tls.h
@@ -35,7 +35,7 @@
 # define READ_THREAD_POINTER() (__builtin_thread_pointer ())
 #else
 /* Note: rd must be $v1 to be ABI-conformant.  */
-# if __mips_isa_rev >= 2
+# if defined __mips_isa_rev && __mips_isa_rev >= 2
 #  define READ_THREAD_POINTER() \
      ({ void *__result;							      \
         asm volatile ("rdhwr\t%0, $29" : "=v" (__result));	      	      \
diff --git a/sysdeps/unix/sysdep.h b/sysdeps/unix/sysdep.h
index 04f30b8cbc..d6c75b14a3 100644
--- a/sysdeps/unix/sysdep.h
+++ b/sysdeps/unix/sysdep.h
@@ -121,29 +121,50 @@ typedef long int __syscall_arg_t;
 # define __SSC(__x) ((__syscall_arg_t) (__x))
 #endif
 
+/* Adjust both the __syscall_cancel and the SYSCALL_CANCEL macro to support
+   7 arguments instead of default 6 (curently only mip32).  It avoid add
+   the requirement to each architecture to support 7 argument macros
+   {INTERNAL,INLINE}_SYSCALL.  */
+#ifdef HAVE_CANCELABLE_SYSCALL_WITH_7_ARGS
+# define __SYSCALL_CANCEL7_ARG_DEF 	, __syscall_arg_t arg7
+# define __SYSCALL_CANCEL7_ARG		, 0
+# define __SYSCALL_CANCEL7_ARG7		, arg7
+#else
+# define __SYSCALL_CANCEL7_ARG_DEF
+# define __SYSCALL_CANCEL7_ARG
+# define __SYSCALL_CANCEL7_ARG7
+#endif
+
 long int __syscall_cancel (__syscall_arg_t nr, __syscall_arg_t arg1,
 			   __syscall_arg_t arg2, __syscall_arg_t arg3,
 			   __syscall_arg_t arg4, __syscall_arg_t arg5,
-			   __syscall_arg_t arg6);
+			   __syscall_arg_t arg6 __SYSCALL_CANCEL7_ARG_DEF);
 libc_hidden_proto (__syscall_cancel);
 
 #define __SYSCALL_CANCEL0(name) \
-  (__syscall_cancel)(__NR_##name, 0, 0, 0, 0, 0, 0)
+  (__syscall_cancel)(__NR_##name, 0, 0, 0, 0, 0, 0 \
+		     __SYSCALL_CANCEL7_ARG)
 #define __SYSCALL_CANCEL1(name, a1) \
-  (__syscall_cancel)(__NR_##name, __SSC(a1), 0, 0, 0, 0, 0)
+  (__syscall_cancel)(__NR_##name, __SSC(a1), 0, 0, 0, 0, 0 \
+		     __SYSCALL_CANCEL7_ARG)
 #define __SYSCALL_CANCEL2(name, a1, a2) \
-  (__syscall_cancel)(__NR_##name, __SSC(a1), __SSC(a2), 0, 0, 0, 0)
+  (__syscall_cancel)(__NR_##name, __SSC(a1), __SSC(a2), 0, 0, 0, 0 \
+		     __SYSCALL_CANCEL7_ARG)
 #define __SYSCALL_CANCEL3(name, a1, a2, a3) \
-  (__syscall_cancel)(__NR_##name, __SSC(a1), __SSC(a2), __SSC(a3), 0, 0, 0)
+  (__syscall_cancel)(__NR_##name, __SSC(a1), __SSC(a2), __SSC(a3), 0, 0, 0 \
+		     __SYSCALL_CANCEL7_ARG)
 #define __SYSCALL_CANCEL4(name, a1, a2, a3, a4) \
   (__syscall_cancel)(__NR_##name, __SSC(a1), __SSC(a2), __SSC(a3), \
-		     __SSC(a4), 0, 0)
+		     __SSC(a4), 0, 0 __SYSCALL_CANCEL7_ARG)
 #define __SYSCALL_CANCEL5(name, a1, a2, a3, a4, a5) \
   (__syscall_cancel)(__NR_##name, __SSC(a1), __SSC(a2), __SSC(a3), \
-		     __SSC(a4), __SSC(a5), 0)
+		     __SSC(a4), __SSC(a5), 0 __SYSCALL_CANCEL7_ARG)
 #define __SYSCALL_CANCEL6(name, a1, a2, a3, a4, a5, a6) \
   (__syscall_cancel)(__NR_##name, __SSC(a1), __SSC(a2), __SSC(a3), \
-		     __SSC(a4), __SSC(a5), __SSC(a6))
+		     __SSC(a4), __SSC(a5), __SSC(a6) __SYSCALL_CANCEL7_ARG)
+#define __SYSCALL_CANCEL7(name, a1, a2, a3, a4, a5, a6, a7) \
+  (__syscall_cancel)(__NR_##name, __SSC(a1), __SSC(a2), __SSC(a3), \
+		     __SSC(a4), __SSC(a5), __SSC(a6), __SSC(a7))
 
 #define __SYSCALL_CANCEL_NARGS_X(a,b,c,d,e,f,g,h,n,...) n
 #define __SYSCALL_CANCEL_NARGS(...) \
diff --git a/sysdeps/unix/sysv/linux/mips/mips32/syscall_cancel.S b/sysdeps/unix/sysv/linux/mips/mips32/syscall_cancel.S
new file mode 100644
index 0000000000..a6445efb4f
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/mips/mips32/syscall_cancel.S
@@ -0,0 +1,128 @@
+/* Cancellable syscall wrapper.  Linux/mips32 version.
+   Copyright (C) 2019 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
+   <http://www.gnu.org/licenses/>.  */
+
+#include <sysdep.h>
+#include <sys/asm.h>
+
+/* long int __syscall_cancel_arch (int *cancelhandling,
+				   __syscall_arg_t nr,
+				   __syscall_arg_t arg1,
+				   __syscall_arg_t arg2,
+				   __syscall_arg_t arg3,
+				   __syscall_arg_t arg4,
+				   __syscall_arg_t arg5,
+				   __syscall_arg_t arg6,
+				   __syscall_arg_t arg7)  */
+
+#define FRAME_SIZE 56
+
+NESTED (__syscall_cancel_arch, FRAME_SIZE, fp)
+	.mask	0xc0070000,-SZREG
+	.fmask	0x00000000,0
+
+	PTR_ADDIU sp, -FRAME_SIZE
+	cfi_def_cfa_offset (FRAME_SIZE)
+
+	sw	fp,48(sp)
+	sw	ra,52(sp)
+	sw	s2,44(sp)
+	sw	s1,40(sp)
+	sw	s0,36(sp)
+#ifdef __PIC__
+	.cprestore	16
+#endif
+	cfi_offset (31, -4)
+	cfi_offset (30, -8)
+	cfi_offset (18, -12)
+	cfi_offset (17, -16)
+	cfi_offset (16, -20)
+	move	fp,sp
+	cfi_def_cfa_register (30)
+
+	.globl __syscall_cancel_arch_start
+	.type __syscall_cancel_arch_start, @function
+__syscall_cancel_arch_start:
+
+	lw	v0,0(a0)
+	andi	v0,v0,0x4
+	bne	v0,zero,2f
+
+	addiu	sp,sp,-16
+	addiu	v0,sp,16
+	sw	v0,24(fp)
+
+	move	s0,a1
+	move	a0,a2
+	move	a1,a3
+	lw	a2,72(fp)
+	lw	a3,76(fp)
+	lw	v0,84(fp)
+	lw	s1,80(fp)
+	lw	s2,88(fp)
+
+	.set	noreorder
+	subu	sp, 32
+	sw	s1, 16(sp)
+	sw	v0, 20(sp)
+	sw	s2, 24(sp)
+	move	v0, $16
+	syscall
+
+	.globl __syscall_cancel_arch_end
+	.type __syscall_cancel_arch_end, @function
+__syscall_cancel_arch_end:
+	addiu	sp, 32
+	.set	reorder
+
+	beq	a3,zero,1f
+	subu	v0,zero,v0
+1:
+	move	sp,fp
+	cfi_remember_state
+	cfi_def_cfa_register (29)
+	lw	ra,52(fp)
+	lw	fp,48(sp)
+	lw	s2,44(sp)
+	lw	s1,40(sp)
+	lw	s0,36(sp)
+	.set	noreorder
+	.set	nomacro
+	jr	ra
+	addiu	sp,sp,FRAME_SIZE
+
+	.set	macro
+	.set	reorder
+
+	cfi_def_cfa_offset (0)
+	cfi_restore (16)
+	cfi_restore (17)
+	cfi_restore (18)
+	cfi_restore (30)
+	cfi_restore (31)
+
+2:
+	cfi_restore_state
+#ifdef __PIC__
+	PTR_LA	t9, __syscall_do_cancel
+	jalr	t9
+#else
+	jal	__syscall_do_cancel
+#endif
+
+END (__syscall_cancel_arch)
+libc_hidden_def (__syscall_cancel_arch)
diff --git a/sysdeps/unix/sysv/linux/mips/mips32/sysdep.h b/sysdeps/unix/sysv/linux/mips/mips32/sysdep.h
index 86347fe91a..c427146a10 100644
--- a/sysdeps/unix/sysv/linux/mips/mips32/sysdep.h
+++ b/sysdeps/unix/sysv/linux/mips/mips32/sysdep.h
@@ -18,6 +18,10 @@
 #ifndef _LINUX_MIPS_MIPS32_SYSDEP_H
 #define _LINUX_MIPS_MIPS32_SYSDEP_H 1
 
+/* mips32 have cancelable syscalls with 7 arguments (currently only
+   sync_file_range).  */
+#define HAVE_CANCELABLE_SYSCALL_WITH_7_ARGS	1
+
 /* There is some commonality.  */
 #include <sysdeps/unix/sysv/linux/mips/sysdep.h>
 #include <sysdeps/unix/sysv/linux/sysdep.h>
diff --git a/sysdeps/unix/sysv/linux/mips/mips64/syscall_cancel.S b/sysdeps/unix/sysv/linux/mips/mips64/syscall_cancel.S
new file mode 100644
index 0000000000..529209ea2c
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/mips/mips64/syscall_cancel.S
@@ -0,0 +1,114 @@
+/* Cancellable syscall wrapper.  Linux/mips64 version.
+   Copyright (C) 2019 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
+   <http://www.gnu.org/licenses/>.  */
+
+#include <sysdep.h>
+#include <sys/asm.h>
+
+/* long int __syscall_cancel_arch (int *cancelhandling,
+				   __syscall_arg_t nr,
+				   __syscall_arg_t arg1,
+				   __syscall_arg_t arg2,
+				   __syscall_arg_t arg3,
+				   __syscall_arg_t arg4,
+				   __syscall_arg_t arg5,
+				   __syscall_arg_t arg6,
+				   __syscall_arg_t arg7)  */
+
+#define FRAME_SIZE 32
+#define ADDIU      LONG_ADDIU
+#define ADDU       LONG_ADDU
+#define SUBU       LONG_SUBU
+#define LOAD_L     LONG_L
+
+NESTED (__syscall_cancel_arch, FRAME_SIZE, fp)
+	.mask	0x90010000, -SZREG
+	.fmask	0x00000000, 0
+	ADDIU	sp, sp, -32
+	cfi_def_cfa_offset (32)
+	sd	gp, 16(sp)
+	cfi_offset (gp, -16)
+	lui	gp, %hi(%neg(%gp_rel(__syscall_cancel_arch)))
+	ADDU	gp, gp, t9
+	sd	ra, 24(sp)
+	sd	s0, 8(sp)
+	cfi_offset (ra, -8)
+	cfi_offset (s0, -24)
+	ADDIU	gp, gp, %lo(%neg(%gp_rel(__syscall_cancel_arch)))
+
+	.global __syscall_cancel_arch_start
+	.type __syscall_cancel_arch_start,%function
+__syscall_cancel_arch_start:
+
+	lw	v0, 0(a0)
+	andi	v0, v0, 0x4
+	.set noreorder
+	.set nomacro
+	bne	v0, zero, 2f
+	move	s0, a1
+	.set macro
+	.set reorder
+
+	move	a0, a2
+	move	a1, a3
+	move	a2, a4
+	move	a3, a5
+	move	a4, a6
+	move	a5, a7
+
+	.set noreorder
+	move	v0, s0
+	syscall
+	.set reorder
+
+	.global __syscall_cancel_arch_end
+	.type __syscall_cancel_arch_end,%function
+__syscall_cancel_arch_end:
+
+	.set noreorder
+	.set nomacro
+	bnel	a3, zero, 1f
+	SUBU	v0, zero, v0
+	.set macro
+	.set reorder
+
+1:
+	ld	ra, 24(sp)
+	ld	gp, 16(sp)
+	ld	s0, 8(sp)
+
+	.set noreorder
+	.set nomacro
+	jr	ra
+	ADDIU	sp, sp, 32
+	.set macro
+	.set reorder
+
+	cfi_remember_state
+	cfi_def_cfa_offset (0)
+	cfi_restore (s0)
+	cfi_restore (gp)
+	cfi_restore (ra)
+
+	.align	3
+2:
+	cfi_restore_state
+	LOAD_L	t9, %got_disp(__syscall_do_cancel)(gp)
+	.reloc	3f, R_MIPS_JALR, __syscall_do_cancel
+3:	jalr	t9
+END (__syscall_cancel_arch)
+libc_hidden_def (__syscall_cancel_arch)
diff --git a/sysdeps/unix/sysv/linux/syscall_cancel.c b/sysdeps/unix/sysv/linux/syscall_cancel.c
index 79d66ec4f4..e845f51980 100644
--- a/sysdeps/unix/sysv/linux/syscall_cancel.c
+++ b/sysdeps/unix/sysv/linux/syscall_cancel.c
@@ -40,7 +40,8 @@ long int
 __syscall_cancel_arch (volatile int *ch, __syscall_arg_t nr,
 		       __syscall_arg_t a1, __syscall_arg_t a2,
 		       __syscall_arg_t a3, __syscall_arg_t a4,
-		       __syscall_arg_t a5, __syscall_arg_t a6)
+		       __syscall_arg_t a5, __syscall_arg_t a6
+		       __SYSCALL_CANCEL7_ARG_DEF)
 {
 #define ADD_LABEL(__label)		\
   asm volatile (			\
@@ -53,7 +54,8 @@ __syscall_cancel_arch (volatile int *ch, __syscall_arg_t nr,
     __syscall_do_cancel();
 
   INTERNAL_SYSCALL_DECL(err);
-  long int result = INTERNAL_SYSCALL_NCS (nr, err, 6, a1, a2, a3, a4, a5, a6);
+  long int result = INTERNAL_SYSCALL_NCS_CALL (nr, err, a1, a2, a3, a4, a5,
+					       a6 __SYSCALL_CANCEL7_ARG7);
   ADD_LABEL ("__syscall_cancel_arch_end");
   if (__glibc_unlikely (INTERNAL_SYSCALL_ERROR_P (result, err)))
     return -INTERNAL_SYSCALL_ERRNO (result, err);
-- 
2.17.1

^ permalink raw reply	[flat|nested] 38+ messages in thread

* [PATCH v3 19/21] nptl: nios2: Fix Race conditions in pthread cancellation (BZ#12683)
  2019-10-14 20:57 [PATCH v3 00/21] nptl: Fix Race conditions in pthread cancellation (BZ#12683) Adhemerval Zanella
                   ` (12 preceding siblings ...)
  2019-10-14 20:57 ` [PATCH v3 06/21] nptl: mips: " Adhemerval Zanella
@ 2019-10-14 20:57 ` Adhemerval Zanella
  2019-10-14 20:57 ` [PATCH v3 03/21] nptl: x86_64: " Adhemerval Zanella
                   ` (6 subsequent siblings)
  20 siblings, 0 replies; 38+ messages in thread
From: Adhemerval Zanella @ 2019-10-14 20:57 UTC (permalink / raw)
  To: libc-alpha

This patch adds the nios2 modifications required for the BZ#12683 fix
by adding the arch-specific cancellation syscall bridge.
---
 .../unix/sysv/linux/nios2/syscall_cancel.S    | 97 +++++++++++++++++++
 1 file changed, 97 insertions(+)
 create mode 100644 sysdeps/unix/sysv/linux/nios2/syscall_cancel.S

diff --git a/sysdeps/unix/sysv/linux/nios2/syscall_cancel.S b/sysdeps/unix/sysv/linux/nios2/syscall_cancel.S
new file mode 100644
index 0000000000..cc19c4525e
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/nios2/syscall_cancel.S
@@ -0,0 +1,97 @@
+/* Cancellable syscall wrapper.  Linux/nios2 version.
+   Copyright (C) 2019 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
+   <http://www.gnu.org/licenses/>.  */
+
+#include <sysdep.h>
+
+/* long int __syscall_cancel_arch (int *cancelhandling,
+				   __syscall_arg_t nr,
+				   __syscall_arg_t arg1,
+				   __syscall_arg_t arg2,
+				   __syscall_arg_t arg3,
+				   __syscall_arg_t arg4,
+				   __syscall_arg_t arg5,
+				   __syscall_arg_t arg6)  */
+
+ENTRY (__syscall_cancel_arch)
+#ifdef SHARED
+	addi	sp, sp, -8
+	stw	r22, 0(sp)
+	nextpc	r22
+1:
+	movhi	r8, %hiadj(_gp_got - 1b)
+	addi	r8, r8, %lo(_gp_got - 1b)
+	stw	ra, 4(sp)
+	add	r22, r22, r8
+#else
+	addi	sp, sp, -4
+	cfi_def_cfa_offset (4)
+	stw	ra, 0(sp)
+	cfi_offset (31, -4)
+#endif
+
+	.globl __syscall_cancel_arch_start
+	.type  __syscall_cancel_arch_start,@function
+__syscall_cancel_arch_start:
+	ldw	r3, 0(r4)
+	andi	r3, r3, 4
+	bne	r3, zero, 3f
+	mov	r10, r6
+	mov	r2, r5
+#ifdef SHARED
+# define STACK_ADJ 4
+#else
+# define STACK_ADJ 0
+#endif
+	ldw	r9, (16 + STACK_ADJ)(sp)
+	mov	r5, r7
+	ldw	r8, (12 + STACK_ADJ)(sp)
+	ldw	r7, (8 + STACK_ADJ)(sp)
+	ldw	r6, (4 + STACK_ADJ)(sp)
+	mov	r4, r10
+	trap
+
+	.globl __syscall_cancel_arch_end
+	.type  __syscall_cancel_arch_end,@function
+__syscall_cancel_arch_end:
+	beq	r7, zero, 2f
+	sub	r2, zero, r2
+2:
+#ifdef SHARED
+	ldw	ra, 4(sp)
+	ldw	r22, 0(sp)
+	addi	sp, sp, 8
+#else
+	ldw	ra, (0 + STACK_ADJ)(sp)
+	cfi_remember_state
+	cfi_restore (31)
+	addi	sp, sp, 4
+	cfi_def_cfa_offset (0)
+#endif
+	ret
+
+3:
+#ifdef SHARED
+	ldw	r2, %call(__syscall_do_cancel)(r22)
+	callr	r2
+#else
+	cfi_restore_state
+	call	__syscall_do_cancel
+#endif
+
+END (__syscall_cancel_arch)
+libc_hidden_def (__syscall_cancel_arch)
-- 
2.17.1

^ permalink raw reply	[flat|nested] 38+ messages in thread

* [PATCH v3 12/21] nptl: sparc: Fix Race conditions in pthread cancellation (BZ#12683)
  2019-10-14 20:57 [PATCH v3 00/21] nptl: Fix Race conditions in pthread cancellation (BZ#12683) Adhemerval Zanella
@ 2019-10-14 20:57 ` Adhemerval Zanella
  2019-10-14 20:57 ` [PATCH v3 08/21] nptl: aarch64: " Adhemerval Zanella
                   ` (19 subsequent siblings)
  20 siblings, 0 replies; 38+ messages in thread
From: Adhemerval Zanella @ 2019-10-14 20:57 UTC (permalink / raw)
  To: libc-alpha

This patch adds the sparc modifications required for the BZ#12683 fix.

Different than other architectures, SPARC passes the sigcontext_t
struct pointer as third argument in the signal handler set with
SA_SIGINFO (some info at [1]) for 64 bits and the pt_regs in 32 bits.
From Linux code:

* arch/sparc/kernel/signal_64.c

428         /* 3. signal handler back-trampoline and parameters */
429         regs->u_regs[UREG_FP] = ((unsigned long) sf) - STACK_BIAS;
430         regs->u_regs[UREG_I0] = ksig->sig;
431         regs->u_regs[UREG_I1] = (unsigned long) &sf->info;
432
433         /* The sigcontext is passed in this way because of how it
434          * is defined in GLIBC's /usr/include/bits/sigcontext.h
435          * for sparc64.  It includes the 128 bytes of siginfo_t.
436          */
437         regs->u_regs[UREG_I2] = (unsigned long) &sf->info;

* arch/sparc/kernel/signal_32.c:

392         regs->u_regs[UREG_FP] = (unsigned long) sf;
393         regs->u_regs[UREG_I0] = ksig->sig;
394         regs->u_regs[UREG_I1] = (unsigned long) &sf->info;
395         regs->u_regs[UREG_I2] = (unsigned long) &sf->regs;
396
397         regs->pc = (unsigned long) ksig->ka.sa.sa_handler;
398         regs->npc = (regs->pc + 4);

So it requires an arch-specific ucontext_add_cancel.

Also on sparc interrupted pause syscall returns with a PC indicating a
side-effect and this deviates from other architectures.  The sparc64
pause fall back to ppool syscall.

Checked on sparc64-linux-gnu and sparcv9-linux-gnu.

[1] https://www.spinics.net/lists/sparclinux/msg05037.html
---
 .../sysv/linux/sparc/cancellation-sigmask.h   | 39 ++++++++++
 .../sysv/linux/sparc/sparc32/syscall_cancel.S | 76 ++++++++++++++++++
 sysdeps/unix/sysv/linux/sparc/sparc64/pause.c | 25 ++++++
 .../sysv/linux/sparc/sparc64/syscall_cancel.S | 77 +++++++++++++++++++
 4 files changed, 217 insertions(+)
 create mode 100644 sysdeps/unix/sysv/linux/sparc/cancellation-sigmask.h
 create mode 100644 sysdeps/unix/sysv/linux/sparc/sparc32/syscall_cancel.S
 create mode 100644 sysdeps/unix/sysv/linux/sparc/sparc64/pause.c
 create mode 100644 sysdeps/unix/sysv/linux/sparc/sparc64/syscall_cancel.S

diff --git a/sysdeps/unix/sysv/linux/sparc/cancellation-sigmask.h b/sysdeps/unix/sysv/linux/sparc/cancellation-sigmask.h
new file mode 100644
index 0000000000..6fd889b1cc
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/sparc/cancellation-sigmask.h
@@ -0,0 +1,39 @@
+/* Architecture specific bits for cancellation handling.
+   Copyright (C) 2019 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
+   <http://www.gnu.org/licenses/>.  */
+
+#ifndef _NPTL_CANCELLATION_SIGMASK_H
+#define _NPTL_CANCELLATION_SIGMASK_H 1
+
+/* Add the SIGCANCEL signal on sigmask set at the ucontext CTX obtained from
+   the sigaction handler.  */
+static void
+ucontext_add_cancel (void *ctx)
+{
+  sigset_t *set;
+#ifdef __arch64__
+  struct pt_regs *regs = (struct pt_regs*) ((siginfo_t *)(ctx) + 1);
+  __siginfo_fpu_t *f = (__siginfo_fpu_t *)(regs + 1);
+  set = (sigset_t *) ((stack_t *)(f + 1) + 1);
+#else
+  struct pt_regs32 *ptregs = (struct pt_regs32 *) (ctx);
+  set = (sigset_t *) (ptregs + 1);
+#endif
+  __sigaddset (set, SIGCANCEL);
+}
+
+#endif
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/syscall_cancel.S b/sysdeps/unix/sysv/linux/sparc/sparc32/syscall_cancel.S
new file mode 100644
index 0000000000..7c86dee33c
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/sparc/sparc32/syscall_cancel.S
@@ -0,0 +1,76 @@
+/* Cancellable syscall wrapper.  Linux/sparc32 version.
+   Copyright (C) 2019 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
+   <http://www.gnu.org/licenses/>.  */
+
+#include <sysdep.h>
+
+/* long int __syscall_cancel_arch (int *cancelhandling,
+				   long int nr,
+				   long int arg1,
+				   long int arg2,
+				   long int arg3,
+				   long int arg4,
+				   long int arg5,
+				   long int arg6)  */
+
+ENTRY (__syscall_cancel_arch)
+	save	%sp, -96, %sp
+
+	cfi_window_save
+	cfi_register (%o7, %i7)
+	cfi_def_cfa_register (%fp)
+
+	.globl __syscall_cancel_arch_start
+	.type  __syscall_cancel_arch_start, @function
+__syscall_cancel_arch_start:
+
+	/* if (*cancelhandling & CANCELED_BITMASK)
+	     __syscall_do_cancel()  */
+	ld	[%i0], %g2
+	andcc	%g2, 4, %g0
+	bne,pn	%icc, 2f
+
+	/* Issue a 6 argument syscall.  */
+	 mov	%i2, %o0
+	mov	%i3, %o1
+	ld	[%fp+92], %o4
+	mov	%i4, %o2
+	mov	%i5, %o3
+	ld	[%fp+96], %o5
+	mov	%i1, %g1
+	ta	0x10
+
+	.globl __syscall_cancel_arch_end
+	.type  __syscall_cancel_arch_end, @function
+__syscall_cancel_arch_end:
+	bcc	1f
+	mov	0, %g1
+	sub	%g0, %o0, %o0
+	mov	1, %g1
+
+1:
+	mov	%o0, %i0
+	return	%i7+8
+	 nop
+
+2:
+	call	__syscall_do_cancel, 0
+	 nop
+	nop
+
+END (__syscall_cancel_arch)
+libc_hidden_def (__syscall_cancel_arch)
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/pause.c b/sysdeps/unix/sysv/linux/sparc/sparc64/pause.c
new file mode 100644
index 0000000000..4a0cf4db59
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/sparc/sparc64/pause.c
@@ -0,0 +1,25 @@
+/* Linux pause syscall implementation.  Linux/sparc64.
+   Copyright (C) 2017 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
+   <http://www.gnu.org/licenses/>.  */
+
+#include <sys/syscall.h>
+
+/* On sparc interrupted pause syscall returns with a PC indicating a
+   side-effect and this deviates from other architectures.  Fall back to
+   ppool implementation.  */
+#undef __NR_pause
+#include <sysdeps/unix/sysv/linux/pause.c>
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/syscall_cancel.S b/sysdeps/unix/sysv/linux/sparc/sparc64/syscall_cancel.S
new file mode 100644
index 0000000000..8a6d5a2fd8
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/sparc/sparc64/syscall_cancel.S
@@ -0,0 +1,77 @@
+/* Cancellable syscall wrapper.  Linux/sparc64 version.
+   Copyright (C) 2019 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
+   <http://www.gnu.org/licenses/>.  */
+
+#include <sysdep.h>
+
+	.register       %g2, #scratch
+
+/* long int __syscall_cancel_arch (int *cancelhandling,
+				   long int nr,
+				   long int arg1,
+				   long int arg2,
+				   long int arg3,
+				   long int arg4,
+				   long int arg5,
+				   long int arg6)  */
+
+ENTRY (__syscall_cancel_arch)
+	save	%sp, -176, %sp
+	cfi_window_save
+	cfi_def_cfa_register (%fp)
+	cfi_register (%o7, %i7)
+
+	.globl __syscall_cancel_arch_start
+	.type  __syscall_cancel_arch_start, @function
+__syscall_cancel_arch_start:
+
+	/* if (*cancelhandling & CANCELED_BITMASK)
+	     __syscall_do_cancel()  */
+	lduw	[%i0], %g2
+	andcc	%g2, 4, %g0
+	bne,pn	%xcc, 2f
+
+	/* Issue a 6 argument syscall.  */
+	 mov	%i2, %o0
+	mov	%i3, %o1
+	mov	%i4, %o2
+	mov	%i5, %o3
+	ldx	[%fp + STACK_BIAS + 176], %o4
+	ldx	[%fp + STACK_BIAS + 184], %o5
+	mov	%i1, %g1
+	ta	0x6d
+
+	.global __syscall_cancel_arch_end
+	.type   __syscall_cancel_arch_end, @function
+__syscall_cancel_arch_end:
+
+	bcc,pt	%xcc, 1f
+	mov	0, %g1
+	sub	%g0, %o0, %o0
+	mov	1, %g1
+1:
+	mov	%o0, %i0
+	return	%i7+8
+	 nop
+
+2:
+	call	__syscall_do_cancel, 0
+	 nop
+	nop
+
+END (__syscall_cancel_arch)
+libc_hidden_def (__syscall_cancel_arch)
-- 
2.17.1

^ permalink raw reply	[flat|nested] 38+ messages in thread

* [PATCH v3 04/21] nptl: x32: Fix Race conditions in pthread cancellation (BZ#12683)
  2019-10-14 20:57 [PATCH v3 00/21] nptl: Fix Race conditions in pthread cancellation (BZ#12683) Adhemerval Zanella
  2019-10-14 20:57 ` [PATCH v3 12/21] nptl: sparc: " Adhemerval Zanella
  2019-10-14 20:57 ` [PATCH v3 08/21] nptl: aarch64: " Adhemerval Zanella
@ 2019-10-14 20:57 ` Adhemerval Zanella
  2019-10-15 11:06   ` Florian Weimer
  2019-10-14 20:57 ` [PATCH v3 20/21] nptl: csky: " Adhemerval Zanella
                   ` (17 subsequent siblings)
  20 siblings, 1 reply; 38+ messages in thread
From: Adhemerval Zanella @ 2019-10-14 20:57 UTC (permalink / raw)
  To: libc-alpha

This patches adds the x32 modification required for the BZ#12683.
It basically adjust the syscall size used to pass the arguments to
the syscall cancel wrappers by zero extending pointers type while
preserting values for default types (such as off_t).

Checked on x86_64-linux-gnu-x32.
---
 include/libc-pointer-arith.h                | 16 +++++++++++-----
 sysdeps/unix/sysv/linux/x86_64/x32/sysdep.h | 13 +++++++++++++
 2 files changed, 24 insertions(+), 5 deletions(-)

diff --git a/include/libc-pointer-arith.h b/include/libc-pointer-arith.h
index b32df719d1..0e5bb83f56 100644
--- a/include/libc-pointer-arith.h
+++ b/include/libc-pointer-arith.h
@@ -25,17 +25,23 @@
 # define __pointer_type(type) (__builtin_classify_type ((type) 0) == 5)
 
 /* intptr_t if P is true, or T if P is false.  */
-# define __integer_if_pointer_type_sub(T, P) \
+# define __integer_if_pointer_type_sub(T, P, INTTYPE) \
   __typeof__ (*(0 ? (__typeof__ (0 ? (T *) 0 : (void *) (P))) 0 \
-		  : (__typeof__ (0 ? (intptr_t *) 0 : (void *) (!(P)))) 0))
+		  : (__typeof__ (0 ? (INTTYPE *) 0 : (void *) (!(P)))) 0))
 
 /* intptr_t if EXPR has a pointer type, or the type of EXPR otherwise.  */
-# define __integer_if_pointer_type(expr) \
+# define __integer_if_pointer_type(expr, inttype) \
   __integer_if_pointer_type_sub(__typeof__ ((__typeof__ (expr)) 0), \
-				__pointer_type (__typeof__ (expr)))
+				__pointer_type (__typeof__ (expr)), \
+				inttype)
 
 /* Cast an integer or a pointer VAL to integer with proper type.  */
-# define cast_to_integer(val) ((__integer_if_pointer_type (val)) (val))
+# define cast_to_integer(val) \
+  ((__integer_if_pointer_type (val, intptr_t)) (val))
+
+/* Cast an integer or a pointer VAL to unsigned integer with proper type.  */
+# define cast_to_uinteger(val) \
+  ((__integer_if_pointer_type (val, uintptr_t)) (val))
 
 /* Align a value by rounding down to closest size.
    e.g. Using size of 4096, we get this behavior:
diff --git a/sysdeps/unix/sysv/linux/x86_64/x32/sysdep.h b/sysdeps/unix/sysv/linux/x86_64/x32/sysdep.h
index 60a144a474..568ca1c959 100644
--- a/sysdeps/unix/sysv/linux/x86_64/x32/sysdep.h
+++ b/sysdeps/unix/sysv/linux/x86_64/x32/sysdep.h
@@ -18,6 +18,19 @@
 #ifndef _LINUX_X32_SYSDEP_H
 #define _LINUX_X32_SYSDEP_H 1
 
+#ifndef __ASSEMBLER__
+#include <libc-internal.h>
+#include <libc-diag.h>
+
+typedef long long int __syscall_arg_t;
+
+/* Syscall arguments for x32 follows x86_64 size, however pointers are 32
+   bits in size.  The idea is to zero extend pointer types while cast to
+   signed 64 bit default arguments.  */
+#define __SSC(__x) ((__syscall_arg_t) cast_to_uinteger (__x))
+
+#endif
+
 /* There is some commonality.  */
 #include <sysdeps/unix/sysv/linux/x86_64/sysdep.h>
 #include <sysdeps/x86_64/x32/sysdep.h>
-- 
2.17.1

^ permalink raw reply	[flat|nested] 38+ messages in thread

* [PATCH v3 03/21] nptl: x86_64: Fix Race conditions in pthread cancellation (BZ#12683)
  2019-10-14 20:57 [PATCH v3 00/21] nptl: Fix Race conditions in pthread cancellation (BZ#12683) Adhemerval Zanella
                   ` (13 preceding siblings ...)
  2019-10-14 20:57 ` [PATCH v3 19/21] nptl: nios2: " Adhemerval Zanella
@ 2019-10-14 20:57 ` Adhemerval Zanella
  2019-10-15 11:03   ` Florian Weimer
  2019-10-14 20:57 ` [PATCH v3 09/21] nptl: arm: " Adhemerval Zanella
                   ` (5 subsequent siblings)
  20 siblings, 1 reply; 38+ messages in thread
From: Adhemerval Zanella @ 2019-10-14 20:57 UTC (permalink / raw)
  To: libc-alpha

This patches adds the x86_64 modification required for the BZ#12683.
The arch-specific {libc-,librt-}cancelation.S files are remove in favor
of the default libc-cancellation implementation, the TCB_CANCELING_BITMASK
is remove since it is now unused, and the arch-specific syscall_cancel
is provided.

Checked on x86_64-linux-gnu.
---
 sysdeps/unix/sysv/linux/x86_64/cancellation.S | 104 ------------------
 .../sysv/linux/x86_64/libc-cancellation.S     |  21 ----
 .../sysv/linux/x86_64/librt-cancellation.S    |  21 ----
 .../unix/sysv/linux/x86_64/syscall_cancel.S   |  61 ++++++++++
 sysdeps/x86_64/nptl/tcb-offsets.sym           |   1 -
 5 files changed, 61 insertions(+), 147 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
 create mode 100644 sysdeps/unix/sysv/linux/x86_64/syscall_cancel.S

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 f8a142da72..0000000000
--- a/sysdeps/unix/sysv/linux/x86_64/cancellation.S
+++ /dev/null
@@ -1,104 +0,0 @@
-/* Copyright (C) 2009-2019 Free Software Foundation, Inc.
-   This file is part of the GNU C Library.
-   Contributed by Ulrich Drepper <drepper@redhat.com>, 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
-   <https://www.gnu.org/licenses/>.  */
-
-#include <sysdep.h>
-#include <tcb-offsets.h>
-#include <kernel-features.h>
-#include <lowlevellock-futex.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
-
-
-#define LOAD_PRIVATE_FUTEX_WAIT(reg) \
-	movl	$(FUTEX_WAIT | FUTEX_PRIVATE_FLAG), reg
-
-/* 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 cf8da66eb7..0000000000
--- a/sysdeps/unix/sysv/linux/x86_64/libc-cancellation.S
+++ /dev/null
@@ -1,21 +0,0 @@
-/* Copyright (C) 2009-2019 Free Software Foundation, Inc.
-   This file is part of the GNU C Library.
-   Contributed by Ulrich Drepper <drepper@redhat.com>, 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
-   <https://www.gnu.org/licenses/>.  */
-
-#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 e7dcc61f6e..0000000000
--- a/sysdeps/unix/sysv/linux/x86_64/librt-cancellation.S
+++ /dev/null
@@ -1,21 +0,0 @@
-/* Copyright (C) 2009-2019 Free Software Foundation, Inc.
-   This file is part of the GNU C Library.
-   Contributed by Ulrich Drepper <drepper@redhat.com>, 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
-   <https://www.gnu.org/licenses/>.  */
-
-#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/syscall_cancel.S b/sysdeps/unix/sysv/linux/x86_64/syscall_cancel.S
new file mode 100644
index 0000000000..c7364bfff8
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/x86_64/syscall_cancel.S
@@ -0,0 +1,61 @@
+/* Cancellable syscall wrapper - x86_64 version.
+   Copyright (C) 2019 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
+   <http://www.gnu.org/licenses/>.  */
+
+#include <sysdep.h>
+
+/* long int [rax] __syscall_cancel_arch (volatile int *cancelhandling [%rdi],
+					 __syscall_arg_t nr   [%rsi],
+					 __syscall_arg_t arg1 [%rdx],
+					 __syscall_arg_t arg2 [%rcx],
+					 __syscall_arg_t arg3 [%r8],
+					 __syscall_arg_t arg4 [%r9],
+					 __syscall_arg_t arg5 [SP+8],
+					 __syscall_arg_t arg6 [SP+16])  */
+
+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()  */
+	mov    (%rdi),%eax
+	testb  $4, (%rdi)
+	jne    __syscall_do_cancel
+
+	/* Issue a 6 argument syscall, the nr [%rax] being the syscall
+	   number.  */
+	mov    %rdi,%r11
+	mov    %rsi,%rax
+	mov    %rdx,%rdi
+	mov    %rcx,%rsi
+	mov    %r8,%rdx
+	mov    %r9,%r10
+	mov    8(%rsp),%r8
+	mov    16(%rsp),%r9
+	mov    %r11,8(%rsp)
+	syscall
+
+	.globl __syscall_cancel_arch_end
+	.type  __syscall_cancel_arch_end,@function
+__syscall_cancel_arch_end:
+	ret
+
+END (__syscall_cancel_arch)
+libc_hidden_def (__syscall_cancel_arch)
diff --git a/sysdeps/x86_64/nptl/tcb-offsets.sym b/sysdeps/x86_64/nptl/tcb-offsets.sym
index ae8034743b..5d033d1ac0 100644
--- a/sysdeps/x86_64/nptl/tcb-offsets.sym
+++ b/sysdeps/x86_64/nptl/tcb-offsets.sym
@@ -18,7 +18,6 @@ SSP_BASE_OFFSET		offsetof (tcbhead_t, ssp_base)
 -- 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
-- 
2.17.1

^ permalink raw reply	[flat|nested] 38+ messages in thread

* [PATCH v3 20/21] nptl: csky: Fix Race conditions in pthread cancellation (BZ#12683)
  2019-10-14 20:57 [PATCH v3 00/21] nptl: Fix Race conditions in pthread cancellation (BZ#12683) Adhemerval Zanella
                   ` (2 preceding siblings ...)
  2019-10-14 20:57 ` [PATCH v3 04/21] nptl: x32: " Adhemerval Zanella
@ 2019-10-14 20:57 ` Adhemerval Zanella
  2019-10-14 20:57 ` [PATCH v3 18/21] nptl: s390: " Adhemerval Zanella
                   ` (16 subsequent siblings)
  20 siblings, 0 replies; 38+ messages in thread
From: Adhemerval Zanella @ 2019-10-14 20:57 UTC (permalink / raw)
  To: libc-alpha

This patch adds the csky modifications required for the BZ#12683 fix
by adding the arch-specific cancellation syscall bridge.
---
 sysdeps/unix/sysv/linux/csky/syscall_cancel.S | 116 ++++++++++++++++++
 1 file changed, 116 insertions(+)
 create mode 100644 sysdeps/unix/sysv/linux/csky/syscall_cancel.S

diff --git a/sysdeps/unix/sysv/linux/csky/syscall_cancel.S b/sysdeps/unix/sysv/linux/csky/syscall_cancel.S
new file mode 100644
index 0000000000..938f86a569
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/csky/syscall_cancel.S
@@ -0,0 +1,116 @@
+/* Cancellable syscall wrapper.  Linux/csky version.
+   Copyright (C) 2019 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
+   <http://www.gnu.org/licenses/>.  */
+
+#include <sysdep.h>
+
+/* long int __syscall_cancel_arch (int *cancelhandling,
+				   __syscall_arg_t nr,
+				   __syscall_arg_t arg1,
+				   __syscall_arg_t arg2,
+				   __syscall_arg_t arg3,
+				   __syscall_arg_t arg4,
+				   __syscall_arg_t arg5,
+				   __syscall_arg_t arg6)  */
+
+#ifdef SHARED
+# define STACK_ADJ 4
+#else
+# define STACK_ADJ 0
+#endif
+
+ENTRY (__syscall_cancel_arch)
+	subi	sp, sp, 16 + STACK_ADJ
+	cfi_def_cfa_offset (16 + STACK_ADJ)
+#ifdef SHARED
+	st.w	gb, (sp, 16)
+	lrw	t1, 1f@GOTPC
+	cfi_offset (gb, -4)
+	grs	gb, 1f
+1:
+#endif
+	st.w	lr, (sp, 12)
+	st.w	l3, (sp, 8)
+	st.w	l1, (sp, 4)
+	st.w	l0, (sp, 0)
+#ifdef SHARED
+	addu	gb, gb, t1
+#endif
+	subi	sp, sp, 16
+	cfi_def_cfa_offset (32 + STACK_ADJ)
+	cfi_offset (lr, -( 4 + STACK_ADJ))
+	cfi_offset (l3, -( 8 + STACK_ADJ))
+	cfi_offset (l1, -(12 + STACK_ADJ))
+	cfi_offset (l0, -(16 + STACK_ADJ))
+
+	mov	l3, a1
+	mov	a1, a3
+	ld.w	a3, (sp, 32 + STACK_ADJ)
+	st.w	a3, (sp, 0)
+	ld.w	a3, (sp, 36 + STACK_ADJ)
+	st.w	a3, (sp, 4)
+	ld.w	a3, (sp, 40 + STACK_ADJ)
+	st.w	a3, (sp, 8)
+	ld.w	a3, (sp, 44 + STACK_ADJ)
+	st.w	a3, (sp, 12)
+
+	.globl __syscall_cancel_arch_start
+	.type  __syscall_cancel_arch_start,@function
+__syscall_cancel_arch_start:
+	ld.w	t0, (a0, 0)
+	andi	t0, t0, 4
+	jbnez	t0, 2f
+	mov	a0, a2
+	ld.w	a3, (sp, 4)
+	ld.w	a2, (sp, 0)
+	ld.w	l0, (sp, 8)
+	ld.w	l1, (sp, 12)
+	trap	0
+
+	.globl __syscall_cancel_arch_end
+	.type  __syscall_cancel_arch_end,@function
+__syscall_cancel_arch_end:
+	addi	sp, sp, 16
+	cfi_remember_state
+	cfi_def_cfa_offset (16 + STACK_ADJ)
+#ifdef SHARED
+	ld.w	gb, (sp, 16)
+	cfi_restore (gb)
+#endif
+	ld.w	lr, (sp, 12)
+	cfi_restore (lr)
+	ld.w	l3, (sp, 8)
+	cfi_restore (l3)
+	ld.w	l1, (sp, 4)
+	cfi_restore (l1)
+	ld.w	l0, (sp, 0)
+	cfi_restore (l0)
+	addi	sp, sp, 16
+	cfi_def_cfa_offset (0)
+	rts
+
+2:
+	cfi_restore_state
+#ifdef SHARED
+	lrw	a3, __syscall_do_cancel@GOTOFF
+	addu	a3, a3, gb
+	jsr	a3
+#else
+	jbsr	__syscall_do_cancel
+#endif
+END (__syscall_cancel_arch)
+libc_hidden_def (__syscall_cancel_arch)
-- 
2.17.1

^ permalink raw reply	[flat|nested] 38+ messages in thread

* [PATCH v3 02/21] nptl: Fix Race conditions in pthread cancellation (BZ#12683)
  2019-10-14 20:57 [PATCH v3 00/21] nptl: Fix Race conditions in pthread cancellation (BZ#12683) Adhemerval Zanella
                   ` (4 preceding siblings ...)
  2019-10-14 20:57 ` [PATCH v3 18/21] nptl: s390: " Adhemerval Zanella
@ 2019-10-14 20:57 ` Adhemerval Zanella
  2019-10-15 10:56   ` Florian Weimer
  2019-10-18 12:38   ` Internal SIGTIMER use (was: Re: [PATCH v3 02/21] nptl: Fix Race conditions in pthread cancellation (BZ#12683)) Florian Weimer
  2019-10-14 20:57 ` [PATCH v3 14/21] nptl: m68k: Fix Race conditions in pthread cancellation (BZ#12683) Adhemerval Zanella
                   ` (14 subsequent siblings)
  20 siblings, 2 replies; 38+ messages in thread
From: Adhemerval Zanella @ 2019-10-14 20:57 UTC (permalink / raw)
  To: libc-alpha

This patch is the initial fix for race conditions in NPTL cancellation codei
by redefining how cancellable syscalls are defined and handled.  Current
buggy approach is to enable asynchronous cancellation prior to making the
syscall and restore the previous cancellation type once the syscall returns.

As decribed in BZ#12683, this approach shows 2 important problems:

  1. Cancellation can act after the syscall has returned from kernel, but
     before userspace saves the return value.  It might result in a resource
     leak if the syscall allocated a resource or a side effect (partial
     read/write), and there is no way to program handle it with cancellation
     handlers.

  2. If a signal is handled while the thread is blocked at a cancellable
     syscall, the entire signal handler runs with asynchronous cancellation
     enabled.  This can lead to issues if the signal handler call functions
     which are async-signal-safe but not async-cancel-safe.

For cancellation to work correctly, there are 5 points at which the
cancellation signal could arrive:

  1. Before the final "testcancel" and before the syscall is made.
  2. Between the "testcancel" and the syscall.
  3. While the syscall is blocked and no side effects have yet taken place.
  4. While the syscall is blocked but with some side effects already having
     taken place (e.g. a partial read or write).
  5. After the syscall has returned.

And GLIBC wants to act on cancellation in cases 1, 2, and 3 but not in case
4 or 5.  The proposed solution follows:

  * Handling case 1 is trivial: do a conditional branch based on whether the
    thread has received a cancellation request;

  * Case 2 can be caught by the signal handler determining that the saved
    program counter (from the ucontext_t) is in some address range beginning
    just before the "testcancel" and ending with the syscall instruction.

  * In this case, except for certain syscalls that ALWAYS fail with EINTR
    even for non-interrupting signals, the kernel will reset the program
    counter to point at the syscall instruction during signal handling, so
    that the syscall is restarted when the signal handler returns. So, from
    the signal handler's standpoint, this looks the same as case 2, and thus
    it's taken care of.

  * In this case, the kernel cannot restart the syscall; when it's
    interrupted by a signal, the kernel must cause the syscall to return
    with whatever partial result it obtained (e.g. partial read or write).

  * In this case, the saved program counter points just after the syscall
    instruction, so the signal handler won't act on cancellation.
    This one is equal to 4. since the program counter is past the syscall
    instruction already.

Another case that needs handling is syscalls that fail with EINTR even
when the signal handler is non-interrupting. In this case, the syscall
wrapper code can just check the cancellation flag when the errno result
is EINTR, and act on cancellation if it's set.

The proposed GLIBC adjustments are:

  1. Remove the enable_asynccancel/disable_asynccancel function usage in
     syscall definition and instead make them call a common symbol that will
     check if cancellation is enabled (__syscall_cancel at
     nptl/libc-cancellation.c), call the arch-specific cancellable
     entry-point (__syscall_cancel_arch) and cancel the thread when required.

  2. Provide a arch-specific symbol that contains global markers. These
     markers will be used in SIGCANCEL handler to check if the interruption
     has been called in a valid syscall and if the syscalls has been
     completed or not.

     A reference implementation sysdeps/unix/sysv/linux/syscall_cancel.c is
     provided.  However the markers may not be set on correct expected places
     depeding of how INTERNAL_SYSCALL_NCS is implemented by the underlying
     architecture, and it is uses compiler-speficic construct (asm volatile)
     to place the required markers.  It is expected that all architectures
     implement an arch-specific.

  3. Rewrite SIGCANCEL asynchronous handler to check for both cancelling type
     and if current IP from signal handler falls between the global markes
     and act accordingly (sigcancel_handler at nptl/nptl-init.c).

  4. Adjust nptl/pthread_cancel.c to send an signal instead of acting
     directly. This avoid synchronization issues when updating the
     cancellation status and also focus the logic on signal handler and
     cancellation syscall code.

  5. Adjust pthread code to replace CANCEL_ASYNC/CANCEL_RESET calls to
     appropriated cancelable futex syscalls.

  6. Adjust libc code to replace LIBC_CANCEL_ASYNC/LIBC_CANCEL_RESET to
     appropriated cancelable syscalls.

  7. Adjust 'lowlevellock-futex.h' arch-specific implementations to provide
     cancelable futex calls (used in libpthread code).

This patch adds the proposed changes to NPTL common code and following patches
add the requires arch-specific bits.  The build for ia64-linux-gnu, mips-*,
and x86_64-* are broken without the arch-specific patches.
---
 manual/llio.texi                              |   4 +-
 nptl/Makefile                                 |  12 +-
 nptl/Versions                                 |   3 +
 nptl/cancellation.c                           | 101 ---------------
 nptl/descr.h                                  |  15 +--
 nptl/libc-cancellation.c                      |  45 ++++++-
 nptl/nptl-init.c                              |  88 +++++++-------
 nptl/pthreadP.h                               |  39 +++++-
 nptl/pthread_cancel.c                         |  69 ++---------
 nptl/pthread_create.c                         |   7 +-
 nptl/pthread_exit.c                           |   5 +-
 nptl/pthread_join_common.c                    |   2 +-
 nptl/pthread_kill.c                           |   7 +-
 .../pthread_kill_internal.c                   |  16 +--
 nptl/pthread_setcanceltype.c                  |   2 +-
 nptl/thrd_sleep.c                             |   7 +-
 nptl/tst-cancel28.c                           | 100 +++++++++++++++
 rt/Makefile                                   |   2 +-
 sysdeps/generic/sysdep-cancel.h               |   2 -
 sysdeps/htl/pthreadP.h                        |   1 +
 sysdeps/nptl/Makefile                         |   3 +-
 sysdeps/nptl/cancellation-pc-check.h          |  40 ++++++
 sysdeps/nptl/cancellation-sigmask.h           |  30 +++++
 sysdeps/unix/sysdep.h                         | 115 ++++++++++++++----
 sysdeps/unix/sysv/linux/clock_nanosleep.c     |   6 +-
 sysdeps/unix/sysv/linux/futex-internal.h      |  18 +--
 sysdeps/unix/sysv/linux/lowlevellock-futex.h  |  45 +++++--
 ...pthread_kill.c => pthread_kill_internal.c} |  22 +---
 sysdeps/unix/sysv/linux/socketcall.h          |  40 ++++--
 sysdeps/unix/sysv/linux/syscall_cancel.c      |  62 ++++++++++
 sysdeps/unix/sysv/linux/sysdep.h              |  20 +++
 31 files changed, 587 insertions(+), 341 deletions(-)
 delete mode 100644 nptl/cancellation.c
 rename sysdeps/nptl/librt-cancellation.c => nptl/pthread_kill_internal.c (70%)
 create mode 100644 nptl/tst-cancel28.c
 create mode 100644 sysdeps/nptl/cancellation-pc-check.h
 create mode 100644 sysdeps/nptl/cancellation-sigmask.h
 rename sysdeps/unix/sysv/linux/{pthread_kill.c => pthread_kill_internal.c} (75%)
 create mode 100644 sysdeps/unix/sysv/linux/syscall_cancel.c

diff --git a/manual/llio.texi b/manual/llio.texi
index 447126b7eb..ecf175341d 100644
--- a/manual/llio.texi
+++ b/manual/llio.texi
@@ -2534,13 +2534,13 @@ aiocb64}, since the LFS transparently replaces the old interface.
 @c     sigemptyset ok
 @c     sigaddset ok
 @c     setjmp ok
-@c     CANCEL_ASYNC -> pthread_enable_asynccancel ok
+@c     __pthread_setcanceltype ok
 @c      do_cancel ok
 @c       pthread_unwind ok
 @c        Unwind_ForcedUnwind or longjmp ok [@ascuheap @acsmem?]
 @c     lll_lock @asulock @aculock
 @c     lll_unlock @asulock @aculock
-@c     CANCEL_RESET -> pthread_disable_asynccancel ok
+@c     __pthread_setcanceltype ok
 @c      lll_futex_wait ok
 @c     ->start_routine ok -----
 @c     call_tls_dtors @asulock @ascuheap @aculock @acsmem
diff --git a/nptl/Makefile b/nptl/Makefile
index 1129fd4516..02dd05f1aa 100644
--- a/nptl/Makefile
+++ b/nptl/Makefile
@@ -34,7 +34,8 @@ routines = alloca_cutoff forward libc-lowlevellock libc-cancellation \
 	   pthread_attr_destroy pthread_attr_init pthread_attr_getdetachstate \
 	   pthread_attr_setdetachstate pthread_attr_getinheritsched \
 	   pthread_attr_setinheritsched pthread_attr_getschedparam \
-	   pthread_attr_setschedparam
+	   pthread_attr_setschedparam \
+	   syscall_cancel
 shared-only-routines = forward
 static-only-routines = pthread_atfork
 
@@ -103,7 +104,8 @@ libpthread-routines = nptl-init nptlfreeres vars events version pt-interp \
 		      pthread_barrierattr_setpshared \
 		      pthread_key_create pthread_key_delete \
 		      pthread_getspecific pthread_setspecific \
-		      pthread_sigmask pthread_kill pthread_sigqueue \
+		      pthread_sigmask pthread_kill pthread_kill_internal \
+		      pthread_sigqueue \
 		      pthread_cancel pthread_testcancel \
 		      pthread_setcancelstate pthread_setcanceltype \
 		      pthread_once \
@@ -117,7 +119,6 @@ libpthread-routines = nptl-init nptlfreeres vars events version pt-interp \
 		      cleanup cleanup_defer cleanup_compat \
 		      cleanup_defer_compat unwind \
 		      pt-longjmp pt-cleanup\
-		      cancellation \
 		      lowlevellock \
 		      lll_timedlock_wait \
 		      pt-fork pt-fcntl \
@@ -171,8 +172,7 @@ CFLAGS-pthread_setcanceltype.c += -fexceptions -fasynchronous-unwind-tables
 
 # These are internal functions which similar functionality as setcancelstate
 # and setcanceltype.
-CFLAGS-cancellation.c += -fasynchronous-unwind-tables
-CFLAGS-libc-cancellation.c += -fasynchronous-unwind-tables
+CFLAGS-libc-cancellation.c += -fexceptions -fasynchronous-unwind-tables
 
 # Calling pthread_exit() must cause the registered cancel handlers to
 # be executed.  Therefore exceptions have to be thrown through this
@@ -286,7 +286,7 @@ tests = tst-attr1 tst-attr2 tst-attr3 tst-default-attr \
 	tst-cancel11 tst-cancel12 tst-cancel13 tst-cancel14 tst-cancel15 \
 	tst-cancel16 tst-cancel17 tst-cancel18 tst-cancel19 tst-cancel20 \
 	tst-cancel21 tst-cancel22 tst-cancel23 tst-cancel24 tst-cancel25 \
-	tst-cancel26 tst-cancel27 \
+	tst-cancel26 tst-cancel27 tst-cancel28 \
 	tst-cancel-self tst-cancel-self-cancelstate \
 	tst-cancel-self-canceltype tst-cancel-self-testcancel \
 	tst-cleanup0 tst-cleanup1 tst-cleanup2 tst-cleanup3 tst-cleanup4 \
diff --git a/nptl/Versions b/nptl/Versions
index be7e810875..afdb448ba9 100644
--- a/nptl/Versions
+++ b/nptl/Versions
@@ -39,6 +39,9 @@ libc {
     __libc_pthread_init;
     __libc_current_sigrtmin_private; __libc_current_sigrtmax_private;
     __libc_allocate_rtsig_private;
+    __syscall_cancel;
+    __syscall_cancel_arch_start;
+    __syscall_cancel_arch_end;
   }
 }
 
diff --git a/nptl/cancellation.c b/nptl/cancellation.c
deleted file mode 100644
index 7712845561..0000000000
--- a/nptl/cancellation.c
+++ /dev/null
@@ -1,101 +0,0 @@
-/* Copyright (C) 2002-2019 Free Software Foundation, Inc.
-   This file is part of the GNU C Library.
-   Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
-
-   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
-   <https://www.gnu.org/licenses/>.  */
-
-#include <setjmp.h>
-#include <stdlib.h>
-#include "pthreadP.h"
-#include <futex-internal.h>
-
-
-/* The next two functions are similar to pthread_setcanceltype() but
-   more specialized for the use in the cancelable functions like write().
-   They do not need to check parameters etc.  */
-int
-attribute_hidden
-__pthread_enable_asynccancel (void)
-{
-  struct pthread *self = THREAD_SELF;
-  int oldval = THREAD_GETMEM (self, cancelhandling);
-
-  while (1)
-    {
-      int newval = oldval | CANCELTYPE_BITMASK;
-
-      if (newval == oldval)
-	break;
-
-      int curval = THREAD_ATOMIC_CMPXCHG_VAL (self, cancelhandling, newval,
-					      oldval);
-      if (__glibc_likely (curval == oldval))
-	{
-	  if (CANCEL_ENABLED_AND_CANCELED_AND_ASYNCHRONOUS (newval))
-	    {
-	      THREAD_SETMEM (self, result, PTHREAD_CANCELED);
-	      __do_cancel ();
-	    }
-
-	  break;
-	}
-
-      /* Prepare the next round.  */
-      oldval = curval;
-    }
-
-  return oldval;
-}
-
-
-void
-attribute_hidden
-__pthread_disable_asynccancel (int oldtype)
-{
-  /* If asynchronous cancellation was enabled before we do not have
-     anything to do.  */
-  if (oldtype & CANCELTYPE_BITMASK)
-    return;
-
-  struct pthread *self = THREAD_SELF;
-  int newval;
-
-  int oldval = THREAD_GETMEM (self, cancelhandling);
-
-  while (1)
-    {
-      newval = oldval & ~CANCELTYPE_BITMASK;
-
-      int curval = THREAD_ATOMIC_CMPXCHG_VAL (self, cancelhandling, newval,
-					      oldval);
-      if (__glibc_likely (curval == oldval))
-	break;
-
-      /* Prepare the next round.  */
-      oldval = curval;
-    }
-
-  /* We cannot return when we are being canceled.  Upon return the
-     thread might be things which would have to be undone.  The
-     following loop should loop until the cancellation signal is
-     delivered.  */
-  while (__builtin_expect ((newval & (CANCELING_BITMASK | CANCELED_BITMASK))
-			   == CANCELING_BITMASK, 0))
-    {
-      futex_wait_simple ((unsigned int *) &self->cancelhandling, newval,
-			 FUTEX_PRIVATE);
-      newval = THREAD_GETMEM (self, cancelhandling);
-    }
-}
diff --git a/nptl/descr.h b/nptl/descr.h
index d3f863aa18..a53f3326e6 100644
--- a/nptl/descr.h
+++ b/nptl/descr.h
@@ -275,23 +275,20 @@ struct pthread
   /* Bit set if asynchronous cancellation mode is selected.  */
 #define CANCELTYPE_BIT		1
 #define CANCELTYPE_BITMASK	(0x01 << CANCELTYPE_BIT)
-  /* Bit set if canceling has been initiated.  */
-#define CANCELING_BIT		2
-#define CANCELING_BITMASK	(0x01 << CANCELING_BIT)
-  /* Bit set if canceled.  */
-#define CANCELED_BIT		3
+  /* Bit set if thread is canceled.  */
+#define CANCELED_BIT		2
 #define CANCELED_BITMASK	(0x01 << CANCELED_BIT)
   /* Bit set if thread is exiting.  */
-#define EXITING_BIT		4
+#define EXITING_BIT		3
 #define EXITING_BITMASK		(0x01 << EXITING_BIT)
   /* Bit set if thread terminated and TCB is freed.  */
-#define TERMINATED_BIT		5
+#define TERMINATED_BIT		4
 #define TERMINATED_BITMASK	(0x01 << TERMINATED_BIT)
   /* Bit set if thread is supposed to change XID.  */
-#define SETXID_BIT		6
+#define SETXID_BIT		5
 #define SETXID_BITMASK		(0x01 << SETXID_BIT)
   /* Mask for the rest.  Helps the compiler to optimize.  */
-#define CANCEL_RESTMASK		0xffffff80
+#define CANCEL_RESTMASK		0xffffffc0
 
 #define CANCEL_ENABLED_AND_CANCELED(value) \
   (((value) & (CANCELSTATE_BITMASK | CANCELED_BITMASK | EXITING_BITMASK	      \
diff --git a/nptl/libc-cancellation.c b/nptl/libc-cancellation.c
index 37654cfcfe..430e0b962e 100644
--- a/nptl/libc-cancellation.c
+++ b/nptl/libc-cancellation.c
@@ -18,7 +18,46 @@
 
 #include "pthreadP.h"
 
+/* Cancellation function called by all cancellable syscalls.  */
+long int
+__syscall_cancel (__syscall_arg_t nr, __syscall_arg_t a1,
+		  __syscall_arg_t a2, __syscall_arg_t a3,
+		  __syscall_arg_t a4, __syscall_arg_t a5,
+		  __syscall_arg_t a6)
+{
+  pthread_t self = (pthread_t) THREAD_SELF;
+  struct pthread *pd = (struct pthread *) self;
+  long int result;
 
-#define __pthread_enable_asynccancel __libc_enable_asynccancel
-#define __pthread_disable_asynccancel __libc_disable_asynccancel
-#include <nptl/cancellation.c>
+  /* If cancellation is not enabled, call the syscall directly.  */
+  if (pd->cancelhandling & CANCELSTATE_BITMASK)
+    {
+      INTERNAL_SYSCALL_DECL (err);
+      result = INTERNAL_SYSCALL_NCS_CALL (nr, err, a1, a2, a3, a4, a5, a6);
+      if (INTERNAL_SYSCALL_ERROR_P (result, err))
+	return -INTERNAL_SYSCALL_ERRNO (result, err);
+      return result;
+    }
+
+  /* Call the arch-specific entry points that contains the globals markers
+     to be checked by SIGCANCEL handler.  */
+  result = __syscall_cancel_arch (&pd->cancelhandling, nr, a1, a2, a3, a4, a5,
+			          a6);
+
+  if ((result == -EINTR)
+      && (pd->cancelhandling & CANCELED_BITMASK)
+      && !(pd->cancelhandling & CANCELSTATE_BITMASK))
+    __do_cancel ();
+
+  return result;
+}
+libc_hidden_def (__syscall_cancel)
+
+/* Since __do_cancel is a always inline function, this creates a symbol the
+   arch-specific symbol can call to cancel the thread.  */
+_Noreturn void
+attribute_hidden
+__syscall_do_cancel (void)
+{
+  __do_cancel ();
+}
diff --git a/nptl/nptl-init.c b/nptl/nptl-init.c
index ea91b9e138..09bfe16d45 100644
--- a/nptl/nptl-init.c
+++ b/nptl/nptl-init.c
@@ -39,6 +39,9 @@
 #include <libc-pointer-arith.h>
 #include <pthread-pids.h>
 #include <pthread_mutex_conf.h>
+#include <sigcontextinfo.h>
+#include <cancellation-sigmask.h>
+#include <cancellation-pc-check.h>
 
 #ifndef TLS_MULTIPLE_THREADS_IN_TCB
 /* Pointer to the corresponding variable in libc.  */
@@ -155,35 +158,23 @@ sigcancel_handler (int sig, siginfo_t *si, void *ctx)
 
   struct pthread *self = THREAD_SELF;
 
-  int oldval = THREAD_GETMEM (self, cancelhandling);
-  while (1)
-    {
-      /* We are canceled now.  When canceled by another thread this flag
-	 is already set but if the signal is directly send (internally or
-	 from another process) is has to be done here.  */
-      int newval = oldval | CANCELING_BITMASK | CANCELED_BITMASK;
-
-      if (oldval == newval || (oldval & EXITING_BITMASK) != 0)
-	/* Already canceled or exiting.  */
-	break;
-
-      int curval = THREAD_ATOMIC_CMPXCHG_VAL (self, cancelhandling, newval,
-					      oldval);
-      if (curval == oldval)
-	{
-	  /* Set the return value.  */
-	  THREAD_SETMEM (self, result, PTHREAD_CANCELED);
-
-	  /* Make sure asynchronous cancellation is still enabled.  */
-	  if ((newval & CANCELTYPE_BITMASK) != 0)
-	    /* Run the registered destructors and terminate the thread.  */
-	    __do_cancel ();
-
-	  break;
-	}
-
-      oldval = curval;
-    }
+  if (((self->cancelhandling & (CANCELSTATE_BITMASK)) != 0)
+      || ((self->cancelhandling & CANCELED_BITMASK) == 0))
+    return;
+
+  /* Add SIGCANCEL on ignored sigmask to avoid the handler to be called
+     again.  */
+  ucontext_add_cancel (ctx);
+
+  /* Check if asynchronous cancellation mode is set or if interrupted
+     instruction pointer falls within the cancellable syscall bridge.  For
+     interruptable syscalls that might generate external side-effects (partial
+     reads or writes, for instance), the kernel will set the IP to after
+     '__syscall_cancel_arch_end', thus disabling the cancellation and allowing
+     the process to handle such conditions.  */
+  if (self->cancelhandling & CANCELTYPE_BITMASK
+      || ucontext_check_pc_boundary (ctx))
+    __do_cancel ();
 }
 #endif
 
@@ -286,38 +277,49 @@ __pthread_initialize_minimal_internal (void)
   THREAD_SETMEM (pd, report_events, __nptl_initial_report_events);
 
 #if defined SIGCANCEL || defined SIGSETXID
-  struct sigaction sa;
-  __sigemptyset (&sa.sa_mask);
 
 # ifdef SIGCANCEL
   /* Install the cancellation signal handler.  If for some reason we
      cannot install the handler we do not abort.  Maybe we should, but
      it is only asynchronous cancellation which is affected.  */
-  sa.sa_sigaction = sigcancel_handler;
-  sa.sa_flags = SA_SIGINFO;
-  (void) __libc_sigaction (SIGCANCEL, &sa, NULL);
+  {
+    struct sigaction sa;
+    sa.sa_sigaction = sigcancel_handler;
+    /* The signal handle should be non-interruptible to avoid the risk of
+       spurious EINTR caused by SIGCANCEL sent to process or if pthread_cancel
+       is called while cancellation is disabled in the target thread.  */
+    sa.sa_flags = SA_SIGINFO | SA_RESTART;
+    sa.sa_mask = SIGALL_SET;
+    __libc_sigaction (SIGCANCEL, &sa, NULL);
+  }
 # endif
 
 # ifdef SIGSETXID
-  /* Install the handle to change the threads' uid/gid.  */
-  sa.sa_sigaction = sighandler_setxid;
-  sa.sa_flags = SA_SIGINFO | SA_RESTART;
-  (void) __libc_sigaction (SIGSETXID, &sa, NULL);
+  {
+    /* Install the handle to change the threads' uid/gid.  */
+    struct sigaction sa;
+    __sigemptyset (&sa.sa_mask);
+    sa.sa_sigaction = sighandler_setxid;
+    sa.sa_flags = SA_SIGINFO | SA_RESTART;
+    __libc_sigaction (SIGSETXID, &sa, NULL);
+  }
 # endif
 
   /* The parent process might have left the signals blocked.  Just in
      case, unblock it.  We reuse the signal mask in the sigaction
      structure.  It is already cleared.  */
+  {
+    struct sigaction sa;
+    __sigemptyset (&sa.sa_mask);
 # ifdef SIGCANCEL
-  __sigaddset (&sa.sa_mask, SIGCANCEL);
+    __sigaddset (&sa.sa_mask, SIGCANCEL);
 # endif
 # ifdef SIGSETXID
-  __sigaddset (&sa.sa_mask, SIGSETXID);
+    __sigaddset (&sa.sa_mask, SIGSETXID);
 # endif
-  {
     INTERNAL_SYSCALL_DECL (err);
-    (void) INTERNAL_SYSCALL (rt_sigprocmask, err, 4, SIG_UNBLOCK, &sa.sa_mask,
-			     NULL, _NSIG / 8);
+    INTERNAL_SYSCALL_CALL (rt_sigprocmask, err, SIG_UNBLOCK, &sa.sa_mask,
+			   NULL, _NSIG / 8);
   }
 #endif
 
diff --git a/nptl/pthreadP.h b/nptl/pthreadP.h
index 070b3afa8d..cafd14f5af 100644
--- a/nptl/pthreadP.h
+++ b/nptl/pthreadP.h
@@ -296,20 +296,46 @@ extern void __nptl_unwind_freeres (void) attribute_hidden;
 #endif
 
 
-/* Called when a thread reacts on a cancellation request.  */
 static inline void
 __attribute ((noreturn, always_inline))
-__do_cancel (void)
+__do_cancel_with_result (void *result)
 {
   struct pthread *self = THREAD_SELF;
 
-  /* Make sure we get no more cancellations.  */
-  THREAD_ATOMIC_BIT_SET (self, cancelhandling, EXITING_BIT);
+  /* Make sure we get no more cancellations by clearing the cancel
+     state.  */
+  int oldval = THREAD_GETMEM (self, cancelhandling);
+  while (1)
+    {
+      int newval = oldval | CANCELSTATE_BITMASK | EXITING_BITMASK;
+      if (oldval == newval)
+	break;
+
+      oldval = THREAD_ATOMIC_CMPXCHG_VAL (self, cancelhandling, newval,
+					  oldval);
+    }
+
+  THREAD_SETMEM (self, result, result);
 
   __pthread_unwind ((__pthread_unwind_buf_t *)
 		    THREAD_GETMEM (self, cleanup_jmp_buf));
 }
 
+/* Called when a thread reacts on a cancellation request.  */
+static inline void
+__attribute ((noreturn, always_inline))
+__do_cancel (void)
+{
+  __do_cancel_with_result (PTHREAD_CANCELED);
+}
+
+extern long int __syscall_cancel_arch (volatile int *, __syscall_arg_t nr,
+     __syscall_arg_t arg1, __syscall_arg_t arg2, __syscall_arg_t arg3,
+     __syscall_arg_t arg4, __syscall_arg_t arg5, __syscall_arg_t arg6);
+libc_hidden_proto (__syscall_cancel_arch);
+
+extern _Noreturn void __syscall_do_cancel (void)
+     attribute_hidden;
 
 /* Internal prototypes.  */
 
@@ -469,11 +495,11 @@ extern int __pthread_equal (pthread_t thread1, pthread_t thread2);
 extern int __pthread_detach (pthread_t th);
 extern int __pthread_cancel (pthread_t th);
 extern int __pthread_kill (pthread_t threadid, int signo);
+extern int __pthread_kill_internal (pthread_t threadid, int signo)
+  attribute_hidden;
 extern void __pthread_exit (void *value) __attribute__ ((__noreturn__));
 extern int __pthread_join (pthread_t threadid, void **thread_return);
 extern int __pthread_setcanceltype (int type, int *oldtype);
-extern int __pthread_enable_asynccancel (void) attribute_hidden;
-extern void __pthread_disable_asynccancel (int oldtype) attribute_hidden;
 extern void __pthread_testcancel (void);
 extern int __pthread_timedjoin_ex (pthread_t, void **, const struct timespec *,
 				   bool);
@@ -496,6 +522,7 @@ hidden_proto (__pthread_testcancel)
 hidden_proto (__pthread_mutexattr_init)
 hidden_proto (__pthread_mutexattr_settype)
 hidden_proto (__pthread_timedjoin_ex)
+hidden_proto (__pthread_kill_internal)
 #endif
 
 extern int __pthread_cond_broadcast_2_0 (pthread_cond_2_0_t *cond);
diff --git a/nptl/pthread_cancel.c b/nptl/pthread_cancel.c
index 64ac12e60a..b20254bdba 100644
--- a/nptl/pthread_cancel.c
+++ b/nptl/pthread_cancel.c
@@ -37,67 +37,24 @@ __pthread_cancel (pthread_t th)
 #ifdef SHARED
   pthread_cancel_init ();
 #endif
-  int result = 0;
-  int oldval;
-  int newval;
-  do
-    {
-    again:
-      oldval = pd->cancelhandling;
-      newval = oldval | CANCELING_BITMASK | CANCELED_BITMASK;
 
-      /* Avoid doing unnecessary work.  The atomic operation can
-	 potentially be expensive if the bug has to be locked and
-	 remote cache lines have to be invalidated.  */
-      if (oldval == newval)
-	break;
+  THREAD_ATOMIC_BIT_SET (pd, cancelhandling, CANCELED_BIT);
 
-      /* If the cancellation is handled asynchronously just send a
-	 signal.  We avoid this if possible since it's more
-	 expensive.  */
-      if (CANCEL_ENABLED_AND_CANCELED_AND_ASYNCHRONOUS (newval))
-	{
-	  /* Mark the cancellation as "in progress".  */
-	  if (atomic_compare_and_exchange_bool_acq (&pd->cancelhandling,
-						    oldval | CANCELING_BITMASK,
-						    oldval))
-	    goto again;
-
-#ifdef SIGCANCEL
-	  /* The cancellation handler will take care of marking the
-	     thread as canceled.  */
-	  pid_t pid = __getpid ();
-
-	  INTERNAL_SYSCALL_DECL (err);
-	  int val = INTERNAL_SYSCALL_CALL (tgkill, err, pid, pd->tid,
-					   SIGCANCEL);
-	  if (INTERNAL_SYSCALL_ERROR_P (val, err))
-	    result = INTERNAL_SYSCALL_ERRNO (val, err);
-#else
-          /* It should be impossible to get here at all, since
-             pthread_setcanceltype should never have allowed
-             PTHREAD_CANCEL_ASYNCHRONOUS to be set.  */
-          abort ();
-#endif
-
-	  break;
-	}
-
-	/* A single-threaded process should be able to kill itself, since
-	   there is nothing in the POSIX specification that says that it
-	   cannot.  So we set multiple_threads to true so that cancellation
-	   points get executed.  */
-	THREAD_SETMEM (THREAD_SELF, header.multiple_threads, 1);
+  /* A single-threaded process should be able to kill itself, since there is
+     nothing in the POSIX specification that says that it cannot.  So we set
+     multiple_threads to true so that cancellation points get executed.  */
+  THREAD_SETMEM (THREAD_SELF, header.multiple_threads, 1);
 #ifndef TLS_MULTIPLE_THREADS_IN_TCB
-	__pthread_multiple_threads = *__libc_multiple_threads_ptr = 1;
+  __pthread_multiple_threads = *__libc_multiple_threads_ptr = 1;
 #endif
-    }
-  /* Mark the thread as canceled.  This has to be done
-     atomically since other bits could be modified as well.  */
-  while (atomic_compare_and_exchange_bool_acq (&pd->cancelhandling, newval,
-					       oldval));
 
-  return result;
+  /* Avoid signaling when thread attempts cancel itself (pthread_kill
+     is expensive).  */
+  if (pd == THREAD_SELF
+      && (THREAD_GETMEM (pd, cancelhandling) & CANCELTYPE_BITMASK) == 0)
+    return 0;
+
+  return __pthread_kill_internal (th, SIGCANCEL);
 }
 weak_alias (__pthread_cancel, pthread_cancel)
 
diff --git a/nptl/pthread_create.c b/nptl/pthread_create.c
index 130937c3c4..8cab7f970c 100644
--- a/nptl/pthread_create.c
+++ b/nptl/pthread_create.c
@@ -406,7 +406,7 @@ START_THREAD_DEFN
   /* If the parent was running cancellation handlers while creating
      the thread the new thread inherited the signal mask.  Reset the
      cancellation signal mask.  */
-  if (__glibc_unlikely (pd->parent_cancelhandling & CANCELING_BITMASK))
+  if (__glibc_unlikely (pd->parent_cancelhandling & CANCELED_BITMASK))
     {
       INTERNAL_SYSCALL_DECL (err);
       sigset_t mask;
@@ -449,7 +449,8 @@ START_THREAD_DEFN
 	 have ownership (see CONCURRENCY NOTES above).  */
       if (__glibc_unlikely (pd->stopped_start))
 	{
-	  int oldtype = CANCEL_ASYNC ();
+	  int ct;
+	  __pthread_setcanceltype (PTHREAD_CANCEL_ASYNCHRONOUS, &ct);
 
 	  /* Get the lock the parent locked to force synchronization.  */
 	  lll_lock (pd->lock, LLL_PRIVATE);
@@ -459,7 +460,7 @@ START_THREAD_DEFN
 	  /* And give it up right away.  */
 	  lll_unlock (pd->lock, LLL_PRIVATE);
 
-	  CANCEL_RESET (oldtype);
+	  __pthread_setcanceltype (ct, NULL);
 	}
 
       LIBC_PROBE (pthread_start, 3, (pthread_t) pd, pd->start_routine, pd->arg);
diff --git a/nptl/pthread_exit.c b/nptl/pthread_exit.c
index 643c85bd6e..6c59cdf652 100644
--- a/nptl/pthread_exit.c
+++ b/nptl/pthread_exit.c
@@ -16,16 +16,13 @@
    License along with the GNU C Library; if not, see
    <https://www.gnu.org/licenses/>.  */
 
-#include <stdlib.h>
 #include "pthreadP.h"
 
 
 void
 __pthread_exit (void *value)
 {
-  THREAD_SETMEM (THREAD_SELF, result, value);
-
-  __do_cancel ();
+  __do_cancel_with_result (value);
 }
 weak_alias (__pthread_exit, pthread_exit)
 
diff --git a/nptl/pthread_join_common.c b/nptl/pthread_join_common.c
index 9545ae4bd3..43cdb2c7bc 100644
--- a/nptl/pthread_join_common.c
+++ b/nptl/pthread_join_common.c
@@ -100,7 +100,7 @@ __pthread_timedjoin_ex (pthread_t threadid, void **thread_return,
   if ((pd == self
        || (self->joinid == pd
 	   && (pd->cancelhandling
-	       & (CANCELING_BITMASK | CANCELED_BITMASK | EXITING_BITMASK
+	       & (CANCELED_BITMASK | EXITING_BITMASK
 		  | TERMINATED_BITMASK)) == 0))
       && !CANCEL_ENABLED_AND_CANCELED (self->cancelhandling))
     /* This is a deadlock situation.  The threads are waiting for each
diff --git a/nptl/pthread_kill.c b/nptl/pthread_kill.c
index 2805c722a6..4c2672ae84 100644
--- a/nptl/pthread_kill.c
+++ b/nptl/pthread_kill.c
@@ -31,8 +31,9 @@ __pthread_kill (pthread_t threadid, int signo)
     /* Not a valid thread handle.  */
     return ESRCH;
 
-  return ENOSYS;
+  if (__is_internal_signal (signo))
+    return EINVAL;
+
+  return __pthread_kill_internal (threadid, signo);
 }
 strong_alias (__pthread_kill, pthread_kill)
-
-stub_warning (pthread_kill)
diff --git a/sysdeps/nptl/librt-cancellation.c b/nptl/pthread_kill_internal.c
similarity index 70%
rename from sysdeps/nptl/librt-cancellation.c
rename to nptl/pthread_kill_internal.c
index 93ebe4aa71..b4f4f6dc78 100644
--- a/sysdeps/nptl/librt-cancellation.c
+++ b/nptl/pthread_kill_internal.c
@@ -1,6 +1,6 @@
-/* Copyright (C) 2002-2019 Free Software Foundation, Inc.
+/* Send a signal to a specific pthread.  Internal version.
+   Copyright (C) 2002-2019 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
-   Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
 
    The GNU C Library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Lesser General Public
@@ -16,9 +16,11 @@
    License along with the GNU C Library; if not, see
    <https://www.gnu.org/licenses/>.  */
 
-#include <nptl/pthreadP.h>
+#include <pthreadP.h>
 
-
-#define __pthread_enable_asynccancel __librt_enable_asynccancel
-#define __pthread_disable_asynccancel __librt_disable_asynccancel
-#include <nptl/cancellation.c>
+int
+__pthread_kill_internal (pthread_t threadid, int signo)
+{
+  return ENOSYS;
+}
+hidden_def (__pthread_kill_internal)
diff --git a/nptl/pthread_setcanceltype.c b/nptl/pthread_setcanceltype.c
index d771c31e46..84cc657aed 100644
--- a/nptl/pthread_setcanceltype.c
+++ b/nptl/pthread_setcanceltype.c
@@ -73,4 +73,4 @@ __pthread_setcanceltype (int type, int *oldtype)
 
   return 0;
 }
-strong_alias (__pthread_setcanceltype, pthread_setcanceltype)
+weak_alias (__pthread_setcanceltype, pthread_setcanceltype)
diff --git a/nptl/thrd_sleep.c b/nptl/thrd_sleep.c
index 2e185dd748..75c0d53f3e 100644
--- a/nptl/thrd_sleep.c
+++ b/nptl/thrd_sleep.c
@@ -24,13 +24,12 @@
 int
 thrd_sleep (const struct timespec* time_point, struct timespec* remaining)
 {
-  INTERNAL_SYSCALL_DECL (err);
-  int ret = INTERNAL_SYSCALL_CANCEL (nanosleep, err, time_point, remaining);
-  if (INTERNAL_SYSCALL_ERROR_P (ret, err))
+  long int ret = INTERNAL_SYSCALL_CANCEL (nanosleep, time_point, remaining);
+  if (SYSCALL_CANCEL_ERROR (ret))
     {
       /* C11 states thrd_sleep function returns -1 if it has been interrupted
 	 by a signal, or a negative value if it fails.  */
-      ret = INTERNAL_SYSCALL_ERRNO (ret, err);
+      ret = -ret;
       if (ret == EINTR)
 	return -1;
       return -2;
diff --git a/nptl/tst-cancel28.c b/nptl/tst-cancel28.c
new file mode 100644
index 0000000000..e27f5a0776
--- /dev/null
+++ b/nptl/tst-cancel28.c
@@ -0,0 +1,100 @@
+/* Check side-effect act for cancellable syscalls (BZ #12683).
+   Copyright (C) 2019 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
+   <http://www.gnu.org/licenses/>.  */
+
+/* This testcase checks if there is resource leakage if the syscall has
+   returned from kernelspace, but before userspace saves the return
+   value.  The 'leaker' thread should be able to close the file descriptor
+   if the resource is already allocated, meaning that if the cancellation
+   signal arrives *after* the open syscal return from kernel, the
+   side-effect should be visible to application.  */
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <stdlib.h>
+
+#include <support/xthread.h>
+#include <support/check.h>
+#include <support/temp_file.h>
+#include <support/support.h>
+#include <support/descriptors.h>
+
+static void *
+writeopener (void *arg)
+{
+  int fd;
+  for (;;)
+    {
+      fd = open (arg, O_WRONLY);
+      close (fd);
+    }
+  return NULL;
+}
+
+static void *
+leaker (void *arg)
+{
+  int fd = open (arg, O_RDONLY);
+  TEST_VERIFY_EXIT (fd > 0);
+  pthread_setcancelstate (PTHREAD_CANCEL_DISABLE, 0);
+  close (fd);
+  return NULL;
+}
+
+
+#define ITER_COUNT 1000
+#define MAX_FILENO 1024
+
+static int
+do_test (void)
+{
+  char *dir = support_create_temp_directory ("tst-cancel28");
+  char *name = xasprintf ("%s/fifo", dir);
+  TEST_COMPARE (mkfifo (name, 0600), 0);
+  add_temp_file (name);
+
+  struct support_descriptors *descrs = support_descriptors_list ();
+
+  srand (1);
+
+  xpthread_create (NULL, writeopener, name);
+  for (int i = 0; i < ITER_COUNT; i++)
+    {
+      pthread_t td = xpthread_create (NULL, leaker, name);
+      struct timespec ts =
+	{ .tv_nsec = rand () % 100000, .tv_sec = 0 };
+      nanosleep (&ts, NULL);
+      /* Ignore pthread_cancel result because it might be the
+	 case when pthread_cancel is called when thread is already
+	 exited.  */
+      pthread_cancel (td);
+      xpthread_join (td);
+    }
+
+  support_descriptors_check (descrs);
+
+  support_descriptors_free (descrs);
+
+  free (name);
+
+  return 0;
+}
+
+#define TIMEOUT 10
+#include <support/test-driver.c>
diff --git a/rt/Makefile b/rt/Makefile
index 6c8365e0c0..a7a9ec4cfc 100644
--- a/rt/Makefile
+++ b/rt/Makefile
@@ -56,7 +56,7 @@ include ../Rules
 CFLAGS-aio_suspend.c += -fexceptions
 CFLAGS-mq_timedreceive.c += -fexceptions -fasynchronous-unwind-tables
 CFLAGS-mq_timedsend.c += -fexceptions -fasynchronous-unwind-tables
-CFLAGS-librt-cancellation.c += -fasynchronous-unwind-tables
+CFLAGS-clock_nanosleep.c += -fexceptions -fasynchronous-unwind-tables
 
 LDFLAGS-rt.so = -Wl,--enable-new-dtags,-z,nodelete
 
diff --git a/sysdeps/generic/sysdep-cancel.h b/sysdeps/generic/sysdep-cancel.h
index d22a786536..5c84b4499a 100644
--- a/sysdeps/generic/sysdep-cancel.h
+++ b/sysdeps/generic/sysdep-cancel.h
@@ -3,5 +3,3 @@
 /* No multi-thread handling enabled.  */
 #define SINGLE_THREAD_P (1)
 #define RTLD_SINGLE_THREAD_P (1)
-#define LIBC_CANCEL_ASYNC()	0 /* Just a dummy value.  */
-#define LIBC_CANCEL_RESET(val)	((void)(val)) /* Nothing, but evaluate it.  */
diff --git a/sysdeps/htl/pthreadP.h b/sysdeps/htl/pthreadP.h
index e745dacac1..5628791de8 100644
--- a/sysdeps/htl/pthreadP.h
+++ b/sysdeps/htl/pthreadP.h
@@ -25,6 +25,7 @@
 
 extern pthread_t __pthread_self (void);
 extern int __pthread_kill (pthread_t threadid, int signo);
+extern int __pthread_kill_internal (pthread_t threadid, int signo);
 extern struct __pthread **__pthread_threads;
 
 extern int _pthread_mutex_init (pthread_mutex_t *mutex, const pthread_mutexattr_t *attr);
diff --git a/sysdeps/nptl/Makefile b/sysdeps/nptl/Makefile
index fbb9800a5c..19293a7b3e 100644
--- a/sysdeps/nptl/Makefile
+++ b/sysdeps/nptl/Makefile
@@ -21,8 +21,7 @@ libpthread-sysdep_routines += errno-loc
 endif
 
 ifeq ($(subdir),rt)
-librt-sysdep_routines += timer_routines librt-cancellation
-CFLAGS-librt-cancellation.c += -fexceptions -fasynchronous-unwind-tables
+librt-sysdep_routines += timer_routines
 
 tests += tst-mqueue8x
 CFLAGS-tst-mqueue8x.c += -fexceptions
diff --git a/sysdeps/nptl/cancellation-pc-check.h b/sysdeps/nptl/cancellation-pc-check.h
new file mode 100644
index 0000000000..8b26c4ec4e
--- /dev/null
+++ b/sysdeps/nptl/cancellation-pc-check.h
@@ -0,0 +1,40 @@
+/* Architecture specific code for pthread cancellation handling.
+   Copyright (C) 2019 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
+   <http://www.gnu.org/licenses/>.  */
+
+#ifndef _NPTL_CANCELLATION_PC_CHECK
+#define _NPTL_CANCELLATION_PC_CHECK
+
+#include <sigcontextinfo.h>
+
+/* Check if the program counter (PC) from ucontext CTX is within the start and
+   then end boundary from the __syscall_cancel_arch bridge.  Return TRUE if
+   the PC is within the boundary, meaning the syscall does not have any side
+   effects; or FALSE otherwise.  */
+static bool
+ucontext_check_pc_boundary (void *ctx)
+{
+  /* Both are defined in syscall_cancel.S.  */
+  extern const char __syscall_cancel_arch_start[1];
+  extern const char __syscall_cancel_arch_end[1];
+
+  uintptr_t pc = sigcontext_get_pc (ctx);
+  return pc >= (uintptr_t) __syscall_cancel_arch_start
+	 && pc < (uintptr_t) __syscall_cancel_arch_end;
+}
+
+#endif
diff --git a/sysdeps/nptl/cancellation-sigmask.h b/sysdeps/nptl/cancellation-sigmask.h
new file mode 100644
index 0000000000..77702c135e
--- /dev/null
+++ b/sysdeps/nptl/cancellation-sigmask.h
@@ -0,0 +1,30 @@
+/* Architecture specific code for pthread cancellation handling.
+   Copyright (C) 2019 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
+   <http://www.gnu.org/licenses/>.  */
+
+#ifndef _NPTL_CANCELLATION_SIGMASK_H
+#define _NPTL_CANCELLATION_SIGMASK_H
+
+/* Add the SIGCANCEL signal on sigmask set at the ucontext CTX obtained from
+   the sigaction handler.  */
+static void
+ucontext_add_cancel (void *ctx)
+{
+  __sigaddset (&((ucontext_t*) ctx)->uc_sigmask, SIGCANCEL);
+}
+
+#endif
diff --git a/sysdeps/unix/sysdep.h b/sysdeps/unix/sysdep.h
index 10468c7129..04f30b8cbc 100644
--- a/sysdeps/unix/sysdep.h
+++ b/sysdeps/unix/sysdep.h
@@ -24,6 +24,9 @@
 #define	SYSCALL__(name, args)	PSEUDO (__##name, name, args)
 #define	SYSCALL(name, args)	PSEUDO (name, name, args)
 
+#ifndef __ASSEMBLER__
+# include <errno.h>
+
 #define __SYSCALL_CONCAT_X(a,b)     a##b
 #define __SYSCALL_CONCAT(a,b)       __SYSCALL_CONCAT_X (a, b)
 
@@ -57,6 +60,29 @@
 #define INTERNAL_SYSCALL_CALL(...) \
   __INTERNAL_SYSCALL_DISP (__INTERNAL_SYSCALL, __VA_ARGS__)
 
+#define __INTERNAL_SYSCALL_NCS0(name, err) \
+  INTERNAL_SYSCALL_NCS (name, err, 0)
+#define __INTERNAL_SYSCALL_NCS1(name, err, a1) \
+  INTERNAL_SYSCALL_NCS (name, err, 1, a1)
+#define __INTERNAL_SYSCALL_NCS2(name, err, a1, a2) \
+  INTERNAL_SYSCALL_NCS (name, err, 2, a1, a2)
+#define __INTERNAL_SYSCALL_NCS3(name, err, a1, a2, a3) \
+  INTERNAL_SYSCALL_NCS (name, err, 3, a1, a2, a3)
+#define __INTERNAL_SYSCALL_NCS4(name, err, a1, a2, a3, a4) \
+  INTERNAL_SYSCALL_NCS (name, err, 4, a1, a2, a3, a4)
+#define __INTERNAL_SYSCALL_NCS5(name, err, a1, a2, a3, a4, a5) \
+  INTERNAL_SYSCALL_NCS (name, err, 5, a1, a2, a3, a4, a5)
+#define __INTERNAL_SYSCALL_NCS6(name, err, a1, a2, a3, a4, a5, a6) \
+  INTERNAL_SYSCALL_NCS (name, err, 6, a1, a2, a3, a4, a5, a6)
+#define __INTERNAL_SYSCALL_NCS7(name, err, a1, a2, a3, a4, a5, a6, a7) \
+  INTERNAL_SYSCALL_NCS (name, err, 7, a1, a2, a3, a4, a5, a6, a7)
+
+/* Issue a syscall defined by syscall number plus any other argument required.
+   It is similar to INTERNAL_SYSCALL_NCS macro, but without the need to pass
+   the expected argument number as third parameter.  */
+#define INTERNAL_SYSCALL_NCS_CALL(...) \
+  __INTERNAL_SYSCALL_DISP (__INTERNAL_SYSCALL_NCS, __VA_ARGS__)
+
 #define __INLINE_SYSCALL0(name) \
   INLINE_SYSCALL (name, 0)
 #define __INLINE_SYSCALL1(name, a1) \
@@ -88,35 +114,70 @@
 #define INLINE_SYSCALL_CALL(...) \
   __INLINE_SYSCALL_DISP (__INLINE_SYSCALL, __VA_ARGS__)
 
-#define SYSCALL_CANCEL(...) \
-  ({									     \
-    long int sc_ret;							     \
-    if (SINGLE_THREAD_P) 						     \
-      sc_ret = INLINE_SYSCALL_CALL (__VA_ARGS__); 			     \
-    else								     \
-      {									     \
-	int sc_cancel_oldtype = LIBC_CANCEL_ASYNC ();			     \
-	sc_ret = INLINE_SYSCALL_CALL (__VA_ARGS__);			     \
-        LIBC_CANCEL_RESET (sc_cancel_oldtype);				     \
-      }									     \
-    sc_ret;								     \
-  })
 
-/* Issue a syscall defined by syscall number plus any other argument
-   required.  Any error will be returned unmodified (including errno).  */
-#define INTERNAL_SYSCALL_CANCEL(...) \
-  ({									     \
-    long int sc_ret;							     \
-    if (SINGLE_THREAD_P) 						     \
-      sc_ret = INTERNAL_SYSCALL_CALL (__VA_ARGS__); 			     \
-    else								     \
-      {									     \
-	int sc_cancel_oldtype = LIBC_CANCEL_ASYNC ();			     \
-	sc_ret = INTERNAL_SYSCALL_CALL (__VA_ARGS__);			     \
-        LIBC_CANCEL_RESET (sc_cancel_oldtype);				     \
-      }									     \
-    sc_ret;								     \
+/* Cancellation macros.  */
+#ifndef __SSC
+typedef long int __syscall_arg_t;
+# define __SSC(__x) ((__syscall_arg_t) (__x))
+#endif
+
+long int __syscall_cancel (__syscall_arg_t nr, __syscall_arg_t arg1,
+			   __syscall_arg_t arg2, __syscall_arg_t arg3,
+			   __syscall_arg_t arg4, __syscall_arg_t arg5,
+			   __syscall_arg_t arg6);
+libc_hidden_proto (__syscall_cancel);
+
+#define __SYSCALL_CANCEL0(name) \
+  (__syscall_cancel)(__NR_##name, 0, 0, 0, 0, 0, 0)
+#define __SYSCALL_CANCEL1(name, a1) \
+  (__syscall_cancel)(__NR_##name, __SSC(a1), 0, 0, 0, 0, 0)
+#define __SYSCALL_CANCEL2(name, a1, a2) \
+  (__syscall_cancel)(__NR_##name, __SSC(a1), __SSC(a2), 0, 0, 0, 0)
+#define __SYSCALL_CANCEL3(name, a1, a2, a3) \
+  (__syscall_cancel)(__NR_##name, __SSC(a1), __SSC(a2), __SSC(a3), 0, 0, 0)
+#define __SYSCALL_CANCEL4(name, a1, a2, a3, a4) \
+  (__syscall_cancel)(__NR_##name, __SSC(a1), __SSC(a2), __SSC(a3), \
+		     __SSC(a4), 0, 0)
+#define __SYSCALL_CANCEL5(name, a1, a2, a3, a4, a5) \
+  (__syscall_cancel)(__NR_##name, __SSC(a1), __SSC(a2), __SSC(a3), \
+		     __SSC(a4), __SSC(a5), 0)
+#define __SYSCALL_CANCEL6(name, a1, a2, a3, a4, a5, a6) \
+  (__syscall_cancel)(__NR_##name, __SSC(a1), __SSC(a2), __SSC(a3), \
+		     __SSC(a4), __SSC(a5), __SSC(a6))
+
+#define __SYSCALL_CANCEL_NARGS_X(a,b,c,d,e,f,g,h,n,...) n
+#define __SYSCALL_CANCEL_NARGS(...) \
+  __SYSCALL_CANCEL_NARGS_X (__VA_ARGS__,7,6,5,4,3,2,1,0,)
+#define __SYSCALL_CANCEL_CONCAT_X(a,b)     a##b
+#define __SYSCALL_CANCEL_CONCAT(a,b)       __SYSCALL_CANCEL_CONCAT_X (a, b)
+#define __SYSCALL_CANCEL_DISP(b,...) \
+  __SYSCALL_CANCEL_CONCAT (b,__SYSCALL_CANCEL_NARGS(__VA_ARGS__))(__VA_ARGS__)
+
+#define __SYSCALL_CANCEL_CALL(...) \
+  __SYSCALL_CANCEL_DISP (__SYSCALL_CANCEL, __VA_ARGS__)
+
+/* Issue a cancellable syscall defined by syscall number NAME plus any other
+   argument required.  If an error occurs its value is returned as an negative
+   number unmodified and errno is not set.  */
+#define INTERNAL_SYSCALL_CANCEL(name, args...) \
+  __SYSCALL_CANCEL_CALL (name, args)
+
+/* Issue a cancellable syscall defined first argument plus any other argument
+   required.  If and error occurs its value, the macro returns -1 and sets
+   errno accordingly.  */
+#if IS_IN (rtld)
+/* The loader does not need to handle thread cancellation, use direct
+   syscall instead.  */
+# define SYSCALL_CANCEL(...) INLINE_SYSCALL_CALL (__VA_ARGS__)
+#else
+# define SYSCALL_CANCEL(...) \
+  ({									\
+    long int sc_ret = __SYSCALL_CANCEL_CALL (__VA_ARGS__);		\
+    SYSCALL_CANCEL_RET ((sc_ret));					\
   })
+#endif
+
+#endif /* __ASSEMBLER__  */
 
 /* Machine-dependent sysdep.h files are expected to define the macro
    PSEUDO (function_name, syscall_name) to emit assembly code to define the
diff --git a/sysdeps/unix/sysv/linux/clock_nanosleep.c b/sysdeps/unix/sysv/linux/clock_nanosleep.c
index 1f240b8720..ddcdddcd5d 100644
--- a/sysdeps/unix/sysv/linux/clock_nanosleep.c
+++ b/sysdeps/unix/sysv/linux/clock_nanosleep.c
@@ -36,11 +36,9 @@ __clock_nanosleep (clockid_t clock_id, int flags, const struct timespec *req,
 
   /* If the call is interrupted by a signal handler or encounters an error,
      it returns a positive value similar to errno.  */
-  INTERNAL_SYSCALL_DECL (err);
-  int r = INTERNAL_SYSCALL_CANCEL (clock_nanosleep, err, clock_id, flags,
+  int r = INTERNAL_SYSCALL_CANCEL (clock_nanosleep, clock_id, flags,
 				   req, rem);
-  return (INTERNAL_SYSCALL_ERROR_P (r, err)
-	  ? INTERNAL_SYSCALL_ERRNO (r, err) : 0);
+  return SYSCALL_CANCEL_ERROR (r) ? -r : 0;
 }
 
 versioned_symbol (libc, __clock_nanosleep, clock_nanosleep, GLIBC_2_17);
diff --git a/sysdeps/unix/sysv/linux/futex-internal.h b/sysdeps/unix/sysv/linux/futex-internal.h
index 5a4f4ff818..b41a4d9919 100644
--- a/sysdeps/unix/sysv/linux/futex-internal.h
+++ b/sysdeps/unix/sysv/linux/futex-internal.h
@@ -75,10 +75,7 @@ static __always_inline int
 futex_wait_cancelable (unsigned int *futex_word, unsigned int expected,
 		       int private)
 {
-  int oldtype;
-  oldtype = __pthread_enable_asynccancel ();
-  int err = lll_futex_timed_wait (futex_word, expected, NULL, private);
-  __pthread_disable_asynccancel (oldtype);
+  int err = lll_futex_timed_wait_cancel (futex_word, expected, NULL, private);
   switch (err)
     {
     case 0:
@@ -129,10 +126,7 @@ futex_reltimed_wait_cancelable (unsigned int *futex_word,
 				unsigned int expected,
 			        const struct timespec *reltime, int private)
 {
-  int oldtype;
-  oldtype = LIBC_CANCEL_ASYNC ();
-  int err = lll_futex_timed_wait (futex_word, expected, reltime, private);
-  LIBC_CANCEL_RESET (oldtype);
+  int err = lll_futex_timed_wait_cancel (futex_word, expected, reltime, private);
   switch (err)
     {
     case 0:
@@ -203,12 +197,8 @@ futex_abstimed_wait_cancelable (unsigned int *futex_word,
      despite them being valid.  */
   if (__glibc_unlikely ((abstime != NULL) && (abstime->tv_sec < 0)))
     return ETIMEDOUT;
-  int oldtype;
-  oldtype = __pthread_enable_asynccancel ();
-  int err = lll_futex_clock_wait_bitset (futex_word, expected,
-					clockid, abstime,
-					private);
-  __pthread_disable_asynccancel (oldtype);
+  int err = lll_futex_clock_wait_bitset_cancel (futex_word, expected, clockid,
+						abstime, private);
   switch (err)
     {
     case 0:
diff --git a/sysdeps/unix/sysv/linux/lowlevellock-futex.h b/sysdeps/unix/sysv/linux/lowlevellock-futex.h
index b423673ed4..bd6d3b7cf7 100644
--- a/sysdeps/unix/sysv/linux/lowlevellock-futex.h
+++ b/sysdeps/unix/sysv/linux/lowlevellock-futex.h
@@ -74,6 +74,12 @@
      ? -INTERNAL_SYSCALL_ERRNO (__ret, __err) : 0);                     \
   })
 
+#define lll_futex_syscall_cp(...)					\
+  ({                                                                    \
+    long int __ret = INTERNAL_SYSCALL_CANCEL (futex, __VA_ARGS__);	\
+    __ret;								\
+  })
+
 #define lll_futex_wait(futexp, val, private) \
   lll_futex_timed_wait (futexp, val, NULL, private)
 
@@ -148,19 +154,36 @@
 
 /* Cancellable futex macros.  */
 #define lll_futex_wait_cancel(futexp, val, private) \
-  ({                                                                   \
-    int __oldtype = CANCEL_ASYNC ();				       \
-    long int __err = lll_futex_wait (futexp, val, LLL_SHARED);	       \
-    CANCEL_RESET (__oldtype);					       \
-    __err;							       \
+  lll_futex_timed_wait_cancel (futexp, val, NULL, private)
+
+#define lll_futex_timed_wait_cancel(futexp, val, timeout, private)	\
+  ({									\
+    long int __ret;							\
+    int __op = FUTEX_WAIT;						\
+    __ret = lll_futex_syscall_cp (futexp,				\
+				  __lll_private_flag (__op, private),	\
+				  val, timeout);			\
+    __ret;								\
   })
 
-#define lll_futex_timed_wait_cancel(futexp, val, timeout, private)	   \
-  ({									   \
-    int __oldtype = CANCEL_ASYNC ();				       	   \
-    long int __err = lll_futex_timed_wait (futexp, val, timeout, private); \
-    CANCEL_RESET (__oldtype);						   \
-    __err;								   \
+#define lll_futex_clock_wait_bitset_cancel(futexp, val, clockid,	\
+					   timeout, private)		\
+  ({									\
+    long int __ret;							\
+    if (lll_futex_supported_clockid (clockid))                          \
+      {                                                                 \
+        const unsigned int clockbit =                                   \
+          (clockid == CLOCK_REALTIME) ? FUTEX_CLOCK_REALTIME : 0;       \
+        const int op =                                                  \
+          __lll_private_flag (FUTEX_WAIT_BITSET | clockbit, private);   \
+									\
+	__ret = lll_futex_syscall_cp (futexp, op, val,			\
+                                      timeout, NULL /* Unused.  */,	\
+                                      FUTEX_BITSET_MATCH_ANY);		\
+      }									\
+    else								\
+      __ret = -EINVAL;							\
+    __ret;								\
   })
 
 #endif  /* !__ASSEMBLER__  */
diff --git a/sysdeps/unix/sysv/linux/pthread_kill.c b/sysdeps/unix/sysv/linux/pthread_kill_internal.c
similarity index 75%
rename from sysdeps/unix/sysv/linux/pthread_kill.c
rename to sysdeps/unix/sysv/linux/pthread_kill_internal.c
index 71305b90c6..31920deae4 100644
--- a/sysdeps/unix/sysv/linux/pthread_kill.c
+++ b/sysdeps/unix/sysv/linux/pthread_kill_internal.c
@@ -16,24 +16,15 @@
    License along with the GNU C Library; if not, see
    <https://www.gnu.org/licenses/>.  */
 
-#include <errno.h>
-#include <signal.h>
-#include <pthreadP.h>
-#include <tls.h>
-#include <sysdep.h>
 #include <unistd.h>
+#include <pthreadP.h>
 
-
+/* Used internally by pthread_cancel, so we can't filter SIGCANCEL.  */
 int
-__pthread_kill (pthread_t threadid, int signo)
+__pthread_kill_internal (pthread_t threadid, int signo)
 {
   struct pthread *pd = (struct pthread *) threadid;
 
-  /* Make sure the descriptor is valid.  */
-  if (DEBUGGING_P && INVALID_TD_P (pd))
-    /* Not a valid thread handle.  */
-    return ESRCH;
-
   /* Force load of pd->tid into local variable or register.  Otherwise
      if a thread exits between ESRCH test and tgkill, we might return
      EINVAL, because pd->tid would be cleared by the kernel.  */
@@ -42,11 +33,6 @@ __pthread_kill (pthread_t threadid, int signo)
     /* Not a valid thread handle.  */
     return ESRCH;
 
-  /* Disallow sending the signal we use for cancellation, timers,
-     for the setxid implementation.  */
-  if (signo == SIGCANCEL || signo == SIGTIMER || signo == SIGSETXID)
-    return EINVAL;
-
   /* We have a special syscall to do the work.  */
   INTERNAL_SYSCALL_DECL (err);
 
@@ -56,4 +42,4 @@ __pthread_kill (pthread_t threadid, int signo)
   return (INTERNAL_SYSCALL_ERROR_P (val, err)
 	  ? INTERNAL_SYSCALL_ERRNO (val, err) : 0);
 }
-strong_alias (__pthread_kill, pthread_kill)
+hidden_def (__pthread_kill_internal)
diff --git a/sysdeps/unix/sysv/linux/socketcall.h b/sysdeps/unix/sysv/linux/socketcall.h
index 1e6387cdbf..38af55feb4 100644
--- a/sysdeps/unix/sysv/linux/socketcall.h
+++ b/sysdeps/unix/sysv/linux/socketcall.h
@@ -87,18 +87,32 @@
   })
 
 
-#if IS_IN (libc)
-# define __pthread_enable_asynccancel  __libc_enable_asynccancel
-# define __pthread_disable_asynccancel __libc_disable_asynccancel
-#endif
-
-#define SOCKETCALL_CANCEL(name, args...)				\
-  ({									\
-    int oldtype = LIBC_CANCEL_ASYNC ();					\
-    long int sc_ret = __SOCKETCALL (SOCKOP_##name, args);		\
-    LIBC_CANCEL_RESET (oldtype);					\
-    sc_ret;								\
-  })
-
+#define __SOCKETCALL_CANCEL1(__name, __a1) \
+  SYSCALL_CANCEL (socketcall, __name, \
+     ((long int [1]) { (long int) __a1 }))
+#define __SOCKETCALL_CANCEL2(__name, __a1, __a2) \
+  SYSCALL_CANCEL (socketcall, __name, \
+     ((long int [2]) { (long int) __a1, (long int) __a2 }))
+#define __SOCKETCALL_CANCEL3(__name, __a1, __a2, __a3) \
+  SYSCALL_CANCEL (socketcall, __name, \
+     ((long int [3]) { (long int) __a1, (long int) __a2, (long int) __a3 }))
+#define __SOCKETCALL_CANCEL4(__name, __a1, __a2, __a3, __a4) \
+  SYSCALL_CANCEL (socketcall, __name, \
+     ((long int [4]) { (long int) __a1, (long int) __a2, (long int) __a3, \
+                       (long int) __a4 }))
+#define __SOCKETCALL_CANCEL5(__name, __a1, __a2, __a3, __a4, __a5) \
+  SYSCALL_CANCEL (socketcall, __name, \
+     ((long int [5]) { (long int) __a1, (long int) __a2, (long int) __a3, \
+                       (long int) __a4, (long int) __a5 }))
+#define __SOCKETCALL_CANCEL6(__name, __a1, __a2, __a3, __a4, __a5, __a6) \
+  SYSCALL_CANCEL (socketcall, __name, \
+     ((long int [6]) { (long int) __a1, (long int) __a2, (long int) __a3, \
+                       (long int) __a4, (long int) __a5, (long int) __a6 }))
+
+#define __SOCKETCALL_CANCEL(...) __SOCKETCALL_DISP (__SOCKETCALL_CANCEL,\
+						    __VA_ARGS__)
+
+#define SOCKETCALL_CANCEL(name, args...) \
+   __SOCKETCALL_CANCEL (SOCKOP_##name, args)
 
 #endif /* sys/socketcall.h */
diff --git a/sysdeps/unix/sysv/linux/syscall_cancel.c b/sysdeps/unix/sysv/linux/syscall_cancel.c
new file mode 100644
index 0000000000..79d66ec4f4
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/syscall_cancel.c
@@ -0,0 +1,62 @@
+/* Default cancellation syscall bridge.
+   Copyright (C) 2019 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
+   <http://www.gnu.org/licenses/>.  */
+
+#include <sysdep.h>
+#include <pthreadP.h>
+
+/* This is the generic version of the cancellable syscall code which
+   adds the label guards (__syscall_cancel_arch_{start,end}) used
+   on SIGCANCEL sigcancel_handler (nptl-init.c) to check if the cancelled
+   syscall have side-effects that need to be signaled to program.
+
+   This implementation should be used a reference one to document the
+   implementation constraints: the __syscall_cancel_arch_end should point
+   to the immediate next instruction after the syscall one.  This is because
+   kernel will signal interrupted syscall with side effects by setting
+   the signal frame program counter (on the ucontext_t third argument from
+   SA_SIGINFO signal handler) right after the syscall instruction.
+
+   If the INTERNAL_SYSCALL_NCS macro use more instructions to get the
+   error condition from kernel (as for powerpc and sparc), uses an
+   out of the line helper (as for ARM thumb), or uses a kernel helper
+   gate (as for i686 or ia64) the architecture should adjust the
+   macro or provide a custom __syscall_cancel_arch implementation.   */
+long int
+__syscall_cancel_arch (volatile int *ch, __syscall_arg_t nr,
+		       __syscall_arg_t a1, __syscall_arg_t a2,
+		       __syscall_arg_t a3, __syscall_arg_t a4,
+		       __syscall_arg_t a5, __syscall_arg_t a6)
+{
+#define ADD_LABEL(__label)		\
+  asm volatile (			\
+    ".global " __label "\t\n"		\
+    ".type " __label ",\%function\t\n" 	\
+    __label ":\n");
+
+  ADD_LABEL ("__syscall_cancel_arch_start");
+  if (__glibc_unlikely (*ch & CANCELED_BITMASK))
+    __syscall_do_cancel();
+
+  INTERNAL_SYSCALL_DECL(err);
+  long int result = INTERNAL_SYSCALL_NCS (nr, err, 6, a1, a2, a3, a4, a5, a6);
+  ADD_LABEL ("__syscall_cancel_arch_end");
+  if (__glibc_unlikely (INTERNAL_SYSCALL_ERROR_P (result, err)))
+    return -INTERNAL_SYSCALL_ERRNO (result, err);
+  return result;
+}
+libc_hidden_def (__syscall_cancel_arch)
diff --git a/sysdeps/unix/sysv/linux/sysdep.h b/sysdeps/unix/sysv/linux/sysdep.h
index fc9af51456..317bb7f973 100644
--- a/sysdeps/unix/sysv/linux/sysdep.h
+++ b/sysdeps/unix/sysv/linux/sysdep.h
@@ -27,6 +27,26 @@
     -1l;					\
   })
 
+/* Check error from cancellable syscall and set errno accordingly.
+   Linux uses a negative return value to indicate syscall errors
+   and since version 2.1 the return value of a system call might be
+   negative even if the call succeeded (e.g., the `lseek' system call
+   might return a large offset).
+   Current contract is kernel make sure the no syscall returns a value
+   in -1 .. -4095 as a valid result so we can savely test with -4095.  */
+#define SYSCALL_CANCEL_ERROR(__ret)		\
+  (__ret > -4096UL)
+
+#define SYSCALL_CANCEL_RET(__ret)		\
+  ({						\
+    if (SYSCALL_CANCEL_ERROR(__ret))		\
+      {						\
+	__set_errno (-__ret);			\
+	__ret = -1;				\
+      }						\
+    __ret;					\
+   })
+
 /* Provide a dummy argument that can be used to force register
    alignment for register pairs if required by the syscall ABI.  */
 #ifdef __ASSUME_ALIGNED_REGISTER_PAIRS
-- 
2.17.1

^ permalink raw reply	[flat|nested] 38+ messages in thread

* [PATCH v3 01/21] nptl: Handle EPIPE on tst-cancel2
  2019-10-14 20:57 [PATCH v3 00/21] nptl: Fix Race conditions in pthread cancellation (BZ#12683) Adhemerval Zanella
                   ` (8 preceding siblings ...)
  2019-10-14 20:57 ` [PATCH v3 07/21] nptl: i386: " Adhemerval Zanella
@ 2019-10-14 20:57 ` Adhemerval Zanella
  2019-10-15  9:03   ` Florian Weimer
  2019-10-14 20:57 ` [PATCH v3 16/21] nptl: sh: Fix Race conditions in pthread cancellation (BZ#12683) Adhemerval Zanella
                   ` (10 subsequent siblings)
  20 siblings, 1 reply; 38+ messages in thread
From: Adhemerval Zanella @ 2019-10-14 20:57 UTC (permalink / raw)
  To: libc-alpha

The SIGPIPE can be catched before SIGCANCEL, which makes write fail
and the thread return an non expected result.

Checked on x86_64-linux-gnu and powerpc64le-linux-gnu.
---
 nptl/tst-cancel2.c | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/nptl/tst-cancel2.c b/nptl/tst-cancel2.c
index b22bd496a7..2df2c00578 100644
--- a/nptl/tst-cancel2.c
+++ b/nptl/tst-cancel2.c
@@ -73,9 +73,6 @@ do_test (void)
       return 1;
     }
 
-  /* This will cause the write in the child to return.  */
-  close (fd[0]);
-
   if (pthread_join (th, &r) != 0)
     {
       puts ("join failed");
-- 
2.17.1

^ permalink raw reply	[flat|nested] 38+ messages in thread

* [PATCH v3 14/21] nptl: m68k: Fix Race conditions in pthread cancellation (BZ#12683)
  2019-10-14 20:57 [PATCH v3 00/21] nptl: Fix Race conditions in pthread cancellation (BZ#12683) Adhemerval Zanella
                   ` (5 preceding siblings ...)
  2019-10-14 20:57 ` [PATCH v3 02/21] nptl: " Adhemerval Zanella
@ 2019-10-14 20:57 ` Adhemerval Zanella
  2019-10-14 21:13   ` Andreas Schwab
  2019-10-14 20:57 ` [PATCH v3 15/21] nptl: alpha: " Adhemerval Zanella
                   ` (13 subsequent siblings)
  20 siblings, 1 reply; 38+ messages in thread
From: Adhemerval Zanella @ 2019-10-14 20:57 UTC (permalink / raw)
  To: libc-alpha

This patch adds the hppa modifications required for the BZ#12683 fix
by adding the arch-specific cancellation syscall bridge.

Checked on m68k-linux-gnu.
---
 sysdeps/unix/sysv/linux/m68k/syscall_cancel.S | 87 +++++++++++++++++++
 1 file changed, 87 insertions(+)
 create mode 100644 sysdeps/unix/sysv/linux/m68k/syscall_cancel.S

diff --git a/sysdeps/unix/sysv/linux/m68k/syscall_cancel.S b/sysdeps/unix/sysv/linux/m68k/syscall_cancel.S
new file mode 100644
index 0000000000..4e5223ee7b
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/m68k/syscall_cancel.S
@@ -0,0 +1,87 @@
+/* Cancellable syscall wrapper.  Linux/m68k version.
+   Copyright (C) 2019 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
+   <http://www.gnu.org/licenses/>.  */
+
+#include <sysdep.h>
+
+/* long int __syscall_cancel_arch (int *cancelhandling,
+				   __syscall_arg_t nr,
+				   __syscall_arg_t arg1,
+				   __syscall_arg_t arg2,
+				   __syscall_arg_t arg3,
+				   __syscall_arg_t arg4,
+				   __syscall_arg_t arg5,
+				   __syscall_arg_t arg6,
+				   __syscall_arg_t arg7)  */
+
+
+ENTRY (__syscall_cancel_arch)
+#ifdef __mcoldfire__
+	lea	(-16,%sp),%sp
+	movem.l	#60,(%sp)
+#else
+	movem.l	#15360,-(%sp)
+#endif
+	cfi_def_cfa_offset (20)
+	cfi_offset (2, -20)
+	cfi_offset (3, -16)
+	cfi_offset (4, -12)
+	cfi_offset (5, -8)
+
+	.global __syscall_cancel_arch_start
+	.type	__syscall_cancel_arch_start,%function
+__syscall_cancel_arch_start:
+
+	move.l	20(%sp),%a0
+	move.l	(%a0),%d0
+#ifdef __mcoldfire__
+	move.w	%d0,%ccr
+	jeq	1f
+#else
+	btst	#2,%d0
+	jne 	1f
+#endif
+
+	move.l	48(%sp),%a0
+	move.l	44(%sp),%d5
+	move.l	40(%sp),%d4
+	move.l	36(%sp),%d3
+	move.l	32(%sp),%d2
+	move.l	28(%sp),%d1
+	move.l	24(%sp),%d0
+	trap #0
+
+	.global __syscall_cancel_arch_end
+	.type	__syscall_cancel_arch_end,%function
+__syscall_cancel_arch_end:
+
+#ifdef __mcoldfire__
+	movem.l	(%sp),#60
+	lea	(16,%sp),%sp
+#else
+	movem.l	(%sp)+,#60
+#endif
+	rts
+
+1:
+#ifdef PIC
+	bsr.l __syscall_do_cancel
+#else
+	jsr __syscall_do_cancel
+#endif
+END (__syscall_cancel_arch)
+libc_hidden_def (__syscall_cancel_arch)
-- 
2.17.1

^ permalink raw reply	[flat|nested] 38+ messages in thread

* [PATCH v3 10/21] nptl: powerpc: Fix Race conditions in pthread cancellation (BZ#12683)
  2019-10-14 20:57 [PATCH v3 00/21] nptl: Fix Race conditions in pthread cancellation (BZ#12683) Adhemerval Zanella
                   ` (15 preceding siblings ...)
  2019-10-14 20:57 ` [PATCH v3 09/21] nptl: arm: " Adhemerval Zanella
@ 2019-10-14 20:57 ` Adhemerval Zanella
  2019-10-14 20:57 ` [PATCH v3 05/21] nptl: ia64: " Adhemerval Zanella
                   ` (3 subsequent siblings)
  20 siblings, 0 replies; 38+ messages in thread
From: Adhemerval Zanella @ 2019-10-14 20:57 UTC (permalink / raw)
  To: libc-alpha

This patch adds the powerpc modifications required for the BZ#12683 fix
by adding the arch-specific cancellation syscall bridge.

Checked on powerpc64le-linux-gnu, powerpc64-linux-gnu and powerpc-linux-gnu.
---
 sysdeps/powerpc/powerpc32/sysdep.h            |  3 +
 sysdeps/powerpc/powerpc64/sysdep.h            | 19 ++++++
 .../unix/sysv/linux/powerpc/syscall_cancel.S  | 67 +++++++++++++++++++
 3 files changed, 89 insertions(+)
 create mode 100644 sysdeps/unix/sysv/linux/powerpc/syscall_cancel.S

diff --git a/sysdeps/powerpc/powerpc32/sysdep.h b/sysdeps/powerpc/powerpc32/sysdep.h
index c21ea87f5a..689a708740 100644
--- a/sysdeps/powerpc/powerpc32/sysdep.h
+++ b/sysdeps/powerpc/powerpc32/sysdep.h
@@ -101,6 +101,9 @@ GOT_LABEL:			;					      \
 # define JUMPTARGET(name) name
 #endif
 
+#define TAIL_CALL_NO_RETURN(__func) \
+    b __func@local
+
 #if defined SHARED && defined PIC && !defined NO_HIDDEN
 # undef HIDDEN_JUMPTARGET
 # define HIDDEN_JUMPTARGET(name) __GI_##name##@local
diff --git a/sysdeps/powerpc/powerpc64/sysdep.h b/sysdeps/powerpc/powerpc64/sysdep.h
index db273f3346..fb6ede3e87 100644
--- a/sysdeps/powerpc/powerpc64/sysdep.h
+++ b/sysdeps/powerpc/powerpc64/sysdep.h
@@ -276,6 +276,25 @@ LT_LABELSUFFIX(name,_name_end): ; \
   ENTRY (name);					\
   DO_CALL (SYS_ify (syscall_name))
 
+#ifdef SHARED
+# define TAIL_CALL_NO_RETURN(__func) \
+    b JUMPTARGET(__func)
+#else
+# define TAIL_CALL_NO_RETURN(__func) \
+    .ifdef .Local ## __func; \
+    b .Local ## __func; \
+    .else; \
+.Local ## __func: \
+    mflr 0; \
+    std 0,FRAME_LR_SAVE(1); \
+    stdu 1,-FRAME_MIN_SIZE(1); \
+    cfi_adjust_cfa_offset(FRAME_MIN_SIZE); \
+    cfi_offset(lr,FRAME_LR_SAVE); \
+    bl JUMPTARGET(__func); \
+    nop; \
+    .endif
+#endif
+
 #ifdef SHARED
 #define TAIL_CALL_SYSCALL_ERROR \
     b JUMPTARGET(__syscall_error)
diff --git a/sysdeps/unix/sysv/linux/powerpc/syscall_cancel.S b/sysdeps/unix/sysv/linux/powerpc/syscall_cancel.S
new file mode 100644
index 0000000000..66d601da2a
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/powerpc/syscall_cancel.S
@@ -0,0 +1,67 @@
+/* Cancellable syscall wrapper.  Linux/powerpc version.
+   Copyright (C) 2019 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
+   <http://www.gnu.org/licenses/>.  */
+
+#include <sysdep.h>
+
+/* long int [r3] __syscall_cancel_arch (int *cancelhandling [r3],
+					long int nr   [r4],
+					long int arg1 [r5],
+					long int arg2 [r6],
+					long int arg3 [r7],
+					long int arg4 [r8],
+					long int arg5 [r9],
+					long int arg6 [r10])  */
+
+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()  */
+	lwz     r0,0(r3)
+	andi.   r0,r0,0x4
+	bne-    1f
+
+	/* Issue a 6 argument syscall, the nr [r4] being the syscall
+	   number.  */
+	mr      r0,r4
+	mr      r3,r5
+	mr      r4,r6
+	mr      r5,r7
+	mr      r6,r8
+	mr      r7,r9
+	mr      r8,r10
+	sc
+
+	.globl __syscall_cancel_arch_end
+	.type  __syscall_cancel_arch_end,@function
+__syscall_cancel_arch_end:
+
+	bnslr+
+	neg	r3,r3
+	blr
+
+	/* Although the __syscall_do_cancel do not return, we need to stack
+	   being set correctly for unwind.  */
+1:
+	TAIL_CALL_NO_RETURN (__syscall_do_cancel)
+
+END (__syscall_cancel_arch)
+libc_hidden_def (__syscall_cancel_arch)
-- 
2.17.1

^ permalink raw reply	[flat|nested] 38+ messages in thread

* [PATCH v3 08/21] nptl: aarch64: Fix Race conditions in pthread cancellation (BZ#12683)
  2019-10-14 20:57 [PATCH v3 00/21] nptl: Fix Race conditions in pthread cancellation (BZ#12683) Adhemerval Zanella
  2019-10-14 20:57 ` [PATCH v3 12/21] nptl: sparc: " Adhemerval Zanella
@ 2019-10-14 20:57 ` Adhemerval Zanella
  2019-10-14 20:57 ` [PATCH v3 04/21] nptl: x32: " Adhemerval Zanella
                   ` (18 subsequent siblings)
  20 siblings, 0 replies; 38+ messages in thread
From: Adhemerval Zanella @ 2019-10-14 20:57 UTC (permalink / raw)
  To: libc-alpha

This patch adds the aarch64 modifications required for the BZ#12683 fix
by adding the arch-specific cancellation syscall bridge.

Checked on aarch64-linux-gnu.
---
 .../unix/sysv/linux/aarch64/syscall_cancel.S  | 61 +++++++++++++++++++
 1 file changed, 61 insertions(+)
 create mode 100644 sysdeps/unix/sysv/linux/aarch64/syscall_cancel.S

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 0000000000..e105480bf3
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/aarch64/syscall_cancel.S
@@ -0,0 +1,61 @@
+/* Cancellable syscall wrapper.  Linux/AArch64 version.
+   Copyright (C) 2019 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
+   <http://www.gnu.org/licenses/>.  */
+
+#include <sysdep.h>
+
+/* long int [r0] __syscall_cancel_arch (int *cancelhandling [r0],
+					long int nr   [r1],
+					long int arg1 [r2],
+					long int arg2 [r3],
+					long int arg3 [SP],
+					long int arg4 [SP+4],
+					long int arg5 [SP+8],
+					long int arg6 [SP+12])  */
+
+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)
-- 
2.17.1

^ permalink raw reply	[flat|nested] 38+ messages in thread

* [PATCH v3 09/21] nptl: arm: Fix Race conditions in pthread cancellation (BZ#12683)
  2019-10-14 20:57 [PATCH v3 00/21] nptl: Fix Race conditions in pthread cancellation (BZ#12683) Adhemerval Zanella
                   ` (14 preceding siblings ...)
  2019-10-14 20:57 ` [PATCH v3 03/21] nptl: x86_64: " Adhemerval Zanella
@ 2019-10-14 20:57 ` Adhemerval Zanella
  2019-10-14 20:57 ` [PATCH v3 10/21] nptl: powerpc: " Adhemerval Zanella
                   ` (4 subsequent siblings)
  20 siblings, 0 replies; 38+ messages in thread
From: Adhemerval Zanella @ 2019-10-14 20:57 UTC (permalink / raw)
  To: libc-alpha

This patch adds the arm modifications required for the BZ#12683 fix
by adding the arch-specific cancellation syscall bridge.

Checked on arm-linux-gnueabihf.
---
 sysdeps/unix/sysv/linux/arm/syscall_cancel.S | 80 ++++++++++++++++++++
 1 file changed, 80 insertions(+)
 create mode 100644 sysdeps/unix/sysv/linux/arm/syscall_cancel.S

diff --git a/sysdeps/unix/sysv/linux/arm/syscall_cancel.S b/sysdeps/unix/sysv/linux/arm/syscall_cancel.S
new file mode 100644
index 0000000000..996334a4bb
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/arm/syscall_cancel.S
@@ -0,0 +1,80 @@
+/* Cancellable syscall wrapper.  Linux/arm version.
+   Copyright (C) 2019 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
+   <http://www.gnu.org/licenses/>.  */
+
+#include <sysdep.h>
+
+/* long int [r0] __syscall_cancel_arch (int *cancelhandling [r0],
+					long int nr   [r1],
+					long int arg1 [r2],
+					long int arg2 [r3],
+					long int arg3 [SP],
+					long int arg4 [SP+4],
+					long int arg5 [SP+8],
+					long int arg6 [SP+12])  */
+
+	.syntax unified
+
+ENTRY (__syscall_cancel_arch)
+	.fnstart
+	mov	ip, sp
+	stmfd	sp!, {r4, r5, r6, r7, lr}
+	.save	{r4, r5, r6, r7, lr}
+
+	cfi_adjust_cfa_offset (20)
+	cfi_rel_offset (r4, 0)
+	cfi_rel_offset (r5, 4)
+	cfi_rel_offset (r6, 8)
+	cfi_rel_offset (r7, 12)
+	cfi_rel_offset (lr, 16)
+
+	.globl __syscall_cancel_arch_start
+	.type  __syscall_cancel_arch_start,%function
+__syscall_cancel_arch_start:
+
+	/* if (*cancelhandling & CANCELED_BITMASK)
+	     __syscall_do_cancel()  */
+	ldr	r0, [r0]
+	tst	r0, #4
+	bne	1f
+
+	/* Issue a 6 argument syscall, the nr [r1] being the syscall
+	   number.  */
+	mov	r7, r1
+	mov	r0, r2
+	mov	r1, r3
+	ldmfd	ip, {r2, r3, r4, r5, r6}
+	svc	0x0
+
+	.globl __syscall_cancel_arch_end
+	.type  __syscall_cancel_arch_end,%function
+__syscall_cancel_arch_end:
+	ldmfd	sp!, {r4, r5, r6, r7, lr}
+	cfi_adjust_cfa_offset (-20)
+        cfi_restore (r4)
+        cfi_restore (r5)
+        cfi_restore (r6)
+        cfi_restore (r7)
+        cfi_restore (lr)
+	BX (lr)
+
+1:
+	ldmfd	sp!, {r4, r5, r6, r7, lr}
+	b	__syscall_do_cancel
+	.fnend
+END (__syscall_cancel_arch)
+libc_hidden_def (__syscall_cancel_arch)
-- 
2.17.1

^ permalink raw reply	[flat|nested] 38+ messages in thread

* [PATCH v3 13/21] nptl: hppa: Fix Race conditions in pthread cancellation (BZ#12683)
  2019-10-14 20:57 [PATCH v3 00/21] nptl: Fix Race conditions in pthread cancellation (BZ#12683) Adhemerval Zanella
                   ` (10 preceding siblings ...)
  2019-10-14 20:57 ` [PATCH v3 16/21] nptl: sh: Fix Race conditions in pthread cancellation (BZ#12683) Adhemerval Zanella
@ 2019-10-14 20:57 ` Adhemerval Zanella
  2019-10-14 20:57 ` [PATCH v3 06/21] nptl: mips: " Adhemerval Zanella
                   ` (8 subsequent siblings)
  20 siblings, 0 replies; 38+ messages in thread
From: Adhemerval Zanella @ 2019-10-14 20:57 UTC (permalink / raw)
  To: libc-alpha

This patch adds the hppa modifications required for the BZ#12683 fix
by adding the arch-specific cancellation syscall bridge.

Checked on hppa-linux-gnu.
---
 sysdeps/unix/sysv/linux/hppa/syscall_cancel.S | 82 +++++++++++++++++++
 1 file changed, 82 insertions(+)
 create mode 100644 sysdeps/unix/sysv/linux/hppa/syscall_cancel.S

diff --git a/sysdeps/unix/sysv/linux/hppa/syscall_cancel.S b/sysdeps/unix/sysv/linux/hppa/syscall_cancel.S
new file mode 100644
index 0000000000..14e1f5f0a7
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/hppa/syscall_cancel.S
@@ -0,0 +1,82 @@
+/* Cancellable syscall wrapper.  Linux/hppa version.
+   Copyright (C) 2019 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
+   <http://www.gnu.org/licenses/>.  */
+
+#include <sysdep.h>
+
+/* long int __syscall_cancel_arch (int *cancelhandling,
+				   long int nr,
+				   long int arg1,
+				   long int arg2,
+				   long int arg3,
+				   long int arg4,
+				   long int arg5,
+				   long int arg6)  */
+
+	.text
+ENTRY(__syscall_cancel_arch)
+	stw	%r2,-20(%r30)
+	ldo	128(%r30),%r30
+	cfi_def_cfa_offset (-128)
+	cfi_offset (2, -20)
+	ldw	-180(%r30),%r28
+	copy	%r24,%r31
+	stw	%r28,-104(%r30)
+	ldw	-184(%r30),%r28
+	stw	%r28,-108(%r30)
+	ldw	-188(%r30),%r28
+	stw	%r28,-112(%r30)
+	ldw	-192(%r30),%r28
+	stw	%r4,-100(%r30)
+	stw	%r28,-116(%r30)
+	copy	%r25,%r28
+	copy	%r23,%r25
+	stw	%r19,-32(%r30)
+	cfi_offset (4, 28)
+
+	.global __syscall_cancel_arch_start
+	.type   __syscall_cancel_arch_start,@function
+__syscall_cancel_arch_start:
+
+	ldw	0(%r26),%r20
+	stw	%r20,-120(%r30)
+	ldw	-120(%r30),%r20
+	bb,<	%r20,29,1f
+	ldw	-116(%r30),%r21
+	ldw	-112(%r30),%r22
+	copy	%r31,%r26
+	ldw	-108(%r30),%r23
+	ldw	-104(%r30),%r24
+	copy	%r19, %r4
+	ble	0x100(%sr2, %r0)
+
+	.global __syscall_cancel_arch_end
+	.type   __syscall_cancel_arch_end,@function
+__syscall_cancel_arch_end:
+
+	copy	%r28, %r20
+	copy	%r4, %r19
+	ldw	-148(%r30),%r2
+	ldw	-100(%r30),%r4
+	bv	%r0(%r2)
+	ldo	-128(%r30),%r30
+1:
+	bl	__syscall_do_cancel,%r2
+	nop
+	nop
+END(__syscall_cancel_arch)
+libc_hidden_def (__syscall_cancel_arch)
-- 
2.17.1

^ permalink raw reply	[flat|nested] 38+ messages in thread

* [PATCH v3 11/21] nptl: microblaze: Fix Race conditions in pthread cancellation (BZ#12683)
  2019-10-14 20:57 [PATCH v3 00/21] nptl: Fix Race conditions in pthread cancellation (BZ#12683) Adhemerval Zanella
                   ` (17 preceding siblings ...)
  2019-10-14 20:57 ` [PATCH v3 05/21] nptl: ia64: " Adhemerval Zanella
@ 2019-10-14 20:57 ` Adhemerval Zanella
  2019-10-14 20:57 ` [PATCH v3 17/21] nptl: riscv: " Adhemerval Zanella
  2019-10-14 20:58 ` [PATCH v3 21/21] Remove sysdep-cancel header Adhemerval Zanella
  20 siblings, 0 replies; 38+ messages in thread
From: Adhemerval Zanella @ 2019-10-14 20:57 UTC (permalink / raw)
  To: libc-alpha

This patch adds the microblaze modifications required for the BZ#12683 fix
by adding the arch-specific cancellation syscall bridge.

Checked against a build and make check run-built-tests=no for
microblaze-linux-gnu.
---
 .../sysv/linux/microblaze/syscall_cancel.S    | 64 +++++++++++++++++++
 1 file changed, 64 insertions(+)
 create mode 100644 sysdeps/unix/sysv/linux/microblaze/syscall_cancel.S

diff --git a/sysdeps/unix/sysv/linux/microblaze/syscall_cancel.S b/sysdeps/unix/sysv/linux/microblaze/syscall_cancel.S
new file mode 100644
index 0000000000..19f566ba61
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/microblaze/syscall_cancel.S
@@ -0,0 +1,64 @@
+/* Cancellable syscall wrapper.  Linux/microblaze version.
+   Copyright (C) 2019 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
+   <http://www.gnu.org/licenses/>.  */
+
+#include <sysdep.h>
+
+/* long int __syscall_cancel_arch (int *cancelhandling,
+				   long int nr,
+				   long int arg1,
+				   long int arg2,
+				   long int arg3,
+				   long int arg4,
+				   long int arg5,
+				   long int arg6)  */
+
+ENTRY (__syscall_cancel_arch)
+
+	.globl __syscall_cancel_arch_start
+	.type  __syscall_cancel_arch_start, @function
+__syscall_cancel_arch_start:
+
+	lwi	r3,r5,0
+	andi	r3,r3,4 #and1
+	bneid	r3,1f
+	addk	r12,r6,r0
+
+	addk	r5,r7,r0
+	addk	r6,r8,r0
+	addk	r7,r9,r0
+	addk	r8,r10,r0
+	lwi	r9,r1,56
+	lwi	r10,r1,60
+	brki	r14,8
+
+	.globl __syscall_cancel_arch_end
+	.type  __syscall_cancel_arch_end, @function
+__syscall_cancel_arch_end:
+
+	nop
+	lwi	r15,r1,0
+	rtsd	r15,8
+	addik	r1,r1,28
+
+1:
+	brlid	r15, __syscall_do_cancel
+	nop
+
+END (__syscall_cancel_arch)
+libc_hidden_def (__syscall_cancel_arch)
+
-- 
2.17.1

^ permalink raw reply	[flat|nested] 38+ messages in thread

* [PATCH v3 15/21] nptl: alpha: Fix Race conditions in pthread cancellation (BZ#12683)
  2019-10-14 20:57 [PATCH v3 00/21] nptl: Fix Race conditions in pthread cancellation (BZ#12683) Adhemerval Zanella
                   ` (6 preceding siblings ...)
  2019-10-14 20:57 ` [PATCH v3 14/21] nptl: m68k: Fix Race conditions in pthread cancellation (BZ#12683) Adhemerval Zanella
@ 2019-10-14 20:57 ` Adhemerval Zanella
  2019-10-17  3:01   ` Matt Turner
  2019-10-14 20:57 ` [PATCH v3 07/21] nptl: i386: " Adhemerval Zanella
                   ` (12 subsequent siblings)
  20 siblings, 1 reply; 38+ messages in thread
From: Adhemerval Zanella @ 2019-10-14 20:57 UTC (permalink / raw)
  To: libc-alpha

This patch adds the hppa modifications required for the BZ#12683 fix
by adding the arch-specific cancellation syscall bridge.

Checked on alpha-linux-gnu.
---
 .../unix/sysv/linux/alpha/syscall_cancel.S    | 82 +++++++++++++++++++
 1 file changed, 82 insertions(+)
 create mode 100644 sysdeps/unix/sysv/linux/alpha/syscall_cancel.S

diff --git a/sysdeps/unix/sysv/linux/alpha/syscall_cancel.S b/sysdeps/unix/sysv/linux/alpha/syscall_cancel.S
new file mode 100644
index 0000000000..e497b1c805
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/alpha/syscall_cancel.S
@@ -0,0 +1,82 @@
+/* Cancellable syscall wrapper.  Linux/alpha version.
+   Copyright (C) 2019 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
+   <http://www.gnu.org/licenses/>.  */
+
+#include <sysdep.h>
+
+/* long int __syscall_cancel_arch (int *cancelhandling,
+				   __syscall_arg_t nr,
+				   __syscall_arg_t arg1,
+				   __syscall_arg_t arg2,
+				   __syscall_arg_t arg3,
+				   __syscall_arg_t arg4,
+				   __syscall_arg_t arg5,
+				   __syscall_arg_t arg6,
+				   __syscall_arg_t arg7)  */
+
+	.set noreorder
+	.set noat
+	.set nomacro
+ENTRY (__syscall_cancel_arch)
+	.frame	sp, 16, ra, 0
+	.mask	0x4000000,-16
+	cfi_startproc
+	ldah	gp, 0(t12)
+	lda	gp, 0(gp)
+	lda	sp, -16(sp)
+	cfi_def_cfa_offset (16)
+	mov	a1, v0
+	stq	ra, 0(sp)
+	cfi_offset (26, -16)
+	.prologue 1
+
+	.global	__syscall_cancel_arch_start
+	.type	__syscall_cancel_arch_start,%function
+__syscall_cancel_arch_start:
+	ldl	t0, 0(a0)
+	addl	zero, t0, t0
+	and	t0, 0x4, t0	/* if (*ch & CANCELED_BITMASK)  */
+	bne	t0, 1f
+	mov	a2, a0
+	mov	a3, a1
+	mov	a4, a2
+	ldq	a4, 16(sp)
+	mov	a5, a3
+	ldq	a5, 24(sp)
+	.set	macro
+	callsys
+	.set	nomacro
+
+	.global __syscall_cancel_arch_end
+	.type	__syscall_cancel_arch_end,%function
+__syscall_cancel_arch_end:
+	subq	zero, v0, t0
+	ldq	ra, 0(sp)
+	cmovne	a3, t0, v0
+	lda	sp, 16(sp)
+	cfi_remember_state
+	cfi_restore (26)
+	cfi_def_cfa_offset (0)
+	ret	zero, (ra), 1
+	.align 4
+1:
+	cfi_restore_state
+	ldq 	t12, __syscall_do_cancel(gp)		!literal!2
+	jsr 	ra, (t12), __syscall_do_cancel		!lituse_jsr!2
+	cfi_endproc
+END (__syscall_cancel_arch)
+libc_hidden_def (__syscall_cancel_arch)
-- 
2.17.1

^ permalink raw reply	[flat|nested] 38+ messages in thread

* [PATCH v3 16/21] nptl: sh: Fix Race conditions in pthread cancellation (BZ#12683)
  2019-10-14 20:57 [PATCH v3 00/21] nptl: Fix Race conditions in pthread cancellation (BZ#12683) Adhemerval Zanella
                   ` (9 preceding siblings ...)
  2019-10-14 20:57 ` [PATCH v3 01/21] nptl: Handle EPIPE on tst-cancel2 Adhemerval Zanella
@ 2019-10-14 20:57 ` Adhemerval Zanella
  2019-10-14 20:57 ` [PATCH v3 13/21] nptl: hppa: " Adhemerval Zanella
                   ` (9 subsequent siblings)
  20 siblings, 0 replies; 38+ messages in thread
From: Adhemerval Zanella @ 2019-10-14 20:57 UTC (permalink / raw)
  To: libc-alpha

This patch adds the sh modifications required for the BZ#12683 fix
by adding the arch-specific cancellation syscall bridge.

Checked against a build and make check run-built-tests=no for
sh4-linux-gnu.
---
 sysdeps/sh/sysdep.h                         |   1 +
 sysdeps/unix/sysv/linux/sh/syscall_cancel.S | 128 ++++++++++++++++++++
 2 files changed, 129 insertions(+)
 create mode 100644 sysdeps/unix/sysv/linux/sh/syscall_cancel.S

diff --git a/sysdeps/sh/sysdep.h b/sysdeps/sh/sysdep.h
index 2f109b241e..31b7f312cd 100644
--- a/sysdeps/sh/sysdep.h
+++ b/sysdeps/sh/sysdep.h
@@ -24,6 +24,7 @@
 
 #define ALIGNARG(log2) log2
 #define ASM_SIZE_DIRECTIVE(name) .size name,.-name
+#define L(label) .L##label
 
 #ifdef SHARED
 #define PLTJMP(_x)	_x##@PLT
diff --git a/sysdeps/unix/sysv/linux/sh/syscall_cancel.S b/sysdeps/unix/sysv/linux/sh/syscall_cancel.S
new file mode 100644
index 0000000000..3bdb939adb
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/sh/syscall_cancel.S
@@ -0,0 +1,128 @@
+/* Cancellable syscall wrapper.  Linux/sh version.
+   Copyright (C) 2019 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
+   <http://www.gnu.org/licenses/>.  */
+
+#include <sysdep.h>
+
+/* long int __syscall_cancel_arch (int *cancelhandling,
+				   long int nr,
+				   long int arg1,
+				   long int arg2,
+				   long int arg3,
+				   long int arg4,
+				   long int arg5,
+				   long int arg6)  */
+
+ENTRY (__syscall_cancel_arch)
+
+#ifdef SHARED
+	mov.l	r12,@-r15
+	cfi_def_cfa_offset (4)
+	cfi_offset (12, -4)
+	mova	L(GT),r0
+	mov.l	L(GT),r12
+	sts.l	pr,@-r15
+	cfi_def_cfa_offset (8)
+	cfi_offset (17, -8)
+	add	r0,r12
+#else
+	sts.l	pr,@-r15
+	cfi_def_cfa_offset (4)
+	cfi_offset (17, -4)
+#endif
+
+	.globl __syscall_cancel_arch_start
+	.type  __syscall_cancel_arch_start,@function
+__syscall_cancel_arch_start:
+
+	/* if (*cancelhandling & CANCELED_BITMASK)
+	     __syscall_do_cancel()  */
+	mov.l	@r4,r0
+	tst	#4,r0
+	bf/s	1f
+
+	/* Issue a 6 argument syscall.  */
+	mov	r5,r3
+	mov	r6,r4
+	mov	r7,r5
+#ifdef SHARED
+	mov.l	@(8,r15),r6
+	mov.l	@(12,r15),r7
+	mov.l	@(16,r15),r0
+	mov.l	@(20,r15),r1
+#else
+	mov.l	@(4,r15),r6
+	mov.l	@(8,r15),r7
+	mov.l	@(12,r15),r0
+	mov.l	@(16,r15),r1
+#endif
+	trapa	#0x16
+
+	.globl __syscall_cancel_arch_end
+	.type  __syscall_cancel_arch_end,@function
+__syscall_cancel_arch_end:
+
+	/* The additional or is a workaround for a hardware issue:
+  	   http://documentation.renesas.com/eng/products/mpumcu/tu/tnsh7456ae.pdf
+	 */
+	or	r0,r0
+	or	r0,r0
+	or	r0,r0
+	or	r0,r0
+	or	r0,r0
+
+	lds.l	@r15+,pr
+	cfi_remember_state
+	cfi_restore (17)
+#ifdef SHARED
+	cfi_def_cfa_offset (4)
+	rts
+	mov.l	@r15+,r12
+	cfi_def_cfa_offset (0)
+	cfi_restore (12)
+	.align 1
+1:
+	cfi_restore_state
+	mov.l	L(SC),r1
+	bsrf	r1
+L(M):
+	nop
+
+	.align 2
+L(GT):
+	.long	_GLOBAL_OFFSET_TABLE_
+L(SC):
+	.long	__syscall_do_cancel-(L(M)+2)
+#else
+	cfi_def_cfa_offset (0)
+	rts
+	nop
+
+	.align 1
+1:
+	cfi_restore_state
+	mov.l	2f,r1
+	jsr	@r1
+	nop
+
+	.align 2
+2:
+	.long	__syscall_do_cancel
+#endif
+
+END (__syscall_cancel_arch)
+libc_hidden_def (__syscall_cancel_arch)
-- 
2.17.1

^ permalink raw reply	[flat|nested] 38+ messages in thread

* [PATCH v3 05/21] nptl: ia64: Fix Race conditions in pthread cancellation (BZ#12683)
  2019-10-14 20:57 [PATCH v3 00/21] nptl: Fix Race conditions in pthread cancellation (BZ#12683) Adhemerval Zanella
                   ` (16 preceding siblings ...)
  2019-10-14 20:57 ` [PATCH v3 10/21] nptl: powerpc: " Adhemerval Zanella
@ 2019-10-14 20:57 ` Adhemerval Zanella
  2019-10-14 20:57 ` [PATCH v3 11/21] nptl: microblaze: " Adhemerval Zanella
                   ` (2 subsequent siblings)
  20 siblings, 0 replies; 38+ messages in thread
From: Adhemerval Zanella @ 2019-10-14 20:57 UTC (permalink / raw)
  To: libc-alpha

This patch adds the ia64 modifications required for the BZ#12683 fix.

The syscall bridge uses the old brk 0x10000 instruction because by
using the vDSO gate the resulting PC value for an interrupted syscall
points to an address outside the expected markers in
__syscall_cancel_arch.  This is similar to i686 issue.

Also the __syscall_cancel_arch issues the 'break 0x100000' on its own
bundle, and __syscall_cancel_arch_end points to end of the previous one.
It requires an arch-specific ucontext_check_pc_boundary to check for the
ri value (embedded in the sc_ip by the kernel) to check if the syscall
had any side-effects.

Also, ia64 issues a sigcontext as third argument for sigaction handler
with SA_SIGINFO which requires an arch-specific ucontext_add_cancel.

Checked on ia64-linux-gnu.
---
 .../sysv/linux/ia64/cancellation-pc-check.h   | 48 +++++++++++
 .../sysv/linux/ia64/cancellation-sigmask.h    | 33 ++++++++
 sysdeps/unix/sysv/linux/ia64/syscall_cancel.S | 83 +++++++++++++++++++
 3 files changed, 164 insertions(+)
 create mode 100644 sysdeps/unix/sysv/linux/ia64/cancellation-pc-check.h
 create mode 100644 sysdeps/unix/sysv/linux/ia64/cancellation-sigmask.h
 create mode 100644 sysdeps/unix/sysv/linux/ia64/syscall_cancel.S

diff --git a/sysdeps/unix/sysv/linux/ia64/cancellation-pc-check.h b/sysdeps/unix/sysv/linux/ia64/cancellation-pc-check.h
new file mode 100644
index 0000000000..bbd0c99fe1
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/ia64/cancellation-pc-check.h
@@ -0,0 +1,48 @@
+/* Architecture specific bits for cancellation handling.
+   Copyright (C) 2019 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
+   <http://www.gnu.org/licenses/>.  */
+
+#ifndef _NPTL_CANCELLATION_PC_CHECK
+#define _NPTL_CANCELLATION_PC_CHECK 1
+
+/* Check if the program counter (PC) from ucontext CTX is within the start and
+   then end boundary from the __syscall_cancel_arch bridge.  Return TRUE if
+   the PC is within the boundary, meaning the syscall does not have any side
+   effects; or FALSE otherwise.  */
+static bool
+ucontext_check_pc_boundary (void *ctx)
+{
+  /* Both are defined in syscall_cancel.S for each architecture.  */
+  extern const char __syscall_cancel_arch_start[1];
+  extern const char __syscall_cancel_arch_end[1];
+
+  uintptr_t sc_ip = ((struct sigcontext *) (ctx))->sc_ip;
+  uintptr_t cr_iip = sc_ip & ~0x3ull;
+  uintptr_t ri = sc_ip & 0x3ull;
+
+  /* IA64 __syscall_cancel_arch issues the 'break 0x100000' on its own bundle,
+     and __syscall_cancel_arch_end points to end of the previous bundle.
+     To check if the syscall had any side-effects we need to check the slot
+     number.  */
+  if (cr_iip == (uintptr_t) __syscall_cancel_arch_end)
+    return ri == 0;
+
+  return cr_iip >= (uintptr_t) __syscall_cancel_arch_start
+	 && cr_iip < (uintptr_t) __syscall_cancel_arch_end;
+}
+
+#endif
diff --git a/sysdeps/unix/sysv/linux/ia64/cancellation-sigmask.h b/sysdeps/unix/sysv/linux/ia64/cancellation-sigmask.h
new file mode 100644
index 0000000000..300f090a82
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/ia64/cancellation-sigmask.h
@@ -0,0 +1,33 @@
+/* Architecture specific bits for cancellation handling.
+   Copyright (C) 2019 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
+   <http://www.gnu.org/licenses/>.  */
+
+#ifndef _NPTL_CANCELLATION_SIGMASK_H
+#define _NPTL_CANCELLATION_SIGMASK_H 1
+
+/* Add the SIGCANCEL signal on sigmask set at the ucontext CTX obtained from
+   the sigaction handler.  */
+static void
+ucontext_add_cancel (void *ctx)
+{
+  /* IA64 issues a sigcontext as third argument for sigaction handler (instead
+     of usual ucontext_t).  */
+  struct sigcontext *sctx = (struct sigcontext *) (ctx);
+  __sigaddset ((sigset_t *) &sctx->sc_mask, SIGCANCEL);
+}
+
+#endif
diff --git a/sysdeps/unix/sysv/linux/ia64/syscall_cancel.S b/sysdeps/unix/sysv/linux/ia64/syscall_cancel.S
new file mode 100644
index 0000000000..bf6ec105db
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/ia64/syscall_cancel.S
@@ -0,0 +1,83 @@
+/* Cancellable syscall wrapper.  Linux/IA64 version.
+   Copyright (C) 2019 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
+   <http://www.gnu.org/licenses/>.  */
+
+#include <sysdep.h>
+#undef ret
+
+/* long int __syscall_cancel_arch (int *cancelhandling, long int nr,
+				   long int arg1, long int arg2, long int arg3,
+				   long int arg4, long int arg5, long int arg6)
+*/
+
+ENTRY (__syscall_cancel_arch)
+	.prologue ASM_UNW_PRLG_RP | ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE (8)
+	.mmi
+	.save ar.pfs, r41
+	alloc r41=ar.pfs,8,3,8,0
+	mov r15=r33
+	.save rp, r40
+	mov r40=b0
+	.body
+	.mmi
+	mov r43=r34
+	mov r44=r35
+	mov r45=r36
+	;;
+	.mmi
+	mov r46=r37
+	mov r47=r38
+	mov r48=r39
+	;;
+
+	.global __syscall_cancel_arch_start
+	.type __syscall_cancel_arch_start,@function
+__syscall_cancel_arch_start:
+	;;
+	.mmi
+	nop 0
+	ld4.acq r14=[r32]
+	nop 0
+	;;
+	.mib
+	nop 0
+	tbit.z p6, p7=r14, 2
+	.pred.safe_across_calls p1-p63
+(p7)	br.call.dpnt.many b0 = __syscall_do_cancel#
+	.pred.safe_across_calls p1-p5,p16-p63
+	;;
+
+	/* Due instruction bundle ia64 has the end marker before the syscall
+           instruction.  Check IA64 ucontext_check_pc_boundary on how the PC
+           is checked.  */
+	.global __syscall_cancel_arch_end
+	.type __syscall_cancel_arch_end,@function
+__syscall_cancel_arch_end:
+	break 0x100000
+	;;
+	.mmi
+	cmp.ne p6, p7=-1, r10
+	nop 0
+	mov b0=r40
+	;;
+	.mib
+(p7)	sub r8=r0, r8
+	mov ar.pfs=r41
+	br.ret.sptk.many b0
+
+END (__syscall_cancel_arch)
+libc_hidden_def (__syscall_cancel_arch)
-- 
2.17.1

^ permalink raw reply	[flat|nested] 38+ messages in thread

* [PATCH v3 21/21] Remove sysdep-cancel header
  2019-10-14 20:57 [PATCH v3 00/21] nptl: Fix Race conditions in pthread cancellation (BZ#12683) Adhemerval Zanella
                   ` (19 preceding siblings ...)
  2019-10-14 20:57 ` [PATCH v3 17/21] nptl: riscv: " Adhemerval Zanella
@ 2019-10-14 20:58 ` Adhemerval Zanella
  20 siblings, 0 replies; 38+ messages in thread
From: Adhemerval Zanella @ 2019-10-14 20:58 UTC (permalink / raw)
  To: libc-alpha

Now that single-thread optimization is provided by single-thread.h header
and the enable/disable asynchronous cancellation functions are no longer
used on cancellable syscalls, the header can be removed.

Checked with a build for all major Linux architectures and for hurd.
---
 elf/dl-close.c                               |  1 -
 elf/dl-lookup.c                              |  1 -
 elf/dl-open.c                                |  1 -
 elf/dl-runtime.c                             |  1 -
 elf/dl-scope.c                               |  1 -
 elf/dl-sym.c                                 |  1 -
 io/creat.c                                   |  1 -
 io/ppoll.c                                   |  1 -
 malloc/malloc.c                              |  3 -
 misc/pselect.c                               |  1 -
 nptl/thrd_sleep.c                            |  1 -
 sysdeps/generic/sysdep-cancel.h              |  5 --
 sysdeps/mach/hurd/sysdep-cancel.h            |  8 ---
 sysdeps/mips/dl-trampoline.c                 |  1 -
 sysdeps/posix/open64.c                       |  1 -
 sysdeps/posix/pause.c                        |  1 -
 sysdeps/posix/sigpause.c                     |  1 -
 sysdeps/posix/sigwait.c                      |  1 -
 sysdeps/posix/waitid.c                       |  1 -
 sysdeps/unix/clock_nanosleep.c               |  1 -
 sysdeps/unix/sysv/linux/accept.c             |  1 -
 sysdeps/unix/sysv/linux/accept4.c            |  1 -
 sysdeps/unix/sysv/linux/access.c             |  2 +-
 sysdeps/unix/sysv/linux/alpha/select.c       |  1 -
 sysdeps/unix/sysv/linux/clock_nanosleep.c    |  1 -
 sysdeps/unix/sysv/linux/close.c              |  1 -
 sysdeps/unix/sysv/linux/close_nocancel.c     |  1 -
 sysdeps/unix/sysv/linux/connect.c            |  1 -
 sysdeps/unix/sysv/linux/copy_file_range.c    |  1 -
 sysdeps/unix/sysv/linux/creat.c              |  1 -
 sysdeps/unix/sysv/linux/creat64.c            |  1 -
 sysdeps/unix/sysv/linux/epoll_pwait.c        |  1 -
 sysdeps/unix/sysv/linux/epoll_wait.c         |  1 -
 sysdeps/unix/sysv/linux/fallocate.c          |  1 -
 sysdeps/unix/sysv/linux/fallocate64.c        |  1 -
 sysdeps/unix/sysv/linux/fcntl.c              |  1 -
 sysdeps/unix/sysv/linux/fcntl64.c            |  1 -
 sysdeps/unix/sysv/linux/fcntl_nocancel.c     |  1 -
 sysdeps/unix/sysv/linux/fdatasync.c          |  2 +-
 sysdeps/unix/sysv/linux/fsync.c              |  2 +-
 sysdeps/unix/sysv/linux/futex-internal.h     |  1 -
 sysdeps/unix/sysv/linux/getrandom.c          |  1 -
 sysdeps/unix/sysv/linux/lowlevellock-futex.h |  1 -
 sysdeps/unix/sysv/linux/mq_timedreceive.c    |  2 +-
 sysdeps/unix/sysv/linux/mq_timedsend.c       |  2 +-
 sysdeps/unix/sysv/linux/msgrcv.c             |  2 +-
 sysdeps/unix/sysv/linux/msgsnd.c             |  2 +-
 sysdeps/unix/sysv/linux/msync.c              |  2 +-
 sysdeps/unix/sysv/linux/nanosleep.c          |  3 +-
 sysdeps/unix/sysv/linux/nanosleep_nocancel.c |  1 -
 sysdeps/unix/sysv/linux/open.c               |  3 +-
 sysdeps/unix/sysv/linux/open64.c             |  4 +-
 sysdeps/unix/sysv/linux/open_by_handle_at.c  |  2 +-
 sysdeps/unix/sysv/linux/open_nocancel.c      |  1 -
 sysdeps/unix/sysv/linux/openat.c             |  3 +-
 sysdeps/unix/sysv/linux/openat64.c           |  3 +-
 sysdeps/unix/sysv/linux/openat64_nocancel.c  |  1 -
 sysdeps/unix/sysv/linux/openat_nocancel.c    |  1 -
 sysdeps/unix/sysv/linux/pause.c              |  2 +-
 sysdeps/unix/sysv/linux/pause_nocancel.c     |  1 -
 sysdeps/unix/sysv/linux/poll.c               |  1 -
 sysdeps/unix/sysv/linux/ppoll.c              |  2 -
 sysdeps/unix/sysv/linux/pread.c              |  2 +-
 sysdeps/unix/sysv/linux/pread64.c            |  2 +-
 sysdeps/unix/sysv/linux/preadv.c             |  2 +-
 sysdeps/unix/sysv/linux/preadv2.c            |  2 +-
 sysdeps/unix/sysv/linux/preadv64.c           |  2 +-
 sysdeps/unix/sysv/linux/preadv64v2.c         |  2 +-
 sysdeps/unix/sysv/linux/pselect.c            |  2 -
 sysdeps/unix/sysv/linux/pwrite.c             |  2 +-
 sysdeps/unix/sysv/linux/pwrite64.c           |  2 +-
 sysdeps/unix/sysv/linux/pwritev.c            |  2 +-
 sysdeps/unix/sysv/linux/pwritev2.c           |  2 +-
 sysdeps/unix/sysv/linux/pwritev64.c          |  2 +-
 sysdeps/unix/sysv/linux/pwritev64v2.c        |  2 +-
 sysdeps/unix/sysv/linux/read.c               |  2 +-
 sysdeps/unix/sysv/linux/read_nocancel.c      |  1 -
 sysdeps/unix/sysv/linux/readv.c              |  2 +-
 sysdeps/unix/sysv/linux/recv.c               |  1 -
 sysdeps/unix/sysv/linux/recvfrom.c           |  1 -
 sysdeps/unix/sysv/linux/recvmmsg.c           |  1 -
 sysdeps/unix/sysv/linux/recvmsg.c            |  1 -
 sysdeps/unix/sysv/linux/select.c             |  1 -
 sysdeps/unix/sysv/linux/send.c               |  1 -
 sysdeps/unix/sysv/linux/sendmmsg.c           |  1 -
 sysdeps/unix/sysv/linux/sendmsg.c            |  1 -
 sysdeps/unix/sysv/linux/sendto.c             |  1 -
 sysdeps/unix/sysv/linux/sigsuspend.c         |  2 +-
 sysdeps/unix/sysv/linux/sigtimedwait.c       |  1 -
 sysdeps/unix/sysv/linux/sigwait.c            |  1 -
 sysdeps/unix/sysv/linux/sigwaitinfo.c        |  1 -
 sysdeps/unix/sysv/linux/socketcall.h         |  2 +
 sysdeps/unix/sysv/linux/splice.c             |  2 +-
 sysdeps/unix/sysv/linux/sync_file_range.c    |  2 +-
 sysdeps/unix/sysv/linux/sysdep-cancel.h      | 67 --------------------
 sysdeps/unix/sysv/linux/tcdrain.c            |  1 -
 sysdeps/unix/sysv/linux/tee.c                |  2 +-
 sysdeps/unix/sysv/linux/timer_routines.c     |  1 -
 sysdeps/unix/sysv/linux/vmsplice.c           |  2 +-
 sysdeps/unix/sysv/linux/wait.c               |  1 -
 sysdeps/unix/sysv/linux/waitid.c             |  1 -
 sysdeps/unix/sysv/linux/waitpid.c            |  1 -
 sysdeps/unix/sysv/linux/waitpid_nocancel.c   |  1 -
 sysdeps/unix/sysv/linux/write.c              |  2 +-
 sysdeps/unix/sysv/linux/write_nocancel.c     |  1 -
 sysdeps/unix/sysv/linux/writev.c             |  2 +-
 106 files changed, 38 insertions(+), 192 deletions(-)
 delete mode 100644 sysdeps/generic/sysdep-cancel.h
 delete mode 100644 sysdeps/mach/hurd/sysdep-cancel.h
 delete mode 100644 sysdeps/unix/sysv/linux/sysdep-cancel.h

diff --git a/elf/dl-close.c b/elf/dl-close.c
index de91c28f72..dfe2bc9be4 100644
--- a/elf/dl-close.c
+++ b/elf/dl-close.c
@@ -29,7 +29,6 @@
 #include <ldsodefs.h>
 #include <sys/types.h>
 #include <sys/mman.h>
-#include <sysdep-cancel.h>
 #include <tls.h>
 #include <stap-probe.h>
 
diff --git a/elf/dl-lookup.c b/elf/dl-lookup.c
index fd44cd4101..ff5c811550 100644
--- a/elf/dl-lookup.c
+++ b/elf/dl-lookup.c
@@ -24,7 +24,6 @@
 #include <ldsodefs.h>
 #include <dl-hash.h>
 #include <dl-machine.h>
-#include <sysdep-cancel.h>
 #include <libc-lock.h>
 #include <tls.h>
 #include <atomic.h>
diff --git a/elf/dl-open.c b/elf/dl-open.c
index a9fd4cbced..2b35209dfd 100644
--- a/elf/dl-open.c
+++ b/elf/dl-open.c
@@ -28,7 +28,6 @@
 #include <sys/param.h>
 #include <libc-lock.h>
 #include <ldsodefs.h>
-#include <sysdep-cancel.h>
 #include <tls.h>
 #include <stap-probe.h>
 #include <atomic.h>
diff --git a/elf/dl-runtime.c b/elf/dl-runtime.c
index 342b794f54..9dedd193de 100644
--- a/elf/dl-runtime.c
+++ b/elf/dl-runtime.c
@@ -23,7 +23,6 @@
 #include <unistd.h>
 #include <sys/param.h>
 #include <ldsodefs.h>
-#include <sysdep-cancel.h>
 #include "dynamic-link.h"
 #include <tls.h>
 #include <dl-irel.h>
diff --git a/elf/dl-scope.c b/elf/dl-scope.c
index f4ba0898df..dff4b1b51b 100644
--- a/elf/dl-scope.c
+++ b/elf/dl-scope.c
@@ -18,7 +18,6 @@
 
 #include <stdlib.h>
 #include <ldsodefs.h>
-#include <sysdep-cancel.h>
 
 
 int
diff --git a/elf/dl-sym.c b/elf/dl-sym.c
index 8209342b13..af1f8549a3 100644
--- a/elf/dl-sym.c
+++ b/elf/dl-sym.c
@@ -25,7 +25,6 @@
 #include <dlfcn.h>
 #include <ldsodefs.h>
 #include <dl-hash.h>
-#include <sysdep-cancel.h>
 #include <dl-tls.h>
 #include <dl-irel.h>
 
diff --git a/io/creat.c b/io/creat.c
index 8e4f0cf2c4..3a93b0947f 100644
--- a/io/creat.c
+++ b/io/creat.c
@@ -17,7 +17,6 @@
 
 #include <fcntl.h>
 #include <sys/types.h>
-#include <sysdep-cancel.h>
 
 #undef	creat
 
diff --git a/io/ppoll.c b/io/ppoll.c
index a387924eeb..f66913f7c7 100644
--- a/io/ppoll.c
+++ b/io/ppoll.c
@@ -21,7 +21,6 @@
 #include <signal.h>
 #include <stddef.h>	/* For NULL.  */
 #include <sys/poll.h>
-#include <sysdep-cancel.h>
 
 
 int
diff --git a/malloc/malloc.c b/malloc/malloc.c
index 5d3e82a8f6..69dac97f28 100644
--- a/malloc/malloc.c
+++ b/malloc/malloc.c
@@ -244,9 +244,6 @@
 
 #include <malloc/malloc-internal.h>
 
-/* For SINGLE_THREAD_P.  */
-#include <sysdep-cancel.h>
-
 /*
   Debugging:
 
diff --git a/misc/pselect.c b/misc/pselect.c
index 76ded850a5..f3939c91a2 100644
--- a/misc/pselect.c
+++ b/misc/pselect.c
@@ -21,7 +21,6 @@
 #include <stddef.h>	/* For NULL.  */
 #include <sys/time.h>
 #include <sys/select.h>
-#include <sysdep-cancel.h>
 
 
 /* Check the first NFDS descriptors each in READFDS (if not NULL) for read
diff --git a/nptl/thrd_sleep.c b/nptl/thrd_sleep.c
index 75c0d53f3e..cfae149bf5 100644
--- a/nptl/thrd_sleep.c
+++ b/nptl/thrd_sleep.c
@@ -17,7 +17,6 @@
    <https://www.gnu.org/licenses/>.  */
 
 #include <time.h>
-#include <sysdep-cancel.h>
 
 #include "thrd_priv.h"
 
diff --git a/sysdeps/generic/sysdep-cancel.h b/sysdeps/generic/sysdep-cancel.h
deleted file mode 100644
index 5c84b4499a..0000000000
--- a/sysdeps/generic/sysdep-cancel.h
+++ /dev/null
@@ -1,5 +0,0 @@
-#include <sysdep.h>
-
-/* No multi-thread handling enabled.  */
-#define SINGLE_THREAD_P (1)
-#define RTLD_SINGLE_THREAD_P (1)
diff --git a/sysdeps/mach/hurd/sysdep-cancel.h b/sysdeps/mach/hurd/sysdep-cancel.h
deleted file mode 100644
index f686a39024..0000000000
--- a/sysdeps/mach/hurd/sysdep-cancel.h
+++ /dev/null
@@ -1,8 +0,0 @@
-#include <sysdep.h>
-
-/* Always multi-thread (since there's at least the sig handler), but no
-   handling enabled.  */
-#define SINGLE_THREAD_P (0)
-#define RTLD_SINGLE_THREAD_P (0)
-#define LIBC_CANCEL_ASYNC()	0 /* Just a dummy value.  */
-#define LIBC_CANCEL_RESET(val)	((void)(val)) /* Nothing, but evaluate it.  */
diff --git a/sysdeps/mips/dl-trampoline.c b/sysdeps/mips/dl-trampoline.c
index 74a2bffdc3..9655ec6de1 100644
--- a/sysdeps/mips/dl-trampoline.c
+++ b/sysdeps/mips/dl-trampoline.c
@@ -24,7 +24,6 @@
 #include <elf.h>
 #include <ldsodefs.h>
 #include <dl-machine.h>
-#include <sysdep-cancel.h>
 
 /* Get link map for callers object containing STUB_PC.  */
 static inline struct link_map *
diff --git a/sysdeps/posix/open64.c b/sysdeps/posix/open64.c
index d163b590bc..34b78a65ae 100644
--- a/sysdeps/posix/open64.c
+++ b/sysdeps/posix/open64.c
@@ -17,7 +17,6 @@
 
 #include <fcntl.h>
 #include <stdarg.h>
-#include <sysdep-cancel.h>
 
 /* Open FILE with access OFLAG.  If O_CREAT or O_TMPFILE is in OFLAG,
    a third argument is the file protection.  */
diff --git a/sysdeps/posix/pause.c b/sysdeps/posix/pause.c
index a3c050dc77..601a596b79 100644
--- a/sysdeps/posix/pause.c
+++ b/sysdeps/posix/pause.c
@@ -18,7 +18,6 @@
 
 #include <signal.h>
 #include <unistd.h>
-#include <sysdep-cancel.h>
 #include <sigsetops.h>
 
 /* Suspend the process until a signal arrives.
diff --git a/sysdeps/posix/sigpause.c b/sysdeps/posix/sigpause.c
index 2d11e011fa..a9e1576c46 100644
--- a/sysdeps/posix/sigpause.c
+++ b/sysdeps/posix/sigpause.c
@@ -22,7 +22,6 @@
 #undef sigpause
 
 #include <sigset-cvt-mask.h>
-#include <sysdep-cancel.h>
 
 int
 __sigpause (int sig_or_mask, int is_sig)
diff --git a/sysdeps/posix/sigwait.c b/sysdeps/posix/sigwait.c
index 675e59fd7a..886fbab66f 100644
--- a/sysdeps/posix/sigwait.c
+++ b/sysdeps/posix/sigwait.c
@@ -20,7 +20,6 @@
 #include <errno.h>
 #include <signal.h>
 #include <stddef.h>		/* For NULL.  */
-#include <sysdep-cancel.h>
 
 /* This is our dummy signal handler we use here.  */
 static void ignore_signal (int sig);
diff --git a/sysdeps/posix/waitid.c b/sysdeps/posix/waitid.c
index 0942623553..3dc0a7cb57 100644
--- a/sysdeps/posix/waitid.c
+++ b/sysdeps/posix/waitid.c
@@ -24,7 +24,6 @@
 #include <stddef.h>
 #include <sys/wait.h>
 #include <sys/types.h>
-#include <sysdep-cancel.h>
 
 
 #ifdef DO_WAITID
diff --git a/sysdeps/unix/clock_nanosleep.c b/sysdeps/unix/clock_nanosleep.c
index 95b4956b12..014a24ab14 100644
--- a/sysdeps/unix/clock_nanosleep.c
+++ b/sysdeps/unix/clock_nanosleep.c
@@ -19,7 +19,6 @@
 #include <assert.h>
 #include <errno.h>
 #include <time.h>
-#include <sysdep-cancel.h>
 #include <shlib-compat.h>
 
 /* This implementation assumes that these is only a `nanosleep' system
diff --git a/sysdeps/unix/sysv/linux/accept.c b/sysdeps/unix/sysv/linux/accept.c
index 9fb6966dff..6dc00deb97 100644
--- a/sysdeps/unix/sysv/linux/accept.c
+++ b/sysdeps/unix/sysv/linux/accept.c
@@ -16,7 +16,6 @@
    <https://www.gnu.org/licenses/>.  */
 
 #include <sys/socket.h>
-#include <sysdep-cancel.h>
 #include <socketcall.h>
 
 int
diff --git a/sysdeps/unix/sysv/linux/accept4.c b/sysdeps/unix/sysv/linux/accept4.c
index 963be98d43..e305ef42ad 100644
--- a/sysdeps/unix/sysv/linux/accept4.c
+++ b/sysdeps/unix/sysv/linux/accept4.c
@@ -20,7 +20,6 @@
 #include <signal.h>
 #include <sys/socket.h>
 
-#include <sysdep-cancel.h>
 #include <sys/syscall.h>
 #include <socketcall.h>
 #include <kernel-features.h>
diff --git a/sysdeps/unix/sysv/linux/access.c b/sysdeps/unix/sysv/linux/access.c
index 690c99a856..ef34824fb1 100644
--- a/sysdeps/unix/sysv/linux/access.c
+++ b/sysdeps/unix/sysv/linux/access.c
@@ -18,7 +18,7 @@
 
 #include <fcntl.h>
 #include <unistd.h>
-#include <sysdep-cancel.h>
+#include <sysdep.h>
 
 int
 __access (const char *file, int type)
diff --git a/sysdeps/unix/sysv/linux/alpha/select.c b/sysdeps/unix/sysv/linux/alpha/select.c
index 2c4fc4c160..e4ed853df9 100644
--- a/sysdeps/unix/sysv/linux/alpha/select.c
+++ b/sysdeps/unix/sysv/linux/alpha/select.c
@@ -20,7 +20,6 @@
 #include <sys/types.h>
 #include <sys/select.h>
 #include <errno.h>
-#include <sysdep-cancel.h>
 #include <shlib-compat.h>
 
 int
diff --git a/sysdeps/unix/sysv/linux/clock_nanosleep.c b/sysdeps/unix/sysv/linux/clock_nanosleep.c
index ddcdddcd5d..0146bc6a37 100644
--- a/sysdeps/unix/sysv/linux/clock_nanosleep.c
+++ b/sysdeps/unix/sysv/linux/clock_nanosleep.c
@@ -18,7 +18,6 @@
 #include <time.h>
 #include <errno.h>
 
-#include <sysdep-cancel.h>
 #include "kernel-posix-cpu-timers.h"
 
 #include <shlib-compat.h>
diff --git a/sysdeps/unix/sysv/linux/close.c b/sysdeps/unix/sysv/linux/close.c
index 0e387a340a..58818eadfd 100644
--- a/sysdeps/unix/sysv/linux/close.c
+++ b/sysdeps/unix/sysv/linux/close.c
@@ -17,7 +17,6 @@
    <https://www.gnu.org/licenses/>.  */
 
 #include <unistd.h>
-#include <sysdep-cancel.h>
 #include <not-cancel.h>
 
 /* Close the file descriptor FD.  */
diff --git a/sysdeps/unix/sysv/linux/close_nocancel.c b/sysdeps/unix/sysv/linux/close_nocancel.c
index bb288199e6..171dfc315a 100644
--- a/sysdeps/unix/sysv/linux/close_nocancel.c
+++ b/sysdeps/unix/sysv/linux/close_nocancel.c
@@ -17,7 +17,6 @@
    <https://www.gnu.org/licenses/>.  */
 
 #include <unistd.h>
-#include <sysdep-cancel.h>
 #include <not-cancel.h>
 
 int
diff --git a/sysdeps/unix/sysv/linux/connect.c b/sysdeps/unix/sysv/linux/connect.c
index 4ada43037d..ec95e4a444 100644
--- a/sysdeps/unix/sysv/linux/connect.c
+++ b/sysdeps/unix/sysv/linux/connect.c
@@ -16,7 +16,6 @@
    <https://www.gnu.org/licenses/>.  */
 
 #include <sys/socket.h>
-#include <sysdep-cancel.h>
 #include <socketcall.h>
 
 int
diff --git a/sysdeps/unix/sysv/linux/copy_file_range.c b/sysdeps/unix/sysv/linux/copy_file_range.c
index 9bbed6bd9e..9361b8e8e3 100644
--- a/sysdeps/unix/sysv/linux/copy_file_range.c
+++ b/sysdeps/unix/sysv/linux/copy_file_range.c
@@ -17,7 +17,6 @@
    <https://www.gnu.org/licenses/>.  */
 
 #include <errno.h>
-#include <sysdep-cancel.h>
 #include <unistd.h>
 
 ssize_t
diff --git a/sysdeps/unix/sysv/linux/creat.c b/sysdeps/unix/sysv/linux/creat.c
index e55514999e..35ad07594d 100644
--- a/sysdeps/unix/sysv/linux/creat.c
+++ b/sysdeps/unix/sysv/linux/creat.c
@@ -19,7 +19,6 @@
 #include <fcntl.h>
 #include <sys/types.h>
 
-#include <sysdep-cancel.h>
 
 #ifndef __OFF_T_MATCHES_OFF64_T
 
diff --git a/sysdeps/unix/sysv/linux/creat64.c b/sysdeps/unix/sysv/linux/creat64.c
index 6b95e7e6de..721ae13632 100644
--- a/sysdeps/unix/sysv/linux/creat64.c
+++ b/sysdeps/unix/sysv/linux/creat64.c
@@ -18,7 +18,6 @@
 
 #include <fcntl.h>
 #include <sys/types.h>
-#include <sysdep-cancel.h>
 
 /* Create FILE with protections MODE.  */
 int
diff --git a/sysdeps/unix/sysv/linux/epoll_pwait.c b/sysdeps/unix/sysv/linux/epoll_pwait.c
index 74d845f436..ab7edb4b69 100644
--- a/sysdeps/unix/sysv/linux/epoll_pwait.c
+++ b/sysdeps/unix/sysv/linux/epoll_pwait.c
@@ -20,7 +20,6 @@
 #include <unistd.h>
 #include <sys/epoll.h>
 
-#include <sysdep-cancel.h>
 #include <sys/syscall.h>
 
 #ifdef __NR_epoll_pwait
diff --git a/sysdeps/unix/sysv/linux/epoll_wait.c b/sysdeps/unix/sysv/linux/epoll_wait.c
index 32406d4c3d..59729904e2 100644
--- a/sysdeps/unix/sysv/linux/epoll_wait.c
+++ b/sysdeps/unix/sysv/linux/epoll_wait.c
@@ -21,7 +21,6 @@
 #include <sys/types.h>
 #include <sys/epoll.h>
 
-#include <sysdep-cancel.h>
 
 int
 epoll_wait (int epfd, struct epoll_event *events, int maxevents, int timeout)
diff --git a/sysdeps/unix/sysv/linux/fallocate.c b/sysdeps/unix/sysv/linux/fallocate.c
index bf1eefbd53..784fb09d62 100644
--- a/sysdeps/unix/sysv/linux/fallocate.c
+++ b/sysdeps/unix/sysv/linux/fallocate.c
@@ -17,7 +17,6 @@
 
 #include <errno.h>
 #include <fcntl.h>
-#include <sysdep-cancel.h>
 
 #ifndef __OFF_T_MATCHES_OFF64_T
 /* Reserve storage for the data of the file associated with FD.  */
diff --git a/sysdeps/unix/sysv/linux/fallocate64.c b/sysdeps/unix/sysv/linux/fallocate64.c
index 3ffc4bcdda..b803b28508 100644
--- a/sysdeps/unix/sysv/linux/fallocate64.c
+++ b/sysdeps/unix/sysv/linux/fallocate64.c
@@ -17,7 +17,6 @@
 
 #include <errno.h>
 #include <fcntl.h>
-#include <sysdep-cancel.h>
 
 
 /* Reserve storage for the data of the file associated with FD.  */
diff --git a/sysdeps/unix/sysv/linux/fcntl.c b/sysdeps/unix/sysv/linux/fcntl.c
index 48bda0db4e..19d688bed7 100644
--- a/sysdeps/unix/sysv/linux/fcntl.c
+++ b/sysdeps/unix/sysv/linux/fcntl.c
@@ -19,7 +19,6 @@
 #include <fcntl.h>
 #include <stdarg.h>
 #include <errno.h>
-#include <sysdep-cancel.h>
 
 #ifndef __OFF_T_MATCHES_OFF64_T
 
diff --git a/sysdeps/unix/sysv/linux/fcntl64.c b/sysdeps/unix/sysv/linux/fcntl64.c
index c66f1c4ca1..42f0379308 100644
--- a/sysdeps/unix/sysv/linux/fcntl64.c
+++ b/sysdeps/unix/sysv/linux/fcntl64.c
@@ -23,7 +23,6 @@
 #undef __fcntl
 #include <stdarg.h>
 #include <errno.h>
-#include <sysdep-cancel.h>
 
 #ifndef __NR_fcntl64
 # define __NR_fcntl64 __NR_fcntl
diff --git a/sysdeps/unix/sysv/linux/fcntl_nocancel.c b/sysdeps/unix/sysv/linux/fcntl_nocancel.c
index d2f5c4fe93..187d27fdb1 100644
--- a/sysdeps/unix/sysv/linux/fcntl_nocancel.c
+++ b/sysdeps/unix/sysv/linux/fcntl_nocancel.c
@@ -19,7 +19,6 @@
 #include <fcntl.h>
 #include <stdarg.h>
 #include <errno.h>
-#include <sysdep-cancel.h>
 #include <not-cancel.h>
 
 #ifndef __NR_fcntl64
diff --git a/sysdeps/unix/sysv/linux/fdatasync.c b/sysdeps/unix/sysv/linux/fdatasync.c
index c6a02f24e9..afd45005d1 100644
--- a/sysdeps/unix/sysv/linux/fdatasync.c
+++ b/sysdeps/unix/sysv/linux/fdatasync.c
@@ -18,7 +18,7 @@
    <https://www.gnu.org/licenses/>.  */
 
 #include <unistd.h>
-#include <sysdep-cancel.h>
+#include <sysdep.h>
 
 /* Synchronize at least the data part of a file with the underlying
    media.  */
diff --git a/sysdeps/unix/sysv/linux/fsync.c b/sysdeps/unix/sysv/linux/fsync.c
index e4b6ee72ee..24789e2c24 100644
--- a/sysdeps/unix/sysv/linux/fsync.c
+++ b/sysdeps/unix/sysv/linux/fsync.c
@@ -18,7 +18,7 @@
    <https://www.gnu.org/licenses/>.  */
 
 #include <unistd.h>
-#include <sysdep-cancel.h>
+#include <sysdep.h>
 
 /* Make all changes done to FD actually appear on disk.  */
 int
diff --git a/sysdeps/unix/sysv/linux/futex-internal.h b/sysdeps/unix/sysv/linux/futex-internal.h
index b41a4d9919..8b7ad1f0df 100644
--- a/sysdeps/unix/sysv/linux/futex-internal.h
+++ b/sysdeps/unix/sysv/linux/futex-internal.h
@@ -22,7 +22,6 @@
 #include <sysdeps/nptl/futex-internal.h>
 #include <errno.h>
 #include <lowlevellock-futex.h>
-#include <sysdep-cancel.h>
 
 /* See sysdeps/nptl/futex-internal.h for documentation; this file only
    contains Linux-specific comments.
diff --git a/sysdeps/unix/sysv/linux/getrandom.c b/sysdeps/unix/sysv/linux/getrandom.c
index 122c695a3e..c69a4c190f 100644
--- a/sysdeps/unix/sysv/linux/getrandom.c
+++ b/sysdeps/unix/sysv/linux/getrandom.c
@@ -19,7 +19,6 @@
 #include <sys/random.h>
 #include <errno.h>
 #include <unistd.h>
-#include <sysdep-cancel.h>
 
 #ifdef __NR_getrandom
 /* Write up to LENGTH bytes of randomness starting at BUFFER.
diff --git a/sysdeps/unix/sysv/linux/lowlevellock-futex.h b/sysdeps/unix/sysv/linux/lowlevellock-futex.h
index bd6d3b7cf7..e43400d070 100644
--- a/sysdeps/unix/sysv/linux/lowlevellock-futex.h
+++ b/sysdeps/unix/sysv/linux/lowlevellock-futex.h
@@ -21,7 +21,6 @@
 
 #ifndef __ASSEMBLER__
 #include <sysdep.h>
-#include <sysdep-cancel.h>
 #include <kernel-features.h>
 #endif
 
diff --git a/sysdeps/unix/sysv/linux/mq_timedreceive.c b/sysdeps/unix/sysv/linux/mq_timedreceive.c
index 9957de44f7..4417d36ced 100644
--- a/sysdeps/unix/sysv/linux/mq_timedreceive.c
+++ b/sysdeps/unix/sysv/linux/mq_timedreceive.c
@@ -17,7 +17,7 @@
    <https://www.gnu.org/licenses/>.  */
 
 #include <mqueue.h>
-#include <sysdep-cancel.h>
+#include <sysdep.h>
 
 /* Receive the oldest from highest priority messages in message queue
    MQDES, stop waiting if ABS_TIMEOUT expires.  */
diff --git a/sysdeps/unix/sysv/linux/mq_timedsend.c b/sysdeps/unix/sysv/linux/mq_timedsend.c
index cd8f77d03f..1befb6b99e 100644
--- a/sysdeps/unix/sysv/linux/mq_timedsend.c
+++ b/sysdeps/unix/sysv/linux/mq_timedsend.c
@@ -17,7 +17,7 @@
    <https://www.gnu.org/licenses/>.  */
 
 #include <mqueue.h>
-#include <sysdep-cancel.h>
+#include <sysdep.h>
 
 /* Add message pointed by MSG_PTR to message queue MQDES, stop blocking
    on full message queue if ABS_TIMEOUT expires.  */
diff --git a/sysdeps/unix/sysv/linux/msgrcv.c b/sysdeps/unix/sysv/linux/msgrcv.c
index 1b06bd6d60..277c26d2d1 100644
--- a/sysdeps/unix/sysv/linux/msgrcv.c
+++ b/sysdeps/unix/sysv/linux/msgrcv.c
@@ -18,7 +18,7 @@
 
 #include <sys/msg.h>
 #include <ipc_priv.h>
-#include <sysdep-cancel.h>
+#include <sysdep.h>
 
 ssize_t
 __libc_msgrcv (int msqid, void *msgp, size_t msgsz, long int msgtyp,
diff --git a/sysdeps/unix/sysv/linux/msgsnd.c b/sysdeps/unix/sysv/linux/msgsnd.c
index 28d46bda25..2a4603ff1e 100644
--- a/sysdeps/unix/sysv/linux/msgsnd.c
+++ b/sysdeps/unix/sysv/linux/msgsnd.c
@@ -18,7 +18,7 @@
 
 #include <sys/msg.h>
 #include <ipc_priv.h>
-#include <sysdep-cancel.h>
+#include <sysdep.h>
 
 int
 __libc_msgsnd (int msqid, const void *msgp, size_t msgsz, int msgflg)
diff --git a/sysdeps/unix/sysv/linux/msync.c b/sysdeps/unix/sysv/linux/msync.c
index 7a597b1fd9..33a007a64b 100644
--- a/sysdeps/unix/sysv/linux/msync.c
+++ b/sysdeps/unix/sysv/linux/msync.c
@@ -17,7 +17,7 @@
    <https://www.gnu.org/licenses/>.  */
 
 #include <sys/mman.h>
-#include <sysdep-cancel.h>
+#include <sysdep.h>
 
 int
 msync (void *addr, size_t length, int flags)
diff --git a/sysdeps/unix/sysv/linux/nanosleep.c b/sysdeps/unix/sysv/linux/nanosleep.c
index 6787909248..4e08c675f8 100644
--- a/sysdeps/unix/sysv/linux/nanosleep.c
+++ b/sysdeps/unix/sysv/linux/nanosleep.c
@@ -17,8 +17,7 @@
    <https://www.gnu.org/licenses/>.  */
 
 #include <time.h>
-#include <sysdep-cancel.h>
-#include <not-cancel.h>
+#include <sysdep.h>
 
 /* Pause execution for a number of nanoseconds.  */
 int
diff --git a/sysdeps/unix/sysv/linux/nanosleep_nocancel.c b/sysdeps/unix/sysv/linux/nanosleep_nocancel.c
index d6442bf4f7..74c999281a 100644
--- a/sysdeps/unix/sysv/linux/nanosleep_nocancel.c
+++ b/sysdeps/unix/sysv/linux/nanosleep_nocancel.c
@@ -17,7 +17,6 @@
    <https://www.gnu.org/licenses/>.  */
 
 #include <time.h>
-#include <sysdep-cancel.h>
 #include <not-cancel.h>
 
 int
diff --git a/sysdeps/unix/sysv/linux/open.c b/sysdeps/unix/sysv/linux/open.c
index a65aec457d..0e14aa0abe 100644
--- a/sysdeps/unix/sysv/linux/open.c
+++ b/sysdeps/unix/sysv/linux/open.c
@@ -21,8 +21,7 @@
 #include <sys/stat.h>
 #include <fcntl.h>
 #include <stdarg.h>
-
-#include <sysdep-cancel.h>
+#include <sysdep.h>
 
 #ifndef __OFF_T_MATCHES_OFF64_T
 
diff --git a/sysdeps/unix/sysv/linux/open64.c b/sysdeps/unix/sysv/linux/open64.c
index d6cefb09d1..d10609d3c0 100644
--- a/sysdeps/unix/sysv/linux/open64.c
+++ b/sysdeps/unix/sysv/linux/open64.c
@@ -20,9 +20,7 @@
 #include <sys/stat.h>
 #include <fcntl.h>
 #include <stdarg.h>
-
-#include <sysdep-cancel.h>
-
+#include <sysdep.h>
 
 #ifdef __OFF_T_MATCHES_OFF64_T
 # define EXTRA_OPEN_FLAGS 0
diff --git a/sysdeps/unix/sysv/linux/open_by_handle_at.c b/sysdeps/unix/sysv/linux/open_by_handle_at.c
index 0888157a33..cfb57737b5 100644
--- a/sysdeps/unix/sysv/linux/open_by_handle_at.c
+++ b/sysdeps/unix/sysv/linux/open_by_handle_at.c
@@ -19,7 +19,7 @@
 #include <fcntl.h>
 #include <sys/types.h>
 #include <sys/stat.h>
-#include <sysdep-cancel.h>
+#include <sysdep.h>
 
 int
 open_by_handle_at (int mount_fd, struct file_handle *handle, int flags)
diff --git a/sysdeps/unix/sysv/linux/open_nocancel.c b/sysdeps/unix/sysv/linux/open_nocancel.c
index 9926218cca..232423bf0d 100644
--- a/sysdeps/unix/sysv/linux/open_nocancel.c
+++ b/sysdeps/unix/sysv/linux/open_nocancel.c
@@ -21,7 +21,6 @@
 #include <fcntl.h>
 #include <stdarg.h>
 
-#include <sysdep-cancel.h>
 #include <not-cancel.h>
 
 #ifndef __OFF_T_MATCHES_OFF64_T
diff --git a/sysdeps/unix/sysv/linux/openat.c b/sysdeps/unix/sysv/linux/openat.c
index a4450445da..0983ed9de2 100644
--- a/sysdeps/unix/sysv/linux/openat.c
+++ b/sysdeps/unix/sysv/linux/openat.c
@@ -18,8 +18,7 @@
 
 #include <fcntl.h>
 #include <stdarg.h>
-
-#include <sysdep-cancel.h>
+#include <sysdep.h>
 
 #ifndef __OFF_T_MATCHES_OFF64_T
 
diff --git a/sysdeps/unix/sysv/linux/openat64.c b/sysdeps/unix/sysv/linux/openat64.c
index dbd893ea9d..96d96080f4 100644
--- a/sysdeps/unix/sysv/linux/openat64.c
+++ b/sysdeps/unix/sysv/linux/openat64.c
@@ -18,8 +18,7 @@
 
 #include <fcntl.h>
 #include <stdarg.h>
-
-#include <sysdep-cancel.h>
+#include <sysdep.h>
 
 #ifdef __OFF_T_MATCHES_OFF64_T
 # define EXTRA_OPEN_FLAGS 0
diff --git a/sysdeps/unix/sysv/linux/openat64_nocancel.c b/sysdeps/unix/sysv/linux/openat64_nocancel.c
index cd077f28cd..97f4af4c23 100644
--- a/sysdeps/unix/sysv/linux/openat64_nocancel.c
+++ b/sysdeps/unix/sysv/linux/openat64_nocancel.c
@@ -19,7 +19,6 @@
 #include <fcntl.h>
 #include <stdarg.h>
 
-#include <sysdep-cancel.h>
 #include <not-cancel.h>
 
 #ifdef __OFF_T_MATCHES_OFF64_T
diff --git a/sysdeps/unix/sysv/linux/openat_nocancel.c b/sysdeps/unix/sysv/linux/openat_nocancel.c
index 25db90ce8e..17c8d29084 100644
--- a/sysdeps/unix/sysv/linux/openat_nocancel.c
+++ b/sysdeps/unix/sysv/linux/openat_nocancel.c
@@ -19,7 +19,6 @@
 #include <fcntl.h>
 #include <stdarg.h>
 
-#include <sysdep-cancel.h>
 #include <not-cancel.h>
 
 #ifndef __OFF_T_MATCHES_OFF64_T
diff --git a/sysdeps/unix/sysv/linux/pause.c b/sysdeps/unix/sysv/linux/pause.c
index c2b9f4fb66..2f5861fbab 100644
--- a/sysdeps/unix/sysv/linux/pause.c
+++ b/sysdeps/unix/sysv/linux/pause.c
@@ -18,7 +18,7 @@
 
 #include <signal.h>
 #include <unistd.h>
-#include <sysdep-cancel.h>
+#include <sysdep.h>
 
 /* Suspend the process until a signal arrives.
    This always returns -1 and sets errno to EINTR.  */
diff --git a/sysdeps/unix/sysv/linux/pause_nocancel.c b/sysdeps/unix/sysv/linux/pause_nocancel.c
index 04f6fcf5e3..dffb07500f 100644
--- a/sysdeps/unix/sysv/linux/pause_nocancel.c
+++ b/sysdeps/unix/sysv/linux/pause_nocancel.c
@@ -18,7 +18,6 @@
 
 #include <signal.h>
 #include <unistd.h>
-#include <sysdep-cancel.h>
 #include <not-cancel.h>
 
 int
diff --git a/sysdeps/unix/sysv/linux/poll.c b/sysdeps/unix/sysv/linux/poll.c
index 8ea00563a4..8f66655cf1 100644
--- a/sysdeps/unix/sysv/linux/poll.c
+++ b/sysdeps/unix/sysv/linux/poll.c
@@ -19,7 +19,6 @@
 #include <errno.h>
 #include <sys/poll.h>
 
-#include <sysdep-cancel.h>
 #include <sys/syscall.h>
 
 int
diff --git a/sysdeps/unix/sysv/linux/ppoll.c b/sysdeps/unix/sysv/linux/ppoll.c
index 8a6ccd1dcc..e9ffd51636 100644
--- a/sysdeps/unix/sysv/linux/ppoll.c
+++ b/sysdeps/unix/sysv/linux/ppoll.c
@@ -20,8 +20,6 @@
 #include <signal.h>
 #include <time.h>
 #include <sys/poll.h>
-#include <sysdep-cancel.h>
-
 
 int
 ppoll (struct pollfd *fds, nfds_t nfds, const struct timespec *timeout,
diff --git a/sysdeps/unix/sysv/linux/pread.c b/sysdeps/unix/sysv/linux/pread.c
index d9faf3cee2..cfc6859892 100644
--- a/sysdeps/unix/sysv/linux/pread.c
+++ b/sysdeps/unix/sysv/linux/pread.c
@@ -17,7 +17,7 @@
    <https://www.gnu.org/licenses/>.  */
 
 #include <unistd.h>
-#include <sysdep-cancel.h>
+#include <sysdep.h>
 
 #ifndef __OFF_T_MATCHES_OFF64_T
 
diff --git a/sysdeps/unix/sysv/linux/pread64.c b/sysdeps/unix/sysv/linux/pread64.c
index 36410292ee..db452ba3e5 100644
--- a/sysdeps/unix/sysv/linux/pread64.c
+++ b/sysdeps/unix/sysv/linux/pread64.c
@@ -17,7 +17,7 @@
    <https://www.gnu.org/licenses/>.  */
 
 #include <unistd.h>
-#include <sysdep-cancel.h>
+#include <sysdep.h>
 
 #ifndef __NR_pread64
 # define __NR_pread64 __NR_pread
diff --git a/sysdeps/unix/sysv/linux/preadv.c b/sysdeps/unix/sysv/linux/preadv.c
index 61007df357..8794c2b677 100644
--- a/sysdeps/unix/sysv/linux/preadv.c
+++ b/sysdeps/unix/sysv/linux/preadv.c
@@ -16,7 +16,7 @@
    <https://www.gnu.org/licenses/>.  */
 
 #include <sys/uio.h>
-#include <sysdep-cancel.h>
+#include <sysdep.h>
 
 #ifndef __OFF_T_MATCHES_OFF64_T
 
diff --git a/sysdeps/unix/sysv/linux/preadv2.c b/sysdeps/unix/sysv/linux/preadv2.c
index 9e3205b8ef..5c2c3752ca 100644
--- a/sysdeps/unix/sysv/linux/preadv2.c
+++ b/sysdeps/unix/sysv/linux/preadv2.c
@@ -17,7 +17,7 @@
    <https://www.gnu.org/licenses/>.  */
 
 #include <sys/uio.h>
-#include <sysdep-cancel.h>
+#include <sysdep.h>
 
 #ifndef __OFF_T_MATCHES_OFF64_T
 
diff --git a/sysdeps/unix/sysv/linux/preadv64.c b/sysdeps/unix/sysv/linux/preadv64.c
index 4b0a66f583..3f99ed2203 100644
--- a/sysdeps/unix/sysv/linux/preadv64.c
+++ b/sysdeps/unix/sysv/linux/preadv64.c
@@ -16,7 +16,7 @@
    <https://www.gnu.org/licenses/>.  */
 
 #include <sys/uio.h>
-#include <sysdep-cancel.h>
+#include <sysdep.h>
 
 #ifdef __ASSUME_PREADV
 
diff --git a/sysdeps/unix/sysv/linux/preadv64v2.c b/sysdeps/unix/sysv/linux/preadv64v2.c
index 724f03d0ef..44cd74e177 100644
--- a/sysdeps/unix/sysv/linux/preadv64v2.c
+++ b/sysdeps/unix/sysv/linux/preadv64v2.c
@@ -17,7 +17,7 @@
    <https://www.gnu.org/licenses/>.  */
 
 #include <sys/uio.h>
-#include <sysdep-cancel.h>
+#include <sysdep.h>
 
 #if !defined(__NR_preadv64v2) && defined(__NR_preadv2)
 # define __NR_preadv64v2 __NR_preadv2
diff --git a/sysdeps/unix/sysv/linux/pselect.c b/sysdeps/unix/sysv/linux/pselect.c
index d07d64114d..f929ff23a8 100644
--- a/sysdeps/unix/sysv/linux/pselect.c
+++ b/sysdeps/unix/sysv/linux/pselect.c
@@ -21,8 +21,6 @@
 #include <time.h>
 #include <sys/poll.h>
 #include <kernel-features.h>
-#include <sysdep-cancel.h>
-
 
 #ifdef __NR_pselect6
 # ifndef __ASSUME_PSELECT
diff --git a/sysdeps/unix/sysv/linux/pwrite.c b/sysdeps/unix/sysv/linux/pwrite.c
index ddfbdef9c1..c59290d12d 100644
--- a/sysdeps/unix/sysv/linux/pwrite.c
+++ b/sysdeps/unix/sysv/linux/pwrite.c
@@ -17,7 +17,7 @@
    <https://www.gnu.org/licenses/>.  */
 
 #include <unistd.h>
-#include <sysdep-cancel.h>
+#include <sysdep.h>
 
 #ifndef __OFF_T_MATCHES_OFF64_T
 
diff --git a/sysdeps/unix/sysv/linux/pwrite64.c b/sysdeps/unix/sysv/linux/pwrite64.c
index db8661c054..d5ba7786c6 100644
--- a/sysdeps/unix/sysv/linux/pwrite64.c
+++ b/sysdeps/unix/sysv/linux/pwrite64.c
@@ -17,7 +17,7 @@
    <https://www.gnu.org/licenses/>.  */
 
 #include <unistd.h>
-#include <sysdep-cancel.h>
+#include <sysdep.h>
 
 #ifndef __NR_pwrite64
 # define __NR_pwrite64 __NR_pwrite
diff --git a/sysdeps/unix/sysv/linux/pwritev.c b/sysdeps/unix/sysv/linux/pwritev.c
index ed25289984..45a801806c 100644
--- a/sysdeps/unix/sysv/linux/pwritev.c
+++ b/sysdeps/unix/sysv/linux/pwritev.c
@@ -16,7 +16,7 @@
    <https://www.gnu.org/licenses/>.  */
 
 #include <sys/uio.h>
-#include <sysdep-cancel.h>
+#include <sysdep.h>
 
 #ifndef __OFF_T_MATCHES_OFF64_T
 
diff --git a/sysdeps/unix/sysv/linux/pwritev2.c b/sysdeps/unix/sysv/linux/pwritev2.c
index a415b2fa89..ccd099a021 100644
--- a/sysdeps/unix/sysv/linux/pwritev2.c
+++ b/sysdeps/unix/sysv/linux/pwritev2.c
@@ -17,7 +17,7 @@
    <https://www.gnu.org/licenses/>.  */
 
 #include <sys/uio.h>
-#include <sysdep-cancel.h>
+#include <sysdep.h>
 
 #ifndef __OFF_T_MATCHES_OFF64_T
 
diff --git a/sysdeps/unix/sysv/linux/pwritev64.c b/sysdeps/unix/sysv/linux/pwritev64.c
index ec9987fefc..50f7774e3c 100644
--- a/sysdeps/unix/sysv/linux/pwritev64.c
+++ b/sysdeps/unix/sysv/linux/pwritev64.c
@@ -16,7 +16,7 @@
    <https://www.gnu.org/licenses/>.  */
 
 #include <sys/uio.h>
-#include <sysdep-cancel.h>
+#include <sysdep.h>
 
 #ifdef __ASSUME_PWRITEV
 
diff --git a/sysdeps/unix/sysv/linux/pwritev64v2.c b/sysdeps/unix/sysv/linux/pwritev64v2.c
index 5683220466..329bb820f4 100644
--- a/sysdeps/unix/sysv/linux/pwritev64v2.c
+++ b/sysdeps/unix/sysv/linux/pwritev64v2.c
@@ -17,7 +17,7 @@
    <https://www.gnu.org/licenses/>.  */
 
 #include <sys/uio.h>
-#include <sysdep-cancel.h>
+#include <sysdep.h>
 
 #if !defined(__NR_pwritev64v2) && defined(__NR_pwritev2)
 # define __NR_pwritev64v2 __NR_pwritev2
diff --git a/sysdeps/unix/sysv/linux/read.c b/sysdeps/unix/sysv/linux/read.c
index 147d45f242..4d49efa439 100644
--- a/sysdeps/unix/sysv/linux/read.c
+++ b/sysdeps/unix/sysv/linux/read.c
@@ -17,7 +17,7 @@
    <https://www.gnu.org/licenses/>.  */
 
 #include <unistd.h>
-#include <sysdep-cancel.h>
+#include <sysdep.h>
 
 /* Read NBYTES into BUF from FD.  Return the number read or -1.  */
 ssize_t
diff --git a/sysdeps/unix/sysv/linux/read_nocancel.c b/sysdeps/unix/sysv/linux/read_nocancel.c
index 9d2a5eedb6..71f7b8776d 100644
--- a/sysdeps/unix/sysv/linux/read_nocancel.c
+++ b/sysdeps/unix/sysv/linux/read_nocancel.c
@@ -17,7 +17,6 @@
    <https://www.gnu.org/licenses/>.  */
 
 #include <unistd.h>
-#include <sysdep-cancel.h>
 #include <not-cancel.h>
 
 ssize_t
diff --git a/sysdeps/unix/sysv/linux/readv.c b/sysdeps/unix/sysv/linux/readv.c
index c0bd1ed6d8..0ed6d91e9a 100644
--- a/sysdeps/unix/sysv/linux/readv.c
+++ b/sysdeps/unix/sysv/linux/readv.c
@@ -18,7 +18,7 @@
 
 #include <unistd.h>
 #include <sys/uio.h>
-#include <sysdep-cancel.h>
+#include <sysdep.h>
 
 ssize_t
 __readv (int fd, const struct iovec *iov, int iovcnt)
diff --git a/sysdeps/unix/sysv/linux/recv.c b/sysdeps/unix/sysv/linux/recv.c
index 5b28449299..de4dbc4f08 100644
--- a/sysdeps/unix/sysv/linux/recv.c
+++ b/sysdeps/unix/sysv/linux/recv.c
@@ -16,7 +16,6 @@
    <https://www.gnu.org/licenses/>.  */
 
 #include <sys/socket.h>
-#include <sysdep-cancel.h>
 #include <socketcall.h>
 
 ssize_t
diff --git a/sysdeps/unix/sysv/linux/recvfrom.c b/sysdeps/unix/sysv/linux/recvfrom.c
index 59115ecea7..6fabaea9c0 100644
--- a/sysdeps/unix/sysv/linux/recvfrom.c
+++ b/sysdeps/unix/sysv/linux/recvfrom.c
@@ -16,7 +16,6 @@
    <https://www.gnu.org/licenses/>.  */
 
 #include <sys/socket.h>
-#include <sysdep-cancel.h>
 #include <socketcall.h>
 
 ssize_t
diff --git a/sysdeps/unix/sysv/linux/recvmmsg.c b/sysdeps/unix/sysv/linux/recvmmsg.c
index bcb5a97f06..157899cfba 100644
--- a/sysdeps/unix/sysv/linux/recvmmsg.c
+++ b/sysdeps/unix/sysv/linux/recvmmsg.c
@@ -19,7 +19,6 @@
 #include <errno.h>
 #include <sys/socket.h>
 
-#include <sysdep-cancel.h>
 #include <sys/syscall.h>
 #include <socketcall.h>
 #include <kernel-features.h>
diff --git a/sysdeps/unix/sysv/linux/recvmsg.c b/sysdeps/unix/sysv/linux/recvmsg.c
index f7ae2b9599..a0c17b5468 100644
--- a/sysdeps/unix/sysv/linux/recvmsg.c
+++ b/sysdeps/unix/sysv/linux/recvmsg.c
@@ -17,7 +17,6 @@
    <https://www.gnu.org/licenses/>.  */
 
 #include <sys/socket.h>
-#include <sysdep-cancel.h>
 #include <socketcall.h>
 #include <shlib-compat.h>
 
diff --git a/sysdeps/unix/sysv/linux/select.c b/sysdeps/unix/sysv/linux/select.c
index 0498970c47..ef1928871b 100644
--- a/sysdeps/unix/sysv/linux/select.c
+++ b/sysdeps/unix/sysv/linux/select.c
@@ -20,7 +20,6 @@
 #include <sys/types.h>
 #include <sys/select.h>
 #include <errno.h>
-#include <sysdep-cancel.h>
 
 /* Check the first NFDS descriptors each in READFDS (if not NULL) for read
    readiness, in WRITEFDS (if not NULL) for write readiness, and in EXCEPTFDS
diff --git a/sysdeps/unix/sysv/linux/send.c b/sysdeps/unix/sysv/linux/send.c
index 0eaca763c3..bee607dbc8 100644
--- a/sysdeps/unix/sysv/linux/send.c
+++ b/sysdeps/unix/sysv/linux/send.c
@@ -16,7 +16,6 @@
    <https://www.gnu.org/licenses/>.  */
 
 #include <sys/socket.h>
-#include <sysdep-cancel.h>
 #include <socketcall.h>
 
 ssize_t
diff --git a/sysdeps/unix/sysv/linux/sendmmsg.c b/sysdeps/unix/sysv/linux/sendmmsg.c
index c53c1b280f..94d78501ac 100644
--- a/sysdeps/unix/sysv/linux/sendmmsg.c
+++ b/sysdeps/unix/sysv/linux/sendmmsg.c
@@ -19,7 +19,6 @@
 #include <errno.h>
 #include <sys/socket.h>
 
-#include <sysdep-cancel.h>
 #include <sys/syscall.h>
 #include <socketcall.h>
 #include <kernel-features.h>
diff --git a/sysdeps/unix/sysv/linux/sendmsg.c b/sysdeps/unix/sysv/linux/sendmsg.c
index 42c4250749..827418ab37 100644
--- a/sysdeps/unix/sysv/linux/sendmsg.c
+++ b/sysdeps/unix/sysv/linux/sendmsg.c
@@ -17,7 +17,6 @@
    <https://www.gnu.org/licenses/>.  */
 
 #include <sys/socket.h>
-#include <sysdep-cancel.h>
 #include <socketcall.h>
 #include <shlib-compat.h>
 
diff --git a/sysdeps/unix/sysv/linux/sendto.c b/sysdeps/unix/sysv/linux/sendto.c
index 78e3b6b2a6..8e91187739 100644
--- a/sysdeps/unix/sysv/linux/sendto.c
+++ b/sysdeps/unix/sysv/linux/sendto.c
@@ -16,7 +16,6 @@
    <https://www.gnu.org/licenses/>.  */
 
 #include <sys/socket.h>
-#include <sysdep-cancel.h>
 #include <socketcall.h>
 
 ssize_t
diff --git a/sysdeps/unix/sysv/linux/sigsuspend.c b/sysdeps/unix/sysv/linux/sigsuspend.c
index 40e1e25f75..e707099ef2 100644
--- a/sysdeps/unix/sysv/linux/sigsuspend.c
+++ b/sysdeps/unix/sysv/linux/sigsuspend.c
@@ -16,7 +16,7 @@
    <https://www.gnu.org/licenses/>.  */
 
 #include <signal.h>
-#include <sysdep-cancel.h>
+#include <sysdep.h>
 
 /* Change the set of blocked signals to SET,
    wait until a signal arrives, and restore the set of blocked signals.  */
diff --git a/sysdeps/unix/sysv/linux/sigtimedwait.c b/sysdeps/unix/sysv/linux/sigtimedwait.c
index 30fc82a249..b69705e354 100644
--- a/sysdeps/unix/sysv/linux/sigtimedwait.c
+++ b/sysdeps/unix/sysv/linux/sigtimedwait.c
@@ -18,7 +18,6 @@
 #include <errno.h>
 #include <signal.h>
 #include <string.h>
-#include <sysdep-cancel.h>
 
 int
 __sigtimedwait (const sigset_t *set, siginfo_t *info,
diff --git a/sysdeps/unix/sysv/linux/sigwait.c b/sysdeps/unix/sysv/linux/sigwait.c
index 360a4d0f5b..420642a550 100644
--- a/sysdeps/unix/sysv/linux/sigwait.c
+++ b/sysdeps/unix/sysv/linux/sigwait.c
@@ -16,7 +16,6 @@
    <https://www.gnu.org/licenses/>.  */
 
 #include <signal.h>
-#include <sysdep-cancel.h>
 #include <errno.h>
 
 int
diff --git a/sysdeps/unix/sysv/linux/sigwaitinfo.c b/sysdeps/unix/sysv/linux/sigwaitinfo.c
index 64735e4a03..8a95b205d5 100644
--- a/sysdeps/unix/sysv/linux/sigwaitinfo.c
+++ b/sysdeps/unix/sysv/linux/sigwaitinfo.c
@@ -16,7 +16,6 @@
    <https://www.gnu.org/licenses/>.  */
 
 #include <signal.h>
-#include <sysdep-cancel.h>
 
 /* Return any pending signal or wait for one for the given time.  */
 int
diff --git a/sysdeps/unix/sysv/linux/socketcall.h b/sysdeps/unix/sysv/linux/socketcall.h
index 38af55feb4..5d345b654c 100644
--- a/sysdeps/unix/sysv/linux/socketcall.h
+++ b/sysdeps/unix/sysv/linux/socketcall.h
@@ -19,6 +19,8 @@
 #ifndef _SYS_SOCKETCALL_H
 #define _SYS_SOCKETCALL_H	1
 
+#include <sysdep.h>
+
 /* Define unique numbers for the operations permitted on socket.  Linux
    uses a single system call for all these functions.  The relevant code
    file is /usr/include/linux/net.h.
diff --git a/sysdeps/unix/sysv/linux/splice.c b/sysdeps/unix/sysv/linux/splice.c
index d9be756718..804e91d1ca 100644
--- a/sysdeps/unix/sysv/linux/splice.c
+++ b/sysdeps/unix/sysv/linux/splice.c
@@ -17,7 +17,7 @@
    <https://www.gnu.org/licenses/>.  */
 
 #include <fcntl.h>
-#include <sysdep-cancel.h>
+#include <sysdep.h>
 
 ssize_t
 splice (int fd_in, loff_t *off_in, int fd_out, loff_t *off_out, size_t len,
diff --git a/sysdeps/unix/sysv/linux/sync_file_range.c b/sysdeps/unix/sysv/linux/sync_file_range.c
index 48ef674746..4649afe6b3 100644
--- a/sysdeps/unix/sysv/linux/sync_file_range.c
+++ b/sysdeps/unix/sysv/linux/sync_file_range.c
@@ -17,7 +17,7 @@
    <https://www.gnu.org/licenses/>.  */
 
 #include <fcntl.h>
-#include <sysdep-cancel.h>
+#include <sysdep.h>
 
 int
 sync_file_range (int fd, __off64_t offset, __off64_t len, unsigned int flags)
diff --git a/sysdeps/unix/sysv/linux/sysdep-cancel.h b/sysdeps/unix/sysv/linux/sysdep-cancel.h
deleted file mode 100644
index c861303d36..0000000000
--- a/sysdeps/unix/sysv/linux/sysdep-cancel.h
+++ /dev/null
@@ -1,67 +0,0 @@
-/* Single-thread optimization definitions.  Linux version.
-   Copyright (C) 2017-2019 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
-   <https://www.gnu.org/licenses/>.  */
-
-#ifndef _SYSDEP_CANCEL_H
-#define _SYSDEP_CANCEL_H
-
-#include <sysdep.h>
-#include <tls.h>
-#include <errno.h>
-
-/* The two functions are in libc.so and not exported.  */
-extern int __libc_enable_asynccancel (void) attribute_hidden;
-extern void __libc_disable_asynccancel (int oldtype) attribute_hidden;
-
-/* The two functions are in librt.so and not exported.  */
-extern int __librt_enable_asynccancel (void) attribute_hidden;
-extern void __librt_disable_asynccancel (int oldtype) attribute_hidden;
-
-/* The two functions are in libpthread.so and not exported.  */
-extern int __pthread_enable_asynccancel (void) attribute_hidden;
-extern void __pthread_disable_asynccancel (int oldtype) attribute_hidden;
-
-/* Set cancellation mode to asynchronous.  */
-#define CANCEL_ASYNC() \
-  __pthread_enable_asynccancel ()
-/* Reset to previous cancellation mode.  */
-#define CANCEL_RESET(oldtype) \
-  __pthread_disable_asynccancel (oldtype)
-
-#if IS_IN (libc)
-/* Same as CANCEL_ASYNC, but for use in libc.so.  */
-# define LIBC_CANCEL_ASYNC() \
-  __libc_enable_asynccancel ()
-/* Same as CANCEL_RESET, but for use in libc.so.  */
-# define LIBC_CANCEL_RESET(oldtype) \
-  __libc_disable_asynccancel (oldtype)
-#elif IS_IN (libpthread)
-# define LIBC_CANCEL_ASYNC() CANCEL_ASYNC ()
-# define LIBC_CANCEL_RESET(val) CANCEL_RESET (val)
-#elif IS_IN (librt)
-# define LIBC_CANCEL_ASYNC() \
-  __librt_enable_asynccancel ()
-# define LIBC_CANCEL_RESET(val) \
-  __librt_disable_asynccancel (val)
-#else
-# define LIBC_CANCEL_ASYNC()	0 /* Just a dummy value.  */
-# define LIBC_CANCEL_RESET(val)	((void)(val)) /* Nothing, but evaluate it.  */
-#endif
-
-
-#endif
diff --git a/sysdeps/unix/sysv/linux/tcdrain.c b/sysdeps/unix/sysv/linux/tcdrain.c
index b3691d0b12..70519f2fc0 100644
--- a/sysdeps/unix/sysv/linux/tcdrain.c
+++ b/sysdeps/unix/sysv/linux/tcdrain.c
@@ -18,7 +18,6 @@
 #include <errno.h>
 #include <termios.h>
 #include <sys/ioctl.h>
-#include <sysdep-cancel.h>
 
 /* Wait for pending output to be written on FD.  */
 int
diff --git a/sysdeps/unix/sysv/linux/tee.c b/sysdeps/unix/sysv/linux/tee.c
index 97228e344e..4eba39cfc3 100644
--- a/sysdeps/unix/sysv/linux/tee.c
+++ b/sysdeps/unix/sysv/linux/tee.c
@@ -17,7 +17,7 @@
    <https://www.gnu.org/licenses/>.  */
 
 #include <fcntl.h>
-#include <sysdep-cancel.h>
+#include <sysdep.h>
 
 ssize_t
 tee (int src, int dest, size_t len, unsigned int flags)
diff --git a/sysdeps/unix/sysv/linux/timer_routines.c b/sysdeps/unix/sysv/linux/timer_routines.c
index d96d963177..40e3460e43 100644
--- a/sysdeps/unix/sysv/linux/timer_routines.c
+++ b/sysdeps/unix/sysv/linux/timer_routines.c
@@ -20,7 +20,6 @@
 #include <setjmp.h>
 #include <signal.h>
 #include <stdbool.h>
-#include <sysdep-cancel.h>
 #include <nptl/pthreadP.h>
 #include "kernel-posix-timers.h"
 
diff --git a/sysdeps/unix/sysv/linux/vmsplice.c b/sysdeps/unix/sysv/linux/vmsplice.c
index 706b933807..cff5afff89 100644
--- a/sysdeps/unix/sysv/linux/vmsplice.c
+++ b/sysdeps/unix/sysv/linux/vmsplice.c
@@ -18,7 +18,7 @@
 
 #include <fcntl.h>
 #include <sys/uio.h>
-#include <sysdep-cancel.h>
+#include <sysdep.h>
 
 ssize_t
 vmsplice (int fd, const struct iovec *iov, size_t count, unsigned int flags)
diff --git a/sysdeps/unix/sysv/linux/wait.c b/sysdeps/unix/sysv/linux/wait.c
index c2385c752e..36deddfdcb 100644
--- a/sysdeps/unix/sysv/linux/wait.c
+++ b/sysdeps/unix/sysv/linux/wait.c
@@ -19,7 +19,6 @@
 #include <errno.h>
 #include <sys/resource.h>
 #include <stddef.h>
-#include <sysdep-cancel.h>
 
 /* Wait for a child to die.  When one does, put its status in *STAT_LOC
    and return its process ID.  For errors, return (pid_t) -1.  */
diff --git a/sysdeps/unix/sysv/linux/waitid.c b/sysdeps/unix/sysv/linux/waitid.c
index e563d3e264..45b7baf40b 100644
--- a/sysdeps/unix/sysv/linux/waitid.c
+++ b/sysdeps/unix/sysv/linux/waitid.c
@@ -19,7 +19,6 @@
 #include <stddef.h>
 #include <errno.h>
 #include <sys/wait.h>
-#include <sysdep-cancel.h>
 
 int
 __waitid (idtype_t idtype, id_t id, siginfo_t *infop, int options)
diff --git a/sysdeps/unix/sysv/linux/waitpid.c b/sysdeps/unix/sysv/linux/waitpid.c
index d35aac01bc..dbd816dbbd 100644
--- a/sysdeps/unix/sysv/linux/waitpid.c
+++ b/sysdeps/unix/sysv/linux/waitpid.c
@@ -17,7 +17,6 @@
    <https://www.gnu.org/licenses/>.  */
 
 #include <errno.h>
-#include <sysdep-cancel.h>
 #include <stdlib.h>
 #include <sys/wait.h>
 
diff --git a/sysdeps/unix/sysv/linux/waitpid_nocancel.c b/sysdeps/unix/sysv/linux/waitpid_nocancel.c
index 3697c6b938..82e4fc6e1e 100644
--- a/sysdeps/unix/sysv/linux/waitpid_nocancel.c
+++ b/sysdeps/unix/sysv/linux/waitpid_nocancel.c
@@ -17,7 +17,6 @@
    <https://www.gnu.org/licenses/>.  */
 
 #include <errno.h>
-#include <sysdep-cancel.h>
 #include <stdlib.h>
 #include <sys/wait.h>
 #include <not-cancel.h>
diff --git a/sysdeps/unix/sysv/linux/write.c b/sysdeps/unix/sysv/linux/write.c
index 1dfb5de8ee..15dc0fd8e2 100644
--- a/sysdeps/unix/sysv/linux/write.c
+++ b/sysdeps/unix/sysv/linux/write.c
@@ -17,7 +17,7 @@
    <https://www.gnu.org/licenses/>.  */
 
 #include <unistd.h>
-#include <sysdep-cancel.h>
+#include <sysdep.h>
 
 /* Write NBYTES of BUF to FD.  Return the number written, or -1.  */
 ssize_t
diff --git a/sysdeps/unix/sysv/linux/write_nocancel.c b/sysdeps/unix/sysv/linux/write_nocancel.c
index f57b53e9c9..589ec6d612 100644
--- a/sysdeps/unix/sysv/linux/write_nocancel.c
+++ b/sysdeps/unix/sysv/linux/write_nocancel.c
@@ -17,7 +17,6 @@
    <https://www.gnu.org/licenses/>.  */
 
 #include <unistd.h>
-#include <sysdep-cancel.h>
 #include <not-cancel.h>
 
 ssize_t
diff --git a/sysdeps/unix/sysv/linux/writev.c b/sysdeps/unix/sysv/linux/writev.c
index 77fc9c92e9..e0621c8546 100644
--- a/sysdeps/unix/sysv/linux/writev.c
+++ b/sysdeps/unix/sysv/linux/writev.c
@@ -18,7 +18,7 @@
 
 #include <unistd.h>
 #include <sys/uio.h>
-#include <sysdep-cancel.h>
+#include <sysdep.h>
 
 ssize_t
 __writev (int fd, const struct iovec *iov, int iovcnt)
-- 
2.17.1

^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [PATCH v3 14/21] nptl: m68k: Fix Race conditions in pthread cancellation (BZ#12683)
  2019-10-14 20:57 ` [PATCH v3 14/21] nptl: m68k: Fix Race conditions in pthread cancellation (BZ#12683) Adhemerval Zanella
@ 2019-10-14 21:13   ` Andreas Schwab
  0 siblings, 0 replies; 38+ messages in thread
From: Andreas Schwab @ 2019-10-14 21:13 UTC (permalink / raw)
  To: Adhemerval Zanella; +Cc: libc-alpha

On Okt 14 2019, Adhemerval Zanella <adhemerval.zanella@linaro.org> wrote:

> This patch adds the hppa modifications required for the BZ#12683 fix

s/hppa/m68k/

Andreas.

-- 
Andreas Schwab, schwab@linux-m68k.org
GPG Key fingerprint = 7578 EB47 D4E5 4D69 2510  2552 DF73 E780 A9DA AEC1
"And now for something completely different."

^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [PATCH v3 17/21] nptl: riscv: Fix Race conditions in pthread cancellation (BZ#12683)
  2019-10-14 20:57 ` [PATCH v3 17/21] nptl: riscv: " Adhemerval Zanella
@ 2019-10-14 23:22   ` Andrew Waterman
  0 siblings, 0 replies; 38+ messages in thread
From: Andrew Waterman @ 2019-10-14 23:22 UTC (permalink / raw)
  To: Adhemerval Zanella; +Cc: libc-alpha

The riscv changes look fine to me (but I didn't do any testing).


On Mon, Oct 14, 2019 at 2:00 PM Adhemerval Zanella
<adhemerval.zanella@linaro.org> wrote:
>
> This patch adds the riscv modifications required for the BZ#12683 fix
> by adding the arch-specific cancellation syscall bridge.
> ---
>  .../unix/sysv/linux/riscv/syscall_cancel.S    | 68 +++++++++++++++++++
>  1 file changed, 68 insertions(+)
>  create mode 100644 sysdeps/unix/sysv/linux/riscv/syscall_cancel.S
>
> diff --git a/sysdeps/unix/sysv/linux/riscv/syscall_cancel.S b/sysdeps/unix/sysv/linux/riscv/syscall_cancel.S
> new file mode 100644
> index 0000000000..38fd630c6d
> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/riscv/syscall_cancel.S
> @@ -0,0 +1,68 @@
> +/* Cancellable syscall wrapper.  Linux/riscv version.
> +   Copyright (C) 2019 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
> +   <http://www.gnu.org/licenses/>.  */
> +
> +#include <sysdep.h>
> +
> +/* long int __syscall_cancel_arch (int *cancelhandling,
> +                                  __syscall_arg_t nr,
> +                                  __syscall_arg_t arg1,
> +                                  __syscall_arg_t arg2,
> +                                  __syscall_arg_t arg3,
> +                                  __syscall_arg_t arg4,
> +                                  __syscall_arg_t arg5,
> +                                  __syscall_arg_t arg6)  */
> +
> +#ifdef SHARED
> +       .option pic
> +#else
> +       .option nopic
> +#endif
> +
> +ENTRY (__syscall_cancel_arch)
> +       mv      t1, a7
> +
> +       .globl __syscall_cancel_arch_start
> +       .type  __syscall_cancel_arch_start,@function
> +__syscall_cancel_arch_start:
> +       lw      a7, 0(a0)
> +       andi    a7, a7, 4       /* if (*ch & CANCELED_BITMASK)  */
> +       bnez    a7, 1f
> +
> +       mv      a7,a1
> +       mv      a0,a2
> +       mv      a1,a3
> +       mv      a2,a4
> +       mv      a3,a5
> +       mv      a4,a6
> +       mv      a5,t1
> +       scall
> +
> +       .globl __syscall_cancel_arch_end
> +       .type  __syscall_cancel_arch_end,@function
> +__syscall_cancel_arch_end:
> +       ret
> +
> +1:
> +       addi    sp, sp, -16
> +       cfi_def_cfa_offset (16)
> +       sd      ra, 8(sp)
> +       cfi_offset (ra, -8)
> +       call    __syscall_do_cancel
> +
> +END (__syscall_cancel_arch)
> +libc_hidden_def (__syscall_cancel_arch)
> --
> 2.17.1
>

^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [PATCH v3 01/21] nptl: Handle EPIPE on tst-cancel2
  2019-10-14 20:57 ` [PATCH v3 01/21] nptl: Handle EPIPE on tst-cancel2 Adhemerval Zanella
@ 2019-10-15  9:03   ` Florian Weimer
  0 siblings, 0 replies; 38+ messages in thread
From: Florian Weimer @ 2019-10-15  9:03 UTC (permalink / raw)
  To: Adhemerval Zanella; +Cc: libc-alpha

* Adhemerval Zanella:

> The SIGPIPE can be catched before SIGCANCEL, which makes write fail
> and the thread return an non expected result.
>
> Checked on x86_64-linux-gnu and powerpc64le-linux-gnu.
> ---
>  nptl/tst-cancel2.c | 3 ---
>  1 file changed, 3 deletions(-)
>
> diff --git a/nptl/tst-cancel2.c b/nptl/tst-cancel2.c
> index b22bd496a7..2df2c00578 100644
> --- a/nptl/tst-cancel2.c
> +++ b/nptl/tst-cancel2.c
> @@ -73,9 +73,6 @@ do_test (void)
>        return 1;
>      }
>  
> -  /* This will cause the write in the child to return.  */
> -  close (fd[0]);
> -
>    if (pthread_join (th, &r) != 0)
>      {
>        puts ("join failed");

Commit subject and message no longer match.

nptl/tst-cancel3.c needs the same change, I think.

Thanks,
Florian

^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [PATCH v3 02/21] nptl: Fix Race conditions in pthread cancellation (BZ#12683)
  2019-10-14 20:57 ` [PATCH v3 02/21] nptl: " Adhemerval Zanella
@ 2019-10-15 10:56   ` Florian Weimer
  2019-10-16 20:42     ` Adhemerval Zanella
  2019-10-18 12:38   ` Internal SIGTIMER use (was: Re: [PATCH v3 02/21] nptl: Fix Race conditions in pthread cancellation (BZ#12683)) Florian Weimer
  1 sibling, 1 reply; 38+ messages in thread
From: Florian Weimer @ 2019-10-15 10:56 UTC (permalink / raw)
  To: Adhemerval Zanella; +Cc: libc-alpha

* Adhemerval Zanella:

> This patch is the initial fix for race conditions in NPTL cancellation codei
> by redefining how cancellable syscalls are defined and handled.  Current
> buggy approach is to enable asynchronous cancellation prior to making the
> syscall and restore the previous cancellation type once the syscall returns.

First sentence appears to be garbled.

> As decribed in BZ#12683, this approach shows 2 important problems:
>
>   1. Cancellation can act after the syscall has returned from kernel, but
>      before userspace saves the return value.  It might result in a resource
>      leak if the syscall allocated a resource or a side effect (partial
>      read/write), and there is no way to program handle it with cancellation
>      handlers.
>
>   2. If a signal is handled while the thread is blocked at a cancellable
>      syscall, the entire signal handler runs with asynchronous cancellation
>      enabled.  This can lead to issues if the signal handler call functions
>      which are async-signal-safe but not async-cancel-safe.

Do you mean “the cancellation signal handler runs” or “any signal
handler runs”?  I think the latter is the much larger issue.

(I think it is customary to wrapper commit messages at column 72 or
something like that.)

> For cancellation to work correctly, there are 5 points at which the
> cancellation signal could arrive:
>
>   1. Before the final "testcancel" and before the syscall is made.
>   2. Between the "testcancel" and the syscall.
>   3. While the syscall is blocked and no side effects have yet taken place.
>   4. While the syscall is blocked but with some side effects already having
>      taken place (e.g. a partial read or write).
>   5. After the syscall has returned.

For clarity, I'd suggest to say whether we want unblocking to take place
(i.e., the cancellation should happen eventually without any further
external event, such as the arrival of more data).

> And GLIBC wants to act on cancellation in cases 1, 2, and 3 but not in case
> 4 or 5.  The proposed solution follows:
>
>   * Handling case 1 is trivial: do a conditional branch based on whether the
>     thread has received a cancellation request;
>
>   * Case 2 can be caught by the signal handler determining that the saved
>     program counter (from the ucontext_t) is in some address range beginning
>     just before the "testcancel" and ending with the syscall instruction.
>
>   * In this case, except for certain syscalls that ALWAYS fail with EINTR
>     even for non-interrupting signals, the kernel will reset the program
>     counter to point at the syscall instruction during signal handling, so
>     that the syscall is restarted when the signal handler returns. So, from
>     the signal handler's standpoint, this looks the same as case 2, and thus
>     it's taken care of.
>
>   * In this case, the kernel cannot restart the syscall; when it's
>     interrupted by a signal, the kernel must cause the syscall to return
>     with whatever partial result it obtained (e.g. partial read or write).
>
>   * In this case, the saved program counter points just after the syscall
>     instruction, so the signal handler won't act on cancellation.
>     This one is equal to 4. since the program counter is past the syscall
>     instruction already.

I'd suggest to match these items to the numbers explicitly.

> Another case that needs handling is syscalls that fail with EINTR even
> when the signal handler is non-interrupting. In this case, the syscall
> wrapper code can just check the cancellation flag when the errno result
> is EINTR, and act on cancellation if it's set.
>
> The proposed GLIBC adjustments are:
>
>   1. Remove the enable_asynccancel/disable_asynccancel function usage in
>      syscall definition and instead make them call a common symbol that will
>      check if cancellation is enabled (__syscall_cancel at
>      nptl/libc-cancellation.c), call the arch-specific cancellable
>      entry-point (__syscall_cancel_arch) and cancel the thread when required.
>
>   2. Provide a arch-specific symbol that contains global markers. These
>      markers will be used in SIGCANCEL handler to check if the interruption
>      has been called in a valid syscall and if the syscalls has been
>      completed or not.

An arch-specific generic system call wrapper function?

>      A reference implementation sysdeps/unix/sysv/linux/syscall_cancel.c is
>      provided.  However the markers may not be set on correct expected places
>      depeding of how INTERNAL_SYSCALL_NCS is implemented by the underlying
>      architecture, and it is uses compiler-speficic construct (asm volatile)
>      to place the required markers.  It is expected that all architectures
>      implement an arch-specific.

Truncated sentence.

>   3. Rewrite SIGCANCEL asynchronous handler to check for both cancelling type
>      and if current IP from signal handler falls between the global markes
>      and act accordingly (sigcancel_handler at nptl/nptl-init.c).

s/markes/markers/

> diff --git a/nptl/libc-cancellation.c b/nptl/libc-cancellation.c
> index 37654cfcfe..430e0b962e 100644
> --- a/nptl/libc-cancellation.c
> +++ b/nptl/libc-cancellation.c
> @@ -18,7 +18,46 @@
>  
>  #include "pthreadP.h"
>  
> +/* Cancellation function called by all cancellable syscalls.  */
> +long int
> +__syscall_cancel (__syscall_arg_t nr, __syscall_arg_t a1,
> +		  __syscall_arg_t a2, __syscall_arg_t a3,
> +		  __syscall_arg_t a4, __syscall_arg_t a5,
> +		  __syscall_arg_t a6)
> +{

long int as the return value may not be quite right on x32.

> +  pthread_t self = (pthread_t) THREAD_SELF;
> +  struct pthread *pd = (struct pthread *) self;
> +  long int result;

I would use inline definitions for new code, but that's your choice.

> @@ -286,38 +277,49 @@ __pthread_initialize_minimal_internal (void)
>    THREAD_SETMEM (pd, report_events, __nptl_initial_report_events);
>  
>  #if defined SIGCANCEL || defined SIGSETXID
> -  struct sigaction sa;
> -  __sigemptyset (&sa.sa_mask);
>  
>  # ifdef SIGCANCEL
>    /* Install the cancellation signal handler.  If for some reason we
>       cannot install the handler we do not abort.  Maybe we should, but
>       it is only asynchronous cancellation which is affected.  */
> -  sa.sa_sigaction = sigcancel_handler;
> -  sa.sa_flags = SA_SIGINFO;
> -  (void) __libc_sigaction (SIGCANCEL, &sa, NULL);
> +  {
> +    struct sigaction sa;
> +    sa.sa_sigaction = sigcancel_handler;
> +    /* The signal handle should be non-interruptible to avoid the risk of
> +       spurious EINTR caused by SIGCANCEL sent to process or if pthread_cancel
> +       is called while cancellation is disabled in the target thread.  */
> +    sa.sa_flags = SA_SIGINFO | SA_RESTART;
> +    sa.sa_mask = SIGALL_SET;
> +    __libc_sigaction (SIGCANCEL, &sa, NULL);
> +  }
>  # endif

I'm a little bit concerned that adding SA_RESTART here adds more case
where we do not act on cancellation promptly.  But that does not happen
because if we observe the cancellation conditions to apply in the
SIGCANCEL handler, we unwind straight from the signal handler, right?

> diff --git a/nptl/pthreadP.h b/nptl/pthreadP.h
> index 070b3afa8d..cafd14f5af 100644
> --- a/nptl/pthreadP.h
> +++ b/nptl/pthreadP.h
> @@ -296,20 +296,46 @@ extern void __nptl_unwind_freeres (void) attribute_hidden;
>  #endif
>  
>  
> -/* Called when a thread reacts on a cancellation request.  */
>  static inline void
>  __attribute ((noreturn, always_inline))
> -__do_cancel (void)
> +__do_cancel_with_result (void *result)
>  {
>    struct pthread *self = THREAD_SELF;
>  
> -  /* Make sure we get no more cancellations.  */
> -  THREAD_ATOMIC_BIT_SET (self, cancelhandling, EXITING_BIT);
> +  /* Make sure we get no more cancellations by clearing the cancel
> +     state.  */
> +  int oldval = THREAD_GETMEM (self, cancelhandling);
> +  while (1)
> +    {
> +      int newval = oldval | CANCELSTATE_BITMASK | EXITING_BITMASK;
> +      if (oldval == newval)
> +	break;
> +
> +      oldval = THREAD_ATOMIC_CMPXCHG_VAL (self, cancelhandling, newval,
> +					  oldval);
> +    }
> +
> +  THREAD_SETMEM (self, result, result);
>  
>    __pthread_unwind ((__pthread_unwind_buf_t *)
>  		    THREAD_GETMEM (self, cleanup_jmp_buf));
>  }

The function name should be more generic because it's for unwinding, not
cancellation.

> diff --git a/nptl/pthread_cancel.c b/nptl/pthread_cancel.c
> index 64ac12e60a..b20254bdba 100644
> --- a/nptl/pthread_cancel.c
> +++ b/nptl/pthread_cancel.c
> @@ -37,67 +37,24 @@ __pthread_cancel (pthread_t th)

> +  /* Avoid signaling when thread attempts cancel itself (pthread_kill
> +     is expensive).  */
> +  if (pd == THREAD_SELF
> +      && (THREAD_GETMEM (pd, cancelhandling) & CANCELTYPE_BITMASK) == 0)
> +    return 0;

I'm not sure if I understand this check.  CANCELTYPE_BITMASK is a bit
misnamed (it's a single-bit masking).  As far as I understand it, it's
set if async-cancel is enabled.  Shouldn't we call __do_cancel directly
here in case of an async self-cancel?  And otherwise defer cancellation?

> diff --git a/nptl/pthread_create.c b/nptl/pthread_create.c
> index 130937c3c4..8cab7f970c 100644
> --- a/nptl/pthread_create.c
> +++ b/nptl/pthread_create.c
> @@ -406,7 +406,7 @@ START_THREAD_DEFN
>    /* If the parent was running cancellation handlers while creating
>       the thread the new thread inherited the signal mask.  Reset the
>       cancellation signal mask.  */
> -  if (__glibc_unlikely (pd->parent_cancelhandling & CANCELING_BITMASK))
> +  if (__glibc_unlikely (pd->parent_cancelhandling & CANCELED_BITMASK))
>      {
>        INTERNAL_SYSCALL_DECL (err);
>        sigset_t mask;

This conflicts with the patch I posted for bug 25098.  My change resets
the SIGCANCEL mask unconditionally, so the check is gone completely and
no longer needs adjustment.

> @@ -449,7 +449,8 @@ START_THREAD_DEFN
>  	 have ownership (see CONCURRENCY NOTES above).  */
>        if (__glibc_unlikely (pd->stopped_start))
>  	{
> -	  int oldtype = CANCEL_ASYNC ();
> +	  int ct;
> +	  __pthread_setcanceltype (PTHREAD_CANCEL_ASYNCHRONOUS, &ct);
>  
>  	  /* Get the lock the parent locked to force synchronization.  */
>  	  lll_lock (pd->lock, LLL_PRIVATE);
> @@ -459,7 +460,7 @@ START_THREAD_DEFN
>  	  /* And give it up right away.  */
>  	  lll_unlock (pd->lock, LLL_PRIVATE);
>  
> -	  CANCEL_RESET (oldtype);
> +	  __pthread_setcanceltype (ct, NULL);
>  	}

I think htis is wrong.  Either you need to use a cancellable lll_lock
here.  Or maybe it is not even necessary to enable cancellation at all
because the new tread is eventually bound to make progress and will wake
up the futuex.

> diff --git a/sysdeps/nptl/librt-cancellation.c b/nptl/pthread_kill_internal.c
> similarity index 70%
> rename from sysdeps/nptl/librt-cancellation.c
> rename to nptl/pthread_kill_internal.c
> index 93ebe4aa71..b4f4f6dc78 100644
> --- a/sysdeps/nptl/librt-cancellation.c
> +++ b/nptl/pthread_kill_internal.c
> @@ -1,6 +1,6 @@
> -/* Copyright (C) 2002-2019 Free Software Foundation, Inc.
> +/* Send a signal to a specific pthread.  Internal version.
> +   Copyright (C) 2002-2019 Free Software Foundation, Inc.
>     This file is part of the GNU C Library.
> -   Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
>  
>     The GNU C Library is free software; you can redistribute it and/or
>     modify it under the terms of the GNU Lesser General Public
> @@ -16,9 +16,11 @@
>     License along with the GNU C Library; if not, see
>     <https://www.gnu.org/licenses/>.  */
>  
> -#include <nptl/pthreadP.h>
> +#include <pthreadP.h>
>  
> -
> -#define __pthread_enable_asynccancel __librt_enable_asynccancel
> -#define __pthread_disable_asynccancel __librt_disable_asynccancel
> -#include <nptl/cancellation.c>
> +int
> +__pthread_kill_internal (pthread_t threadid, int signo)
> +{
> +  return ENOSYS;
> +}
> +hidden_def (__pthread_kill_internal)

I don't think we need this stub.

> diff --git a/nptl/pthread_setcanceltype.c b/nptl/pthread_setcanceltype.c
> index d771c31e46..84cc657aed 100644
> --- a/nptl/pthread_setcanceltype.c
> +++ b/nptl/pthread_setcanceltype.c
> @@ -73,4 +73,4 @@ __pthread_setcanceltype (int type, int *oldtype)
>  
>    return 0;
>  }
> -strong_alias (__pthread_setcanceltype, pthread_setcanceltype)
> +weak_alias (__pthread_setcanceltype, pthread_setcanceltype)

Why is this change necessary?  pthread_setcanceltype is the only
function defined in this file, so there are no issues with static
linking.  I'm concerned that this hides a problem elsewhere.

> diff --git a/nptl/thrd_sleep.c b/nptl/thrd_sleep.c
> index 2e185dd748..75c0d53f3e 100644
> --- a/nptl/thrd_sleep.c
> +++ b/nptl/thrd_sleep.c
> @@ -24,13 +24,12 @@
>  int
>  thrd_sleep (const struct timespec* time_point, struct timespec* remaining)
>  {
> -  INTERNAL_SYSCALL_DECL (err);
> -  int ret = INTERNAL_SYSCALL_CANCEL (nanosleep, err, time_point, remaining);
> -  if (INTERNAL_SYSCALL_ERROR_P (ret, err))
> +  long int ret = INTERNAL_SYSCALL_CANCEL (nanosleep, time_point, remaining);

The return type may need adjustment if the return type for the
cancellation wrapper changes.

> diff --git a/nptl/tst-cancel28.c b/nptl/tst-cancel28.c
> new file mode 100644
> index 0000000000..e27f5a0776
> --- /dev/null
> +++ b/nptl/tst-cancel28.c

> +static void *
> +writeopener (void *arg)
> +{
> +  int fd;
> +  for (;;)
> +    {
> +      fd = open (arg, O_WRONLY);
> +      close (fd);
> +    }
> +  return NULL;
> +}
> +
> +static void *
> +leaker (void *arg)
> +{
> +  int fd = open (arg, O_RDONLY);
> +  TEST_VERIFY_EXIT (fd > 0);
> +  pthread_setcancelstate (PTHREAD_CANCEL_DISABLE, 0);
> +  close (fd);
> +  return NULL;
> +}

I think these two functions *really* should check the return value of
close (or use xclose).

> +#define ITER_COUNT 1000
> +#define MAX_FILENO 1024

MAX_FILENO appears to be unused.

> +#define TIMEOUT 10
> +#include <support/test-driver.c>

TIMEOUT is smaller than the default test timeout.

> diff --git a/sysdeps/htl/pthreadP.h b/sysdeps/htl/pthreadP.h
> index e745dacac1..5628791de8 100644
> --- a/sysdeps/htl/pthreadP.h
> +++ b/sysdeps/htl/pthreadP.h
> @@ -25,6 +25,7 @@
>  
>  extern pthread_t __pthread_self (void);
>  extern int __pthread_kill (pthread_t threadid, int signo);
> +extern int __pthread_kill_internal (pthread_t threadid, int signo);
>  extern struct __pthread **__pthread_threads;
>  
>  extern int _pthread_mutex_init (pthread_mutex_t *mutex, const pthread_mutexattr_t *attr);

This change appears unnecessary because __pthread_kill_internal does not
seem to be used outside of nptl.

> diff --git a/sysdeps/nptl/cancellation-pc-check.h b/sysdeps/nptl/cancellation-pc-check.h
> new file mode 100644
> index 0000000000..8b26c4ec4e
> --- /dev/null
> +++ b/sysdeps/nptl/cancellation-pc-check.h

> +/* Check if the program counter (PC) from ucontext CTX is within the start and
> +   then end boundary from the __syscall_cancel_arch bridge.  Return TRUE if
> +   the PC is within the boundary, meaning the syscall does not have any side
> +   effects; or FALSE otherwise.  */
> +static bool
> +ucontext_check_pc_boundary (void *ctx)
> +{
> +  /* Both are defined in syscall_cancel.S.  */
> +  extern const char __syscall_cancel_arch_start[1];
> +  extern const char __syscall_cancel_arch_end[1];
> +
> +  uintptr_t pc = sigcontext_get_pc (ctx);
> +  return pc >= (uintptr_t) __syscall_cancel_arch_start
> +	 && pc < (uintptr_t) __syscall_cancel_arch_end;
> +}

The name of this function should reflect that it is related to
cancellation.

Please add a comment explaining the kernel behavior regarding PC
(non-interrupted vs interrupted system calls), as found in the commit
message.

> +#endif
> diff --git a/sysdeps/nptl/cancellation-sigmask.h b/sysdeps/nptl/cancellation-sigmask.h
> new file mode 100644
> index 0000000000..77702c135e
> --- /dev/null
> +++ b/sysdeps/nptl/cancellation-sigmask.h

> +/* Add the SIGCANCEL signal on sigmask set at the ucontext CTX obtained from
> +   the sigaction handler.  */
> +static void
> +ucontext_add_cancel (void *ctx)
> +{
> +  __sigaddset (&((ucontext_t*) ctx)->uc_sigmask, SIGCANCEL);
> +}

I find the name of the function rather unclear.  Maybe
ucontext_block_sigcancel or something like that.

> diff --git a/sysdeps/unix/sysdep.h b/sysdeps/unix/sysdep.h
> index 10468c7129..04f30b8cbc 100644
> --- a/sysdeps/unix/sysdep.h
> +++ b/sysdeps/unix/sysdep.h

> +#define __SYSCALL_CANCEL0(name) \
> +  (__syscall_cancel)(__NR_##name, 0, 0, 0, 0, 0, 0)

There are a bunch of formatting nits in the changes to this file.
“)(” should be “) (”.  Likewise for “__SSC(”.

> diff --git a/sysdeps/unix/sysv/linux/clock_nanosleep.c b/sysdeps/unix/sysv/linux/clock_nanosleep.c
> index 1f240b8720..ddcdddcd5d 100644
> --- a/sysdeps/unix/sysv/linux/clock_nanosleep.c
> +++ b/sysdeps/unix/sysv/linux/clock_nanosleep.c
> @@ -36,11 +36,9 @@ __clock_nanosleep (clockid_t clock_id, int flags, const struct timespec *req,
>  
>    /* If the call is interrupted by a signal handler or encounters an error,
>       it returns a positive value similar to errno.  */
> -  INTERNAL_SYSCALL_DECL (err);
> -  int r = INTERNAL_SYSCALL_CANCEL (clock_nanosleep, err, clock_id, flags,
> +  int r = INTERNAL_SYSCALL_CANCEL (clock_nanosleep, clock_id, flags,
>  				   req, rem);
> -  return (INTERNAL_SYSCALL_ERROR_P (r, err)
> -	  ? INTERNAL_SYSCALL_ERRNO (r, err) : 0);
> +  return SYSCALL_CANCEL_ERROR (r) ? -r : 0;
>  }

Shouldn't r change type here?

> diff --git a/sysdeps/unix/sysv/linux/lowlevellock-futex.h b/sysdeps/unix/sysv/linux/lowlevellock-futex.h
> index b423673ed4..bd6d3b7cf7 100644
> --- a/sysdeps/unix/sysv/linux/lowlevellock-futex.h
> +++ b/sysdeps/unix/sysv/linux/lowlevellock-futex.h
> @@ -74,6 +74,12 @@
>       ? -INTERNAL_SYSCALL_ERRNO (__ret, __err) : 0);                     \
>    })
>  
> +#define lll_futex_syscall_cp(...)					\
> +  ({                                                                    \
> +    long int __ret = INTERNAL_SYSCALL_CANCEL (futex, __VA_ARGS__);	\
> +    __ret;								\
> +  })
> +

The statement expression appears unnecessary here.

> +#define lll_futex_timed_wait_cancel(futexp, val, timeout, private)	\
> +  ({									\
> +    long int __ret;							\
> +    int __op = FUTEX_WAIT;						\
> +    __ret = lll_futex_syscall_cp (futexp,				\
> +				  __lll_private_flag (__op, private),	\
> +				  val, timeout);			\
> +    __ret;								\
>    })

Is the statement expression needed?  Should this be an inline function?

>  
> -#define lll_futex_timed_wait_cancel(futexp, val, timeout, private)	   \
> -  ({									   \
> -    int __oldtype = CANCEL_ASYNC ();				       	   \
> -    long int __err = lll_futex_timed_wait (futexp, val, timeout, private); \
> -    CANCEL_RESET (__oldtype);						   \
> -    __err;								   \
> +#define lll_futex_clock_wait_bitset_cancel(futexp, val, clockid,	\
> +					   timeout, private)		\
> +  ({									\
> +    long int __ret;							\
> +    if (lll_futex_supported_clockid (clockid))                          \
> +      {                                                                 \
> +        const unsigned int clockbit =                                   \
> +          (clockid == CLOCK_REALTIME) ? FUTEX_CLOCK_REALTIME : 0;       \
> +        const int op =                                                  \
> +          __lll_private_flag (FUTEX_WAIT_BITSET | clockbit, private);   \
> +									\
> +	__ret = lll_futex_syscall_cp (futexp, op, val,			\
> +                                      timeout, NULL /* Unused.  */,	\
> +                                      FUTEX_BITSET_MATCH_ANY);		\
> +      }									\
> +    else								\
> +      __ret = -EINVAL;							\
> +    __ret;								\
>    })

I do think this should be an inline function.

> --- a/sysdeps/unix/sysv/linux/pthread_kill.c
> +++ b/sysdeps/unix/sysv/linux/pthread_kill_internal.c
> @@ -16,24 +16,15 @@

> -strong_alias (__pthread_kill, pthread_kill)
> +hidden_def (__pthread_kill_internal)

Why hidden_def?  I think you should use attribute_hidden on the
declaration and drop the libc_hidden_proto instead.

> diff --git a/sysdeps/unix/sysv/linux/syscall_cancel.c b/sysdeps/unix/sysv/linux/syscall_cancel.c
> new file mode 100644
> index 0000000000..79d66ec4f4
> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/syscall_cancel.c

> +long int
> +__syscall_cancel_arch (volatile int *ch, __syscall_arg_t nr,
> +		       __syscall_arg_t a1, __syscall_arg_t a2,
> +		       __syscall_arg_t a3, __syscall_arg_t a4,
> +		       __syscall_arg_t a5, __syscall_arg_t a6)
> +{
> +#define ADD_LABEL(__label)		\
> +  asm volatile (			\
> +    ".global " __label "\t\n"		\
> +    ".type " __label ",\%function\t\n" 	\
> +    __label ":\n");
> +
> +  ADD_LABEL ("__syscall_cancel_arch_start");
> +  if (__glibc_unlikely (*ch & CANCELED_BITMASK))
> +    __syscall_do_cancel();
> +
> +  INTERNAL_SYSCALL_DECL(err);
> +  long int result = INTERNAL_SYSCALL_NCS (nr, err, 6, a1, a2, a3, a4, a5, a6);
> +  ADD_LABEL ("__syscall_cancel_arch_end");
> +  if (__glibc_unlikely (INTERNAL_SYSCALL_ERROR_P (result, err)))
> +    return -INTERNAL_SYSCALL_ERRNO (result, err);
> +  return result;
> +}
> +libc_hidden_def (__syscall_cancel_arch)

For bootstrapping, this is good enough, but I think we really, *really*
should remove this function, so that new ports do not use it by
accident.

> diff --git a/sysdeps/unix/sysv/linux/sysdep.h b/sysdeps/unix/sysv/linux/sysdep.h
> index fc9af51456..317bb7f973 100644
> --- a/sysdeps/unix/sysv/linux/sysdep.h
> +++ b/sysdeps/unix/sysv/linux/sysdep.h
> @@ -27,6 +27,26 @@
>      -1l;					\
>    })
>  
> +/* Check error from cancellable syscall and set errno accordingly.
> +   Linux uses a negative return value to indicate syscall errors
> +   and since version 2.1 the return value of a system call might be
> +   negative even if the call succeeded (e.g., the `lseek' system call
> +   might return a large offset).
> +   Current contract is kernel make sure the no syscall returns a value
> +   in -1 .. -4095 as a valid result so we can savely test with -4095.  */
> +#define SYSCALL_CANCEL_ERROR(__ret)		\
> +  (__ret > -4096UL)

This doesn't look particularly type-safe.  Does it have to be a macro?
If it is a macro, can we add type checks?

> +#define SYSCALL_CANCEL_RET(__ret)		\
> +  ({						\
> +    if (SYSCALL_CANCEL_ERROR(__ret))		\
> +      {						\
> +	__set_errno (-__ret);			\
> +	__ret = -1;				\
> +      }						\
> +    __ret;					\
> +   })
> +
>  /* Provide a dummy argument that can be used to force register
>     alignment for register pairs if required by the syscall ABI.  */
>  #ifdef __ASSUME_ALIGNED_REGISTER_PAIRS

I initially found this split from sysdeps/unix/sysdep.h a bit strange,
but I guess it does reflect the current layering.

Additional notes: {LIBC_,}CANCEL_{ASYNC,RESET} should be removed
everywhere as soon as possible.  This may have a knockpm-effect where
__pthread_disable_asynccancel etc. can go as well.

Thanks,
Florian

^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [PATCH v3 03/21] nptl: x86_64: Fix Race conditions in pthread cancellation (BZ#12683)
  2019-10-14 20:57 ` [PATCH v3 03/21] nptl: x86_64: " Adhemerval Zanella
@ 2019-10-15 11:03   ` Florian Weimer
  2019-10-16 21:22     ` Adhemerval Zanella
  0 siblings, 1 reply; 38+ messages in thread
From: Florian Weimer @ 2019-10-15 11:03 UTC (permalink / raw)
  To: Adhemerval Zanella; +Cc: libc-alpha

* Adhemerval Zanella:

> diff --git a/sysdeps/unix/sysv/linux/x86_64/syscall_cancel.S b/sysdeps/unix/sysv/linux/x86_64/syscall_cancel.S
> new file mode 100644
> index 0000000000..c7364bfff8
> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/x86_64/syscall_cancel.S

> +ENTRY (__syscall_cancel_arch)
> +
> +	.globl __syscall_cancel_arch_start
> +	.type  __syscall_cancel_arch_start,@function

I don't think we should specify a type for this symbol.  It's not a
function.

> +__syscall_cancel_arch_start:
> +
> +	/* if (*cancelhandling & CANCELED_BITMASK)
> +	     __syscall_do_cancel()  */
> +	mov    (%rdi),%eax
> +	testb  $4, (%rdi)
> +	jne    __syscall_do_cancel

I'm pretty sure 4 should be one of the _BITMASK constants.

> +	/* Issue a 6 argument syscall, the nr [%rax] being the syscall
> +	   number.  */
> +	mov    %rdi,%r11
> +	mov    %rsi,%rax
> +	mov    %rdx,%rdi
> +	mov    %rcx,%rsi
> +	mov    %r8,%rdx
> +	mov    %r9,%r10
> +	mov    8(%rsp),%r8
> +	mov    16(%rsp),%r9
> +	mov    %r11,8(%rsp)
> +	syscall
> +
> +	.globl __syscall_cancel_arch_end
> +	.type  __syscall_cancel_arch_end,@function

Again, no type here please.  It will confuse the disassembler.

Thanks,
Florian

^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [PATCH v3 04/21] nptl: x32: Fix Race conditions in pthread cancellation (BZ#12683)
  2019-10-14 20:57 ` [PATCH v3 04/21] nptl: x32: " Adhemerval Zanella
@ 2019-10-15 11:06   ` Florian Weimer
  0 siblings, 0 replies; 38+ messages in thread
From: Florian Weimer @ 2019-10-15 11:06 UTC (permalink / raw)
  To: Adhemerval Zanella; +Cc: libc-alpha

* Adhemerval Zanella:

> This patches adds the x32 modification required for the BZ#12683.
> It basically adjust the syscall size used to pass the arguments to
> the syscall cancel wrappers by zero extending pointers type while
> preserting values for default types (such as off_t).

The commit message does not discuss the changes to
include/libc-pointer-arith.h, but I think it should.

I've already raised in the first patch whether

> +typedef long long int __syscall_arg_t;

should affect the return value of the syscall wrapper, too.

Thanks,
Florian

^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [PATCH v3 18/21] nptl: s390: Fix Race conditions in pthread cancellation (BZ#12683)
  2019-10-14 20:57 ` [PATCH v3 18/21] nptl: s390: " Adhemerval Zanella
@ 2019-10-16 15:46   ` Stefan Liebler
  2019-10-17 13:54     ` Adhemerval Zanella
  0 siblings, 1 reply; 38+ messages in thread
From: Stefan Liebler @ 2019-10-16 15:46 UTC (permalink / raw)
  To: libc-alpha

[-- Attachment #1: Type: text/plain, Size: 7914 bytes --]

Hi Adhemerval,

I've added some notes below to the s390-64 file, but the same applies 
also for s390-32. I've also attached a diff.

I've also recognized that a call starting from e.g. write () involves 
various shuffling of the argument registers at each level:
write (ARGS in r2-r4)
-> __syscall_cancel (r2=nr, ARGS in r3-r6 and two stack-slots)
--> __syscall_cancel_arch (r2=*ch, r3=nr, ARGS in r4-r6 and three 
stack-slots)
---> "syscall-instruction" (ARGS in r2-r7)

Just as a quick idea (I don't know if there are other limitations), 
those shuffling instructions could perhaps be omitted if the nr / ch 
arguments of the __syscall_cancel / __syscall_cancel_arch functions 
would be the last arguments instead of the first ones.
I assume that also other archs could benefit from such an ordering.

Bye,
Stefan

On 10/14/19 10:56 PM, Adhemerval Zanella wrote:
> This patch adds the s390 modifications required for the BZ#12683 fix
> by adding the arch-specific cancellation syscall bridge.
> 
> Checked on s390-linux-gnu and s390x-linux-gnu.
> ---
>   .../sysv/linux/s390/s390-32/syscall_cancel.S  | 83 +++++++++++++++++++
>   .../sysv/linux/s390/s390-64/syscall_cancel.S  | 83 +++++++++++++++++++
>   2 files changed, 166 insertions(+)
>   create mode 100644 sysdeps/unix/sysv/linux/s390/s390-32/syscall_cancel.S
>   create mode 100644 sysdeps/unix/sysv/linux/s390/s390-64/syscall_cancel.S
> 
> diff --git a/sysdeps/unix/sysv/linux/s390/s390-32/syscall_cancel.S b/sysdeps/unix/sysv/linux/s390/s390-32/syscall_cancel.S
> new file mode 100644
> index 0000000000..3c934addbd
> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/s390/s390-32/syscall_cancel.S
> @@ -0,0 +1,83 @@
> +/* Cancellable syscall wrapper.  Linux/s390 version.
> +   Copyright (C) 2019 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
> +   <http://www.gnu.org/licenses/>.  */
> +
> +#include <sysdep.h>
> +
> +/* long int __syscall_cancel_arch (int *cancelhandling,
> +				   __syscall_arg_t nr,
> +				   __syscall_arg_t arg1,
> +				   __syscall_arg_t arg2,
> +				   __syscall_arg_t arg3,
> +				   __syscall_arg_t arg4,
> +				   __syscall_arg_t arg5,
> +				   __syscall_arg_t arg6)  */
> +
> +ENTRY (__syscall_cancel_arch)
> +	stm	%r6,%r15,24(%r15)
> +	cfi_offset (6, -72)
> +	cfi_offset (7, -68)
> +	cfi_offset (8, -64)
> +	cfi_offset (9, -60)
> +	cfi_offset (10, -56)
> +	cfi_offset (11, -52)
> +	cfi_offset (12, -48)
> +	cfi_offset (13, -44)
> +	cfi_offset (14, -40)
> +	cfi_offset (15, -36)
> +	ahi	%r15, -96
> +	cfi_def_cfa_offset (192)
> +
> +	.globl __syscall_cancel_arch_start
> +	.type  __syscall_cancel_arch_start,@function
> +__syscall_cancel_arch_start:
> +	l	%r0, 0(%r2)
> +	tml	%r0, 4
> +	jne	1f
> +	lr	%r1, %r3
> +	lr	%r2, %r4
> +	lr	%r3, %r5
> +	lr	%r4, %r6
> +	l	%r5, 192(%r15)
> +	l	%r6, 196(%r15)
> +	l	%r7, 200(%r15)
> +	svc	0
> +
> +	.globl __syscall_cancel_arch_end
> +	.type  __syscall_cancel_arch_end,@function
> +__syscall_cancel_arch_end:
> +	l	%r4, 152(%r15)
> +	lm	%r6, %r15, 120(%r15)
> +	cfi_remember_state
> +	cfi_restore (15)
> +	cfi_restore (14)
> +	cfi_restore (13)
> +	cfi_restore (12)
> +	cfi_restore (11)
> +	cfi_restore (10)
> +	cfi_restore (9)
> +	cfi_restore (8)
> +	cfi_restore (7)
> +	cfi_restore (6)
> +	cfi_def_cfa_offset (96)
> +	br	%r4
> +
> +1:
> +	cfi_restore_state
> +	brasl	%r14, __syscall_do_cancel
> +END (__syscall_cancel_arch)
> +libc_hidden_def (__syscall_cancel_arch)
> 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 0000000000..3480020fbb
> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/s390/s390-64/syscall_cancel.S
> @@ -0,0 +1,83 @@
> +/* Cancellable syscall wrapper.  Linux/s390x version.
> +   Copyright (C) 2019 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
> +   <http://www.gnu.org/licenses/>.  */
> +
> +#include <sysdep.h>
> +
> +/* long int __syscall_cancel_arch (int *cancelhandling,
> +				   __syscall_arg_t nr,
> +				   __syscall_arg_t arg1,
> +				   __syscall_arg_t arg2,
> +				   __syscall_arg_t arg3,
> +				   __syscall_arg_t arg4,
> +				   __syscall_arg_t arg5,
> +				   __syscall_arg_t arg6)  */
> +
> +ENTRY (__syscall_cancel_arch)
> +	stmg	%r6, %r15, 48(%r15)
Please omit the spaces between the operands to have the same style as 
below (the same applies to multiple instructions in the s390-32 file.

> +	cfi_offset (6, -112)
Please use e.g. %r6 instead of just 6 for the cfi statements here and 
below for cfi_restore.
> +	cfi_offset (7, -104)
> +	cfi_offset (8, -96)
> +	cfi_offset (9, -88)
> +	cfi_offset (10, -80)
> +	cfi_offset (11, -72)
> +	cfi_offset (12, -64)
> +	cfi_offset (13, -56)
> +	cfi_offset (14, -48)
> +	cfi_offset (15, -40)
> +	aghi	%r15,-160
> +	cfi_def_cfa_offset (320)
I think the new stack frame is not needed at all.  The kernel does not 
clobber any registers and also does not need an own stack frame.
(I've recognized that syscall.S also contains an extra frame and I will 
work on a patch)

Then r8-r15 are not clobbered here and we just have to store and restore 
r6 and r7.
> +
> +	.globl __syscall_cancel_arch_start
> +	.type  __syscall_cancel_arch_start,@function
> +__syscall_cancel_arch_start:
Could you add the comments like e.g. done in the x86_64 patch?
	/* if (*cancelhandling & CANCELED_BITMASK)
	     __syscall_do_cancel()  */
> +	l	%r0,0(%r2)
> +	tmll	%r0,4
We can combine l and tmll here:
tm 3(%r2),4

> +	jne	1f
	/* Issue a 6 argument syscall, the nr [%r1] being the syscall
	   number.  */
> +	lgr	%r1,%r3
> +	lgr	%r2,%r4
> +	lgr	%r3,%r5
> +	lgr	%r4,%r6
> +	lg	%r5,320(%r15)
> +	lg	%r6,328(%r15)
> +	lg	%r7,336(%r15)
We can use lmg in order to load r5-r7.
> +	svc	0
> +
> +	.globl __syscall_cancel_arch_end
> +	.type  __syscall_cancel_arch_end,@function
> +__syscall_cancel_arch_end:
> +	lg	%r4,272(%r15)
> +	lmg	%r6,%r15,208(%r15)
> +	cfi_remember_state
> +	cfi_restore (15)
> +	cfi_restore (14)
> +	cfi_restore (13)
> +	cfi_restore (12)
> +	cfi_restore (11)
> +	cfi_restore (10)
> +	cfi_restore (9)
> +	cfi_restore (8)
> +	cfi_restore (7)
> +	cfi_restore (6)
> +	cfi_def_cfa_offset (160)
> +	br	%r4
> +
> +1:
> +	cfi_restore_state
> +	brasl	%r14, __syscall_do_cancel
We can just use jg __syscall_do_cancel for this not-returning-tail-call.
(For the s390-32 part: Both instructions are z900 instructions, but as 
gcc has removed support for g5 and g6, this is okay at this point of time)
> +END (__syscall_cancel_arch)
> +libc_hidden_def (__syscall_cancel_arch)
> 


[-- Attachment #2: 20191016_s390_syscall_cancel.patch --]
[-- Type: text/x-patch, Size: 3715 bytes --]

diff --git a/sysdeps/unix/sysv/linux/s390/s390-32/syscall_cancel.S b/sysdeps/unix/sysv/linux/s390/s390-32/syscall_cancel.S
index 3c934addbd..faa32b3e99 100644
--- a/sysdeps/unix/sysv/linux/s390/s390-32/syscall_cancel.S
+++ b/sysdeps/unix/sysv/linux/s390/s390-32/syscall_cancel.S
@@ -28,56 +28,38 @@
 				   __syscall_arg_t arg6)  */
 
 ENTRY (__syscall_cancel_arch)
-	stm	%r6,%r15,24(%r15)
-	cfi_offset (6, -72)
-	cfi_offset (7, -68)
-	cfi_offset (8, -64)
-	cfi_offset (9, -60)
-	cfi_offset (10, -56)
-	cfi_offset (11, -52)
-	cfi_offset (12, -48)
-	cfi_offset (13, -44)
-	cfi_offset (14, -40)
-	cfi_offset (15, -36)
-	ahi	%r15, -96
-	cfi_def_cfa_offset (192)
+	stm	%r6,%r7,24(%r15)
+	cfi_offset (%r6, -72)
+	cfi_offset (%r7, -68)
 
 	.globl __syscall_cancel_arch_start
 	.type  __syscall_cancel_arch_start,@function
 __syscall_cancel_arch_start:
-	l	%r0, 0(%r2)
-	tml	%r0, 4
+	/* if (*cancelhandling & CANCELED_BITMASK)
+	     __syscall_do_cancel()  */
+	tm	3(%r2),4
 	jne	1f
-	lr	%r1, %r3
-	lr	%r2, %r4
-	lr	%r3, %r5
-	lr	%r4, %r6
-	l	%r5, 192(%r15)
-	l	%r6, 196(%r15)
-	l	%r7, 200(%r15)
+
+	/* Issue a 6 argument syscall, the nr [%r1] being the syscall
+	   number.  */
+	lr	%r1,%r3
+	lr	%r2,%r4
+	lr	%r3,%r5
+	lr	%r4,%r6
+	lm	%r5,%r7,96(%r15)
 	svc	0
 
 	.globl __syscall_cancel_arch_end
 	.type  __syscall_cancel_arch_end,@function
 __syscall_cancel_arch_end:
-	l	%r4, 152(%r15)
-	lm	%r6, %r15, 120(%r15)
+	lm	%r6,%r7,24(%r15)
 	cfi_remember_state
-	cfi_restore (15)
-	cfi_restore (14)
-	cfi_restore (13)
-	cfi_restore (12)
-	cfi_restore (11)
-	cfi_restore (10)
-	cfi_restore (9)
-	cfi_restore (8)
-	cfi_restore (7)
-	cfi_restore (6)
-	cfi_def_cfa_offset (96)
-	br	%r4
+	cfi_restore (%r7)
+	cfi_restore (%r6)
+	br	%r14
 
 1:
 	cfi_restore_state
-	brasl	%r14, __syscall_do_cancel
+	jg	__syscall_do_cancel
 END (__syscall_cancel_arch)
 libc_hidden_def (__syscall_cancel_arch)
diff --git a/sysdeps/unix/sysv/linux/s390/s390-64/syscall_cancel.S b/sysdeps/unix/sysv/linux/s390/s390-64/syscall_cancel.S
index 3480020fbb..7ea6bf48be 100644
--- a/sysdeps/unix/sysv/linux/s390/s390-64/syscall_cancel.S
+++ b/sysdeps/unix/sysv/linux/s390/s390-64/syscall_cancel.S
@@ -28,56 +28,38 @@
 				   __syscall_arg_t arg6)  */
 
 ENTRY (__syscall_cancel_arch)
-	stmg	%r6, %r15, 48(%r15)
-	cfi_offset (6, -112)
-	cfi_offset (7, -104)
-	cfi_offset (8, -96)
-	cfi_offset (9, -88)
-	cfi_offset (10, -80)
-	cfi_offset (11, -72)
-	cfi_offset (12, -64)
-	cfi_offset (13, -56)
-	cfi_offset (14, -48)
-	cfi_offset (15, -40)
-	aghi	%r15,-160
-	cfi_def_cfa_offset (320)
+	stmg	%r6,%r7,48(%r15)
+	cfi_offset (%r6, -112)
+	cfi_offset (%r7, -104)
 
 	.globl __syscall_cancel_arch_start
 	.type  __syscall_cancel_arch_start,@function
 __syscall_cancel_arch_start:
-	l	%r0,0(%r2)
-	tmll	%r0,4
+	/* if (*cancelhandling & CANCELED_BITMASK)
+	     __syscall_do_cancel()  */
+	tm	3(%r2),4
 	jne	1f
+
+	/* Issue a 6 argument syscall, the nr [%r1] being the syscall
+	   number.  */
 	lgr	%r1,%r3
 	lgr	%r2,%r4
 	lgr	%r3,%r5
 	lgr	%r4,%r6
-	lg	%r5,320(%r15)
-	lg	%r6,328(%r15)
-	lg	%r7,336(%r15)
+	lmg	%r5,%r7,160(%r15)
 	svc	0
 
 	.globl __syscall_cancel_arch_end
 	.type  __syscall_cancel_arch_end,@function
 __syscall_cancel_arch_end:
-	lg	%r4,272(%r15)
-	lmg	%r6,%r15,208(%r15)
+	lmg	%r6,%r7,48(%r15)
 	cfi_remember_state
-	cfi_restore (15)
-	cfi_restore (14)
-	cfi_restore (13)
-	cfi_restore (12)
-	cfi_restore (11)
-	cfi_restore (10)
-	cfi_restore (9)
-	cfi_restore (8)
-	cfi_restore (7)
-	cfi_restore (6)
-	cfi_def_cfa_offset (160)
-	br	%r4
+	cfi_restore (%r7)
+	cfi_restore (%r6)
+	br	%r14
 
 1:
 	cfi_restore_state
-	brasl	%r14, __syscall_do_cancel
+	jg	__syscall_do_cancel
 END (__syscall_cancel_arch)
 libc_hidden_def (__syscall_cancel_arch)

^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [PATCH v3 02/21] nptl: Fix Race conditions in pthread cancellation (BZ#12683)
  2019-10-15 10:56   ` Florian Weimer
@ 2019-10-16 20:42     ` Adhemerval Zanella
  0 siblings, 0 replies; 38+ messages in thread
From: Adhemerval Zanella @ 2019-10-16 20:42 UTC (permalink / raw)
  To: Florian Weimer; +Cc: libc-alpha



On 15/10/2019 07:56, Florian Weimer wrote:
> * Adhemerval Zanella:
> 
>> This patch is the initial fix for race conditions in NPTL cancellation codei
>> by redefining how cancellable syscalls are defined and handled.  Current
>> buggy approach is to enable asynchronous cancellation prior to making the
>> syscall and restore the previous cancellation type once the syscall returns.
> 
> First sentence appears to be garbled.

Ack, I also reformatted to fix it to wrap at 72 column.

> 
>> As decribed in BZ#12683, this approach shows 2 important problems:
>>
>>   1. Cancellation can act after the syscall has returned from kernel, but
>>      before userspace saves the return value.  It might result in a resource
>>      leak if the syscall allocated a resource or a side effect (partial
>>      read/write), and there is no way to program handle it with cancellation
>>      handlers.
>>
>>   2. If a signal is handled while the thread is blocked at a cancellable
>>      syscall, the entire signal handler runs with asynchronous cancellation
>>      enabled.  This can lead to issues if the signal handler call functions
>>      which are async-signal-safe but not async-cancel-safe.
> 
> Do you mean “the cancellation signal handler runs” or “any signal
> handler runs”?  I think the latter is the much larger issue.

Any signal handler since __pthread_enable_asynccancel explicit enables
async cancellation on all cancellable entrypoints. 

> 
> (I think it is customary to wrapper commit messages at column 72 or
> something like that.)

Ack.

> 
>> For cancellation to work correctly, there are 5 points at which the
>> cancellation signal could arrive:
>>
>>   1. Before the final "testcancel" and before the syscall is made.
>>   2. Between the "testcancel" and the syscall.
>>   3. While the syscall is blocked and no side effects have yet taken place.
>>   4. While the syscall is blocked but with some side effects already having
>>      taken place (e.g. a partial read or write).
>>   5. After the syscall has returned.
> 
> For clarity, I'd suggest to say whether we want unblocking to take place
> (i.e., the cancellation should happen eventually without any further
> external event, such as the arrival of more data).

[...]

> 
>> And GLIBC wants to act on cancellation in cases 1, 2, and 3 but not in case
>> 4 or 5.  The proposed solution follows:

What about adding:

  And GLIBC wants to act on cancellation in cases 1, 2, and 3 but not in case
  4 or 5.  For the 4 and 5 cases, the cancellation will eventually happen in
  the next cancellable entrypoint without any further external event.

  The proposed solution follows:

>>
>>   * Handling case 1 is trivial: do a conditional branch based on whether the
>>     thread has received a cancellation request;
>>
>>   * Case 2 can be caught by the signal handler determining that the saved
>>     program counter (from the ucontext_t) is in some address range beginning
>>     just before the "testcancel" and ending with the syscall instruction.
>>
>>   * In this case, except for certain syscalls that ALWAYS fail with EINTR
>>     even for non-interrupting signals, the kernel will reset the program
>>     counter to point at the syscall instruction during signal handling, so
>>     that the syscall is restarted when the signal handler returns. So, from
>>     the signal handler's standpoint, this looks the same as case 2, and thus
>>     it's taken care of.
>>
>>   * In this case, the kernel cannot restart the syscall; when it's
>>     interrupted by a signal, the kernel must cause the syscall to return
>>     with whatever partial result it obtained (e.g. partial read or write).
>>
>>   * In this case, the saved program counter points just after the syscall
>>     instruction, so the signal handler won't act on cancellation.
>>     This one is equal to 4. since the program counter is past the syscall
>>     instruction already.
> 
> I'd suggest to match these items to the numbers explicitly.

Ack, I changed to:

The proposed solution follows for each case:

  1. Do a conditional branch based on whether the thread has received
     a cancellation request;

  2. It can caught by the signal handler determining that the saved
     program counter (from the ucontext_t) is in some address range
     beginning just before the "testcancel" and ending with the
     syscall instruction.

  3. In this case, except for certain syscalls that ALWAYS fail with
     EINTR even for non-interrupting signals, the kernel will reset
     the program counter to point at the syscall instruction during
     signal handling, so that the syscall is restarted when the signal
     handler returns.  So, from the signal handler's standpoint, this
     looks the same as case 2, and thus it's taken care of.

  4. For syscals with side-effects, the kernel cannot restart the
     syscall; when it's interrupted by a signal, the kernel must cause 
     the syscall to return with whatever partial result it obtained 
     (e.g. partial read or write).

  5. In this case, the saved program counter points just after the
     syscall instruction, so the signal handler won't act on
     cancellation.  This is similar to 4. since the program counter 
     is past the syscall instruction.

> 
>> Another case that needs handling is syscalls that fail with EINTR even
>> when the signal handler is non-interrupting. In this case, the syscall
>> wrapper code can just check the cancellation flag when the errno result
>> is EINTR, and act on cancellation if it's set.
>>
>> The proposed GLIBC adjustments are:
>>
>>   1. Remove the enable_asynccancel/disable_asynccancel function usage in
>>      syscall definition and instead make them call a common symbol that will
>>      check if cancellation is enabled (__syscall_cancel at
>>      nptl/libc-cancellation.c), call the arch-specific cancellable
>>      entry-point (__syscall_cancel_arch) and cancel the thread when required.
>>
>>   2. Provide a arch-specific symbol that contains global markers. These
>>      markers will be used in SIGCANCEL handler to check if the interruption
>>      has been called in a valid syscall and if the syscalls has been
>>      completed or not.
> 
> An arch-specific generic system call wrapper function?

Ack.

> 
>>      A reference implementation sysdeps/unix/sysv/linux/syscall_cancel.c is
>>      provided.  However the markers may not be set on correct expected places
>>      depeding of how INTERNAL_SYSCALL_NCS is implemented by the underlying
>>      architecture, and it is uses compiler-speficic construct (asm volatile)
>>      to place the required markers.  It is expected that all architectures
>>      implement an arch-specific.
> 
> Truncated sentence.

Ack.

> 
>>   3. Rewrite SIGCANCEL asynchronous handler to check for both cancelling type
>>      and if current IP from signal handler falls between the global markes
>>      and act accordingly (sigcancel_handler at nptl/nptl-init.c).
> 
> s/markes/markers/

Ack.

> 
>> diff --git a/nptl/libc-cancellation.c b/nptl/libc-cancellation.c
>> index 37654cfcfe..430e0b962e 100644
>> --- a/nptl/libc-cancellation.c
>> +++ b/nptl/libc-cancellation.c
>> @@ -18,7 +18,46 @@
>>  
>>  #include "pthreadP.h"
>>  
>> +/* Cancellation function called by all cancellable syscalls.  */
>> +long int
>> +__syscall_cancel (__syscall_arg_t nr, __syscall_arg_t a1,
>> +		  __syscall_arg_t a2, __syscall_arg_t a3,
>> +		  __syscall_arg_t a4, __syscall_arg_t a5,
>> +		  __syscall_arg_t a6)
>> +{
> 
> long int as the return value may not be quite right on x32.

My understanding is it should be safe since the current required
syscalls that might returns a value larger than 'long int' are
already handled by arch-specific implementations (lseek and lseek64).

And I followed that x86_64 sysdep.h already is doing for 
{INTERNAL,INLINE}_SYSCALL, since it does expect the return value
to a unsigned long int and then it cast the return to long int.

It shouldn't work for syscalls that might return a 64-bit value,
but currently there is none that is a cancellation entrypoint.
Do you think we should also parametrize the return type to possible
handle such cases on x32?

> 
>> +  pthread_t self = (pthread_t) THREAD_SELF;
>> +  struct pthread *pd = (struct pthread *) self;
>> +  long int result;
> 
> I would use inline definitions for new code, but that's your choice.

Ack, I will check it.

> 
>> @@ -286,38 +277,49 @@ __pthread_initialize_minimal_internal (void)
>>    THREAD_SETMEM (pd, report_events, __nptl_initial_report_events);
>>  
>>  #if defined SIGCANCEL || defined SIGSETXID
>> -  struct sigaction sa;
>> -  __sigemptyset (&sa.sa_mask);
>>  
>>  # ifdef SIGCANCEL
>>    /* Install the cancellation signal handler.  If for some reason we
>>       cannot install the handler we do not abort.  Maybe we should, but
>>       it is only asynchronous cancellation which is affected.  */
>> -  sa.sa_sigaction = sigcancel_handler;
>> -  sa.sa_flags = SA_SIGINFO;
>> -  (void) __libc_sigaction (SIGCANCEL, &sa, NULL);
>> +  {
>> +    struct sigaction sa;
>> +    sa.sa_sigaction = sigcancel_handler;
>> +    /* The signal handle should be non-interruptible to avoid the risk of
>> +       spurious EINTR caused by SIGCANCEL sent to process or if pthread_cancel
>> +       is called while cancellation is disabled in the target thread.  */
>> +    sa.sa_flags = SA_SIGINFO | SA_RESTART;
>> +    sa.sa_mask = SIGALL_SET;
>> +    __libc_sigaction (SIGCANCEL, &sa, NULL);
>> +  }
>>  # endif
> 
> I'm a little bit concerned that adding SA_RESTART here adds more case
> where we do not act on cancellation promptly.  But that does not happen
> because if we observe the cancellation conditions to apply in the
> SIGCANCEL handler, we unwind straight from the signal handler, right?

Correct, is the cancel type is set to asynchronous *or* if the program
counter is within the permitted range (between the start marker and
just before the syscall instruction) the cancellation/unwind is done
on signal handler.

> 
>> diff --git a/nptl/pthreadP.h b/nptl/pthreadP.h
>> index 070b3afa8d..cafd14f5af 100644
>> --- a/nptl/pthreadP.h
>> +++ b/nptl/pthreadP.h
>> @@ -296,20 +296,46 @@ extern void __nptl_unwind_freeres (void) attribute_hidden;
>>  #endif
>>  
>>  
>> -/* Called when a thread reacts on a cancellation request.  */
>>  static inline void
>>  __attribute ((noreturn, always_inline))
>> -__do_cancel (void)
>> +__do_cancel_with_result (void *result)
>>  {
>>    struct pthread *self = THREAD_SELF;
>>  
>> -  /* Make sure we get no more cancellations.  */
>> -  THREAD_ATOMIC_BIT_SET (self, cancelhandling, EXITING_BIT);
>> +  /* Make sure we get no more cancellations by clearing the cancel
>> +     state.  */
>> +  int oldval = THREAD_GETMEM (self, cancelhandling);
>> +  while (1)
>> +    {
>> +      int newval = oldval | CANCELSTATE_BITMASK | EXITING_BITMASK;
>> +      if (oldval == newval)
>> +	break;
>> +
>> +      oldval = THREAD_ATOMIC_CMPXCHG_VAL (self, cancelhandling, newval,
>> +					  oldval);
>> +    }
>> +
>> +  THREAD_SETMEM (self, result, result);
>>  
>>    __pthread_unwind ((__pthread_unwind_buf_t *)
>>  		    THREAD_GETMEM (self, cleanup_jmp_buf));
>>  }
> 
> The function name should be more generic because it's for unwinding, not
> cancellation.

Unwind in glibc is an implementation detail; the idea is indeed to
cancel thread execution.  It is used on pthread_exit, cancellable
syscalls (through __syscall_cancel function), SIGCANCEL handler, and
pthread_setcancel{state,type}. I don't think adding unwind on its name
really signify what the functions aims to do.

> 
>> diff --git a/nptl/pthread_cancel.c b/nptl/pthread_cancel.c
>> index 64ac12e60a..b20254bdba 100644
>> --- a/nptl/pthread_cancel.c
>> +++ b/nptl/pthread_cancel.c
>> @@ -37,67 +37,24 @@ __pthread_cancel (pthread_t th)
> 
>> +  /* Avoid signaling when thread attempts cancel itself (pthread_kill
>> +     is expensive).  */
>> +  if (pd == THREAD_SELF
>> +      && (THREAD_GETMEM (pd, cancelhandling) & CANCELTYPE_BITMASK) == 0)
>> +    return 0;
> 
> I'm not sure if I understand this check.  CANCELTYPE_BITMASK is a bit
> misnamed (it's a single-bit masking).  As far as I understand it, it's
> set if async-cancel is enabled.  Shouldn't we call __do_cancel directly
> here in case of an async self-cancel?  And otherwise defer cancellation?

The 'cancelhandling' is indeed needless convoluted to hold not only
cancellation internal state, but also thread cancellation mode
(PTHREAD_CANCEL_ENABLE, PTHREAD_CANCEL_DISABLE) and type
(PTHREAD_CANCEL_DEFERRED, PTHREAD_CANCEL_ASYNCHRONOUS).  I have a
following patch that aims to simplify it a bit.

The check '(THREAD_GETMEM (pd, cancelhandling) & CANCELTYPE_BITMASK) == 0)' 
is basically check if the cancellation type is PTHREAD_CANCEL_DEFERRED.
In this case, instead of signalling to make the signal handler cancel
the thread, we just set the cancellation to act on next cancellation
entrypoint.

> 
>> diff --git a/nptl/pthread_create.c b/nptl/pthread_create.c
>> index 130937c3c4..8cab7f970c 100644
>> --- a/nptl/pthread_create.c
>> +++ b/nptl/pthread_create.c
>> @@ -406,7 +406,7 @@ START_THREAD_DEFN
>>    /* If the parent was running cancellation handlers while creating
>>       the thread the new thread inherited the signal mask.  Reset the
>>       cancellation signal mask.  */
>> -  if (__glibc_unlikely (pd->parent_cancelhandling & CANCELING_BITMASK))
>> +  if (__glibc_unlikely (pd->parent_cancelhandling & CANCELED_BITMASK))
>>      {
>>        INTERNAL_SYSCALL_DECL (err);
>>        sigset_t mask;
> 
> This conflicts with the patch I posted for bug 25098.  My change resets
> the SIGCANCEL mask unconditionally, so the check is gone completely and
> no longer needs adjustment.

Ack, I will rebase once it is pushed upstream.

> 
>> @@ -449,7 +449,8 @@ START_THREAD_DEFN
>>  	 have ownership (see CONCURRENCY NOTES above).  */
>>        if (__glibc_unlikely (pd->stopped_start))
>>  	{
>> -	  int oldtype = CANCEL_ASYNC ();
>> +	  int ct;
>> +	  __pthread_setcanceltype (PTHREAD_CANCEL_ASYNCHRONOUS, &ct);
>>  
>>  	  /* Get the lock the parent locked to force synchronization.  */
>>  	  lll_lock (pd->lock, LLL_PRIVATE);
>> @@ -459,7 +460,7 @@ START_THREAD_DEFN
>>  	  /* And give it up right away.  */
>>  	  lll_unlock (pd->lock, LLL_PRIVATE);
>>  
>> -	  CANCEL_RESET (oldtype);
>> +	  __pthread_setcanceltype (ct, NULL);
>>  	}
> 
> I think htis is wrong.  Either you need to use a cancellable lll_lock
> here.  Or maybe it is not even necessary to enable cancellation at all
> because the new tread is eventually bound to make progress and will wake
> up the futuex.

This is essentially a mechanical change, since CANCEL_ASYNC/CANCEL_RESET
is removed. I think we should track this potential issue in a separated
discussion.

> 
>> diff --git a/sysdeps/nptl/librt-cancellation.c b/nptl/pthread_kill_internal.c
>> similarity index 70%
>> rename from sysdeps/nptl/librt-cancellation.c
>> rename to nptl/pthread_kill_internal.c
>> index 93ebe4aa71..b4f4f6dc78 100644
>> --- a/sysdeps/nptl/librt-cancellation.c
>> +++ b/nptl/pthread_kill_internal.c
>> @@ -1,6 +1,6 @@
>> -/* Copyright (C) 2002-2019 Free Software Foundation, Inc.
>> +/* Send a signal to a specific pthread.  Internal version.
>> +   Copyright (C) 2002-2019 Free Software Foundation, Inc.
>>     This file is part of the GNU C Library.
>> -   Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
>>  
>>     The GNU C Library is free software; you can redistribute it and/or
>>     modify it under the terms of the GNU Lesser General Public
>> @@ -16,9 +16,11 @@
>>     License along with the GNU C Library; if not, see
>>     <https://www.gnu.org/licenses/>.  */
>>  
>> -#include <nptl/pthreadP.h>
>> +#include <pthreadP.h>
>>  
>> -
>> -#define __pthread_enable_asynccancel __librt_enable_asynccancel
>> -#define __pthread_disable_asynccancel __librt_disable_asynccancel
>> -#include <nptl/cancellation.c>
>> +int
>> +__pthread_kill_internal (pthread_t threadid, int signo)
>> +{
>> +  return ENOSYS;
>> +}
>> +hidden_def (__pthread_kill_internal)
> 
> I don't think we need this stub.

Indeed nptl is already Linux specific that there is no gain in
adding another compat layer. I did:

git mv sysdeps/unix/sysv/linux/pthread_kill_internal.c nptl/pthread_kill_internal.c -f

> 
>> diff --git a/nptl/pthread_setcanceltype.c b/nptl/pthread_setcanceltype.c
>> index d771c31e46..84cc657aed 100644
>> --- a/nptl/pthread_setcanceltype.c
>> +++ b/nptl/pthread_setcanceltype.c
>> @@ -73,4 +73,4 @@ __pthread_setcanceltype (int type, int *oldtype)
>>  
>>    return 0;
>>  }
>> -strong_alias (__pthread_setcanceltype, pthread_setcanceltype)
>> +weak_alias (__pthread_setcanceltype, pthread_setcanceltype)
> 
> Why is this change necessary?  pthread_setcanceltype is the only
> function defined in this file, so there are no issues with static
> linking.  I'm concerned that this hides a problem elsewhere.

This is to avoid the linknamespace issue:

$ cat conform/ISO11/threads.h/linknamespace.out 
[initial] thrd_create -> [libpthread.a(thrd_create.o)] __pthread_create_2_1 -> [libpthread.a(pthread_create.o)] __pthread_setcanceltype -> [libpthread.a(pthread_setcanceltype.o)] pthread_setcanceltype

> 
>> diff --git a/nptl/thrd_sleep.c b/nptl/thrd_sleep.c
>> index 2e185dd748..75c0d53f3e 100644
>> --- a/nptl/thrd_sleep.c
>> +++ b/nptl/thrd_sleep.c
>> @@ -24,13 +24,12 @@
>>  int
>>  thrd_sleep (const struct timespec* time_point, struct timespec* remaining)
>>  {
>> -  INTERNAL_SYSCALL_DECL (err);
>> -  int ret = INTERNAL_SYSCALL_CANCEL (nanosleep, err, time_point, remaining);
>> -  if (INTERNAL_SYSCALL_ERROR_P (ret, err))
>> +  long int ret = INTERNAL_SYSCALL_CANCEL (nanosleep, time_point, remaining);
> 
> The return type may need adjustment if the return type for the
> cancellation wrapper changes.

Do you mean for the x32 case?

> 
>> diff --git a/nptl/tst-cancel28.c b/nptl/tst-cancel28.c
>> new file mode 100644
>> index 0000000000..e27f5a0776
>> --- /dev/null
>> +++ b/nptl/tst-cancel28.c
> 
>> +static void *
>> +writeopener (void *arg)
>> +{
>> +  int fd;
>> +  for (;;)
>> +    {
>> +      fd = open (arg, O_WRONLY);
>> +      close (fd);
>> +    }
>> +  return NULL;
>> +}
>> +
>> +static void *
>> +leaker (void *arg)
>> +{
>> +  int fd = open (arg, O_RDONLY);
>> +  TEST_VERIFY_EXIT (fd > 0);
>> +  pthread_setcancelstate (PTHREAD_CANCEL_DISABLE, 0);
>> +  close (fd);
>> +  return NULL;
>> +}
> 
> I think these two functions *really* should check the return value of
> close (or use xclose).

Ack.

> 
>> +#define ITER_COUNT 1000
>> +#define MAX_FILENO 1024
> 
> MAX_FILENO appears to be unused.
> 
>> +#define TIMEOUT 10
>> +#include <support/test-driver.c>
> 
> TIMEOUT is smaller than the default test timeout.

Ack, I removed it.

> 
>> diff --git a/sysdeps/htl/pthreadP.h b/sysdeps/htl/pthreadP.h
>> index e745dacac1..5628791de8 100644
>> --- a/sysdeps/htl/pthreadP.h
>> +++ b/sysdeps/htl/pthreadP.h
>> @@ -25,6 +25,7 @@
>>  
>>  extern pthread_t __pthread_self (void);
>>  extern int __pthread_kill (pthread_t threadid, int signo);
>> +extern int __pthread_kill_internal (pthread_t threadid, int signo);
>>  extern struct __pthread **__pthread_threads;
>>  
>>  extern int _pthread_mutex_init (pthread_mutex_t *mutex, const pthread_mutexattr_t *attr);
> 
> This change appears unnecessary because __pthread_kill_internal does not
> seem to be used outside of nptl.

Ack.

> 
>> diff --git a/sysdeps/nptl/cancellation-pc-check.h b/sysdeps/nptl/cancellation-pc-check.h
>> new file mode 100644
>> index 0000000000..8b26c4ec4e
>> --- /dev/null
>> +++ b/sysdeps/nptl/cancellation-pc-check.h
> 
>> +/* Check if the program counter (PC) from ucontext CTX is within the start and
>> +   then end boundary from the __syscall_cancel_arch bridge.  Return TRUE if
>> +   the PC is within the boundary, meaning the syscall does not have any side
>> +   effects; or FALSE otherwise.  */
>> +static bool
>> +ucontext_check_pc_boundary (void *ctx)
>> +{
>> +  /* Both are defined in syscall_cancel.S.  */
>> +  extern const char __syscall_cancel_arch_start[1];
>> +  extern const char __syscall_cancel_arch_end[1];
>> +
>> +  uintptr_t pc = sigcontext_get_pc (ctx);
>> +  return pc >= (uintptr_t) __syscall_cancel_arch_start
>> +	 && pc < (uintptr_t) __syscall_cancel_arch_end;
>> +}
> 
> The name of this function should reflect that it is related to
> cancellation.
> 
> Please add a comment explaining the kernel behavior regarding PC
> (non-interrupted vs interrupted system calls), as found in the commit
> message.

Ack, I have changed the comment to:

/* For syscalls with side-effects, the kernel cannot restart the syscall; when
   it is interrupted by a signal, the kernel must cause the syscall to return
   with whatever partial result is obtained (e.g. partial read or write).  In
   this case, the saved program counter points just after the syscall
   instruction, so the SIGCANCEL handler should not act on cancellation.

   The __syscall_cancel_arch function, used for all cancellable syscalls,
   contains two extra markers, __syscall_cancel_arch_start and
   __syscall_cancel_arch_end.  The former points to just before the initial
   conditional branch that checks if the thread has received a cancellation
   request, while former points to the instruction after the one responsible
   to issue the syscall.

   The function check if the program counter (PC) from ucontext_t CTX is
   within the start and then end boundary from the __syscall_cancel_arch
   bridge.  Return TRUE if the PC is within the boundary, meaning the
   syscall does not have any side effects; or FALSE otherwise.  */

> 
>> +#endif
>> diff --git a/sysdeps/nptl/cancellation-sigmask.h b/sysdeps/nptl/cancellation-sigmask.h
>> new file mode 100644
>> index 0000000000..77702c135e
>> --- /dev/null
>> +++ b/sysdeps/nptl/cancellation-sigmask.h
> 
>> +/* Add the SIGCANCEL signal on sigmask set at the ucontext CTX obtained from
>> +   the sigaction handler.  */
>> +static void
>> +ucontext_add_cancel (void *ctx)
>> +{
>> +  __sigaddset (&((ucontext_t*) ctx)->uc_sigmask, SIGCANCEL);
>> +}
> 
> I find the name of the function rather unclear.  Maybe
> ucontext_block_sigcancel or something like that.

Ack, I changed to ucontext_block_sigcancel.

> 
>> diff --git a/sysdeps/unix/sysdep.h b/sysdeps/unix/sysdep.h
>> index 10468c7129..04f30b8cbc 100644
>> --- a/sysdeps/unix/sysdep.h
>> +++ b/sysdeps/unix/sysdep.h
> 
>> +#define __SYSCALL_CANCEL0(name) \
>> +  (__syscall_cancel)(__NR_##name, 0, 0, 0, 0, 0, 0)
> 
> There are a bunch of formatting nits in the changes to this file.
> “)(” should be “) (”.  Likewise for “__SSC(”.

Ack.

> 
>> diff --git a/sysdeps/unix/sysv/linux/clock_nanosleep.c b/sysdeps/unix/sysv/linux/clock_nanosleep.c
>> index 1f240b8720..ddcdddcd5d 100644
>> --- a/sysdeps/unix/sysv/linux/clock_nanosleep.c
>> +++ b/sysdeps/unix/sysv/linux/clock_nanosleep.c
>> @@ -36,11 +36,9 @@ __clock_nanosleep (clockid_t clock_id, int flags, const struct timespec *req,
>>  
>>    /* If the call is interrupted by a signal handler or encounters an error,
>>       it returns a positive value similar to errno.  */
>> -  INTERNAL_SYSCALL_DECL (err);
>> -  int r = INTERNAL_SYSCALL_CANCEL (clock_nanosleep, err, clock_id, flags,
>> +  int r = INTERNAL_SYSCALL_CANCEL (clock_nanosleep, clock_id, flags,
>>  				   req, rem);
>> -  return (INTERNAL_SYSCALL_ERROR_P (r, err)
>> -	  ? INTERNAL_SYSCALL_ERRNO (r, err) : 0);
>> +  return SYSCALL_CANCEL_ERROR (r) ? -r : 0;
>>  }
> 
> Shouldn't r change type here?

Not strickly required, but I agree that it would be better to change
to long int.

> 
>> diff --git a/sysdeps/unix/sysv/linux/lowlevellock-futex.h b/sysdeps/unix/sysv/linux/lowlevellock-futex.h
>> index b423673ed4..bd6d3b7cf7 100644
>> --- a/sysdeps/unix/sysv/linux/lowlevellock-futex.h
>> +++ b/sysdeps/unix/sysv/linux/lowlevellock-futex.h
>> @@ -74,6 +74,12 @@
>>       ? -INTERNAL_SYSCALL_ERRNO (__ret, __err) : 0);                     \
>>    })
>>  
>> +#define lll_futex_syscall_cp(...)					\
>> +  ({                                                                    \
>> +    long int __ret = INTERNAL_SYSCALL_CANCEL (futex, __VA_ARGS__);	\
>> +    __ret;								\
>> +  })
>> +
> 
> The statement expression appears unnecessary here.
> 
>> +#define lll_futex_timed_wait_cancel(futexp, val, timeout, private)	\
>> +  ({									\
>> +    long int __ret;							\
>> +    int __op = FUTEX_WAIT;						\
>> +    __ret = lll_futex_syscall_cp (futexp,				\
>> +				  __lll_private_flag (__op, private),	\
>> +				  val, timeout);			\
>> +    __ret;								\
>>    })
> 
> Is the statement expression needed?  Should this be an inline function?
> 
>>  
>> -#define lll_futex_timed_wait_cancel(futexp, val, timeout, private)	   \
>> -  ({									   \
>> -    int __oldtype = CANCEL_ASYNC ();				       	   \
>> -    long int __err = lll_futex_timed_wait (futexp, val, timeout, private); \
>> -    CANCEL_RESET (__oldtype);						   \
>> -    __err;								   \
>> +#define lll_futex_clock_wait_bitset_cancel(futexp, val, clockid,	\
>> +					   timeout, private)		\
>> +  ({									\
>> +    long int __ret;							\
>> +    if (lll_futex_supported_clockid (clockid))                          \
>> +      {                                                                 \
>> +        const unsigned int clockbit =                                   \
>> +          (clockid == CLOCK_REALTIME) ? FUTEX_CLOCK_REALTIME : 0;       \
>> +        const int op =                                                  \
>> +          __lll_private_flag (FUTEX_WAIT_BITSET | clockbit, private);   \
>> +									\
>> +	__ret = lll_futex_syscall_cp (futexp, op, val,			\
>> +                                      timeout, NULL /* Unused.  */,	\
>> +                                      FUTEX_BITSET_MATCH_ANY);		\
>> +      }									\
>> +    else								\
>> +      __ret = -EINVAL;							\
>> +    __ret;								\
>>    })
> 
> I do think this should be an inline function.

I followed the current practice for this file, but I agree that we should
move to inline function in this cases.  I adjusted to use the types defined
on sysdeps/unix/sysv/linux/futex-internal.h (unsigned int * for futex
address) which requires some extra casts on nptl/pthread_join_common.c.

> 
>> --- a/sysdeps/unix/sysv/linux/pthread_kill.c
>> +++ b/sysdeps/unix/sysv/linux/pthread_kill_internal.c
>> @@ -16,24 +16,15 @@
> 
>> -strong_alias (__pthread_kill, pthread_kill)
>> +hidden_def (__pthread_kill_internal)
> 
> Why hidden_def?  I think you should use attribute_hidden on the
> declaration and drop the libc_hidden_proto instead.

Ack.

> 
>> diff --git a/sysdeps/unix/sysv/linux/syscall_cancel.c b/sysdeps/unix/sysv/linux/syscall_cancel.c
>> new file mode 100644
>> index 0000000000..79d66ec4f4
>> --- /dev/null
>> +++ b/sysdeps/unix/sysv/linux/syscall_cancel.c
> 
>> +long int
>> +__syscall_cancel_arch (volatile int *ch, __syscall_arg_t nr,
>> +		       __syscall_arg_t a1, __syscall_arg_t a2,
>> +		       __syscall_arg_t a3, __syscall_arg_t a4,
>> +		       __syscall_arg_t a5, __syscall_arg_t a6)
>> +{
>> +#define ADD_LABEL(__label)		\
>> +  asm volatile (			\
>> +    ".global " __label "\t\n"		\
>> +    ".type " __label ",\%function\t\n" 	\
>> +    __label ":\n");
>> +
>> +  ADD_LABEL ("__syscall_cancel_arch_start");
>> +  if (__glibc_unlikely (*ch & CANCELED_BITMASK))
>> +    __syscall_do_cancel();
>> +
>> +  INTERNAL_SYSCALL_DECL(err);
>> +  long int result = INTERNAL_SYSCALL_NCS (nr, err, 6, a1, a2, a3, a4, a5, a6);
>> +  ADD_LABEL ("__syscall_cancel_arch_end");
>> +  if (__glibc_unlikely (INTERNAL_SYSCALL_ERROR_P (result, err)))
>> +    return -INTERNAL_SYSCALL_ERRNO (result, err);
>> +  return result;
>> +}
>> +libc_hidden_def (__syscall_cancel_arch)
> 
> For bootstrapping, this is good enough, but I think we really, *really*
> should remove this function, so that new ports do not use it by
> accident.
> 

What about adding a #warning to state this file should not be use?

#warning "This implementation should be use just as reference or for bootstrapping"

>> diff --git a/sysdeps/unix/sysv/linux/sysdep.h b/sysdeps/unix/sysv/linux/sysdep.h
>> index fc9af51456..317bb7f973 100644
>> --- a/sysdeps/unix/sysv/linux/sysdep.h
>> +++ b/sysdeps/unix/sysv/linux/sysdep.h
>> @@ -27,6 +27,26 @@
>>      -1l;					\
>>    })
>>  
>> +/* Check error from cancellable syscall and set errno accordingly.
>> +   Linux uses a negative return value to indicate syscall errors
>> +   and since version 2.1 the return value of a system call might be
>> +   negative even if the call succeeded (e.g., the `lseek' system call
>> +   might return a large offset).
>> +   Current contract is kernel make sure the no syscall returns a value
>> +   in -1 .. -4095 as a valid result so we can savely test with -4095.  */
>> +#define SYSCALL_CANCEL_ERROR(__ret)		\
>> +  (__ret > -4096UL)
> 
> This doesn't look particularly type-safe.  Does it have to be a macro?
> If it is a macro, can we add type checks?

__set_errno(ev) ((errno) = (ev))

> 
>> +#define SYSCALL_CANCEL_RET(__ret)		\
>> +  ({						\
>> +    if (SYSCALL_CANCEL_ERROR(__ret))		\
>> +      {						\
>> +	__set_errno (-__ret);			\
>> +	__ret = -1;				\
>> +      }						\
>> +    __ret;					\
>> +   })
>> +
>>  /* Provide a dummy argument that can be used to force register
>>     alignment for register pairs if required by the syscall ABI.  */
>>  #ifdef __ASSUME_ALIGNED_REGISTER_PAIRS> 
> I initially found this split from sysdeps/unix/sysdep.h a bit strange,
> but I guess it does reflect the current layering.
> 
> Additional notes: {LIBC_,}CANCEL_{ASYNC,RESET} should be removed
> everywhere as soon as possible.  This may have a knockpm-effect where
> __pthread_disable_asynccancel etc. can go as well.

The __pthread_{enable,disable}_asynccancel are completely removed in
this patch.  The only missing {LIBC_,}CANCEL_{ASYNC,RESET} reference
I forgot to remove is at manual/process.texi.

^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [PATCH v3 03/21] nptl: x86_64: Fix Race conditions in pthread cancellation (BZ#12683)
  2019-10-15 11:03   ` Florian Weimer
@ 2019-10-16 21:22     ` Adhemerval Zanella
  0 siblings, 0 replies; 38+ messages in thread
From: Adhemerval Zanella @ 2019-10-16 21:22 UTC (permalink / raw)
  To: Florian Weimer; +Cc: libc-alpha



On 15/10/2019 08:03, Florian Weimer wrote:
> * Adhemerval Zanella:
> 
>> diff --git a/sysdeps/unix/sysv/linux/x86_64/syscall_cancel.S b/sysdeps/unix/sysv/linux/x86_64/syscall_cancel.S
>> new file mode 100644
>> index 0000000000..c7364bfff8
>> --- /dev/null
>> +++ b/sysdeps/unix/sysv/linux/x86_64/syscall_cancel.S
> 
>> +ENTRY (__syscall_cancel_arch)
>> +
>> +	.globl __syscall_cancel_arch_start
>> +	.type  __syscall_cancel_arch_start,@function
> 
> I don't think we should specify a type for this symbol.  It's not a
> function.

Ack, I can't recall exactly I have added it on previous iterations.
I removed it.

> 
>> +__syscall_cancel_arch_start:
>> +
>> +	/* if (*cancelhandling & CANCELED_BITMASK)
>> +	     __syscall_do_cancel()  */
>> +	mov    (%rdi),%eax
>> +	testb  $4, (%rdi)
>> +	jne    __syscall_do_cancel
> 
> I'm pretty sure 4 should be one of the _BITMASK constants.

Right, I think we should use TCB_CANCELED_BITMASK macro for this (and
add it for architectures that do not define it already).

> 
>> +	/* Issue a 6 argument syscall, the nr [%rax] being the syscall
>> +	   number.  */
>> +	mov    %rdi,%r11
>> +	mov    %rsi,%rax
>> +	mov    %rdx,%rdi
>> +	mov    %rcx,%rsi
>> +	mov    %r8,%rdx
>> +	mov    %r9,%r10
>> +	mov    8(%rsp),%r8
>> +	mov    16(%rsp),%r9
>> +	mov    %r11,8(%rsp)
>> +	syscall
>> +
>> +	.globl __syscall_cancel_arch_end
>> +	.type  __syscall_cancel_arch_end,@function
> 
> Again, no type here please.  It will confuse the disassembler.

Ack.

> 
> Thanks,
> Florian
> 

^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [PATCH v3 15/21] nptl: alpha: Fix Race conditions in pthread cancellation (BZ#12683)
  2019-10-14 20:57 ` [PATCH v3 15/21] nptl: alpha: " Adhemerval Zanella
@ 2019-10-17  3:01   ` Matt Turner
  0 siblings, 0 replies; 38+ messages in thread
From: Matt Turner @ 2019-10-17  3:01 UTC (permalink / raw)
  To: Adhemerval Zanella; +Cc: GNU C Library

On Mon, Oct 14, 2019 at 1:59 PM Adhemerval Zanella
<adhemerval.zanella@linaro.org> wrote:
>
> This patch adds the hppa modifications required for the BZ#12683 fix

s/hppa/alpha/

^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [PATCH v3 18/21] nptl: s390: Fix Race conditions in pthread cancellation (BZ#12683)
  2019-10-16 15:46   ` Stefan Liebler
@ 2019-10-17 13:54     ` Adhemerval Zanella
  2019-10-17 15:01       ` Stefan Liebler
  0 siblings, 1 reply; 38+ messages in thread
From: Adhemerval Zanella @ 2019-10-17 13:54 UTC (permalink / raw)
  To: libc-alpha



On 16/10/2019 12:46, Stefan Liebler wrote:
> Hi Adhemerval,
> 
> I've added some notes below to the s390-64 file, but the same applies also for s390-32. I've also attached a diff.
> 
> I've also recognized that a call starting from e.g. write () involves various shuffling of the argument registers at each level:
> write (ARGS in r2-r4)
> -> __syscall_cancel (r2=nr, ARGS in r3-r6 and two stack-slots)
> --> __syscall_cancel_arch (r2=*ch, r3=nr, ARGS in r4-r6 and three stack-slots)
> ---> "syscall-instruction" (ARGS in r2-r7)
> 
> Just as a quick idea (I don't know if there are other limitations), those shuffling instructions could perhaps be omitted if the nr / ch arguments of the __syscall_cancel / __syscall_cancel_arch functions would be the last arguments instead of the first ones.
> I assume that also other archs could benefit from such an ordering.

Thanks, I have applied your changes.  Indeed for some architectures the 
syscall_cancel.S might not be the most optimized one, I used the reference 
C implementation as base and gcc might not generate the best code in some
cases.

> 
> Bye,
> Stefan
> 
> On 10/14/19 10:56 PM, Adhemerval Zanella wrote:
>> This patch adds the s390 modifications required for the BZ#12683 fix
>> by adding the arch-specific cancellation syscall bridge.
>>
>> Checked on s390-linux-gnu and s390x-linux-gnu.
>> ---
>>   .../sysv/linux/s390/s390-32/syscall_cancel.S  | 83 +++++++++++++++++++
>>   .../sysv/linux/s390/s390-64/syscall_cancel.S  | 83 +++++++++++++++++++
>>   2 files changed, 166 insertions(+)
>>   create mode 100644 sysdeps/unix/sysv/linux/s390/s390-32/syscall_cancel.S
>>   create mode 100644 sysdeps/unix/sysv/linux/s390/s390-64/syscall_cancel.S
>>
>> diff --git a/sysdeps/unix/sysv/linux/s390/s390-32/syscall_cancel.S b/sysdeps/unix/sysv/linux/s390/s390-32/syscall_cancel.S
>> new file mode 100644
>> index 0000000000..3c934addbd
>> --- /dev/null
>> +++ b/sysdeps/unix/sysv/linux/s390/s390-32/syscall_cancel.S
>> @@ -0,0 +1,83 @@
>> +/* Cancellable syscall wrapper.  Linux/s390 version.
>> +   Copyright (C) 2019 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
>> +   <http://www.gnu.org/licenses/>.  */
>> +
>> +#include <sysdep.h>
>> +
>> +/* long int __syscall_cancel_arch (int *cancelhandling,
>> +                   __syscall_arg_t nr,
>> +                   __syscall_arg_t arg1,
>> +                   __syscall_arg_t arg2,
>> +                   __syscall_arg_t arg3,
>> +                   __syscall_arg_t arg4,
>> +                   __syscall_arg_t arg5,
>> +                   __syscall_arg_t arg6)  */
>> +
>> +ENTRY (__syscall_cancel_arch)
>> +    stm    %r6,%r15,24(%r15)
>> +    cfi_offset (6, -72)
>> +    cfi_offset (7, -68)
>> +    cfi_offset (8, -64)
>> +    cfi_offset (9, -60)
>> +    cfi_offset (10, -56)
>> +    cfi_offset (11, -52)
>> +    cfi_offset (12, -48)
>> +    cfi_offset (13, -44)
>> +    cfi_offset (14, -40)
>> +    cfi_offset (15, -36)
>> +    ahi    %r15, -96
>> +    cfi_def_cfa_offset (192)
>> +
>> +    .globl __syscall_cancel_arch_start
>> +    .type  __syscall_cancel_arch_start,@function
>> +__syscall_cancel_arch_start:
>> +    l    %r0, 0(%r2)
>> +    tml    %r0, 4
>> +    jne    1f
>> +    lr    %r1, %r3
>> +    lr    %r2, %r4
>> +    lr    %r3, %r5
>> +    lr    %r4, %r6
>> +    l    %r5, 192(%r15)
>> +    l    %r6, 196(%r15)
>> +    l    %r7, 200(%r15)
>> +    svc    0
>> +
>> +    .globl __syscall_cancel_arch_end
>> +    .type  __syscall_cancel_arch_end,@function
>> +__syscall_cancel_arch_end:
>> +    l    %r4, 152(%r15)
>> +    lm    %r6, %r15, 120(%r15)
>> +    cfi_remember_state
>> +    cfi_restore (15)
>> +    cfi_restore (14)
>> +    cfi_restore (13)
>> +    cfi_restore (12)
>> +    cfi_restore (11)
>> +    cfi_restore (10)
>> +    cfi_restore (9)
>> +    cfi_restore (8)
>> +    cfi_restore (7)
>> +    cfi_restore (6)
>> +    cfi_def_cfa_offset (96)
>> +    br    %r4
>> +
>> +1:
>> +    cfi_restore_state
>> +    brasl    %r14, __syscall_do_cancel
>> +END (__syscall_cancel_arch)
>> +libc_hidden_def (__syscall_cancel_arch)
>> 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 0000000000..3480020fbb
>> --- /dev/null
>> +++ b/sysdeps/unix/sysv/linux/s390/s390-64/syscall_cancel.S
>> @@ -0,0 +1,83 @@
>> +/* Cancellable syscall wrapper.  Linux/s390x version.
>> +   Copyright (C) 2019 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
>> +   <http://www.gnu.org/licenses/>.  */
>> +
>> +#include <sysdep.h>
>> +
>> +/* long int __syscall_cancel_arch (int *cancelhandling,
>> +                   __syscall_arg_t nr,
>> +                   __syscall_arg_t arg1,
>> +                   __syscall_arg_t arg2,
>> +                   __syscall_arg_t arg3,
>> +                   __syscall_arg_t arg4,
>> +                   __syscall_arg_t arg5,
>> +                   __syscall_arg_t arg6)  */
>> +
>> +ENTRY (__syscall_cancel_arch)
>> +    stmg    %r6, %r15, 48(%r15)
> Please omit the spaces between the operands to have the same style as below (the same applies to multiple instructions in the s390-32 file.
> 

Ack.

>> +    cfi_offset (6, -112)
> Please use e.g. %r6 instead of just 6 for the cfi statements here and below for cfi_restore.
>> +    cfi_offset (7, -104)
>> +    cfi_offset (8, -96)
>> +    cfi_offset (9, -88)
>> +    cfi_offset (10, -80)
>> +    cfi_offset (11, -72)
>> +    cfi_offset (12, -64)
>> +    cfi_offset (13, -56)
>> +    cfi_offset (14, -48)
>> +    cfi_offset (15, -40)
>> +    aghi    %r15,-160
>> +    cfi_def_cfa_offset (320)
> I think the new stack frame is not needed at all.  The kernel does not clobber any registers and also does not need an own stack frame.
> (I've recognized that syscall.S also contains an extra frame and I will work on a patch)
> 
> Then r8-r15 are not clobbered here and we just have to store and restore r6 and r7.

ack.

>> +
>> +    .globl __syscall_cancel_arch_start
>> +    .type  __syscall_cancel_arch_start,@function
>> +__syscall_cancel_arch_start:
> Could you add the comments like e.g. done in the x86_64 patch?
>     /* if (*cancelhandling & CANCELED_BITMASK)
>          __syscall_do_cancel()  */

Certainly, I also changes to use TCB_CANCELED_BITMASK from tcb-offsets.h
instead of hard-code the values.

>> +    l    %r0,0(%r2)
>> +    tmll    %r0,4
> We can combine l and tmll here:
> tm 3(%r2),4
> 

Ack.

>> +    jne    1f
>     /* Issue a 6 argument syscall, the nr [%r1] being the syscall
>        number.  */
>> +    lgr    %r1,%r3
>> +    lgr    %r2,%r4
>> +    lgr    %r3,%r5
>> +    lgr    %r4,%r6
>> +    lg    %r5,320(%r15)
>> +    lg    %r6,328(%r15)
>> +    lg    %r7,336(%r15)
> We can use lmg in order to load r5-r7.

Ack.

>> +    svc    0
>> +
>> +    .globl __syscall_cancel_arch_end
>> +    .type  __syscall_cancel_arch_end,@function
>> +__syscall_cancel_arch_end:
>> +    lg    %r4,272(%r15)
>> +    lmg    %r6,%r15,208(%r15)
>> +    cfi_remember_state
>> +    cfi_restore (15)
>> +    cfi_restore (14)
>> +    cfi_restore (13)
>> +    cfi_restore (12)
>> +    cfi_restore (11)
>> +    cfi_restore (10)
>> +    cfi_restore (9)
>> +    cfi_restore (8)
>> +    cfi_restore (7)
>> +    cfi_restore (6)
>> +    cfi_def_cfa_offset (160)
>> +    br    %r4
>> +
>> +1:
>> +    cfi_restore_state
>> +    brasl    %r14, __syscall_do_cancel
> We can just use jg __syscall_do_cancel for this not-returning-tail-call.
> (For the s390-32 part: Both instructions are z900 instructions, but as gcc has removed support for g5 and g6, this is okay at this point of time)
>> +END (__syscall_cancel_arch)
>> +libc_hidden_def (__syscall_cancel_arch)
>>
> 

Ack.

^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [PATCH v3 18/21] nptl: s390: Fix Race conditions in pthread cancellation (BZ#12683)
  2019-10-17 13:54     ` Adhemerval Zanella
@ 2019-10-17 15:01       ` Stefan Liebler
  2019-10-17 19:46         ` Adhemerval Zanella
  0 siblings, 1 reply; 38+ messages in thread
From: Stefan Liebler @ 2019-10-17 15:01 UTC (permalink / raw)
  To: libc-alpha

On 10/17/19 3:53 PM, Adhemerval Zanella wrote:
> 
> 
> On 16/10/2019 12:46, Stefan Liebler wrote:
>> Hi Adhemerval,
>>
>> I've added some notes below to the s390-64 file, but the same applies also for s390-32. I've also attached a diff.
>>
>> I've also recognized that a call starting from e.g. write () involves various shuffling of the argument registers at each level:
>> write (ARGS in r2-r4)
>> -> __syscall_cancel (r2=nr, ARGS in r3-r6 and two stack-slots)
>> --> __syscall_cancel_arch (r2=*ch, r3=nr, ARGS in r4-r6 and three stack-slots)
>> ---> "syscall-instruction" (ARGS in r2-r7)
>>
>> Just as a quick idea (I don't know if there are other limitations), those shuffling instructions could perhaps be omitted if the nr / ch arguments of the __syscall_cancel / __syscall_cancel_arch functions would be the last arguments instead of the first ones.
>> I assume that also other archs could benefit from such an ordering.
> 
> Thanks, I have applied your changes.  Indeed for some architectures the
> syscall_cancel.S might not be the most optimized one, I used the reference
> C implementation as base and gcc might not generate the best code in some
> cases.
> 
The implementation in syscall_cancel.S contains just one of the three 
parts of the mentioned register move instructions. Those needs also to 
be generated in write() and __syscall_cancel().
My point was, if we could preserve the values passed in registers to 
e.g. write() in the same registers until the syscall is invoked in 
__syscall_cancel_arch, we won't need to move them from registers to 
registers at all:
write (ARGS in r2-r4)
-> __syscall_cancel (ARGS in r2-r6 and first stack-slot, nr in second 
stack-slot)
--> __syscall_cacnel_arch (ARGS in r2-r6 and first stack-slot, nr in 
second stack-slot, ch in third stack-slot)
---> "syscall-instruction" (ARGS in r2-r7)

>>
>> Bye,
>> Stefan
>>
>> On 10/14/19 10:56 PM, Adhemerval Zanella wrote:
>>> This patch adds the s390 modifications required for the BZ#12683 fix
>>> by adding the arch-specific cancellation syscall bridge.
>>>
>>> Checked on s390-linux-gnu and s390x-linux-gnu.
>>> ---
>>>    .../sysv/linux/s390/s390-32/syscall_cancel.S  | 83 +++++++++++++++++++
>>>    .../sysv/linux/s390/s390-64/syscall_cancel.S  | 83 +++++++++++++++++++
>>>    2 files changed, 166 insertions(+)
>>>    create mode 100644 sysdeps/unix/sysv/linux/s390/s390-32/syscall_cancel.S
>>>    create mode 100644 sysdeps/unix/sysv/linux/s390/s390-64/syscall_cancel.S
>>>
>>> diff --git a/sysdeps/unix/sysv/linux/s390/s390-32/syscall_cancel.S b/sysdeps/unix/sysv/linux/s390/s390-32/syscall_cancel.S
>>> new file mode 100644
>>> index 0000000000..3c934addbd
>>> --- /dev/null
>>> +++ b/sysdeps/unix/sysv/linux/s390/s390-32/syscall_cancel.S
>>> @@ -0,0 +1,83 @@
>>> +/* Cancellable syscall wrapper.  Linux/s390 version.
>>> +   Copyright (C) 2019 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
>>> +   <http://www.gnu.org/licenses/>.  */
>>> +
>>> +#include <sysdep.h>
>>> +
>>> +/* long int __syscall_cancel_arch (int *cancelhandling,
>>> +                   __syscall_arg_t nr,
>>> +                   __syscall_arg_t arg1,
>>> +                   __syscall_arg_t arg2,
>>> +                   __syscall_arg_t arg3,
>>> +                   __syscall_arg_t arg4,
>>> +                   __syscall_arg_t arg5,
>>> +                   __syscall_arg_t arg6)  */
>>> +
>>> +ENTRY (__syscall_cancel_arch)
>>> +    stm    %r6,%r15,24(%r15)
>>> +    cfi_offset (6, -72)
>>> +    cfi_offset (7, -68)
>>> +    cfi_offset (8, -64)
>>> +    cfi_offset (9, -60)
>>> +    cfi_offset (10, -56)
>>> +    cfi_offset (11, -52)
>>> +    cfi_offset (12, -48)
>>> +    cfi_offset (13, -44)
>>> +    cfi_offset (14, -40)
>>> +    cfi_offset (15, -36)
>>> +    ahi    %r15, -96
>>> +    cfi_def_cfa_offset (192)
>>> +
>>> +    .globl __syscall_cancel_arch_start
>>> +    .type  __syscall_cancel_arch_start,@function
>>> +__syscall_cancel_arch_start:
>>> +    l    %r0, 0(%r2)
>>> +    tml    %r0, 4
>>> +    jne    1f
>>> +    lr    %r1, %r3
>>> +    lr    %r2, %r4
>>> +    lr    %r3, %r5
>>> +    lr    %r4, %r6
>>> +    l    %r5, 192(%r15)
>>> +    l    %r6, 196(%r15)
>>> +    l    %r7, 200(%r15)
>>> +    svc    0
>>> +
>>> +    .globl __syscall_cancel_arch_end
>>> +    .type  __syscall_cancel_arch_end,@function
>>> +__syscall_cancel_arch_end:
>>> +    l    %r4, 152(%r15)
>>> +    lm    %r6, %r15, 120(%r15)
>>> +    cfi_remember_state
>>> +    cfi_restore (15)
>>> +    cfi_restore (14)
>>> +    cfi_restore (13)
>>> +    cfi_restore (12)
>>> +    cfi_restore (11)
>>> +    cfi_restore (10)
>>> +    cfi_restore (9)
>>> +    cfi_restore (8)
>>> +    cfi_restore (7)
>>> +    cfi_restore (6)
>>> +    cfi_def_cfa_offset (96)
>>> +    br    %r4
>>> +
>>> +1:
>>> +    cfi_restore_state
>>> +    brasl    %r14, __syscall_do_cancel
>>> +END (__syscall_cancel_arch)
>>> +libc_hidden_def (__syscall_cancel_arch)
>>> 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 0000000000..3480020fbb
>>> --- /dev/null
>>> +++ b/sysdeps/unix/sysv/linux/s390/s390-64/syscall_cancel.S
>>> @@ -0,0 +1,83 @@
>>> +/* Cancellable syscall wrapper.  Linux/s390x version.
>>> +   Copyright (C) 2019 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
>>> +   <http://www.gnu.org/licenses/>.  */
>>> +
>>> +#include <sysdep.h>
>>> +
>>> +/* long int __syscall_cancel_arch (int *cancelhandling,
>>> +                   __syscall_arg_t nr,
>>> +                   __syscall_arg_t arg1,
>>> +                   __syscall_arg_t arg2,
>>> +                   __syscall_arg_t arg3,
>>> +                   __syscall_arg_t arg4,
>>> +                   __syscall_arg_t arg5,
>>> +                   __syscall_arg_t arg6)  */
>>> +
>>> +ENTRY (__syscall_cancel_arch)
>>> +    stmg    %r6, %r15, 48(%r15)
>> Please omit the spaces between the operands to have the same style as below (the same applies to multiple instructions in the s390-32 file.
>>
> 
> Ack.
> 
>>> +    cfi_offset (6, -112)
>> Please use e.g. %r6 instead of just 6 for the cfi statements here and below for cfi_restore.
>>> +    cfi_offset (7, -104)
>>> +    cfi_offset (8, -96)
>>> +    cfi_offset (9, -88)
>>> +    cfi_offset (10, -80)
>>> +    cfi_offset (11, -72)
>>> +    cfi_offset (12, -64)
>>> +    cfi_offset (13, -56)
>>> +    cfi_offset (14, -48)
>>> +    cfi_offset (15, -40)
>>> +    aghi    %r15,-160
>>> +    cfi_def_cfa_offset (320)
>> I think the new stack frame is not needed at all.  The kernel does not clobber any registers and also does not need an own stack frame.
>> (I've recognized that syscall.S also contains an extra frame and I will work on a patch)
>>
>> Then r8-r15 are not clobbered here and we just have to store and restore r6 and r7.
> 
> ack.
> 
>>> +
>>> +    .globl __syscall_cancel_arch_start
>>> +    .type  __syscall_cancel_arch_start,@function
>>> +__syscall_cancel_arch_start:
>> Could you add the comments like e.g. done in the x86_64 patch?
>>      /* if (*cancelhandling & CANCELED_BITMASK)
>>           __syscall_do_cancel()  */
> 
> Certainly, I also changes to use TCB_CANCELED_BITMASK from tcb-offsets.h
> instead of hard-code the values.
> 
>>> +    l    %r0,0(%r2)
>>> +    tmll    %r0,4
>> We can combine l and tmll here:
>> tm 3(%r2),4
>>
> 
> Ack.
> 
>>> +    jne    1f
>>      /* Issue a 6 argument syscall, the nr [%r1] being the syscall
>>         number.  */
>>> +    lgr    %r1,%r3
>>> +    lgr    %r2,%r4
>>> +    lgr    %r3,%r5
>>> +    lgr    %r4,%r6
>>> +    lg    %r5,320(%r15)
>>> +    lg    %r6,328(%r15)
>>> +    lg    %r7,336(%r15)
>> We can use lmg in order to load r5-r7.
> 
> Ack.
> 
>>> +    svc    0
>>> +
>>> +    .globl __syscall_cancel_arch_end
>>> +    .type  __syscall_cancel_arch_end,@function
>>> +__syscall_cancel_arch_end:
>>> +    lg    %r4,272(%r15)
>>> +    lmg    %r6,%r15,208(%r15)
>>> +    cfi_remember_state
>>> +    cfi_restore (15)
>>> +    cfi_restore (14)
>>> +    cfi_restore (13)
>>> +    cfi_restore (12)
>>> +    cfi_restore (11)
>>> +    cfi_restore (10)
>>> +    cfi_restore (9)
>>> +    cfi_restore (8)
>>> +    cfi_restore (7)
>>> +    cfi_restore (6)
>>> +    cfi_def_cfa_offset (160)
>>> +    br    %r4
>>> +
>>> +1:
>>> +    cfi_restore_state
>>> +    brasl    %r14, __syscall_do_cancel
>> We can just use jg __syscall_do_cancel for this not-returning-tail-call.
>> (For the s390-32 part: Both instructions are z900 instructions, but as gcc has removed support for g5 and g6, this is okay at this point of time)
>>> +END (__syscall_cancel_arch)
>>> +libc_hidden_def (__syscall_cancel_arch)
>>>
>>
> 
> Ack.
> 

^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [PATCH v3 18/21] nptl: s390: Fix Race conditions in pthread cancellation (BZ#12683)
  2019-10-17 15:01       ` Stefan Liebler
@ 2019-10-17 19:46         ` Adhemerval Zanella
  2019-10-18 12:58           ` Stefan Liebler
  0 siblings, 1 reply; 38+ messages in thread
From: Adhemerval Zanella @ 2019-10-17 19:46 UTC (permalink / raw)
  To: libc-alpha



On 17/10/2019 12:00, Stefan Liebler wrote:
> On 10/17/19 3:53 PM, Adhemerval Zanella wrote:
>>
>>
>> On 16/10/2019 12:46, Stefan Liebler wrote:
>>> Hi Adhemerval,
>>>
>>> I've added some notes below to the s390-64 file, but the same applies also for s390-32. I've also attached a diff.
>>>
>>> I've also recognized that a call starting from e.g. write () involves various shuffling of the argument registers at each level:
>>> write (ARGS in r2-r4)
>>> -> __syscall_cancel (r2=nr, ARGS in r3-r6 and two stack-slots)
>>> --> __syscall_cancel_arch (r2=*ch, r3=nr, ARGS in r4-r6 and three stack-slots)
>>> ---> "syscall-instruction" (ARGS in r2-r7)
>>>
>>> Just as a quick idea (I don't know if there are other limitations), those shuffling instructions could perhaps be omitted if the nr / ch arguments of the __syscall_cancel / __syscall_cancel_arch functions would be the last arguments instead of the first ones.
>>> I assume that also other archs could benefit from such an ordering.
>>
>> Thanks, I have applied your changes.  Indeed for some architectures the
>> syscall_cancel.S might not be the most optimized one, I used the reference
>> C implementation as base and gcc might not generate the best code in some
>> cases.
>>
> The implementation in syscall_cancel.S contains just one of the three parts of the mentioned register move instructions. Those needs also to be generated in write() and __syscall_cancel().
> My point was, if we could preserve the values passed in registers to e.g. write() in the same registers until the syscall is invoked in __syscall_cancel_arch, we won't need to move them from registers to registers at all:
> write (ARGS in r2-r4)
> -> __syscall_cancel (ARGS in r2-r6 and first stack-slot, nr in second stack-slot)
> --> __syscall_cacnel_arch (ARGS in r2-r6 and first stack-slot, nr in second stack-slot, ch in third stack-slot)
> ---> "syscall-instruction" (ARGS in r2-r7)

Well I think it might be feasible, so for instance write would call:

ssize_t _libc_write (int fd, const void *buf, size_t nbytes)
\_ __syscall_cancel (fd, buf, nbytes, 0, 0, 0, __NR_write)
   \_ __syscall_cancel_arch (fd, buf, nbytes, 0, 0, 0, __NR_write, &pd->cancellation)
      ...

I don't have a strong opinion here, I would expect that since the
cancellation points are potentially blocking syscall both the
latency of the syscall itself and the potentially unbounded time
spent in kernel might shadow any potentially micro-optimization in
argument shuffling. 

Also, this patch has the advantage of removing the atomic operation
from __pthread_{enable,disable}_asynccancel, which for some 
architectures are way costly than register shuffling or spilling.


^ permalink raw reply	[flat|nested] 38+ messages in thread

* Internal SIGTIMER use (was: Re: [PATCH v3 02/21] nptl: Fix Race conditions in pthread cancellation (BZ#12683))
  2019-10-14 20:57 ` [PATCH v3 02/21] nptl: " Adhemerval Zanella
  2019-10-15 10:56   ` Florian Weimer
@ 2019-10-18 12:38   ` Florian Weimer
  2019-10-21 13:29     ` Adhemerval Zanella
  1 sibling, 1 reply; 38+ messages in thread
From: Florian Weimer @ 2019-10-18 12:38 UTC (permalink / raw)
  To: Adhemerval Zanella; +Cc: libc-alpha

* Adhemerval Zanella:

> -  sa.sa_sigaction = sigcancel_handler;
> -  sa.sa_flags = SA_SIGINFO;
> -  (void) __libc_sigaction (SIGCANCEL, &sa, NULL);
> +  {
> +    struct sigaction sa;
> +    sa.sa_sigaction = sigcancel_handler;
> +    /* The signal handle should be non-interruptible to avoid the risk of
> +       spurious EINTR caused by SIGCANCEL sent to process or if pthread_cancel
> +       is called while cancellation is disabled in the target thread.  */
> +    sa.sa_flags = SA_SIGINFO | SA_RESTART;
> +    sa.sa_mask = SIGALL_SET;
> +    __libc_sigaction (SIGCANCEL, &sa, NULL);
> +  }

Since SIGCANCEL and SIGTIMER are the same, I wondered whether this
change impacts timer_create.

Here is what i found: timer_create arranges for SIGCANCEL/SIGTIMER to be
sent to the internal helper thread, which does this:

      /* sigwaitinfo cannot be used here, since it deletes
         SIGCANCEL == SIGTIMER from the set.  */

      /* XXX The size argument hopefully will have to be changed to the
         real size of the user-level sigset_t.  */
      int result = SYSCALL_CANCEL (rt_sigtimedwait, &ss, &si, NULL, _NSIG / 8);

      if (result > 0)
        {
          if (si.si_code == SI_TIMER)
            {
              struct timer *tk = (struct timer *) si.si_ptr;
…
          else if (si.si_code == SI_TKILL)
            /* The thread is canceled.  */
            pthread_exit (NULL);
        }

This suggests to me that the helper thread does NOT depend on EINTR
being generated for SIGCANCEL/SIGTIMER, and it should be fine to use
SA_RESTART for that signal as far as timer_create is concerned.

If you agree, it probably makes sense to add this bit of information to
the commit message.

Thanks,
Florian

^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [PATCH v3 18/21] nptl: s390: Fix Race conditions in pthread cancellation (BZ#12683)
  2019-10-17 19:46         ` Adhemerval Zanella
@ 2019-10-18 12:58           ` Stefan Liebler
  0 siblings, 0 replies; 38+ messages in thread
From: Stefan Liebler @ 2019-10-18 12:58 UTC (permalink / raw)
  To: libc-alpha

On 10/17/19 9:46 PM, Adhemerval Zanella wrote:
> 
> 
> On 17/10/2019 12:00, Stefan Liebler wrote:
>> On 10/17/19 3:53 PM, Adhemerval Zanella wrote:
>>>
>>>
>>> On 16/10/2019 12:46, Stefan Liebler wrote:
>>>> Hi Adhemerval,
>>>>
>>>> I've added some notes below to the s390-64 file, but the same applies also for s390-32. I've also attached a diff.
>>>>
>>>> I've also recognized that a call starting from e.g. write () involves various shuffling of the argument registers at each level:
>>>> write (ARGS in r2-r4)
>>>> -> __syscall_cancel (r2=nr, ARGS in r3-r6 and two stack-slots)
>>>> --> __syscall_cancel_arch (r2=*ch, r3=nr, ARGS in r4-r6 and three stack-slots)
>>>> ---> "syscall-instruction" (ARGS in r2-r7)
>>>>
>>>> Just as a quick idea (I don't know if there are other limitations), those shuffling instructions could perhaps be omitted if the nr / ch arguments of the __syscall_cancel / __syscall_cancel_arch functions would be the last arguments instead of the first ones.
>>>> I assume that also other archs could benefit from such an ordering.
>>>
>>> Thanks, I have applied your changes.  Indeed for some architectures the
>>> syscall_cancel.S might not be the most optimized one, I used the reference
>>> C implementation as base and gcc might not generate the best code in some
>>> cases.
>>>
>> The implementation in syscall_cancel.S contains just one of the three parts of the mentioned register move instructions. Those needs also to be generated in write() and __syscall_cancel().
>> My point was, if we could preserve the values passed in registers to e.g. write() in the same registers until the syscall is invoked in __syscall_cancel_arch, we won't need to move them from registers to registers at all:
>> write (ARGS in r2-r4)
>> -> __syscall_cancel (ARGS in r2-r6 and first stack-slot, nr in second stack-slot)
>> --> __syscall_cacnel_arch (ARGS in r2-r6 and first stack-slot, nr in second stack-slot, ch in third stack-slot)
>> ---> "syscall-instruction" (ARGS in r2-r7)
> 
> Well I think it might be feasible, so for instance write would call:
> 
> ssize_t _libc_write (int fd, const void *buf, size_t nbytes)
> \_ __syscall_cancel (fd, buf, nbytes, 0, 0, 0, __NR_write)
>     \_ __syscall_cancel_arch (fd, buf, nbytes, 0, 0, 0, __NR_write, &pd->cancellation)
>        ...
> 
> I don't have a strong opinion here, I would expect that since the
> cancellation points are potentially blocking syscall both the
> latency of the syscall itself and the potentially unbounded time
> spent in kernel might shadow any potentially micro-optimization in
> argument shuffling.
Sure. The syscall spends the most time.
Beneath the timing aspect, this also affects the code-size in various 
places. And if somebody reads / debugs the code starting from e.g. write 
until the syscall, the instruction sequence looks confusing. (Not only 
on s390)

> 
> Also, this patch has the advantage of removing the atomic operation
> from __pthread_{enable,disable}_asynccancel, which for some
> architectures are way costly than register shuffling or spilling.

^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: Internal SIGTIMER use (was: Re: [PATCH v3 02/21] nptl: Fix Race conditions in pthread cancellation (BZ#12683))
  2019-10-18 12:38   ` Internal SIGTIMER use (was: Re: [PATCH v3 02/21] nptl: Fix Race conditions in pthread cancellation (BZ#12683)) Florian Weimer
@ 2019-10-21 13:29     ` Adhemerval Zanella
  0 siblings, 0 replies; 38+ messages in thread
From: Adhemerval Zanella @ 2019-10-21 13:29 UTC (permalink / raw)
  To: Florian Weimer; +Cc: libc-alpha



On 18/10/2019 09:37, Florian Weimer wrote:
> * Adhemerval Zanella:
> 
>> -  sa.sa_sigaction = sigcancel_handler;
>> -  sa.sa_flags = SA_SIGINFO;
>> -  (void) __libc_sigaction (SIGCANCEL, &sa, NULL);
>> +  {
>> +    struct sigaction sa;
>> +    sa.sa_sigaction = sigcancel_handler;
>> +    /* The signal handle should be non-interruptible to avoid the risk of
>> +       spurious EINTR caused by SIGCANCEL sent to process or if pthread_cancel
>> +       is called while cancellation is disabled in the target thread.  */
>> +    sa.sa_flags = SA_SIGINFO | SA_RESTART;
>> +    sa.sa_mask = SIGALL_SET;
>> +    __libc_sigaction (SIGCANCEL, &sa, NULL);
>> +  }
> 
> Since SIGCANCEL and SIGTIMER are the same, I wondered whether this
> change impacts timer_create.
> 
> Here is what i found: timer_create arranges for SIGCANCEL/SIGTIMER to be
> sent to the internal helper thread, which does this:
> 
>       /* sigwaitinfo cannot be used here, since it deletes
>          SIGCANCEL == SIGTIMER from the set.  */
> 
>       /* XXX The size argument hopefully will have to be changed to the
>          real size of the user-level sigset_t.  */
>       int result = SYSCALL_CANCEL (rt_sigtimedwait, &ss, &si, NULL, _NSIG / 8);
> 
>       if (result > 0)
>         {
>           if (si.si_code == SI_TIMER)
>             {
>               struct timer *tk = (struct timer *) si.si_ptr;
> …
>           else if (si.si_code == SI_TKILL)
>             /* The thread is canceled.  */
>             pthread_exit (NULL);
>         }
> 
> This suggests to me that the helper thread does NOT depend on EINTR
> being generated for SIGCANCEL/SIGTIMER, and it should be fine to use
> SA_RESTART for that signal as far as timer_create is concerned.
> 
> If you agree, it probably makes sense to add this bit of information to
> the commit message.

Ack, this is what I have added:

--

As a side note regarding SIGCANCEL and SIGTIMER being the the same,
it should not impact timer_create functionality.  It arranges for
SIGCANCEL/SIGTIMER to be sent to the internal helper thread, which
in turn check if the si.si_code is SI_TIMER and call pthread_exit
otherwise (sysdeps/unix/sysv/linux/timer_routines.c:129).

This suggests that the helper thread does NOT depend on EINTR
being generated for SIGCANCEL/SIGTIMER, and it should be fine to use
SA_RESTART for that signal as far as timer_create is concerned.

^ permalink raw reply	[flat|nested] 38+ messages in thread

end of thread, other threads:[~2019-10-21 13:29 UTC | newest]

Thread overview: 38+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-10-14 20:57 [PATCH v3 00/21] nptl: Fix Race conditions in pthread cancellation (BZ#12683) Adhemerval Zanella
2019-10-14 20:57 ` [PATCH v3 12/21] nptl: sparc: " Adhemerval Zanella
2019-10-14 20:57 ` [PATCH v3 08/21] nptl: aarch64: " Adhemerval Zanella
2019-10-14 20:57 ` [PATCH v3 04/21] nptl: x32: " Adhemerval Zanella
2019-10-15 11:06   ` Florian Weimer
2019-10-14 20:57 ` [PATCH v3 20/21] nptl: csky: " Adhemerval Zanella
2019-10-14 20:57 ` [PATCH v3 18/21] nptl: s390: " Adhemerval Zanella
2019-10-16 15:46   ` Stefan Liebler
2019-10-17 13:54     ` Adhemerval Zanella
2019-10-17 15:01       ` Stefan Liebler
2019-10-17 19:46         ` Adhemerval Zanella
2019-10-18 12:58           ` Stefan Liebler
2019-10-14 20:57 ` [PATCH v3 02/21] nptl: " Adhemerval Zanella
2019-10-15 10:56   ` Florian Weimer
2019-10-16 20:42     ` Adhemerval Zanella
2019-10-18 12:38   ` Internal SIGTIMER use (was: Re: [PATCH v3 02/21] nptl: Fix Race conditions in pthread cancellation (BZ#12683)) Florian Weimer
2019-10-21 13:29     ` Adhemerval Zanella
2019-10-14 20:57 ` [PATCH v3 14/21] nptl: m68k: Fix Race conditions in pthread cancellation (BZ#12683) Adhemerval Zanella
2019-10-14 21:13   ` Andreas Schwab
2019-10-14 20:57 ` [PATCH v3 15/21] nptl: alpha: " Adhemerval Zanella
2019-10-17  3:01   ` Matt Turner
2019-10-14 20:57 ` [PATCH v3 07/21] nptl: i386: " Adhemerval Zanella
2019-10-14 20:57 ` [PATCH v3 01/21] nptl: Handle EPIPE on tst-cancel2 Adhemerval Zanella
2019-10-15  9:03   ` Florian Weimer
2019-10-14 20:57 ` [PATCH v3 16/21] nptl: sh: Fix Race conditions in pthread cancellation (BZ#12683) Adhemerval Zanella
2019-10-14 20:57 ` [PATCH v3 13/21] nptl: hppa: " Adhemerval Zanella
2019-10-14 20:57 ` [PATCH v3 06/21] nptl: mips: " Adhemerval Zanella
2019-10-14 20:57 ` [PATCH v3 19/21] nptl: nios2: " Adhemerval Zanella
2019-10-14 20:57 ` [PATCH v3 03/21] nptl: x86_64: " Adhemerval Zanella
2019-10-15 11:03   ` Florian Weimer
2019-10-16 21:22     ` Adhemerval Zanella
2019-10-14 20:57 ` [PATCH v3 09/21] nptl: arm: " Adhemerval Zanella
2019-10-14 20:57 ` [PATCH v3 10/21] nptl: powerpc: " Adhemerval Zanella
2019-10-14 20:57 ` [PATCH v3 05/21] nptl: ia64: " Adhemerval Zanella
2019-10-14 20:57 ` [PATCH v3 11/21] nptl: microblaze: " Adhemerval Zanella
2019-10-14 20:57 ` [PATCH v3 17/21] nptl: riscv: " Adhemerval Zanella
2019-10-14 23:22   ` Andrew Waterman
2019-10-14 20:58 ` [PATCH v3 21/21] Remove sysdep-cancel header Adhemerval Zanella

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).