unofficial mirror of libc-alpha@sourceware.org
 help / color / mirror / Atom feed
* [PATCH v4 00/21] nptl: Fix Race conditions in pthread cancellation [BZ#12683]
@ 2020-04-03 20:31 Adhemerval Zanella via Libc-alpha
  2020-04-03 20:31 ` [PATCH v4 01/21] nptl: Do not close the pipe on tst-cancel{2,3} Adhemerval Zanella via Libc-alpha
                   ` (20 more replies)
  0 siblings, 21 replies; 46+ messages in thread
From: Adhemerval Zanella via Libc-alpha @ 2020-04-03 20:31 UTC (permalink / raw
  To: libc-alpha

This is an updated version of my previous version [1] to fix BZ#12683
and it is based on cancel type and state refactor [2] [3] (still
pending review).

The changes from previous version are:

  - Use CANCELED_BITMASK on syscall_cancel.S instead of hardcoded
    value and remove the archors type.

  - Reorganized the __do_cancel macro and its usage on various
    pthread functions (and once pthread_exit is moved to libc.so it
    can be replaced by __pthread_exit call).

  - Reword x32 fix to use the its expected kernel ABI.

Below there are the system where I could 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/pipermail/libc-alpha/2019-October/107284.html
[2] https://sourceware.org/pipermail/libc-alpha/2020-April/112416.html
[3] https://sourceware.org/pipermail/libc-alpha/2020-April/112417.html

Adhemerval Zanella (21):
  nptl: Do not close the pipe on tst-cancel{2,3}
  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: i386: 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: 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]
  Linux: 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 -
 io/creat.c                                    |   1 -
 io/ppoll.c                                    |   2 -
 malloc/malloc.c                               |   3 -
 manual/llio.texi                              |   4 +-
 nptl/Makefile                                 |  10 +-
 nptl/Versions                                 |   4 +
 nptl/cancellation.c                           |  78 ----------
 nptl/descr.h                                  |   3 -
 nptl/libc-cancellation.c                      |  44 +++++-
 nptl/nptl-init.c                              |  92 ++++++------
 nptl/pthreadP.h                               |  58 ++++++--
 nptl/pthread_cancel.c                         |  66 ++-------
 nptl/pthread_create.c                         |   7 +-
 nptl/pthread_exit.c                           |   9 +-
 nptl/pthread_join_common.c                    |   7 +-
 nptl/pthread_kill.c                           |   7 +-
 .../pthread_kill_internal.c                   |  21 +--
 nptl/pthread_setcanceltype.c                  |   2 +-
 nptl/pthread_testcancel.c                     |  12 +-
 nptl/sem_wait.c                               |   2 +-
 nptl/tst-cancel2.c                            |   3 -
 nptl/tst-cancel29.c                           | 100 +++++++++++++
 nptl/tst-cancel3.c                            |   3 -
 posix/nanosleep.c                             |   1 -
 rt/Makefile                                   |   2 +-
 sysdeps/aarch64/nptl/tcb-offsets.sym          |   3 +
 sysdeps/alpha/nptl/tcb-offsets.sym            |   3 +
 sysdeps/arm/nptl/tcb-offsets.sym              |   3 +
 sysdeps/csky/nptl/tcb-offsets.sym             |   3 +
 .../syscall_types.h}                          |  13 +-
 sysdeps/generic/sysdep-cancel.h               |   7 -
 sysdeps/hppa/nptl/tcb-offsets.sym             |   3 +
 sysdeps/i386/nptl/tcb-offsets.sym             |   3 +
 sysdeps/ia64/nptl/tcb-offsets.sym             |   3 +
 sysdeps/m68k/nptl/tcb-offsets.sym             |   3 +
 sysdeps/microblaze/nptl/tcb-offsets.sym       |   3 +
 sysdeps/mips/dl-trampoline.c                  |   1 -
 sysdeps/mips/nptl/tcb-offsets.sym             |   3 +
 sysdeps/nios2/nptl/tcb-offsets.sym            |   3 +
 sysdeps/nptl/Makefile                         |   3 +-
 sysdeps/nptl/cancellation-pc-check.h          |  53 +++++++
 sysdeps/nptl/cancellation-sigmask.h           |  30 ++++
 sysdeps/nptl/futex-internal.h                 |  19 +--
 sysdeps/nptl/lowlevellock-futex.h             |  42 ++++--
 sysdeps/posix/open64.c                        |   1 -
 sysdeps/posix/pause.c                         |   1 -
 sysdeps/posix/sigpause.c                      |   1 -
 sysdeps/posix/sigwait.c                       |   1 -
 sysdeps/powerpc/nptl/tcb-offsets.sym          |   3 +
 sysdeps/powerpc/powerpc32/sysdep.h            |   3 +
 sysdeps/powerpc/powerpc64/sysdep.h            |  19 +++
 sysdeps/pthread/thrd_sleep.c                  |   1 -
 sysdeps/riscv/nptl/tcb-offsets.sym            |   3 +
 sysdeps/riscv/nptl/tls.h                      |   2 +
 sysdeps/s390/nptl/tcb-offsets.sym             |   3 +
 sysdeps/sh/nptl/tcb-offsets.sym               |   3 +
 sysdeps/sh/sysdep.h                           |   1 +
 sysdeps/sparc/nptl/tcb-offsets.sym            |   3 +
 sysdeps/unix/sysdep.h                         | 139 ++++++++++++++----
 .../unix/sysv/linux/aarch64/syscall_cancel.S  |  59 ++++++++
 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    |  81 ++++++++++
 sysdeps/unix/sysv/linux/arm/syscall_cancel.S  |  78 ++++++++++
 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/csky/syscall_cancel.S | 115 +++++++++++++++
 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 +-
 .../unix/sysv/linux/generic/inotify_init.c    |   5 +-
 sysdeps/unix/sysv/linux/getrandom.c           |   1 -
 sysdeps/unix/sysv/linux/hppa/syscall_cancel.S |  83 +++++++++++
 sysdeps/unix/sysv/linux/hppa/sysdep.h         |   1 +
 sysdeps/unix/sysv/linux/i386/Makefile         |   2 +-
 sysdeps/unix/sysv/linux/i386/syscall_cancel.S | 104 +++++++++++++
 .../sysv/linux/ia64/cancellation-pc-check.h   |  48 ++++++
 .../sysv/linux/ia64/cancellation-sigmask.h    |  33 +++++
 sysdeps/unix/sysv/linux/ia64/syscall_cancel.S |  81 ++++++++++
 sysdeps/unix/sysv/linux/m68k/syscall_cancel.S |  85 +++++++++++
 sysdeps/unix/sysv/linux/microblaze/pselect.c  |   1 -
 .../sysv/linux/microblaze/syscall_cancel.S    |  61 ++++++++
 sysdeps/unix/sysv/linux/microblaze/sysdep.h   |   1 +
 .../sysv/linux/mips/mips32/syscall_cancel.S   | 128 ++++++++++++++++
 sysdeps/unix/sysv/linux/mips/mips32/sysdep.h  |   4 +
 .../linux/mips/mips64/n32/syscall_types.h     |  28 ++++
 .../sysv/linux/mips/mips64/syscall_cancel.S   | 130 ++++++++++++++++
 sysdeps/unix/sysv/linux/mips/mips64/sysdep.h  |  52 +++----
 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 +-
 .../unix/sysv/linux/nios2/syscall_cancel.S    |  95 ++++++++++++
 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/poll.c                |   1 -
 .../unix/sysv/linux/powerpc/syscall_cancel.S  |  65 ++++++++
 sysdeps/unix/sysv/linux/ppoll.c               |   3 -
 sysdeps/unix/sysv/linux/pread.c               |   2 +-
 sysdeps/unix/sysv/linux/pread64.c             |   2 +-
 sysdeps/unix/sysv/linux/pread64_nocancel.c    |   1 -
 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             |   5 +-
 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    |  67 +++++++++
 .../sysv/linux/s390/s390-32/syscall_cancel.S  |  63 ++++++++
 .../sysv/linux/s390/s390-64/syscall_cancel.S  |  62 ++++++++
 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   | 126 ++++++++++++++++
 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 |  71 +++++++++
 sysdeps/unix/sysv/linux/sparc/sparc64/pause.c |  25 ++++
 .../sysv/linux/sparc/sparc64/syscall_cancel.S |  74 ++++++++++
 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              |   9 ++
 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/wait4.c               |   2 +-
 sysdeps/unix/sysv/linux/waitid.c              |   1 -
 sysdeps/unix/sysv/linux/write.c               |   2 +-
 sysdeps/unix/sysv/linux/write_nocancel.c      |   1 -
 sysdeps/unix/sysv/linux/writev.c              |   2 +-
 .../unix/sysv/linux/x86_64/syscall_cancel.S   |  59 ++++++++
 .../sysv/linux/x86_64/x32/syscall_types.h     |  40 +++++
 180 files changed, 2661 insertions(+), 544 deletions(-)
 delete mode 100644 nptl/cancellation.c
 rename sysdeps/unix/sysv/linux/pthread_kill.c => nptl/pthread_kill_internal.c (75%)
 create mode 100644 nptl/tst-cancel29.c
 rename sysdeps/{nptl/librt-cancellation.c => generic/syscall_types.h} (70%)
 delete mode 100644 sysdeps/generic/sysdep-cancel.h
 create mode 100644 sysdeps/nptl/cancellation-pc-check.h
 create mode 100644 sysdeps/nptl/cancellation-sigmask.h
 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/n32/syscall_types.h
 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
 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
 create mode 100644 sysdeps/unix/sysv/linux/sparc/sparc64/pause.c
 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
 create mode 100644 sysdeps/unix/sysv/linux/x86_64/syscall_cancel.S
 create mode 100644 sysdeps/unix/sysv/linux/x86_64/x32/syscall_types.h

-- 
2.17.1


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

* [PATCH v4 01/21] nptl: Do not close the pipe on tst-cancel{2,3}
  2020-04-03 20:31 [PATCH v4 00/21] nptl: Fix Race conditions in pthread cancellation [BZ#12683] Adhemerval Zanella via Libc-alpha
@ 2020-04-03 20:31 ` Adhemerval Zanella via Libc-alpha
  2020-04-07 15:24   ` Zack Weinberg
  2020-04-03 20:31 ` [PATCH v4 02/21] nptl: Fix Race conditions in pthread cancellation [BZ#12683] Adhemerval Zanella via Libc-alpha
                   ` (19 subsequent siblings)
  20 siblings, 1 reply; 46+ messages in thread
From: Adhemerval Zanella via Libc-alpha @ 2020-04-03 20:31 UTC (permalink / raw
  To: libc-alpha

This can cause a SIGPIPE before SIGCANCEL is processed, 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 ---
 nptl/tst-cancel3.c | 3 ---
 2 files changed, 6 deletions(-)

diff --git a/nptl/tst-cancel2.c b/nptl/tst-cancel2.c
index 1e86711596..1732980b0f 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");
diff --git a/nptl/tst-cancel3.c b/nptl/tst-cancel3.c
index 0a531dbcdb..3a0acac5e2 100644
--- a/nptl/tst-cancel3.c
+++ b/nptl/tst-cancel3.c
@@ -75,9 +75,6 @@ do_test (void)
       return 1;
     }
 
-  /* This will cause the read in the child to return.  */
-  close (fd[0]);
-
   if (pthread_join (th, &r) != 0)
     {
       puts ("join failed");
-- 
2.17.1


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

* [PATCH v4 02/21] nptl: Fix Race conditions in pthread cancellation [BZ#12683]
  2020-04-03 20:31 [PATCH v4 00/21] nptl: Fix Race conditions in pthread cancellation [BZ#12683] Adhemerval Zanella via Libc-alpha
  2020-04-03 20:31 ` [PATCH v4 01/21] nptl: Do not close the pipe on tst-cancel{2,3} Adhemerval Zanella via Libc-alpha
@ 2020-04-03 20:31 ` Adhemerval Zanella via Libc-alpha
  2020-04-07 18:24   ` Zack Weinberg
  2020-04-03 20:31 ` [PATCH v4 03/21] nptl: x86_64: " Adhemerval Zanella via Libc-alpha
                   ` (18 subsequent siblings)
  20 siblings, 1 reply; 46+ messages in thread
From: Adhemerval Zanella via Libc-alpha @ 2020-04-03 20:31 UTC (permalink / raw
  To: libc-alpha

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

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

  1. Cancellation can act after the syscall has returned from the
     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 the 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 cases 4 or 5.  For the 4 and 5 cases, the cancellation will eventually
happen in the next cancellable entry point without any further external
event.

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 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.

  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 syscalls 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 is 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 an arch-specific generic system call wrapper function
     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 have 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 depending on how INTERNAL_SYSCALL_NCS is
     implemented by the architecture and it uses compiler-specific
     construct (asm volatile) to place the required markers.
     It is expected that all architectures add an arch-specific
     implementation.

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

  4. Adjust nptl/pthread_cancel.c to send a signal instead of acting
     directly. This avoids synchronization issues when updating the
     cancellation status and also focuses the logic on the 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 the
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.

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.
---
 manual/llio.texi                              |   4 +-
 nptl/Makefile                                 |  10 +-
 nptl/Versions                                 |   4 +
 nptl/cancellation.c                           |  78 ------------
 nptl/descr.h                                  |   3 -
 nptl/libc-cancellation.c                      |  43 ++++++-
 nptl/nptl-init.c                              |  92 +++++++-------
 nptl/pthreadP.h                               |  57 ++++++---
 nptl/pthread_cancel.c                         |  66 +++-------
 nptl/pthread_create.c                         |   7 +-
 nptl/pthread_exit.c                           |   9 +-
 nptl/pthread_join_common.c                    |   7 +-
 nptl/pthread_kill.c                           |   7 +-
 .../pthread_kill_internal.c                   |  21 +---
 nptl/pthread_setcanceltype.c                  |   2 +-
 nptl/pthread_testcancel.c                     |  12 +-
 nptl/sem_wait.c                               |   2 +-
 nptl/tst-cancel29.c                           | 100 +++++++++++++++
 rt/Makefile                                   |   2 +-
 .../syscall_types.h}                          |  13 +-
 sysdeps/generic/sysdep-cancel.h               |   2 -
 sysdeps/nptl/Makefile                         |   3 +-
 sysdeps/nptl/cancellation-pc-check.h          |  53 ++++++++
 sysdeps/nptl/cancellation-sigmask.h           |  30 +++++
 sysdeps/nptl/futex-internal.h                 |  19 +--
 sysdeps/nptl/lowlevellock-futex.h             |  41 ++++--
 sysdeps/unix/sysdep.h                         | 118 ++++++++++++++----
 sysdeps/unix/sysv/linux/socketcall.h          |  40 ++++--
 sysdeps/unix/sysv/linux/syscall_cancel.c      |  62 +++++++++
 sysdeps/unix/sysv/linux/sysdep-cancel.h       |  42 -------
 sysdeps/unix/sysv/linux/sysdep.h              |   9 ++
 31 files changed, 591 insertions(+), 367 deletions(-)
 delete mode 100644 nptl/cancellation.c
 rename sysdeps/unix/sysv/linux/pthread_kill.c => nptl/pthread_kill_internal.c (75%)
 create mode 100644 nptl/tst-cancel29.c
 rename sysdeps/{nptl/librt-cancellation.c => generic/syscall_types.h} (70%)
 create mode 100644 sysdeps/nptl/cancellation-pc-check.h
 create mode 100644 sysdeps/nptl/cancellation-sigmask.h
 create mode 100644 sysdeps/unix/sysv/linux/syscall_cancel.c

diff --git a/manual/llio.texi b/manual/llio.texi
index fe59002915..c02ee83428 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 e554a3898d..0cb724eb76 100644
--- a/nptl/Makefile
+++ b/nptl/Makefile
@@ -60,6 +60,7 @@ routines = \
   pthread_self \
   pthread_setschedparam \
   register-atfork \
+  syscall_cancel
 
 shared-only-routines = forward
 static-only-routines = pthread_atfork
@@ -123,7 +124,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 \
@@ -137,7 +139,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 \
@@ -187,8 +188,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-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-cancel26 tst-cancel27 tst-cancel28 \
+	tst-cancel26 tst-cancel27 tst-cancel28 tst-cancel29 \
 	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 543dddc4ee..41d732e1dd 100644
--- a/nptl/Versions
+++ b/nptl/Versions
@@ -41,6 +41,10 @@ libc {
     __libc_allocate_rtsig_private;
     # Used by the C11 threads implementation.
     __pthread_cond_destroy; __pthread_cond_init;
+    # Used by pthread cancellation.
+    __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 7127f9ae91..0000000000
--- a/nptl/cancellation.c
+++ /dev/null
@@ -1,78 +0,0 @@
-/* Copyright (C) 2002-2020 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.  These functions must be
-   AS-safe, with the exception of the actual cancellation, because they
-   are called by wrappers around AS-safe functions like write().*/
-int
-attribute_hidden
-__pthread_enable_asynccancel (void)
-{
-  struct pthread *self = THREAD_SELF;
-
-  int oldval = THREAD_GETMEM (self, canceltype);
-  THREAD_SETMEM (self, canceltype, PTHREAD_CANCEL_ASYNCHRONOUS);
-
-  int ch = THREAD_GETMEM (self, cancelhandling);
-
-  if (self->cancelstate == PTHREAD_CANCEL_ENABLE
-      && (ch & (CANCELED_BITMASK | EXITING_BITMASK | TERMINATED_BITMASK))
-	  == CANCELED_BITMASK)
-    {
-      THREAD_SETMEM (self, result, PTHREAD_CANCELED);
-      __do_cancel ();
-    }
-
-  return oldval;
-}
-
-/* See the comment for __pthread_enable_asynccancel regarding
-   the AS-safety of this function.  */
-void
-attribute_hidden
-__pthread_disable_asynccancel (int oldtype)
-{
-  /* If asynchronous cancellation was enabled before we do not have
-     anything to do.  */
-  if (oldtype == PTHREAD_CANCEL_ASYNCHRONOUS)
-    return;
-
-  struct pthread *self = THREAD_SELF;
-  THREAD_SETMEM (self, canceltype, PTHREAD_CANCEL_DEFERRED);
-
-  /* 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.  */
-  int ch = THREAD_GETMEM (self, cancelhandling);
-  while (__glibc_unlikely ((ch & (CANCELING_BITMASK | CANCELED_BITMASK))
-			    == CANCELING_BITMASK))
-    {
-      futex_wait_simple ((unsigned int *) &self->cancelhandling, ch,
-			 FUTEX_PRIVATE);
-      ch = THREAD_GETMEM (self, cancelhandling);
-    }
-}
diff --git a/nptl/descr.h b/nptl/descr.h
index bae9457e33..c0b8f6c40e 100644
--- a/nptl/descr.h
+++ b/nptl/descr.h
@@ -269,9 +269,6 @@ struct pthread
 
   /* Flags determining processing of cancellation.  */
   int cancelhandling;
-  /* 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
 #define CANCELED_BITMASK	(0x01 << CANCELED_BIT)
diff --git a/nptl/libc-cancellation.c b/nptl/libc-cancellation.c
index eae81d504c..e695d67417 100644
--- a/nptl/libc-cancellation.c
+++ b/nptl/libc-cancellation.c
@@ -18,7 +18,44 @@
 
 #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)
+{
+  struct pthread *pd = THREAD_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->cancelstate == PTHREAD_CANCEL_DISABLE)
+    {
+      result = INTERNAL_SYSCALL_NCS_CALL (nr, a1, a2, a3, a4, a5, a6);
+      if (INTERNAL_SYSCALL_ERROR_P (result))
+	return -INTERNAL_SYSCALL_ERRNO (result);
+      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
+      && __pthread_self_cancelled ()
+      && pd->cancelstate == PTHREAD_CANCEL_ENABLE)
+    __do_cancel (PTHREAD_CANCELED);
+
+  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 (PTHREAD_CANCELED);
+}
diff --git a/nptl/nptl-init.c b/nptl/nptl-init.c
index 89f58d2e5e..75225965c4 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.  */
@@ -137,35 +140,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 (self->canceltype == PTHREAD_CANCEL_ASYNCHRONOUS)
-	    /* Run the registered destructors and terminate the thread.  */
-	    __do_cancel ();
-
-	  break;
-	}
-
-      oldval = curval;
-    }
+  if (!__pthread_self_cancelled ()
+      || self->cancelstate == PTHREAD_CANCEL_DISABLE)
+    return;
+
+  /* Add SIGCANCEL on ignored sigmask to avoid the handler to be called
+     again.  */
+  ucontext_block_sigcancel (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->canceltype == PTHREAD_CANCEL_ASYNCHRONOUS
+      || cancellation_pc_check (ctx))
+    __do_cancel (PTHREAD_CANCELED);
 }
 
 
@@ -260,28 +251,39 @@ __pthread_initialize_minimal_internal (void)
      had to set __nptl_initial_report_events.  Propagate its setting.  */
   THREAD_SETMEM (pd, report_events, __nptl_initial_report_events);
 
-  struct sigaction sa;
-  __sigemptyset (&sa.sa_mask);
-
   /* 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);
+  }
 
-  /* 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);
+  }
 
   /* 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.  */
-  __sigaddset (&sa.sa_mask, SIGCANCEL);
-  __sigaddset (&sa.sa_mask, SIGSETXID);
-  INTERNAL_SYSCALL_CALL (rt_sigprocmask, SIG_UNBLOCK, &sa.sa_mask,
-			 NULL, _NSIG / 8);
+     case, unblock it.  */
+  {
+    struct sigaction sa;
+    __sigemptyset (&sa.sa_mask);
+    __sigaddset (&sa.sa_mask, SIGCANCEL);
+    __sigaddset (&sa.sa_mask, SIGSETXID);
+    INTERNAL_SYSCALL_CALL (rt_sigprocmask, SIG_UNBLOCK, &sa.sa_mask,
+			   NULL, _NSIG / 8);
+  }
 
   /* Get the size of the static and alignment requirements for the TLS
      block.  */
diff --git a/nptl/pthreadP.h b/nptl/pthreadP.h
index d55c3b26a4..a20b136f14 100644
--- a/nptl/pthreadP.h
+++ b/nptl/pthreadP.h
@@ -286,20 +286,13 @@ 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)
-{
-  struct pthread *self = THREAD_SELF;
-
-  /* Make sure we get no more cancellations.  */
-  THREAD_ATOMIC_BIT_SET (self, cancelhandling, EXITING_BIT);
-
-  __pthread_unwind ((__pthread_unwind_buf_t *)
-		    THREAD_GETMEM (self, cleanup_jmp_buf));
-}
+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.  */
 
@@ -461,12 +454,13 @@ 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 void __pthread_exit (void *value) __attribute__ ((__noreturn__));
+extern int __pthread_kill_internal (pthread_t threadid, int signo)
+  attribute_hidden;
+extern void _Noreturn __pthread_exit (void *value);
 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 void __pthread_exit (void *value);
 extern int __pthread_clockjoin_ex (pthread_t, void **, clockid_t,
 				   const struct timespec *, bool)
   attribute_hidden;
@@ -487,10 +481,41 @@ hidden_proto (__pthread_setspecific)
 hidden_proto (__pthread_once)
 hidden_proto (__pthread_setcancelstate)
 hidden_proto (__pthread_testcancel)
+hidden_proto (__pthread_exit)
 hidden_proto (__pthread_mutexattr_init)
 hidden_proto (__pthread_mutexattr_settype)
 #endif
 
+/* Called when a thread reacts on a cancellation request.  */
+_Noreturn static inline void
+__do_cancel (void *value)
+{
+  struct pthread *self = THREAD_SELF;
+
+  /* Make sure we get no more cancellations by clearing the cancel
+     state.  */
+  THREAD_SETMEM (self, cancelstate, PTHREAD_CANCEL_DISABLE);
+  THREAD_SETMEM (self, canceltype, PTHREAD_CANCEL_DEFERRED);
+
+  THREAD_SETMEM (self, result, value);
+
+  THREAD_ATOMIC_BIT_SET (self, cancelhandling, EXITING_BIT);
+
+  __pthread_unwind ((__pthread_unwind_buf_t *)
+		    THREAD_GETMEM (self, cleanup_jmp_buf));
+}
+
+static inline bool
+__pthread_self_cancelled (void)
+{
+  struct pthread *self = THREAD_SELF;
+  int cancelhandling = THREAD_GETMEM (self, cancelhandling);
+  return self->cancelstate == PTHREAD_CANCEL_ENABLE
+	  && (cancelhandling & (CANCELED_BITMASK | EXITING_BITMASK
+			        | TERMINATED_BITMASK))
+	      == CANCELED_BITMASK;
+}
+
 extern int __pthread_cond_broadcast_2_0 (pthread_cond_2_0_t *cond);
 extern int __pthread_cond_destroy_2_0 (pthread_cond_2_0_t *cond);
 extern int __pthread_cond_init_2_0 (pthread_cond_2_0_t *cond,
diff --git a/nptl/pthread_cancel.c b/nptl/pthread_cancel.c
index 7518c0b8bf..3873a47af8 100644
--- a/nptl/pthread_cancel.c
+++ b/nptl/pthread_cancel.c
@@ -37,63 +37,29 @@ __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;
-
-      /* If the cancellation is handled asynchronously just send a
-	 signal.  We avoid this if possible since it's more
-	 expensive.  */
-      if (pd->cancelstate == PTHREAD_CANCEL_ENABLE
-	  && pd->canceltype == PTHREAD_CANCEL_ASYNCHRONOUS
-	  && (newval & (CANCELED_BITMASK | EXITING_BITMASK
-			| TERMINATED_BITMASK))
-	      == CANCELED_BITMASK)
-	{
-	  /* Mark the cancellation as "in progress".  */
-	  if (atomic_compare_and_exchange_bool_acq (&pd->cancelhandling,
-						    oldval | CANCELING_BITMASK,
-						    oldval))
-	    goto again;
 
-	  /* The cancellation handler will take care of marking the
-	     thread as canceled.  */
-	  pid_t pid = __getpid ();
+  THREAD_ATOMIC_BIT_SET (pd, cancelhandling, CANCELED_BIT);
 
-	  int val = INTERNAL_SYSCALL_CALL (tgkill, pid, pd->tid,
-					   SIGCANCEL);
-	  if (INTERNAL_SYSCALL_ERROR_P (val))
-	    result = INTERNAL_SYSCALL_ERRNO (val);
+  /* 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);
 
-	  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);
 #ifndef TLS_MULTIPLE_THREADS_IN_TCB
-	__pthread_multiple_threads = *__libc_multiple_threads_ptr = 1;
+  __pthread_multiple_threads = *__libc_multiple_threads_ptr = 1;
 #endif
+
+  /* Avoid signaling when thread attempts cancel itself (pthread_kill
+     is expensive).  */
+  if (pd == THREAD_SELF)
+    {
+      if (pd->cancelstate == PTHREAD_CANCEL_ENABLE
+	  && pd->canceltype == PTHREAD_CANCEL_ASYNCHRONOUS)
+	__pthread_exit (PTHREAD_CANCELED);
+      return 0;
     }
-  /* 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;
+  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 7c752d0f99..bc9dd2d965 100644
--- a/nptl/pthread_create.c
+++ b/nptl/pthread_create.c
@@ -402,7 +402,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))
     {
       sigset_t mask;
       __sigemptyset (&mask);
@@ -443,7 +443,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);
@@ -453,7 +454,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 e9b5e62c86..059b30623d 100644
--- a/nptl/pthread_exit.c
+++ b/nptl/pthread_exit.c
@@ -16,18 +16,15 @@
    License along with the GNU C Library; if not, see
    <https://www.gnu.org/licenses/>.  */
 
-#include <stdlib.h>
 #include "pthreadP.h"
 
-
-void
+_Noreturn void
 __pthread_exit (void *value)
 {
-  THREAD_SETMEM (THREAD_SELF, result, value);
-
-  __do_cancel ();
+  __do_cancel (value);
 }
 weak_alias (__pthread_exit, pthread_exit)
+hidden_def (__pthread_exit)
 
 /* After a thread terminates, __libc_start_main decrements
    __nptl_nthreads defined in pthread_create.c.  */
diff --git a/nptl/pthread_join_common.c b/nptl/pthread_join_common.c
index 03e202136f..4d1898c52b 100644
--- a/nptl/pthread_join_common.c
+++ b/nptl/pthread_join_common.c
@@ -70,7 +70,8 @@ clockwait_tid (pid_t *tidp, clockid_t clockid, const struct timespec *abstime)
       /* If *tidp == tid, wait until thread terminates or the wait times out.
          The kernel up to version 3.16.3 does not use the private futex
          operations for futex wake-up when the clone terminates.  */
-      if (lll_futex_timed_wait_cancel (tidp, tid, &rt, LLL_SHARED)
+      if (lll_futex_timed_wait_cancel ((unsigned int *) tidp, tid, &rt,
+				       LLL_SHARED)
 	  == -ETIMEDOUT)
         return ETIMEDOUT;
     }
@@ -103,7 +104,7 @@ __pthread_clockjoin_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))
       && !(self->cancelstate == PTHREAD_CANCEL_ENABLE
 	   && (pd->cancelhandling & (CANCELED_BITMASK | EXITING_BITMASK
@@ -145,7 +146,7 @@ __pthread_clockjoin_ex (pthread_t threadid, void **thread_return,
 	  /* We need acquire MO here so that we synchronize with the
 	     kernel's store to 0 when the clone terminates. (see above)  */
 	  while ((tid = atomic_load_acquire (&pd->tid)) != 0)
-	    lll_futex_wait_cancel (&pd->tid, tid, LLL_SHARED);
+	    lll_futex_wait_cancel ((unsigned int *) &pd->tid, tid, LLL_SHARED);
 	}
 
       pthread_cleanup_pop (0);
diff --git a/nptl/pthread_kill.c b/nptl/pthread_kill.c
index 73144a07ec..bf9e9bb81f 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/unix/sysv/linux/pthread_kill.c b/nptl/pthread_kill_internal.c
similarity index 75%
rename from sysdeps/unix/sysv/linux/pthread_kill.c
rename to nptl/pthread_kill_internal.c
index 4dfe08ffcd..f428a46f57 100644
--- a/sysdeps/unix/sysv/linux/pthread_kill.c
+++ b/nptl/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.  */
   pid_t pid = __getpid ();
 
@@ -54,4 +40,3 @@ __pthread_kill (pthread_t threadid, int signo)
   return (INTERNAL_SYSCALL_ERROR_P (val)
 	  ? INTERNAL_SYSCALL_ERRNO (val) : 0);
 }
-strong_alias (__pthread_kill, pthread_kill)
diff --git a/nptl/pthread_setcanceltype.c b/nptl/pthread_setcanceltype.c
index d8cb54736d..77e4adf537 100644
--- a/nptl/pthread_setcanceltype.c
+++ b/nptl/pthread_setcanceltype.c
@@ -37,4 +37,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/pthread_testcancel.c b/nptl/pthread_testcancel.c
index 026c20f82e..584ff242be 100644
--- a/nptl/pthread_testcancel.c
+++ b/nptl/pthread_testcancel.c
@@ -23,16 +23,8 @@
 void
 __pthread_testcancel (void)
 {
-  struct pthread *self = THREAD_SELF;
-  int cancelhandling = THREAD_GETMEM (self, cancelhandling);
-  if (self->cancelstate == PTHREAD_CANCEL_ENABLE
-      && (cancelhandling & (CANCELED_BITMASK | EXITING_BITMASK
-			    | TERMINATED_BITMASK))
-	  == CANCELED_BITMASK)
-    {
-      THREAD_SETMEM (self, result, PTHREAD_CANCELED);
-      __do_cancel ();
-    }
+  if (__pthread_self_cancelled ())
+    __do_cancel (PTHREAD_CANCELED);
 }
 weak_alias (__pthread_testcancel, pthread_testcancel)
 hidden_def (__pthread_testcancel)
diff --git a/nptl/sem_wait.c b/nptl/sem_wait.c
index 171716fdbc..1ba9926c0e 100644
--- a/nptl/sem_wait.c
+++ b/nptl/sem_wait.c
@@ -58,7 +58,7 @@ __old_sem_wait (sem_t *sem)
 	return 0;
 
       /* Always assume the semaphore is shared.  */
-      err = lll_futex_wait_cancel (futex, 0, LLL_SHARED);
+      err = lll_futex_wait_cancel ((unsigned int *) futex, 0, LLL_SHARED);
     }
   while (err == 0 || err == -EWOULDBLOCK);
 
diff --git a/nptl/tst-cancel29.c b/nptl/tst-cancel29.c
new file mode 100644
index 0000000000..1671cfe04f
--- /dev/null
+++ b/nptl/tst-cancel29.c
@@ -0,0 +1,100 @@
+/* Check side-effect act for cancellable syscalls (BZ #12683).
+   Copyright (C) 2020 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/>.  */
+
+/* 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/xunistd.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);
+      xclose (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);
+  xclose (fd);
+  return NULL;
+}
+
+static int
+do_test (void)
+{
+  enum {
+    iter_count = 1000
+  };
+
+  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;
+}
+
+#include <support/test-driver.c>
diff --git a/rt/Makefile b/rt/Makefile
index dab5d62a57..565b76c9c4 100644
--- a/rt/Makefile
+++ b/rt/Makefile
@@ -57,7 +57,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/nptl/librt-cancellation.c b/sysdeps/generic/syscall_types.h
similarity index 70%
rename from sysdeps/nptl/librt-cancellation.c
rename to sysdeps/generic/syscall_types.h
index af1d11b2e6..cf11956fd7 100644
--- a/sysdeps/nptl/librt-cancellation.c
+++ b/sysdeps/generic/syscall_types.h
@@ -1,6 +1,6 @@
-/* Copyright (C) 2002-2020 Free Software Foundation, Inc.
+/* Types and macros used for syscall issuing.
+   Copyright (C) 2020 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,10 @@
    License along with the GNU C Library; if not, see
    <https://www.gnu.org/licenses/>.  */
 
-#include <nptl/pthreadP.h>
+#ifndef _SYSCALL_TYPES_H
+#define _SYSCALL_TYPES_H
 
+typedef long int __syscall_arg_t;
+#define __SSC(__x) ((__syscall_arg_t) (__x))
 
-#define __pthread_enable_asynccancel __librt_enable_asynccancel
-#define __pthread_disable_asynccancel __librt_disable_asynccancel
-#include <nptl/cancellation.c>
+#endif
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/nptl/Makefile b/sysdeps/nptl/Makefile
index 0631a870c8..30f9c8e91e 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..ae124fcced
--- /dev/null
+++ b/sysdeps/nptl/cancellation-pc-check.h
@@ -0,0 +1,53 @@
+/* Architecture specific code for pthread cancellation handling.
+   Copyright (C) 2020 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>
+
+/* 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.  */
+static bool
+cancellation_pc_check (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..80c2a2d2f2
--- /dev/null
+++ b/sysdeps/nptl/cancellation-sigmask.h
@@ -0,0 +1,30 @@
+/* Architecture specific code for pthread cancellation handling.
+   Copyright (C) 2020 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_t CTX obtained from
+   the sigaction handler.  */
+static void
+ucontext_block_sigcancel (void *ctx)
+{
+  __sigaddset (&((ucontext_t*) ctx)->uc_sigmask, SIGCANCEL);
+}
+
+#endif
diff --git a/sysdeps/nptl/futex-internal.h b/sysdeps/nptl/futex-internal.h
index d622122ddc..9bce768afc 100644
--- a/sysdeps/nptl/futex-internal.h
+++ b/sysdeps/nptl/futex-internal.h
@@ -178,10 +178,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:
@@ -239,10 +236,8 @@ 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:
@@ -315,12 +310,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/nptl/lowlevellock-futex.h b/sysdeps/nptl/lowlevellock-futex.h
index 2209ca76a1..4b72deda95 100644
--- a/sysdeps/nptl/lowlevellock-futex.h
+++ b/sysdeps/nptl/lowlevellock-futex.h
@@ -174,21 +174,36 @@
 		     nr_wake, nr_move, mutex, val)
 
 /* Like lll_futex_wait, but acting as a cancellable entrypoint.  */
-# 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;							       \
-  })
+# define lll_futex_wait_cancel(futexp, val, private)			\
+  lll_futex_timed_wait_cancel (futexp, val, NULL, private)
 
 /* Like lll_futex_timed_wait, but acting as a cancellable entrypoint.  */
-# 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_timed_wait_cancel(futexp, val, timeout, private) 	\
+  ({									\
+     int __op = __lll_private_flag (FUTEX_WAIT, private);		\
+     INTERNAL_SYSCALL_CANCEL (futex, futexp, __op, val, timeout);	\
+  })
+
+/* Like lll_futex_clock_wait_bitset, but acting as a cancellable
+   entrypoint.  */
+# 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 = INTERNAL_SYSCALL_CANCEL (futex, futexp, __op, val,	\
+					 timeout, NULL,			\
+					 FUTEX_BITSET_MATCH_ANY);	\
+      }								 	\
+    else								\
+      __ret = -EINVAL;							\
+    __ret;								\
   })
 
 #endif  /* !__ASSEMBLER__  */
diff --git a/sysdeps/unix/sysdep.h b/sysdeps/unix/sysdep.h
index 3c687a717a..c19cffabee 100644
--- a/sysdeps/unix/sysdep.h
+++ b/sysdeps/unix/sysdep.h
@@ -15,6 +15,9 @@
    License along with the GNU C Library; if not, see
    <https://www.gnu.org/licenses/>.  */
 
+#ifndef _SYSDEP_UNIX_H
+#define _SYSDEP_UNIX_H 1
+
 #include <sysdeps/generic/sysdep.h>
 #include <single-thread.h>
 #include <sys/syscall.h>
@@ -24,6 +27,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 +63,29 @@
 #define INTERNAL_SYSCALL_CALL(...) \
   __INTERNAL_SYSCALL_DISP (__INTERNAL_SYSCALL, __VA_ARGS__)
 
+#define __INTERNAL_SYSCALL_NCS0(name) \
+  INTERNAL_SYSCALL_NCS (name, 0)
+#define __INTERNAL_SYSCALL_NCS1(name, a1) \
+  INTERNAL_SYSCALL_NCS (name, 1, a1)
+#define __INTERNAL_SYSCALL_NCS2(name, a1, a2) \
+  INTERNAL_SYSCALL_NCS (name, 2, a1, a2)
+#define __INTERNAL_SYSCALL_NCS3(name, a1, a2, a3) \
+  INTERNAL_SYSCALL_NCS (name, 3, a1, a2, a3)
+#define __INTERNAL_SYSCALL_NCS4(name, a1, a2, a3, a4) \
+  INTERNAL_SYSCALL_NCS (name, 4, a1, a2, a3, a4)
+#define __INTERNAL_SYSCALL_NCS5(name, a1, a2, a3, a4, a5) \
+  INTERNAL_SYSCALL_NCS (name, 5, a1, a2, a3, a4, a5)
+#define __INTERNAL_SYSCALL_NCS6(name, a1, a2, a3, a4, a5, a6) \
+  INTERNAL_SYSCALL_NCS (name, 6, a1, a2, a3, a4, a5, a6)
+#define __INTERNAL_SYSCALL_NCS7(name, a1, a2, a3, a4, a5, a6, a7) \
+  INTERNAL_SYSCALL_NCS (name, 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 +117,68 @@
 #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.  */
+#include <syscall_types.h>
+
+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
@@ -146,3 +208,5 @@
 #ifndef INLINE_SYSCALL
 #define INLINE_SYSCALL(name, nr, args...) __syscall_##name (args)
 #endif
+
+#endif /* _SYSDEP_UNIX_H  */
diff --git a/sysdeps/unix/sysv/linux/socketcall.h b/sysdeps/unix/sysv/linux/socketcall.h
index 75c2a6404d..64af566e18 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..003e485b5c
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/syscall_cancel.c
@@ -0,0 +1,62 @@
+/* Default cancellation syscall bridge.
+   Copyright (C) 2020 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>
+
+#warning "This implementation should be use just as reference or for bootstrapping"
+
+/* 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"		\
+    __label ":\n");
+
+  ADD_LABEL ("__syscall_cancel_arch_start");
+  if (__glibc_unlikely (*ch & CANCELED_BITMASK))
+    __syscall_do_cancel();
+
+  long int result = INTERNAL_SYSCALL_NCS_CALL (nr, a1, a2, a3, a4, a5, a6);
+  ADD_LABEL ("__syscall_cancel_arch_end");
+  if (__glibc_unlikely (INTERNAL_SYSCALL_ERROR_P (result)))
+    return -INTERNAL_SYSCALL_ERRNO (result);
+  return result;
+}
+libc_hidden_def (__syscall_cancel_arch)
diff --git a/sysdeps/unix/sysv/linux/sysdep-cancel.h b/sysdeps/unix/sysv/linux/sysdep-cancel.h
index 61d3348768..20824bc096 100644
--- a/sysdeps/unix/sysv/linux/sysdep-cancel.h
+++ b/sysdeps/unix/sysv/linux/sysdep-cancel.h
@@ -21,47 +21,5 @@
 #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/sysdep.h b/sysdeps/unix/sysv/linux/sysdep.h
index 5e7b6c5765..8442de9b13 100644
--- a/sysdeps/unix/sysv/linux/sysdep.h
+++ b/sysdeps/unix/sysv/linux/sysdep.h
@@ -58,6 +58,15 @@
     -1l;					\
   })
 
+/* The return error from cancellable syscall has the same semantic as non
+   cancellable ones.  */
+#define SYSCALL_CANCEL_RET(__ret)				\
+  ({								\
+    __glibc_unlikely (INTERNAL_SYSCALL_ERROR_P (__ret))		\
+    ? SYSCALL_ERROR_LABEL (INTERNAL_SYSCALL_ERRNO (__ret))	\
+    : __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 related	[flat|nested] 46+ messages in thread

* [PATCH v4 03/21] nptl: x86_64: Fix Race conditions in pthread cancellation [BZ#12683]
  2020-04-03 20:31 [PATCH v4 00/21] nptl: Fix Race conditions in pthread cancellation [BZ#12683] Adhemerval Zanella via Libc-alpha
  2020-04-03 20:31 ` [PATCH v4 01/21] nptl: Do not close the pipe on tst-cancel{2,3} Adhemerval Zanella via Libc-alpha
  2020-04-03 20:31 ` [PATCH v4 02/21] nptl: Fix Race conditions in pthread cancellation [BZ#12683] Adhemerval Zanella via Libc-alpha
@ 2020-04-03 20:31 ` Adhemerval Zanella via Libc-alpha
  2020-04-03 20:31 ` [PATCH v4 04/21] nptl: x32: " Adhemerval Zanella via Libc-alpha
                   ` (17 subsequent siblings)
  20 siblings, 0 replies; 46+ messages in thread
From: Adhemerval Zanella via Libc-alpha @ 2020-04-03 20:31 UTC (permalink / raw
  To: libc-alpha

This patches adds the x86_64 modification required for the BZ#12683.

Checked on x86_64-linux-gnu.
---
 .../unix/sysv/linux/x86_64/syscall_cancel.S   | 59 +++++++++++++++++++
 1 file changed, 59 insertions(+)
 create mode 100644 sysdeps/unix/sysv/linux/x86_64/syscall_cancel.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..11c3eeb084
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/x86_64/syscall_cancel.S
@@ -0,0 +1,59 @@
+/* Cancellable syscall wrapper - x86_64 version.
+   Copyright (C) 2020 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
+__syscall_cancel_arch_start:
+
+	/* if (*cancelhandling & CANCELED_BITMASK)
+	     __syscall_do_cancel()  */
+	mov    (%rdi),%eax
+	testb  $TCB_CANCELED_BITMASK, (%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
+__syscall_cancel_arch_end:
+	ret
+
+END (__syscall_cancel_arch)
+libc_hidden_def (__syscall_cancel_arch)
-- 
2.17.1


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

* [PATCH v4 04/21] nptl: x32: Fix Race conditions in pthread cancellation [BZ#12683]
  2020-04-03 20:31 [PATCH v4 00/21] nptl: Fix Race conditions in pthread cancellation [BZ#12683] Adhemerval Zanella via Libc-alpha
                   ` (2 preceding siblings ...)
  2020-04-03 20:31 ` [PATCH v4 03/21] nptl: x86_64: " Adhemerval Zanella via Libc-alpha
@ 2020-04-03 20:31 ` Adhemerval Zanella via Libc-alpha
  2020-04-03 21:22   ` Joseph Myers
  2020-04-03 20:31 ` [PATCH v4 05/21] nptl: i386: " Adhemerval Zanella via Libc-alpha
                   ` (16 subsequent siblings)
  20 siblings, 1 reply; 46+ messages in thread
From: Adhemerval Zanella via Libc-alpha @ 2020-04-03 20:31 UTC (permalink / raw
  To: libc-alpha

This patches adds the x32 modification required for the BZ#12683.
It follows the x86_64-x32 ABI and pointers are zero-extended.
However, compiler may not see such cases and accuse a cast from pointer
to integer of different size and for such cases the warning is
explict disabled.

Checked on x86_64-linux-gnu-x32.
---
 .../sysv/linux/x86_64/x32/syscall_types.h     | 40 +++++++++++++++++++
 1 file changed, 40 insertions(+)
 create mode 100644 sysdeps/unix/sysv/linux/x86_64/x32/syscall_types.h

diff --git a/sysdeps/unix/sysv/linux/x86_64/x32/syscall_types.h b/sysdeps/unix/sysv/linux/x86_64/x32/syscall_types.h
new file mode 100644
index 0000000000..25b10a0b28
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/x86_64/x32/syscall_types.h
@@ -0,0 +1,40 @@
+/* Types and macros used for syscall issuing.  x86_64/x32 version.
+   Copyright (C) 2020 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 _SYSCALL_TYPES_H
+#define _SYSCALL_TYPES_H
+
+#include <libc-diag.h>
+
+typedef long long int __syscall_arg_t;
+
+/* Syscall arguments for x32 follows x86_64 ABI, however pointers are 32 bits
+   should be zero extended.  However compiler may not see such cases and
+   accuse a cast from pointer to integer of different size.  */
+#define __SSC(__x)						\
+  ({								\
+    DIAG_PUSH_NEEDS_COMMENT;					\
+    DIAG_IGNORE_NEEDS_COMMENT (5, "-Wpointer-to-int-cast");	\
+    __syscall_arg_t __arg = sizeof (1 ? (__x) : 0ULL) < 8	\
+			    ? (unsigned long int) (__x) 	\
+			    : (long long int) ((__x));		\
+    DIAG_POP_NEEDS_COMMENT;					\
+    __arg;							\
+  })
+
+#endif
-- 
2.17.1


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

* [PATCH v4 05/21] nptl: i386: Fix Race conditions in pthread cancellation [BZ#12683]
  2020-04-03 20:31 [PATCH v4 00/21] nptl: Fix Race conditions in pthread cancellation [BZ#12683] Adhemerval Zanella via Libc-alpha
                   ` (3 preceding siblings ...)
  2020-04-03 20:31 ` [PATCH v4 04/21] nptl: x32: " Adhemerval Zanella via Libc-alpha
@ 2020-04-03 20:31 ` Adhemerval Zanella via Libc-alpha
  2020-04-03 20:31 ` [PATCH v4 06/21] nptl: ia64: " Adhemerval Zanella via Libc-alpha
                   ` (15 subsequent siblings)
  20 siblings, 0 replies; 46+ messages in thread
From: Adhemerval Zanella via Libc-alpha @ 2020-04-03 20:31 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/i386/nptl/tcb-offsets.sym             |   3 +
 sysdeps/unix/sysv/linux/i386/Makefile         |   2 +-
 sysdeps/unix/sysv/linux/i386/syscall_cancel.S | 104 ++++++++++++++++++
 3 files changed, 108 insertions(+), 1 deletion(-)
 create mode 100644 sysdeps/unix/sysv/linux/i386/syscall_cancel.S

diff --git a/sysdeps/i386/nptl/tcb-offsets.sym b/sysdeps/i386/nptl/tcb-offsets.sym
index 2ec9e787c1..2dc3bf2869 100644
--- a/sysdeps/i386/nptl/tcb-offsets.sym
+++ b/sysdeps/i386/nptl/tcb-offsets.sym
@@ -14,3 +14,6 @@ MUTEX_FUTEX		offsetof (pthread_mutex_t, __data.__lock)
 POINTER_GUARD		offsetof (tcbhead_t, pointer_guard)
 FEATURE_1_OFFSET	offsetof (tcbhead_t, feature_1)
 SSP_BASE_OFFSET		offsetof (tcbhead_t, ssp_base)
+
+-- Not strictly offsets, used on syscall_cancel.S
+TCB_CANCELED_BITMASK	CANCELED_BITMASK
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..d2d4cfe522
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/i386/syscall_cancel.S
@@ -0,0 +1,104 @@
+/* Cancellable syscall wrapper.  Linux/i686 version.
+   Copyright (C) 2020 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
+__syscall_cancel_arch_start:
+
+	/* if (*cancelhandling & CANCELED_BITMASK)
+	     __syscall_do_cancel()  */
+	testb	$TCB_CANCELED_BITMASK, (%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 related	[flat|nested] 46+ messages in thread

* [PATCH v4 06/21] nptl: ia64: Fix Race conditions in pthread cancellation [BZ#12683]
  2020-04-03 20:31 [PATCH v4 00/21] nptl: Fix Race conditions in pthread cancellation [BZ#12683] Adhemerval Zanella via Libc-alpha
                   ` (4 preceding siblings ...)
  2020-04-03 20:31 ` [PATCH v4 05/21] nptl: i386: " Adhemerval Zanella via Libc-alpha
@ 2020-04-03 20:31 ` Adhemerval Zanella via Libc-alpha
  2020-04-03 20:31 ` [PATCH v4 07/21] nptl: mips: " Adhemerval Zanella via Libc-alpha
                   ` (14 subsequent siblings)
  20 siblings, 0 replies; 46+ messages in thread
From: Adhemerval Zanella via Libc-alpha @ 2020-04-03 20:31 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.
---
 sysdeps/ia64/nptl/tcb-offsets.sym             |  3 +
 .../sysv/linux/ia64/cancellation-pc-check.h   | 48 +++++++++++
 .../sysv/linux/ia64/cancellation-sigmask.h    | 33 ++++++++
 sysdeps/unix/sysv/linux/ia64/syscall_cancel.S | 81 +++++++++++++++++++
 4 files changed, 165 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/ia64/nptl/tcb-offsets.sym b/sysdeps/ia64/nptl/tcb-offsets.sym
index b01f712be2..202046cd5b 100644
--- a/sysdeps/ia64/nptl/tcb-offsets.sym
+++ b/sysdeps/ia64/nptl/tcb-offsets.sym
@@ -4,3 +4,6 @@
 TID			offsetof (struct pthread, tid) - TLS_PRE_TCB_SIZE
 MULTIPLE_THREADS_OFFSET offsetof (struct pthread, header.multiple_threads) - TLS_PRE_TCB_SIZE
 SYSINFO_OFFSET		offsetof (tcbhead_t, __private)
+
+-- Not strictly offsets, used on syscall_cancel.S
+TCB_CANCELED_BIT	 CANCELED_BIT
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..cadb4ac055
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/ia64/cancellation-pc-check.h
@@ -0,0 +1,48 @@
+/* Architecture specific bits for cancellation handling.
+   Copyright (C) 2020 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
+cancellation_pc_check (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..05c3f90ab9
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/ia64/cancellation-sigmask.h
@@ -0,0 +1,33 @@
+/* Architecture specific bits for cancellation handling.
+   Copyright (C) 2020 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_block_sigcancel (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..92f358ab2e
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/ia64/syscall_cancel.S
@@ -0,0 +1,81 @@
+/* Cancellable syscall wrapper.  Linux/IA64 version.
+   Copyright (C) 2020 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
+__syscall_cancel_arch_start:
+	;;
+	.mmi
+	nop 0
+	ld4.acq r14=[r32]
+	nop 0
+	;;
+	.mib
+	nop 0
+	tbit.z p6, p7=r14, TCB_CANCELED_BIT
+	.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
+__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 related	[flat|nested] 46+ messages in thread

* [PATCH v4 07/21] nptl: mips: Fix Race conditions in pthread cancellation [BZ#12683]
  2020-04-03 20:31 [PATCH v4 00/21] nptl: Fix Race conditions in pthread cancellation [BZ#12683] Adhemerval Zanella via Libc-alpha
                   ` (5 preceding siblings ...)
  2020-04-03 20:31 ` [PATCH v4 06/21] nptl: ia64: " Adhemerval Zanella via Libc-alpha
@ 2020-04-03 20:31 ` Adhemerval Zanella via Libc-alpha
  2020-04-03 20:31 ` [PATCH v4 08/21] nptl: aarch64: " Adhemerval Zanella via Libc-alpha
                   ` (13 subsequent siblings)
  20 siblings, 0 replies; 46+ messages in thread
From: Adhemerval Zanella via Libc-alpha @ 2020-04-03 20:31 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/tcb-offsets.sym             |   3 +
 sysdeps/unix/sysdep.h                         |  37 +++--
 .../sysv/linux/mips/mips32/syscall_cancel.S   | 128 +++++++++++++++++
 sysdeps/unix/sysv/linux/mips/mips32/sysdep.h  |   4 +
 .../linux/mips/mips64/n32/syscall_types.h     |  28 ++++
 .../sysv/linux/mips/mips64/syscall_cancel.S   | 130 ++++++++++++++++++
 sysdeps/unix/sysv/linux/mips/mips64/sysdep.h  |  52 +++----
 sysdeps/unix/sysv/linux/syscall_cancel.c      |   6 +-
 10 files changed, 354 insertions(+), 44 deletions(-)
 create mode 100644 sysdeps/unix/sysv/linux/mips/mips32/syscall_cancel.S
 create mode 100644 sysdeps/unix/sysv/linux/mips/mips64/n32/syscall_types.h
 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 e695d67417..94cd40aac8 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)
 {
   struct pthread *pd = THREAD_SELF;
   long int result;
@@ -31,7 +31,8 @@ __syscall_cancel (__syscall_arg_t nr, __syscall_arg_t a1,
   /* If cancellation is not enabled, call the syscall directly.  */
   if (pd->cancelstate == PTHREAD_CANCEL_DISABLE)
     {
-      result = INTERNAL_SYSCALL_NCS_CALL (nr, a1, a2, a3, a4, a5, a6);
+      result = INTERNAL_SYSCALL_NCS_CALL (nr, a1, a2, a3, a4, a5, a6
+					  __SYSCALL_CANCEL7_ARG7);
       if (INTERNAL_SYSCALL_ERROR_P (result))
 	return -INTERNAL_SYSCALL_ERRNO (result);
       return result;
@@ -40,7 +41,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
       && __pthread_self_cancelled ()
diff --git a/nptl/pthreadP.h b/nptl/pthreadP.h
index a20b136f14..3b5db3c14a 100644
--- a/nptl/pthreadP.h
+++ b/nptl/pthreadP.h
@@ -288,7 +288,8 @@ extern void __nptl_unwind_freeres (void) attribute_hidden;
 
 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/tcb-offsets.sym b/sysdeps/mips/nptl/tcb-offsets.sym
index 9ea25b94a8..fb14294594 100644
--- a/sysdeps/mips/nptl/tcb-offsets.sym
+++ b/sysdeps/mips/nptl/tcb-offsets.sym
@@ -8,3 +8,6 @@
 
 MULTIPLE_THREADS_OFFSET		thread_offsetof (header.multiple_threads)
 TID_OFFSET			thread_offsetof (tid)
+
+-- Not strictly offsets, used on syscall_cancel.S
+TCB_CANCELED_BITMASK		CANCELED_BITMASK
diff --git a/sysdeps/unix/sysdep.h b/sysdeps/unix/sysdep.h
index c19cffabee..bd18f6ad82 100644
--- a/sysdeps/unix/sysdep.h
+++ b/sysdeps/unix/sysdep.h
@@ -121,30 +121,51 @@
 /* Cancellation macros.  */
 #include <syscall_types.h>
 
+/* 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)
+		    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..52ae003100
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/mips/mips32/syscall_cancel.S
@@ -0,0 +1,128 @@
+/* Cancellable syscall wrapper.  Linux/mips32 version.
+   Copyright (C) 2020 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 (ra, -4)
+	cfi_offset (fp, -8)
+	cfi_offset (s2, -12)
+	cfi_offset (s1, -16)
+	cfi_offset (s0, -20)
+
+	move	fp ,sp
+	cfi_def_cfa_register (fp)
+
+	.globl __syscall_cancel_arch_start
+__syscall_cancel_arch_start:
+
+	lw	v0, 0(a0)
+	andi	v0, v0, TCB_CANCELED_BITMASK
+	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, s0
+	syscall
+
+	.globl __syscall_cancel_arch_end
+__syscall_cancel_arch_end:
+	addiu	sp, sp, 32
+	.set	reorder
+
+	beq	a3, zero, 1f
+	subu	v0, zero, v0
+1:
+	move	sp, fp
+	cfi_remember_state
+	cfi_def_cfa_register (sp)
+	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 (s0)
+	cfi_restore (s1)
+	cfi_restore (s2)
+	cfi_restore (fp)
+	cfi_restore (ra)
+
+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 c5bcd90c25..7a60cfeb87 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/n32/syscall_types.h b/sysdeps/unix/sysv/linux/mips/mips64/n32/syscall_types.h
new file mode 100644
index 0000000000..63d2877893
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/mips/mips64/n32/syscall_types.h
@@ -0,0 +1,28 @@
+/* Types and macros used for syscall issuing.  MIPS64n32 version.
+   Copyright (C) 2020 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 _SYSCALL_TYPES_H
+#define _SYSCALL_TYPES_H
+
+typedef long long int __syscall_arg_t;
+
+/* Convert X to a long long, without losing any bits if it is one
+   already or warning if it is a 32-bit pointer.  */
+#define __SSC(__x) ((__syscall_arg_t) (__typeof__ ((__x) - (__x))) (__x))
+
+#endif
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..28bdf41d3d
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/mips/mips64/syscall_cancel.S
@@ -0,0 +1,130 @@
+/* Cancellable syscall wrapper.  Linux/mips64 version.
+   Copyright (C) 2020 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)  */
+
+#if _MIPS_SIM == _ABIN32
+# define FRAME_SIZE 16
+# define MASK       0x80010000
+# define RA_OFF     8
+# define S0_OFF     0
+#else
+# define FRAME_SIZE 32
+# define MASK       0x90010000
+# define RA_OFF     24
+# define S0_OFF     8
+#endif
+#define ADDIU      LONG_ADDIU
+#define ADDU       LONG_ADDU
+#define SUBU       LONG_SUBU
+#define LOAD_L     LONG_L
+
+	.text
+NESTED (__syscall_cancel_arch, FRAME_SIZE, ra)
+	.mask	MASK, -SZREG
+	.fmask	0x00000000, 0
+	ADDIU	sp, sp, -FRAME_SIZE
+	cfi_def_cfa_offset (FRAME_SIZE)
+	sd	gp, 16(sp)
+	cfi_offset (gp, -16)
+#if _MIPS_SIM == _ABI64
+	lui	gp, %hi(%neg(%gp_rel(__syscall_cancel_arch)))
+	ADDU	gp, gp, t9
+	daddiu	gp, gp, %lo(%neg(%gp_rel(__syscall_cancel_arch)))
+#endif
+	sd	ra, RA_OFF(sp)
+	sd	s0, S0_OFF(sp)
+	cfi_offset (ra, -RA_OFF)
+	cfi_offset (s0, -S0_OFF)
+
+	.global __syscall_cancel_arch_start
+__syscall_cancel_arch_start:
+
+	lw	v0, 0(a0)
+	andi	v0, v0, TCB_CANCELED_BITMASK
+	.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
+__syscall_cancel_arch_end:
+
+	.set noreorder
+	.set nomacro
+	bnel	a3, zero, 1f
+	SUBU	v0, zero, v0
+	.set macro
+	.set reorder
+
+1:
+#if _MIPS_SIM == _ABI64
+	ld	gp, 16(sp)
+#endif
+	ld	ra, RA_OFF(sp)
+	ld	s0, S0_OFF(sp)
+
+	.set	noreorder
+	.set	nomacro
+	jr	ra
+	daddiu	sp, sp, FRAME_SIZE
+	.set	macro
+	.set	reorder
+
+	cfi_remember_state
+	cfi_def_cfa_offset (0)
+#if _MIPS_SIM == _ABI64
+	cfi_restore (gp)
+#endif
+	.align	3
+2:
+	cfi_restore_state
+#if _MIPS_SIM == _ABI64
+	ld	t9, %got_disp(__syscall_do_cancel)(gp)
+	.reloc	3f, R_MIPS_JALR, __syscall_do_cancel
+3:	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/mips64/sysdep.h b/sysdeps/unix/sysv/linux/mips/mips64/sysdep.h
index 1882fe4e73..9a3dcd800a 100644
--- a/sysdeps/unix/sysv/linux/mips/mips64/sysdep.h
+++ b/sysdeps/unix/sysv/linux/mips/mips64/sysdep.h
@@ -41,15 +41,7 @@
 
 #else   /* ! __ASSEMBLER__ */
 
-#if _MIPS_SIM == _ABIN32
-/* Convert X to a long long, without losing any bits if it is one
-   already or warning if it is a 32-bit pointer.  */
-# define ARGIFY(X) ((long long int) (__typeof__ ((X) - (X))) (X))
-typedef long long int __syscall_arg_t;
-#else
-# define ARGIFY(X) ((long int) (X))
-typedef long int __syscall_arg_t;
-#endif
+#include <syscall_types.h>
 
 /* Note that the original Linux syscall restart convention required the
    instruction immediately preceding SYSCALL to initialize $v0 with the
@@ -117,7 +109,7 @@ typedef long int __syscall_arg_t;
 	long int _sys_result;						\
 									\
 	{								\
-	__syscall_arg_t _arg1 = ARGIFY (arg1);				\
+	__syscall_arg_t _arg1 = __SSC (arg1);				\
 	register __syscall_arg_t __s0 asm ("$16") __attribute__ ((unused))\
 	  = (number);							\
 	register __syscall_arg_t __v0 asm ("$2");			\
@@ -141,8 +133,8 @@ typedef long int __syscall_arg_t;
 	long int _sys_result;						\
 									\
 	{								\
-	__syscall_arg_t _arg1 = ARGIFY (arg1);				\
-	__syscall_arg_t _arg2 = ARGIFY (arg2);				\
+	__syscall_arg_t _arg1 = __SSC (arg1);				\
+	__syscall_arg_t _arg2 = __SSC (arg2);				\
 	register __syscall_arg_t __s0 asm ("$16") __attribute__ ((unused))\
 	  = (number);							\
 	register __syscall_arg_t __v0 asm ("$2");			\
@@ -167,9 +159,9 @@ typedef long int __syscall_arg_t;
 	long int _sys_result;						\
 									\
 	{								\
-	__syscall_arg_t _arg1 = ARGIFY (arg1);				\
-	__syscall_arg_t _arg2 = ARGIFY (arg2);				\
-	__syscall_arg_t _arg3 = ARGIFY (arg3);				\
+	__syscall_arg_t _arg1 = __SSC (arg1);				\
+	__syscall_arg_t _arg2 = __SSC (arg2);				\
+	__syscall_arg_t _arg3 = __SSC (arg3);				\
 	register __syscall_arg_t __s0 asm ("$16") __attribute__ ((unused))\
 	  = (number);							\
 	register __syscall_arg_t __v0 asm ("$2");			\
@@ -196,10 +188,10 @@ typedef long int __syscall_arg_t;
 	long int _sys_result;						\
 									\
 	{								\
-	__syscall_arg_t _arg1 = ARGIFY (arg1);				\
-	__syscall_arg_t _arg2 = ARGIFY (arg2);				\
-	__syscall_arg_t _arg3 = ARGIFY (arg3);				\
-	__syscall_arg_t _arg4 = ARGIFY (arg4);				\
+	__syscall_arg_t _arg1 = __SSC (arg1);				\
+	__syscall_arg_t _arg2 = __SSC (arg2);				\
+	__syscall_arg_t _arg3 = __SSC (arg3);				\
+	__syscall_arg_t _arg4 = __SSC (arg4);				\
 	register __syscall_arg_t __s0 asm ("$16") __attribute__ ((unused))\
 	  = (number);							\
 	register __syscall_arg_t __v0 asm ("$2");			\
@@ -226,11 +218,11 @@ typedef long int __syscall_arg_t;
 	long int _sys_result;						\
 									\
 	{								\
-	__syscall_arg_t _arg1 = ARGIFY (arg1);				\
-	__syscall_arg_t _arg2 = ARGIFY (arg2);				\
-	__syscall_arg_t _arg3 = ARGIFY (arg3);				\
-	__syscall_arg_t _arg4 = ARGIFY (arg4);				\
-	__syscall_arg_t _arg5 = ARGIFY (arg5);				\
+	__syscall_arg_t _arg1 = __SSC (arg1);				\
+	__syscall_arg_t _arg2 = __SSC (arg2);				\
+	__syscall_arg_t _arg3 = __SSC (arg3);				\
+	__syscall_arg_t _arg4 = __SSC (arg4);				\
+	__syscall_arg_t _arg5 = __SSC (arg5);				\
 	register __syscall_arg_t __s0 asm ("$16") __attribute__ ((unused))\
 	  = (number);							\
 	register __syscall_arg_t __v0 asm ("$2");			\
@@ -258,12 +250,12 @@ typedef long int __syscall_arg_t;
 	long int _sys_result;						\
 									\
 	{								\
-	__syscall_arg_t _arg1 = ARGIFY (arg1);				\
-	__syscall_arg_t _arg2 = ARGIFY (arg2);				\
-	__syscall_arg_t _arg3 = ARGIFY (arg3);				\
-	__syscall_arg_t _arg4 = ARGIFY (arg4);				\
-	__syscall_arg_t _arg5 = ARGIFY (arg5);				\
-	__syscall_arg_t _arg6 = ARGIFY (arg6);				\
+	__syscall_arg_t _arg1 = __SSC (arg1);				\
+	__syscall_arg_t _arg2 = __SSC (arg2);				\
+	__syscall_arg_t _arg3 = __SSC (arg3);				\
+	__syscall_arg_t _arg4 = __SSC (arg4);				\
+	__syscall_arg_t _arg5 = __SSC (arg5);				\
+	__syscall_arg_t _arg6 = __SSC (arg6);				\
 	register __syscall_arg_t __s0 asm ("$16") __attribute__ ((unused))\
 	  = (number);							\
 	register __syscall_arg_t __v0 asm ("$2");			\
diff --git a/sysdeps/unix/sysv/linux/syscall_cancel.c b/sysdeps/unix/sysv/linux/syscall_cancel.c
index 003e485b5c..5385c9510e 100644
--- a/sysdeps/unix/sysv/linux/syscall_cancel.c
+++ b/sysdeps/unix/sysv/linux/syscall_cancel.c
@@ -42,7 +42,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,
   if (__glibc_unlikely (*ch & CANCELED_BITMASK))
     __syscall_do_cancel();
 
-  long int result = INTERNAL_SYSCALL_NCS_CALL (nr, a1, a2, a3, a4, a5, a6);
+  long int result = INTERNAL_SYSCALL_NCS_CALL (nr, a1, a2, a3, a4, a5, a6
+					       __SYSCALL_CANCEL7_ARG7);
   ADD_LABEL ("__syscall_cancel_arch_end");
   if (__glibc_unlikely (INTERNAL_SYSCALL_ERROR_P (result)))
     return -INTERNAL_SYSCALL_ERRNO (result);
-- 
2.17.1


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

* [PATCH v4 08/21] nptl: aarch64: Fix Race conditions in pthread cancellation [BZ#12683]
  2020-04-03 20:31 [PATCH v4 00/21] nptl: Fix Race conditions in pthread cancellation [BZ#12683] Adhemerval Zanella via Libc-alpha
                   ` (6 preceding siblings ...)
  2020-04-03 20:31 ` [PATCH v4 07/21] nptl: mips: " Adhemerval Zanella via Libc-alpha
@ 2020-04-03 20:31 ` Adhemerval Zanella via Libc-alpha
  2020-04-12 15:29   ` Stepan Golosunov
  2020-04-03 20:31 ` [PATCH v4 09/21] nptl: arm: " Adhemerval Zanella via Libc-alpha
                   ` (12 subsequent siblings)
  20 siblings, 1 reply; 46+ messages in thread
From: Adhemerval Zanella via Libc-alpha @ 2020-04-03 20:31 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.
---
 sysdeps/aarch64/nptl/tcb-offsets.sym          |  3 +
 .../unix/sysv/linux/aarch64/syscall_cancel.S  | 59 +++++++++++++++++++
 2 files changed, 62 insertions(+)
 create mode 100644 sysdeps/unix/sysv/linux/aarch64/syscall_cancel.S

diff --git a/sysdeps/aarch64/nptl/tcb-offsets.sym b/sysdeps/aarch64/nptl/tcb-offsets.sym
index 238647dd47..614ea23034 100644
--- a/sysdeps/aarch64/nptl/tcb-offsets.sym
+++ b/sysdeps/aarch64/nptl/tcb-offsets.sym
@@ -4,3 +4,6 @@
 PTHREAD_MULTIPLE_THREADS_OFFSET		offsetof (struct pthread, header.multiple_threads)
 PTHREAD_TID_OFFSET			offsetof (struct pthread, tid)
 PTHREAD_SIZEOF				sizeof (struct pthread)
+
+-- Not strictly offsets, used on syscall_cancel.S
+TCB_CANCELED_BIT			CANCELED_BIT
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..fcb7cf66bf
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/aarch64/syscall_cancel.S
@@ -0,0 +1,59 @@
+/* Cancellable syscall wrapper.  Linux/AArch64 version.
+   Copyright (C) 2020 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
+__syscall_cancel_arch_start:
+
+	/* if (*cancelhandling & CANCELED_BITMASK)
+	     __syscall_do_cancel()  */
+	ldr	w0, [x0]
+	tbnz    w0, TCB_CANCELED_BIT, 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
+__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 related	[flat|nested] 46+ messages in thread

* [PATCH v4 09/21] nptl: arm: Fix Race conditions in pthread cancellation [BZ#12683]
  2020-04-03 20:31 [PATCH v4 00/21] nptl: Fix Race conditions in pthread cancellation [BZ#12683] Adhemerval Zanella via Libc-alpha
                   ` (7 preceding siblings ...)
  2020-04-03 20:31 ` [PATCH v4 08/21] nptl: aarch64: " Adhemerval Zanella via Libc-alpha
@ 2020-04-03 20:31 ` Adhemerval Zanella via Libc-alpha
  2020-04-03 20:31 ` [PATCH v4 10/21] nptl: powerpc: " Adhemerval Zanella via Libc-alpha
                   ` (11 subsequent siblings)
  20 siblings, 0 replies; 46+ messages in thread
From: Adhemerval Zanella via Libc-alpha @ 2020-04-03 20:31 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/arm/nptl/tcb-offsets.sym             |  3 +
 sysdeps/unix/sysv/linux/arm/syscall_cancel.S | 78 ++++++++++++++++++++
 2 files changed, 81 insertions(+)
 create mode 100644 sysdeps/unix/sysv/linux/arm/syscall_cancel.S

diff --git a/sysdeps/arm/nptl/tcb-offsets.sym b/sysdeps/arm/nptl/tcb-offsets.sym
index bf9c0a1c17..c0e25630a2 100644
--- a/sysdeps/arm/nptl/tcb-offsets.sym
+++ b/sysdeps/arm/nptl/tcb-offsets.sym
@@ -8,3 +8,6 @@
 
 MULTIPLE_THREADS_OFFSET		thread_offsetof (header.multiple_threads)
 TID_OFFSET			thread_offsetof (tid)
+
+-- Not strictly offsets, used on syscall_cancel.S
+TCB_CANCELED_BITMASK		CANCELED_BITMASK
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..3410bfc0f2
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/arm/syscall_cancel.S
@@ -0,0 +1,78 @@
+/* Cancellable syscall wrapper.  Linux/arm version.
+   Copyright (C) 2020 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
+__syscall_cancel_arch_start:
+
+	/* if (*cancelhandling & CANCELED_BITMASK)
+	     __syscall_do_cancel()  */
+	ldr	r0, [r0]
+	tst	r0, #TCB_CANCELED_BITMASK
+	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
+__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 related	[flat|nested] 46+ messages in thread

* [PATCH v4 10/21] nptl: powerpc: Fix Race conditions in pthread cancellation [BZ#12683]
  2020-04-03 20:31 [PATCH v4 00/21] nptl: Fix Race conditions in pthread cancellation [BZ#12683] Adhemerval Zanella via Libc-alpha
                   ` (8 preceding siblings ...)
  2020-04-03 20:31 ` [PATCH v4 09/21] nptl: arm: " Adhemerval Zanella via Libc-alpha
@ 2020-04-03 20:31 ` Adhemerval Zanella via Libc-alpha
  2020-04-03 20:31 ` [PATCH v4 11/21] nptl: microblaze: " Adhemerval Zanella via Libc-alpha
                   ` (10 subsequent siblings)
  20 siblings, 0 replies; 46+ messages in thread
From: Adhemerval Zanella via Libc-alpha @ 2020-04-03 20:31 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/nptl/tcb-offsets.sym          |  3 +
 sysdeps/powerpc/powerpc32/sysdep.h            |  3 +
 sysdeps/powerpc/powerpc64/sysdep.h            | 19 ++++++
 .../unix/sysv/linux/powerpc/syscall_cancel.S  | 65 +++++++++++++++++++
 4 files changed, 90 insertions(+)
 create mode 100644 sysdeps/unix/sysv/linux/powerpc/syscall_cancel.S

diff --git a/sysdeps/powerpc/nptl/tcb-offsets.sym b/sysdeps/powerpc/nptl/tcb-offsets.sym
index 4c01615ad0..768f1c34a4 100644
--- a/sysdeps/powerpc/nptl/tcb-offsets.sym
+++ b/sysdeps/powerpc/nptl/tcb-offsets.sym
@@ -26,3 +26,6 @@ TCB_AT_PLATFORM			(offsetof (tcbhead_t, at_platform) - TLS_TCB_OFFSET - sizeof(t
 PADDING				(offsetof (tcbhead_t, padding) - TLS_TCB_OFFSET - sizeof(tcbhead_t))
 #endif
 TCB_HWCAP			(offsetof (tcbhead_t, hwcap) - TLS_TCB_OFFSET - sizeof (tcbhead_t))
+
+-- Not strictly offsets, used on syscall_cancel.S
+TCB_CANCELED_BITMASK		CANCELED_BITMASK
diff --git a/sysdeps/powerpc/powerpc32/sysdep.h b/sysdeps/powerpc/powerpc32/sysdep.h
index 2ba009e919..1ffe331881 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 d6616ac905..fc14f21d58 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..9e1b0fa686
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/powerpc/syscall_cancel.S
@@ -0,0 +1,65 @@
+/* Cancellable syscall wrapper.  Linux/powerpc version.
+   Copyright (C) 2020 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
+__syscall_cancel_arch_start:
+
+	/* if (*cancelhandling & CANCELED_BITMASK)
+	     __syscall_do_cancel()  */
+	lwz     r0,0(r3)
+	andi.   r0,r0,TCB_CANCELED_BITMASK
+	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
+__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 related	[flat|nested] 46+ messages in thread

* [PATCH v4 11/21] nptl: microblaze: Fix Race conditions in pthread cancellation [BZ#12683]
  2020-04-03 20:31 [PATCH v4 00/21] nptl: Fix Race conditions in pthread cancellation [BZ#12683] Adhemerval Zanella via Libc-alpha
                   ` (9 preceding siblings ...)
  2020-04-03 20:31 ` [PATCH v4 10/21] nptl: powerpc: " Adhemerval Zanella via Libc-alpha
@ 2020-04-03 20:31 ` Adhemerval Zanella via Libc-alpha
  2020-04-03 20:31 ` [PATCH v4 12/21] nptl: sparc: " Adhemerval Zanella via Libc-alpha
                   ` (9 subsequent siblings)
  20 siblings, 0 replies; 46+ messages in thread
From: Adhemerval Zanella via Libc-alpha @ 2020-04-03 20:31 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.
---
 sysdeps/microblaze/nptl/tcb-offsets.sym       |  3 +
 .../sysv/linux/microblaze/syscall_cancel.S    | 61 +++++++++++++++++++
 sysdeps/unix/sysv/linux/microblaze/sysdep.h   |  1 +
 3 files changed, 65 insertions(+)
 create mode 100644 sysdeps/unix/sysv/linux/microblaze/syscall_cancel.S

diff --git a/sysdeps/microblaze/nptl/tcb-offsets.sym b/sysdeps/microblaze/nptl/tcb-offsets.sym
index 614f0dfed6..bb39e23d57 100644
--- a/sysdeps/microblaze/nptl/tcb-offsets.sym
+++ b/sysdeps/microblaze/nptl/tcb-offsets.sym
@@ -8,3 +8,6 @@
 
 MULTIPLE_THREADS_OFFSET	thread_offsetof (header.multiple_threads)
 TID_OFFSET			thread_offsetof (tid)
+
+-- Not strictly offsets, used on syscall_cancel.S
+TCB_CANCELED_BITMASK		CANCELED_BITMASK
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..74d22f3560
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/microblaze/syscall_cancel.S
@@ -0,0 +1,61 @@
+/* Cancellable syscall wrapper.  Linux/microblaze version.
+   Copyright (C) 2020 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
+__syscall_cancel_arch_start:
+
+	lwi	r3,r5,0
+	andi	r3,r3,TCB_CANCELED_BITMASK
+	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
+__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)
diff --git a/sysdeps/unix/sysv/linux/microblaze/sysdep.h b/sysdeps/unix/sysv/linux/microblaze/sysdep.h
index d500172114..7d96cdf6ac 100644
--- a/sysdeps/unix/sysv/linux/microblaze/sysdep.h
+++ b/sysdeps/unix/sysv/linux/microblaze/sysdep.h
@@ -22,6 +22,7 @@
 #include <sysdeps/unix/sysdep.h>
 #include <sysdeps/unix/sysv/linux/sysdep.h>
 #include <sysdeps/microblaze/sysdep.h>
+#include <tls.h>
 
 /* Defines RTLD_PRIVATE_ERRNO.  */
 #include <dl-sysdep.h>
-- 
2.17.1


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

* [PATCH v4 12/21] nptl: sparc: Fix Race conditions in pthread cancellation [BZ#12683]
  2020-04-03 20:31 [PATCH v4 00/21] nptl: Fix Race conditions in pthread cancellation [BZ#12683] Adhemerval Zanella via Libc-alpha
                   ` (10 preceding siblings ...)
  2020-04-03 20:31 ` [PATCH v4 11/21] nptl: microblaze: " Adhemerval Zanella via Libc-alpha
@ 2020-04-03 20:31 ` Adhemerval Zanella via Libc-alpha
  2020-04-12 15:33   ` Stepan Golosunov
  2020-04-03 20:31 ` [PATCH v4 13/21] nptl: hppa: " Adhemerval Zanella via Libc-alpha
                   ` (8 subsequent siblings)
  20 siblings, 1 reply; 46+ messages in thread
From: Adhemerval Zanella via Libc-alpha @ 2020-04-03 20:31 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
---
 sysdeps/sparc/nptl/tcb-offsets.sym            |  3 +
 .../sysv/linux/sparc/cancellation-sigmask.h   | 39 ++++++++++
 .../sysv/linux/sparc/sparc32/syscall_cancel.S | 71 ++++++++++++++++++
 sysdeps/unix/sysv/linux/sparc/sparc64/pause.c | 25 +++++++
 .../sysv/linux/sparc/sparc64/syscall_cancel.S | 74 +++++++++++++++++++
 5 files changed, 212 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/sparc/nptl/tcb-offsets.sym b/sysdeps/sparc/nptl/tcb-offsets.sym
index f75d02065e..8112290d88 100644
--- a/sysdeps/sparc/nptl/tcb-offsets.sym
+++ b/sysdeps/sparc/nptl/tcb-offsets.sym
@@ -4,3 +4,6 @@
 MULTIPLE_THREADS_OFFSET		offsetof (tcbhead_t, multiple_threads)
 POINTER_GUARD			offsetof (tcbhead_t, pointer_guard)
 TID				offsetof (struct pthread, tid)
+
+-- Not strictly offsets, used on syscall_cancel.S
+TCB_CANCELED_BITMASK		CANCELED_BITMASK
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..8086228828
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/sparc/cancellation-sigmask.h
@@ -0,0 +1,39 @@
+/* Architecture specific bits for cancellation handling.
+   Copyright (C) 2020 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_block_sigcancel (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..2393bf9be0
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/sparc/sparc32/syscall_cancel.S
@@ -0,0 +1,71 @@
+/* Cancellable syscall wrapper.  Linux/sparc32 version.
+   Copyright (C) 2020 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
+__syscall_cancel_arch_start:
+
+	/* if (*cancelhandling & CANCELED_BITMASK)
+	     __syscall_do_cancel()  */
+	ld	[%i0], %g2
+	andcc	%g2, TCB_CANCELED_BITMASK, %g0
+	bne,pn	%icc, 2f
+	/* Issue a 6 argument syscall.  */
+	 mov	%i1, %g1
+	mov	%i2, %o0
+	mov	%i3, %o1
+	mov	%i4, %o2
+	mov	%i5, %o3
+	ld	[%fp+92], %o4
+	ld	[%fp+96], %o5
+	ta	0x10
+
+	.globl __syscall_cancel_arch_end
+__syscall_cancel_arch_end:
+	bcc	1f
+	 nop
+	sub	%g0, %o0, %o0
+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..4fae573091
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/sparc/sparc64/pause.c
@@ -0,0 +1,25 @@
+/* Linux pause syscall implementation.  Linux/sparc64.
+   Copyright (C) 2020 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..f9ecb4a851
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/sparc/sparc64/syscall_cancel.S
@@ -0,0 +1,74 @@
+/* Cancellable syscall wrapper.  Linux/sparc64 version.
+   Copyright (C) 2020 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_register (%o7, %i7)
+	cfi_def_cfa_register (%fp)
+
+	.globl __syscall_cancel_arch_start
+__syscall_cancel_arch_start:
+
+	/* if (*cancelhandling & CANCELED_BITMASK)
+	     __syscall_do_cancel()  */
+	lduw	[%i0], %g2
+	andcc	%g2, TCB_CANCELED_BITMASK, %g0
+	bne,pn	%xcc, 2f
+	/* Issue a 6 argument syscall.  */
+	 mov	%i1, %g1
+	mov	%i2, %o0
+	mov	%i3, %o1
+	mov	%i4, %o2
+	mov	%i5, %o3
+	ldx	[%fp + STACK_BIAS + 176], %o4
+	ldx	[%fp + STACK_BIAS + 184], %o5
+	ta	0x6d
+
+	.global __syscall_cancel_arch_end
+__syscall_cancel_arch_end:
+
+	bcc,pt	%xcc, 1f
+	 nop
+	sub	%g0, %o0, %o0
+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 related	[flat|nested] 46+ messages in thread

* [PATCH v4 13/21] nptl: hppa: Fix Race conditions in pthread cancellation [BZ#12683]
  2020-04-03 20:31 [PATCH v4 00/21] nptl: Fix Race conditions in pthread cancellation [BZ#12683] Adhemerval Zanella via Libc-alpha
                   ` (11 preceding siblings ...)
  2020-04-03 20:31 ` [PATCH v4 12/21] nptl: sparc: " Adhemerval Zanella via Libc-alpha
@ 2020-04-03 20:31 ` Adhemerval Zanella via Libc-alpha
  2020-04-03 20:31 ` [PATCH v4 14/21] nptl: m68k: " Adhemerval Zanella via Libc-alpha
                   ` (7 subsequent siblings)
  20 siblings, 0 replies; 46+ messages in thread
From: Adhemerval Zanella via Libc-alpha @ 2020-04-03 20:31 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/hppa/nptl/tcb-offsets.sym             |  3 +
 sysdeps/unix/sysv/linux/hppa/syscall_cancel.S | 83 +++++++++++++++++++
 sysdeps/unix/sysv/linux/hppa/sysdep.h         |  1 +
 3 files changed, 87 insertions(+)
 create mode 100644 sysdeps/unix/sysv/linux/hppa/syscall_cancel.S

diff --git a/sysdeps/hppa/nptl/tcb-offsets.sym b/sysdeps/hppa/nptl/tcb-offsets.sym
index 6e852f35b1..0aff5f32d5 100644
--- a/sysdeps/hppa/nptl/tcb-offsets.sym
+++ b/sysdeps/hppa/nptl/tcb-offsets.sym
@@ -15,3 +15,6 @@ MUTEX_FUTEX		offsetof (pthread_mutex_t, __data.__lock)
 #define thread_offsetof(mem)    (unsigned int)(offsetof(struct pthread, mem) - sizeof(struct pthread))
 TID_THREAD_OFFSET		thread_offsetof (tid)
 MULTIPLE_THREADS_THREAD_OFFSET	thread_offsetof (header.multiple_threads)
+
+-- Not strictly offsets, used on syscall_cancel.S
+TCB_CANCELED_BIT	CANCELED_BIT
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..4fe0dcf55d
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/hppa/syscall_cancel.S
@@ -0,0 +1,83 @@
+/* Cancellable syscall wrapper.  Linux/hppa version.
+   Copyright (C) 2020 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)
+#ifndef __PIC__
+	cfi_offset (4, 28)
+#endif
+	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
+#ifdef __PIC__
+	stw	%r19,-32(%r30)
+	cfi_offset (4, 28)
+#endif
+
+	.global __syscall_cancel_arch_start
+__syscall_cancel_arch_start:
+
+	ldw	0(%r26),%r20
+	bb,<	%r20,31-TCB_CANCELED_BIT,1f
+	ldw	-120(%r30),%r21
+	ldw	-116(%r30),%r22
+	copy	%r31,%r26
+	ldw	-112(%r30),%r23
+	ldw	-108(%r30),%r24
+	copy	%r19, %r4
+	ble	0x100(%sr2, %r0)
+
+	.global __syscall_cancel_arch_end
+__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)
diff --git a/sysdeps/unix/sysv/linux/hppa/sysdep.h b/sysdeps/unix/sysv/linux/hppa/sysdep.h
index 7f8da30d23..c0d47318b3 100644
--- a/sysdeps/unix/sysv/linux/hppa/sysdep.h
+++ b/sysdeps/unix/sysv/linux/hppa/sysdep.h
@@ -24,6 +24,7 @@
 #include <sysdeps/unix/sysdep.h>
 #include <sysdeps/unix/sysv/linux/sysdep.h>
 #include <sysdeps/hppa/sysdep.h>
+#include <tls.h>
 
 /* Defines RTLD_PRIVATE_ERRNO.  */
 #include <dl-sysdep.h>
-- 
2.17.1


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

* [PATCH v4 14/21] nptl: m68k: Fix Race conditions in pthread cancellation [BZ#12683]
  2020-04-03 20:31 [PATCH v4 00/21] nptl: Fix Race conditions in pthread cancellation [BZ#12683] Adhemerval Zanella via Libc-alpha
                   ` (12 preceding siblings ...)
  2020-04-03 20:31 ` [PATCH v4 13/21] nptl: hppa: " Adhemerval Zanella via Libc-alpha
@ 2020-04-03 20:31 ` Adhemerval Zanella via Libc-alpha
  2020-04-03 21:34   ` Andreas Schwab
  2020-04-12 15:42   ` Stepan Golosunov
  2020-04-03 20:31 ` [PATCH v4 15/21] nptl: alpha: " Adhemerval Zanella via Libc-alpha
                   ` (6 subsequent siblings)
  20 siblings, 2 replies; 46+ messages in thread
From: Adhemerval Zanella via Libc-alpha @ 2020-04-03 20:31 UTC (permalink / raw
  To: libc-alpha

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

Checked on m68k-linux-gnu.
---
 sysdeps/m68k/nptl/tcb-offsets.sym             |  3 +
 sysdeps/unix/sysv/linux/m68k/syscall_cancel.S | 85 +++++++++++++++++++
 2 files changed, 88 insertions(+)
 create mode 100644 sysdeps/unix/sysv/linux/m68k/syscall_cancel.S

diff --git a/sysdeps/m68k/nptl/tcb-offsets.sym b/sysdeps/m68k/nptl/tcb-offsets.sym
index 241fb8b47c..59c9f78f8c 100644
--- a/sysdeps/m68k/nptl/tcb-offsets.sym
+++ b/sysdeps/m68k/nptl/tcb-offsets.sym
@@ -8,3 +8,6 @@
 
 MULTIPLE_THREADS_OFFSET		thread_offsetof (header.multiple_threads)
 TID_OFFSET			thread_offsetof (tid)
+
+-- Not strictly offsets, used on syscall_cancel.S
+TCB_CANCELED_BIT		CANCELED_BIT
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..59df082a28
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/m68k/syscall_cancel.S
@@ -0,0 +1,85 @@
+/* Cancellable syscall wrapper.  Linux/m68k version.
+   Copyright (C) 2020 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
+__syscall_cancel_arch_start:
+
+	move.l	20(%sp),%a0
+	move.l	(%a0),%d0
+#ifdef __mcoldfire__
+	move.w	%d0,%ccr
+	jeq	1f
+#else
+	btst	#TCB_CANCELED_BIT,%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
+__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 related	[flat|nested] 46+ messages in thread

* [PATCH v4 15/21] nptl: alpha: Fix Race conditions in pthread cancellation [BZ#12683]
  2020-04-03 20:31 [PATCH v4 00/21] nptl: Fix Race conditions in pthread cancellation [BZ#12683] Adhemerval Zanella via Libc-alpha
                   ` (13 preceding siblings ...)
  2020-04-03 20:31 ` [PATCH v4 14/21] nptl: m68k: " Adhemerval Zanella via Libc-alpha
@ 2020-04-03 20:31 ` Adhemerval Zanella via Libc-alpha
  2020-04-03 20:31 ` [PATCH v4 16/21] nptl: sh: " Adhemerval Zanella via Libc-alpha
                   ` (5 subsequent siblings)
  20 siblings, 0 replies; 46+ messages in thread
From: Adhemerval Zanella via Libc-alpha @ 2020-04-03 20:31 UTC (permalink / raw
  To: libc-alpha

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

Checked on alpha-linux-gnu.
---
 sysdeps/alpha/nptl/tcb-offsets.sym            |  3 +
 .../unix/sysv/linux/alpha/syscall_cancel.S    | 81 +++++++++++++++++++
 2 files changed, 84 insertions(+)
 create mode 100644 sysdeps/unix/sysv/linux/alpha/syscall_cancel.S

diff --git a/sysdeps/alpha/nptl/tcb-offsets.sym b/sysdeps/alpha/nptl/tcb-offsets.sym
index 1005621b37..15f2042278 100644
--- a/sysdeps/alpha/nptl/tcb-offsets.sym
+++ b/sysdeps/alpha/nptl/tcb-offsets.sym
@@ -11,3 +11,6 @@
 
 MULTIPLE_THREADS_OFFSET		thread_offsetof (header.multiple_threads)
 TID_OFFSET			thread_offsetof (tid)
+
+-- Not strictly offsets, used on syscall_cancel.S
+TCB_CANCELED_BITMASK		CANCELED_BITMASK
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..e91667692a
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/alpha/syscall_cancel.S
@@ -0,0 +1,81 @@
+/* Cancellable syscall wrapper.  Linux/alpha version.
+   Copyright (C) 2020 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 *ch,
+				   __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
+__syscall_cancel_arch_start:
+	ldl	t0, 0(a0)
+	addl	zero, t0, t0
+	/* if (*ch & CANCELED_BITMASK)  */
+	and	t0, TCB_CANCELED_BITMASK, t0
+	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
+__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 related	[flat|nested] 46+ messages in thread

* [PATCH v4 16/21] nptl: sh: Fix Race conditions in pthread cancellation [BZ#12683]
  2020-04-03 20:31 [PATCH v4 00/21] nptl: Fix Race conditions in pthread cancellation [BZ#12683] Adhemerval Zanella via Libc-alpha
                   ` (14 preceding siblings ...)
  2020-04-03 20:31 ` [PATCH v4 15/21] nptl: alpha: " Adhemerval Zanella via Libc-alpha
@ 2020-04-03 20:31 ` Adhemerval Zanella via Libc-alpha
  2020-04-03 20:31 ` [PATCH v4 17/21] nptl: riscv: " Adhemerval Zanella via Libc-alpha
                   ` (4 subsequent siblings)
  20 siblings, 0 replies; 46+ messages in thread
From: Adhemerval Zanella via Libc-alpha @ 2020-04-03 20:31 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/nptl/tcb-offsets.sym             |   3 +
 sysdeps/sh/sysdep.h                         |   1 +
 sysdeps/unix/sysv/linux/sh/syscall_cancel.S | 126 ++++++++++++++++++++
 3 files changed, 130 insertions(+)
 create mode 100644 sysdeps/unix/sysv/linux/sh/syscall_cancel.S

diff --git a/sysdeps/sh/nptl/tcb-offsets.sym b/sysdeps/sh/nptl/tcb-offsets.sym
index 234207779d..35dad27d70 100644
--- a/sysdeps/sh/nptl/tcb-offsets.sym
+++ b/sysdeps/sh/nptl/tcb-offsets.sym
@@ -10,3 +10,6 @@ MULTIPLE_THREADS_OFFSET	offsetof (struct pthread, header.multiple_threads)
 TLS_PRE_TCB_SIZE	sizeof (struct pthread)
 MUTEX_FUTEX		offsetof (pthread_mutex_t, __data.__lock)
 POINTER_GUARD		offsetof (tcbhead_t, pointer_guard)
+
+-- Not strictly offsets, used on syscall_cancel.S
+TCB_CANCELED_BITMASK	CANCELED_BITMASK
diff --git a/sysdeps/sh/sysdep.h b/sysdeps/sh/sysdep.h
index cf83bab024..e496f769c5 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..5f916ab9b0
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/sh/syscall_cancel.S
@@ -0,0 +1,126 @@
+/* Cancellable syscall wrapper.  Linux/sh version.
+   Copyright (C) 2020 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
+__syscall_cancel_arch_start:
+
+	/* if (*cancelhandling & CANCELED_BITMASK)
+	     __syscall_do_cancel()  */
+	mov.l	@r4,r0
+	tst	#TCB_CANCELED_BITMASK,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
+__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 related	[flat|nested] 46+ messages in thread

* [PATCH v4 17/21] nptl: riscv: Fix Race conditions in pthread cancellation [BZ#12683]
  2020-04-03 20:31 [PATCH v4 00/21] nptl: Fix Race conditions in pthread cancellation [BZ#12683] Adhemerval Zanella via Libc-alpha
                   ` (15 preceding siblings ...)
  2020-04-03 20:31 ` [PATCH v4 16/21] nptl: sh: " Adhemerval Zanella via Libc-alpha
@ 2020-04-03 20:31 ` Adhemerval Zanella via Libc-alpha
  2020-04-03 20:31 ` [PATCH v4 18/21] nptl: s390: " Adhemerval Zanella via Libc-alpha
                   ` (3 subsequent siblings)
  20 siblings, 0 replies; 46+ messages in thread
From: Adhemerval Zanella via Libc-alpha @ 2020-04-03 20:31 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.

Reviewed-by: Andrew Waterman <aswaterman@gmail.com>
---
 sysdeps/riscv/nptl/tcb-offsets.sym            |  3 +
 sysdeps/riscv/nptl/tls.h                      |  2 +
 .../unix/sysv/linux/riscv/syscall_cancel.S    | 67 +++++++++++++++++++
 3 files changed, 72 insertions(+)
 create mode 100644 sysdeps/unix/sysv/linux/riscv/syscall_cancel.S

diff --git a/sysdeps/riscv/nptl/tcb-offsets.sym b/sysdeps/riscv/nptl/tcb-offsets.sym
index ab4981f2e2..bcee223d1e 100644
--- a/sysdeps/riscv/nptl/tcb-offsets.sym
+++ b/sysdeps/riscv/nptl/tcb-offsets.sym
@@ -4,3 +4,6 @@
 #define thread_offsetof(mem)	(long)(offsetof (struct pthread, mem) - TLS_TCB_OFFSET - TLS_PRE_TCB_SIZE)
 
 MULTIPLE_THREADS_OFFSET		thread_offsetof (header.multiple_threads)
+
+-- Not strictly offsets, used on syscall_cancel.S
+TCB_CANCELED_BITMASK		CANCELED_BITMASK
diff --git a/sysdeps/riscv/nptl/tls.h b/sysdeps/riscv/nptl/tls.h
index a9167bc143..21e9124564 100644
--- a/sysdeps/riscv/nptl/tls.h
+++ b/sysdeps/riscv/nptl/tls.h
@@ -142,6 +142,8 @@ typedef struct
 # define THREAD_GSCOPE_WAIT() \
   GL(dl_wait_lookup_done) ()
 
+#else /* __ASSEMBLER__ */
+# include <tcb-offsets.h>
 #endif /* __ASSEMBLER__ */
 
 #endif	/* tls.h */
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..520e25aa3a
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/riscv/syscall_cancel.S
@@ -0,0 +1,67 @@
+/* Cancellable syscall wrapper.  Linux/riscv version.
+   Copyright (C) 2020 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
+__syscall_cancel_arch_start:
+	lw	a7, 0(a0)
+	/* if (*ch & CANCELED_BITMASK)  */
+	andi	a7, a7, TCB_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
+__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 related	[flat|nested] 46+ messages in thread

* [PATCH v4 18/21] nptl: s390: Fix Race conditions in pthread cancellation [BZ#12683]
  2020-04-03 20:31 [PATCH v4 00/21] nptl: Fix Race conditions in pthread cancellation [BZ#12683] Adhemerval Zanella via Libc-alpha
                   ` (16 preceding siblings ...)
  2020-04-03 20:31 ` [PATCH v4 17/21] nptl: riscv: " Adhemerval Zanella via Libc-alpha
@ 2020-04-03 20:31 ` Adhemerval Zanella via Libc-alpha
  2020-04-03 20:31 ` [PATCH v4 19/21] nptl: nios2: " Adhemerval Zanella via Libc-alpha
                   ` (2 subsequent siblings)
  20 siblings, 0 replies; 46+ messages in thread
From: Adhemerval Zanella via Libc-alpha @ 2020-04-03 20:31 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.

Co-authored-by: Stefan Liebler <stli@linux.ibm.com>
---
 sysdeps/s390/nptl/tcb-offsets.sym             |  3 +
 .../sysv/linux/s390/s390-32/syscall_cancel.S  | 63 +++++++++++++++++++
 .../sysv/linux/s390/s390-64/syscall_cancel.S  | 62 ++++++++++++++++++
 3 files changed, 128 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/s390/nptl/tcb-offsets.sym b/sysdeps/s390/nptl/tcb-offsets.sym
index 9c1c01f353..5d173db2ea 100644
--- a/sysdeps/s390/nptl/tcb-offsets.sym
+++ b/sysdeps/s390/nptl/tcb-offsets.sym
@@ -4,3 +4,6 @@
 MULTIPLE_THREADS_OFFSET		offsetof (tcbhead_t, multiple_threads)
 STACK_GUARD			offsetof (tcbhead_t, stack_guard)
 TID				offsetof (struct pthread, tid)
+
+-- Not strictly offsets, used on syscall_cancel.S
+TCB_CANCELED_BITMASK		CANCELED_BITMASK
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..48d932a9cb
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/s390/s390-32/syscall_cancel.S
@@ -0,0 +1,63 @@
+/* Cancellable syscall wrapper.  Linux/s390 version.
+   Copyright (C) 2020 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,%r7,24(%r15)
+	cfi_offset (%r6, -72)
+	cfi_offset (%r7, -68)
+
+	.globl __syscall_cancel_arch_start
+__syscall_cancel_arch_start:
+	/* if (*cancelhandling & CANCELED_BITMASK)
+	     __syscall_do_cancel()  */
+	tm	3(%r2), TCB_CANCELED_BITMASK
+	jne	1f
+
+	/* 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
+__syscall_cancel_arch_end:
+	lm	%r6,%r7,24(%r15)
+	cfi_remember_state
+
+	cfi_restore (%r7)
+	cfi_restore (%r6)
+	br	%r14
+1:
+	cfi_restore_state
+	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
new file mode 100644
index 0000000000..034bf7ebef
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/s390/s390-64/syscall_cancel.S
@@ -0,0 +1,62 @@
+/* Cancellable syscall wrapper.  Linux/s390x version.
+   Copyright (C) 2020 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,%r7,48(%r15)
+	cfi_offset (%r6, -112)
+	cfi_offset (%r7, -104)
+
+	.globl __syscall_cancel_arch_start
+__syscall_cancel_arch_start:
+	/* if (*cancelhandling & CANCELED_BITMASK)
+	     __syscall_do_cancel()  */
+	tm	3(%r2),TCB_CANCELED_BITMASK
+
+	/* Issue a 6 argument syscall, the nr [%r1] being the syscall
+	   number.  */
+	jne	1f
+	lgr	%r1,%r3
+	lgr	%r2,%r4
+	lgr	%r3,%r5
+	lgr	%r4,%r6
+	lmg	%r5,%r7,160(%r15)
+	svc	0
+
+	.globl __syscall_cancel_arch_end
+__syscall_cancel_arch_end:
+	lmg	%r6,%r7,48(%r15)
+	cfi_remember_state
+	cfi_restore (%r7)
+	cfi_restore (%r6)
+	br	%r14
+1:
+	cfi_restore_state
+	jg	__syscall_do_cancel
+END (__syscall_cancel_arch)
+libc_hidden_def (__syscall_cancel_arch)
-- 
2.17.1


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

* [PATCH v4 19/21] nptl: nios2: Fix Race conditions in pthread cancellation [BZ#12683]
  2020-04-03 20:31 [PATCH v4 00/21] nptl: Fix Race conditions in pthread cancellation [BZ#12683] Adhemerval Zanella via Libc-alpha
                   ` (17 preceding siblings ...)
  2020-04-03 20:31 ` [PATCH v4 18/21] nptl: s390: " Adhemerval Zanella via Libc-alpha
@ 2020-04-03 20:31 ` Adhemerval Zanella via Libc-alpha
  2020-04-03 20:32 ` [PATCH v4 20/21] nptl: csky: " Adhemerval Zanella via Libc-alpha
  2020-04-03 20:32 ` [PATCH v4 21/21] Linux: Remove sysdep-cancel header Adhemerval Zanella via Libc-alpha
  20 siblings, 0 replies; 46+ messages in thread
From: Adhemerval Zanella via Libc-alpha @ 2020-04-03 20:31 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.

Checked against a build and make check run-built-tests=no for
nios2-linux-gnu.
---
 sysdeps/nios2/nptl/tcb-offsets.sym            |  3 +
 .../unix/sysv/linux/nios2/syscall_cancel.S    | 95 +++++++++++++++++++
 2 files changed, 98 insertions(+)
 create mode 100644 sysdeps/unix/sysv/linux/nios2/syscall_cancel.S

diff --git a/sysdeps/nios2/nptl/tcb-offsets.sym b/sysdeps/nios2/nptl/tcb-offsets.sym
index 3cd8d984ac..3b0d37f93f 100644
--- a/sysdeps/nios2/nptl/tcb-offsets.sym
+++ b/sysdeps/nios2/nptl/tcb-offsets.sym
@@ -11,3 +11,6 @@
 MULTIPLE_THREADS_OFFSET		thread_offsetof (header.multiple_threads)
 TID_OFFSET			thread_offsetof (tid)
 POINTER_GUARD			(offsetof (tcbhead_t, pointer_guard) - TLS_TCB_OFFSET - sizeof (tcbhead_t))
+
+-- Not strictly offsets, used on syscall_cancel.S
+TCB_CANCELED_BITMASK		CANCELED_BITMASK
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..a8940e8b88
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/nios2/syscall_cancel.S
@@ -0,0 +1,95 @@
+/* Cancellable syscall wrapper.  Linux/nios2 version.
+   Copyright (C) 2020 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
+__syscall_cancel_arch_start:
+	ldw	r3, 0(r4)
+	andi	r3, r3, TCB_CANCELED_BITMASK
+	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
+__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 related	[flat|nested] 46+ messages in thread

* [PATCH v4 20/21] nptl: csky: Fix Race conditions in pthread cancellation [BZ#12683]
  2020-04-03 20:31 [PATCH v4 00/21] nptl: Fix Race conditions in pthread cancellation [BZ#12683] Adhemerval Zanella via Libc-alpha
                   ` (18 preceding siblings ...)
  2020-04-03 20:31 ` [PATCH v4 19/21] nptl: nios2: " Adhemerval Zanella via Libc-alpha
@ 2020-04-03 20:32 ` Adhemerval Zanella via Libc-alpha
  2020-04-03 20:32 ` [PATCH v4 21/21] Linux: Remove sysdep-cancel header Adhemerval Zanella via Libc-alpha
  20 siblings, 0 replies; 46+ messages in thread
From: Adhemerval Zanella via Libc-alpha @ 2020-04-03 20:32 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.

Checked against a build and make check run-built-tests=no for
csky-linux-gnuabiv2.
---
 sysdeps/csky/nptl/tcb-offsets.sym             |   3 +
 sysdeps/unix/sysv/linux/csky/syscall_cancel.S | 115 ++++++++++++++++++
 2 files changed, 118 insertions(+)
 create mode 100644 sysdeps/unix/sysv/linux/csky/syscall_cancel.S

diff --git a/sysdeps/csky/nptl/tcb-offsets.sym b/sysdeps/csky/nptl/tcb-offsets.sym
index f1105205c0..dab7518aa4 100644
--- a/sysdeps/csky/nptl/tcb-offsets.sym
+++ b/sysdeps/csky/nptl/tcb-offsets.sym
@@ -8,3 +8,6 @@
 
 MULTIPLE_THREADS_OFFSET		thread_offsetof (header.multiple_threads)
 TID_OFFSET			thread_offsetof (tid)
+
+-- Not strictly offsets, used on syscall_cancel.S
+TCB_CANCELED_BITMASK		CANCELED_BITMASK
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..a730225a22
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/csky/syscall_cancel.S
@@ -0,0 +1,115 @@
+/* Cancellable syscall wrapper.  Linux/csky version.
+   Copyright (C) 2020 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
+__syscall_cancel_arch_start:
+	ld.w	t0, (a0, 0)
+	andi	t0, t0, TCB_CANCELED_BITMASK
+	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 related	[flat|nested] 46+ messages in thread

* [PATCH v4 21/21] Linux: Remove sysdep-cancel header
  2020-04-03 20:31 [PATCH v4 00/21] nptl: Fix Race conditions in pthread cancellation [BZ#12683] Adhemerval Zanella via Libc-alpha
                   ` (19 preceding siblings ...)
  2020-04-03 20:32 ` [PATCH v4 20/21] nptl: csky: " Adhemerval Zanella via Libc-alpha
@ 2020-04-03 20:32 ` Adhemerval Zanella via Libc-alpha
  20 siblings, 0 replies; 46+ messages in thread
From: Adhemerval Zanella via Libc-alpha @ 2020-04-03 20:32 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                                    |  2 --
 malloc/malloc.c                               |  3 ---
 posix/nanosleep.c                             |  1 -
 sysdeps/generic/sysdep-cancel.h               |  5 ----
 sysdeps/mips/dl-trampoline.c                  |  1 -
 sysdeps/nptl/lowlevellock-futex.h             |  1 -
 sysdeps/posix/open64.c                        |  1 -
 sysdeps/posix/pause.c                         |  1 -
 sysdeps/posix/sigpause.c                      |  1 -
 sysdeps/posix/sigwait.c                       |  1 -
 sysdeps/pthread/thrd_sleep.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 +-
 .../unix/sysv/linux/generic/inotify_init.c    |  5 +---
 sysdeps/unix/sysv/linux/getrandom.c           |  1 -
 sysdeps/unix/sysv/linux/microblaze/pselect.c  |  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/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/poll.c                |  1 -
 sysdeps/unix/sysv/linux/ppoll.c               |  3 ---
 sysdeps/unix/sysv/linux/pread.c               |  2 +-
 sysdeps/unix/sysv/linux/pread64.c             |  2 +-
 sysdeps/unix/sysv/linux/pread64_nocancel.c    |  1 -
 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             |  5 +++-
 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       | 25 -------------------
 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/wait4.c               |  2 +-
 sysdeps/unix/sysv/linux/waitid.c              |  1 -
 sysdeps/unix/sysv/linux/write.c               |  2 +-
 sysdeps/unix/sysv/linux/write_nocancel.c      |  1 -
 sysdeps/unix/sysv/linux/writev.c              |  2 +-
 100 files changed, 43 insertions(+), 140 deletions(-)
 delete mode 100644 sysdeps/generic/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 73b2817bbf..eb3aa6daae 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 12a229f06c..54216db4fa 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 7b3b177aa6..a771c76dcd 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 cf5f1d3e82..58679fd3e0 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 b20a882799..637b3a2639 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 361b926ea9..4134145cac 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>
 #include <dl-sym-post.h>
diff --git a/io/creat.c b/io/creat.c
index cf72a9451a..4dab1f3a19 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 2b880426fc..2871623775 100644
--- a/io/ppoll.c
+++ b/io/ppoll.c
@@ -21,8 +21,6 @@
 #include <signal.h>
 #include <stddef.h>	/* For NULL.  */
 #include <sys/poll.h>
-#include <sysdep-cancel.h>
-#include <time.h>
 
 
 int
diff --git a/malloc/malloc.c b/malloc/malloc.c
index 6acb5ad43a..2e165c00fa 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/posix/nanosleep.c b/posix/nanosleep.c
index 120a288322..afe1733a16 100644
--- a/posix/nanosleep.c
+++ b/posix/nanosleep.c
@@ -18,7 +18,6 @@
 #include <errno.h>
 #include <time.h>
 
-
 /* Pause execution for a number of nanoseconds.  */
 int
 __nanosleep (const struct timespec *requested_time,
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/mips/dl-trampoline.c b/sysdeps/mips/dl-trampoline.c
index 3289e04ff5..7ba1fd98bf 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/nptl/lowlevellock-futex.h b/sysdeps/nptl/lowlevellock-futex.h
index 4b72deda95..2260b55ada 100644
--- a/sysdeps/nptl/lowlevellock-futex.h
+++ b/sysdeps/nptl/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/posix/open64.c b/sysdeps/posix/open64.c
index abd6ef3709..371905c0e9 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 42aa2598f2..2ad2b771f9 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 ad803cca93..d45063323b 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 64c6054caa..e7741bec78 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/pthread/thrd_sleep.c b/sysdeps/pthread/thrd_sleep.c
index c9805d5fd1..5103959997 100644
--- a/sysdeps/pthread/thrd_sleep.c
+++ b/sysdeps/pthread/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/unix/sysv/linux/accept.c b/sysdeps/unix/sysv/linux/accept.c
index f6021a75e7..aec5b6f470 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 85cdeef0e8..691e04165b 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 d5e8949013..026d791b16 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 7793dfd6b1..ee1991067c 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 cc7a09569d..479c21fd52 100644
--- a/sysdeps/unix/sysv/linux/clock_nanosleep.c
+++ b/sysdeps/unix/sysv/linux/clock_nanosleep.c
@@ -19,7 +19,6 @@
 #include <kernel-features.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 602ab558e6..df70725e95 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 23ebcd0df5..988c1a5424 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 0e970b41ed..ac94e02832 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 a73c89f079..2bb445e7df 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 184e5f55f7..c74ac75c4f 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 d29323ad64..7423e5b579 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 66f04482c7..28622e10ce 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>
 
 /* Wait for events on an epoll instance "epfd". Returns the number of
diff --git a/sysdeps/unix/sysv/linux/epoll_wait.c b/sysdeps/unix/sysv/linux/epoll_wait.c
index 4e343b9344..f8403cc95d 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 e40d0c4a23..a21e997c2d 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 b2d2fab797..2be1711673 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 14ac328cf5..0ea45b51f0 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 783f564cba..bed464ff33 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 ed9211001f..3a552e75fc 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 87175b47d1..28a9dcfed1 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 afcca6e862..3b7e51acc1 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/generic/inotify_init.c b/sysdeps/unix/sysv/linux/generic/inotify_init.c
index 7f84124850..25a323f7e7 100644
--- a/sysdeps/unix/sysv/linux/generic/inotify_init.c
+++ b/sysdeps/unix/sysv/linux/generic/inotify_init.c
@@ -16,11 +16,8 @@
    License along with the GNU C Library.  If not, see
    <https://www.gnu.org/licenses/>.  */
 
-#include <stddef.h>
-#include <errno.h>
-#include <unistd.h>
-#include <sys/types.h>
 #include <sys/inotify.h>
+#include <sysdep.h>
 
 libc_hidden_proto (inotify_init)
 
diff --git a/sysdeps/unix/sysv/linux/getrandom.c b/sysdeps/unix/sysv/linux/getrandom.c
index 63b8d36bf4..4739852ea0 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>
 
 /* Write up to LENGTH bytes of randomness starting at BUFFER.
    Return the number of bytes written, or -1 on error.  */
diff --git a/sysdeps/unix/sysv/linux/microblaze/pselect.c b/sysdeps/unix/sysv/linux/microblaze/pselect.c
index 1dfc3b8fc9..cd089f99ff 100644
--- a/sysdeps/unix/sysv/linux/microblaze/pselect.c
+++ b/sysdeps/unix/sysv/linux/microblaze/pselect.c
@@ -20,7 +20,6 @@
 #include <signal.h>
 #include <time.h>
 #include <sys/poll.h>
-#include <sysdep-cancel.h>
 
 #ifndef __ASSUME_PSELECT
 # define __pselect __pselect_syscall
diff --git a/sysdeps/unix/sysv/linux/mq_timedreceive.c b/sysdeps/unix/sysv/linux/mq_timedreceive.c
index 73a1d63e41..56ce3bc184 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 888ec6744a..77d482d586 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 95edc7a787..e43bbc4255 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 554516f2ca..7923738b6a 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 de1dd2ac5e..327371beaf 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/open.c b/sysdeps/unix/sysv/linux/open.c
index 0c006fb22e..d626365c3d 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 f2d0c55810..c4e7ae89ae 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 6c9c53291a..b5a21fe575 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 cec8609916..a5f4a90951 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 af72c0214c..d032559fe8 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 46da3ecc04..f50187b5a3 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 80fe66210d..afcd161a29 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 caba9e0f88..22388d7d6f 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 02042ebb83..c384565dcf 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/poll.c b/sysdeps/unix/sysv/linux/poll.c
index 1c41ade1b7..d85ad2f160 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 4ffb23710e..6fa843c2cb 100644
--- a/sysdeps/unix/sysv/linux/ppoll.c
+++ b/sysdeps/unix/sysv/linux/ppoll.c
@@ -20,9 +20,6 @@
 #include <signal.h>
 #include <time.h>
 #include <sys/poll.h>
-#include <sysdep-cancel.h>
-#include <kernel-features.h>
-
 
 int
 __ppoll64 (struct pollfd *fds, nfds_t nfds, const struct __timespec64 *timeout,
diff --git a/sysdeps/unix/sysv/linux/pread.c b/sysdeps/unix/sysv/linux/pread.c
index 8dd87b3976..8872ad9b80 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 3d4ffbafc1..da5cff4167 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>
 
 ssize_t
 __libc_pread64 (int fd, void *buf, size_t count, off64_t offset)
diff --git a/sysdeps/unix/sysv/linux/pread64_nocancel.c b/sysdeps/unix/sysv/linux/pread64_nocancel.c
index af33985959..6ef4bf25b3 100644
--- a/sysdeps/unix/sysv/linux/pread64_nocancel.c
+++ b/sysdeps/unix/sysv/linux/pread64_nocancel.c
@@ -17,7 +17,6 @@
    <http://www.gnu.org/licenses/>.  */
 
 #include <unistd.h>
-#include <sysdep-cancel.h>
 #include <not-cancel.h>
 
 ssize_t
diff --git a/sysdeps/unix/sysv/linux/preadv.c b/sysdeps/unix/sysv/linux/preadv.c
index 9fccb917a1..bc55607109 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 4e3aa923da..e3dd0121d9 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 9fe43522a5..91a96cf736 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 1bf1a4c696..8a91f13292 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>
 
 ssize_t
 preadv64v2 (int fd, const struct iovec *vector, int count, off64_t offset,
diff --git a/sysdeps/unix/sysv/linux/pselect.c b/sysdeps/unix/sysv/linux/pselect.c
index d7c6ff8fdb..91a2094da1 100644
--- a/sysdeps/unix/sysv/linux/pselect.c
+++ b/sysdeps/unix/sysv/linux/pselect.c
@@ -17,7 +17,10 @@
    <https://www.gnu.org/licenses/>.  */
 
 #include <sys/select.h>
-#include <sysdep-cancel.h>
+#include <signal.h>
+#include <stddef.h>
+#include <stdint.h>
+#include <sysdep.h>
 
 int
 __pselect (int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
diff --git a/sysdeps/unix/sysv/linux/pwrite.c b/sysdeps/unix/sysv/linux/pwrite.c
index 17964686e5..9a1cb401d6 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 709775c207..2baf8bf48a 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>
 
 ssize_t
 __libc_pwrite64 (int fd, const void *buf, size_t count, off64_t offset)
diff --git a/sysdeps/unix/sysv/linux/pwritev.c b/sysdeps/unix/sysv/linux/pwritev.c
index d6cb3c8d5c..ce5787d442 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 a179654970..4899508821 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 08bda27d4f..7d812fd426 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 8df32528b7..cac7dd9d14 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>
 
 ssize_t
 pwritev64v2 (int fd, const struct iovec *vector, int count, off64_t offset,
diff --git a/sysdeps/unix/sysv/linux/read.c b/sysdeps/unix/sysv/linux/read.c
index 64f558a587..b81e47b159 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 f9d8a3b563..2b5a261859 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 1a4305c597..40ba701800 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 79fb3c32d1..7e8a05f1d7 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 70532529c9..ba89cec82d 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 42c80c59c3..ee303f558a 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 a86d502922..6c430780b2 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 54c50edba2..aa799c83c8 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 aed7d06585..39472a8b52 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 378de59c64..1790a37574 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 f8f955098f..0a06ff67ae 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 670d0679ea..d34590297b 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 dd5df5af25..9887524e70 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 6b3d8f705f..b3509e5d0c 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 dcfcdc767c..770317e7ef 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 80b9ed313a..ff20a108f6 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 64af566e18..6cf21a55ad 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 fe21cf1988..90f69d64a1 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 18c43c54a8..086ee80c14 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 20824bc096..0000000000
--- a/sysdeps/unix/sysv/linux/sysdep-cancel.h
+++ /dev/null
@@ -1,25 +0,0 @@
-/* Single-thread optimization definitions.  Linux version.
-   Copyright (C) 2017-2020 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>
-
-#endif
diff --git a/sysdeps/unix/sysv/linux/tcdrain.c b/sysdeps/unix/sysv/linux/tcdrain.c
index 14ae76884d..6e65cb5d9e 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 0e62c226dd..6c898d9779 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 63083f6f91..07eb5fdca6 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 17cc7bf8e7..7c2c0b6817 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/wait4.c b/sysdeps/unix/sysv/linux/wait4.c
index d14bd4da27..98ca3f55e9 100644
--- a/sysdeps/unix/sysv/linux/wait4.c
+++ b/sysdeps/unix/sysv/linux/wait4.c
@@ -19,8 +19,8 @@
 #include <sys/wait.h>
 #include <sys/resource.h>
 #include <sys/types.h>
-#include <sysdep-cancel.h>
 #include <tv32-compat.h>
+#include <sysdep.h>
 
 pid_t
 __wait4_time64 (pid_t pid, int *stat_loc, int options, struct __rusage64 *usage)
diff --git a/sysdeps/unix/sysv/linux/waitid.c b/sysdeps/unix/sysv/linux/waitid.c
index 023fa95f4f..9de60beccb 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/write.c b/sysdeps/unix/sysv/linux/write.c
index 7848f7de27..025bdfca09 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 36d406cf74..011b3ebdf5 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 8d628535f8..10c295ecea 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 related	[flat|nested] 46+ messages in thread

* Re: [PATCH v4 04/21] nptl: x32: Fix Race conditions in pthread cancellation [BZ#12683]
  2020-04-03 20:31 ` [PATCH v4 04/21] nptl: x32: " Adhemerval Zanella via Libc-alpha
@ 2020-04-03 21:22   ` Joseph Myers
  2020-04-07 12:47     ` Adhemerval Zanella via Libc-alpha
  0 siblings, 1 reply; 46+ messages in thread
From: Joseph Myers @ 2020-04-03 21:22 UTC (permalink / raw
  To: Adhemerval Zanella; +Cc: libc-alpha

On Fri, 3 Apr 2020, Adhemerval Zanella via Libc-alpha wrote:

> This patches adds the x32 modification required for the BZ#12683.
> It follows the x86_64-x32 ABI and pointers are zero-extended.
> However, compiler may not see such cases and accuse a cast from pointer
> to integer of different size and for such cases the warning is
> explict disabled.

MIPS n32 uses an intermediate cast to (__typeof__ ((X) - (X))), so that a 
conversion to a different size is never directly from a pointer type.  
Does something like that help here to avoid the warning without needing to 
use diagnostic pragmas?

-- 
Joseph S. Myers
joseph@codesourcery.com

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

* Re: [PATCH v4 14/21] nptl: m68k: Fix Race conditions in pthread cancellation [BZ#12683]
  2020-04-03 20:31 ` [PATCH v4 14/21] nptl: m68k: " Adhemerval Zanella via Libc-alpha
@ 2020-04-03 21:34   ` Andreas Schwab
  2020-04-07 12:46     ` Adhemerval Zanella via Libc-alpha
  2020-04-12 15:42   ` Stepan Golosunov
  1 sibling, 1 reply; 46+ messages in thread
From: Andreas Schwab @ 2020-04-03 21:34 UTC (permalink / raw
  To: Adhemerval Zanella via Libc-alpha

On Apr 03 2020, Adhemerval Zanella via Libc-alpha wrote:

> +ENTRY (__syscall_cancel_arch)
> +#ifdef __mcoldfire__
> +	lea	(-16,%sp),%sp
> +	movem.l	#60,(%sp)
> +#else
> +	movem.l	#15360,-(%sp)
> +#endif

Please use register names.

> +#ifdef __mcoldfire__
> +	movem.l	(%sp),#60
> +	lea	(16,%sp),%sp
> +#else
> +	movem.l	(%sp)+,#60
> +#endif

Likewise.

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] 46+ messages in thread

* Re: [PATCH v4 14/21] nptl: m68k: Fix Race conditions in pthread cancellation [BZ#12683]
  2020-04-03 21:34   ` Andreas Schwab
@ 2020-04-07 12:46     ` Adhemerval Zanella via Libc-alpha
  0 siblings, 0 replies; 46+ messages in thread
From: Adhemerval Zanella via Libc-alpha @ 2020-04-07 12:46 UTC (permalink / raw
  To: Andreas Schwab, Adhemerval Zanella via Libc-alpha



On 03/04/2020 18:34, Andreas Schwab wrote:
> On Apr 03 2020, Adhemerval Zanella via Libc-alpha wrote:
> 
>> +ENTRY (__syscall_cancel_arch)
>> +#ifdef __mcoldfire__
>> +	lea	(-16,%sp),%sp
>> +	movem.l	#60,(%sp)
>> +#else
>> +	movem.l	#15360,-(%sp)
>> +#endif
> 
> Please use register names.
> 
>> +#ifdef __mcoldfire__
>> +	movem.l	(%sp),#60
>> +	lea	(16,%sp),%sp
>> +#else
>> +	movem.l	(%sp)+,#60
>> +#endif
> 
> Likewise.
> 
> Andreas.
> 

Ack.

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

* Re: [PATCH v4 04/21] nptl: x32: Fix Race conditions in pthread cancellation [BZ#12683]
  2020-04-03 21:22   ` Joseph Myers
@ 2020-04-07 12:47     ` Adhemerval Zanella via Libc-alpha
  2020-04-07 12:54       ` H.J. Lu via Libc-alpha
  0 siblings, 1 reply; 46+ messages in thread
From: Adhemerval Zanella via Libc-alpha @ 2020-04-07 12:47 UTC (permalink / raw
  To: Joseph Myers; +Cc: libc-alpha



On 03/04/2020 18:22, Joseph Myers wrote:
> On Fri, 3 Apr 2020, Adhemerval Zanella via Libc-alpha wrote:
> 
>> This patches adds the x32 modification required for the BZ#12683.
>> It follows the x86_64-x32 ABI and pointers are zero-extended.
>> However, compiler may not see such cases and accuse a cast from pointer
>> to integer of different size and for such cases the warning is
>> explict disabled.
> 
> MIPS n32 uses an intermediate cast to (__typeof__ ((X) - (X))), so that a 
> conversion to a different size is never directly from a pointer type.  
> Does something like that help here to avoid the warning without needing to 
> use diagnostic pragmas?

The intermediate cast to (__typeof__ ((X) - (X))) is not suffice for x32
(the resulting argumetn it will passed as function argument instead of
asm input).  I have replaced with:

  #define __SSC(__x)                                              \
  ({                                                            \
    __syscall_arg_t __arg = sizeof (1 ? (__x) : 0ULL) < 8       \
      ? (unsigned long int) (uintptr_t)(__x)                    \
      : (__syscall_arg_t) (__typeof__ ((__x) - (__x))) (__x);   \
    __arg;                                                      \
  })


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

* Re: [PATCH v4 04/21] nptl: x32: Fix Race conditions in pthread cancellation [BZ#12683]
  2020-04-07 12:47     ` Adhemerval Zanella via Libc-alpha
@ 2020-04-07 12:54       ` H.J. Lu via Libc-alpha
  2020-04-07 13:33         ` Adhemerval Zanella via Libc-alpha
  0 siblings, 1 reply; 46+ messages in thread
From: H.J. Lu via Libc-alpha @ 2020-04-07 12:54 UTC (permalink / raw
  To: Adhemerval Zanella; +Cc: GNU C Library, Joseph Myers

On Tue, Apr 7, 2020 at 5:47 AM Adhemerval Zanella via Libc-alpha
<libc-alpha@sourceware.org> wrote:
>
>
>
> On 03/04/2020 18:22, Joseph Myers wrote:
> > On Fri, 3 Apr 2020, Adhemerval Zanella via Libc-alpha wrote:
> >
> >> This patches adds the x32 modification required for the BZ#12683.
> >> It follows the x86_64-x32 ABI and pointers are zero-extended.
> >> However, compiler may not see such cases and accuse a cast from pointer
> >> to integer of different size and for such cases the warning is
> >> explict disabled.
> >
> > MIPS n32 uses an intermediate cast to (__typeof__ ((X) - (X))), so that a
> > conversion to a different size is never directly from a pointer type.
> > Does something like that help here to avoid the warning without needing to
> > use diagnostic pragmas?
>
> The intermediate cast to (__typeof__ ((X) - (X))) is not suffice for x32
> (the resulting argumetn it will passed as function argument instead of
> asm input).  I have replaced with:
>
>   #define __SSC(__x)                                              \
>   ({                                                            \
>     __syscall_arg_t __arg = sizeof (1 ? (__x) : 0ULL) < 8       \
>       ? (unsigned long int) (uintptr_t)(__x)                    \
>       : (__syscall_arg_t) (__typeof__ ((__x) - (__x))) (__x);   \
>     __arg;                                                      \
>   })
>

Have you looked at libc-pointer-arith.h?

-- 
H.J.

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

* Re: [PATCH v4 04/21] nptl: x32: Fix Race conditions in pthread cancellation [BZ#12683]
  2020-04-07 12:54       ` H.J. Lu via Libc-alpha
@ 2020-04-07 13:33         ` Adhemerval Zanella via Libc-alpha
  2020-04-07 13:40           ` H.J. Lu via Libc-alpha
  0 siblings, 1 reply; 46+ messages in thread
From: Adhemerval Zanella via Libc-alpha @ 2020-04-07 13:33 UTC (permalink / raw
  To: H.J. Lu; +Cc: GNU C Library, Joseph Myers



On 07/04/2020 09:54, H.J. Lu wrote:
> On Tue, Apr 7, 2020 at 5:47 AM Adhemerval Zanella via Libc-alpha
> <libc-alpha@sourceware.org> wrote:
>>
>>
>>
>> On 03/04/2020 18:22, Joseph Myers wrote:
>>> On Fri, 3 Apr 2020, Adhemerval Zanella via Libc-alpha wrote:
>>>
>>>> This patches adds the x32 modification required for the BZ#12683.
>>>> It follows the x86_64-x32 ABI and pointers are zero-extended.
>>>> However, compiler may not see such cases and accuse a cast from pointer
>>>> to integer of different size and for such cases the warning is
>>>> explict disabled.
>>>
>>> MIPS n32 uses an intermediate cast to (__typeof__ ((X) - (X))), so that a
>>> conversion to a different size is never directly from a pointer type.
>>> Does something like that help here to avoid the warning without needing to
>>> use diagnostic pragmas?
>>
>> The intermediate cast to (__typeof__ ((X) - (X))) is not suffice for x32
>> (the resulting argumetn it will passed as function argument instead of
>> asm input).  I have replaced with:
>>
>>   #define __SSC(__x)                                              \
>>   ({                                                            \
>>     __syscall_arg_t __arg = sizeof (1 ? (__x) : 0ULL) < 8       \
>>       ? (unsigned long int) (uintptr_t)(__x)                    \
>>       : (__syscall_arg_t) (__typeof__ ((__x) - (__x))) (__x);   \
>>     __arg;                                                      \
>>   })
>>
> 
> Have you looked at libc-pointer-arith.h?

That was my first approach, by using cast_to_integer macro. I tried to
change its internals to zero extend pointers correctly, but I couldn't
find a easier way without also adding the cast point suppression
warning in this original patch.  

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

* Re: [PATCH v4 04/21] nptl: x32: Fix Race conditions in pthread cancellation [BZ#12683]
  2020-04-07 13:33         ` Adhemerval Zanella via Libc-alpha
@ 2020-04-07 13:40           ` H.J. Lu via Libc-alpha
  2020-04-07 13:41             ` H.J. Lu via Libc-alpha
  0 siblings, 1 reply; 46+ messages in thread
From: H.J. Lu via Libc-alpha @ 2020-04-07 13:40 UTC (permalink / raw
  To: Adhemerval Zanella; +Cc: GNU C Library, Joseph Myers

On Tue, Apr 7, 2020 at 6:33 AM Adhemerval Zanella
<adhemerval.zanella@linaro.org> wrote:
>
>
>
> On 07/04/2020 09:54, H.J. Lu wrote:
> > On Tue, Apr 7, 2020 at 5:47 AM Adhemerval Zanella via Libc-alpha
> > <libc-alpha@sourceware.org> wrote:
> >>
> >>
> >>
> >> On 03/04/2020 18:22, Joseph Myers wrote:
> >>> On Fri, 3 Apr 2020, Adhemerval Zanella via Libc-alpha wrote:
> >>>
> >>>> This patches adds the x32 modification required for the BZ#12683.
> >>>> It follows the x86_64-x32 ABI and pointers are zero-extended.
> >>>> However, compiler may not see such cases and accuse a cast from pointer
> >>>> to integer of different size and for such cases the warning is
> >>>> explict disabled.
> >>>
> >>> MIPS n32 uses an intermediate cast to (__typeof__ ((X) - (X))), so that a
> >>> conversion to a different size is never directly from a pointer type.
> >>> Does something like that help here to avoid the warning without needing to
> >>> use diagnostic pragmas?
> >>
> >> The intermediate cast to (__typeof__ ((X) - (X))) is not suffice for x32
> >> (the resulting argumetn it will passed as function argument instead of
> >> asm input).  I have replaced with:
> >>
> >>   #define __SSC(__x)                                              \
> >>   ({                                                            \
> >>     __syscall_arg_t __arg = sizeof (1 ? (__x) : 0ULL) < 8       \
> >>       ? (unsigned long int) (uintptr_t)(__x)                    \
> >>       : (__syscall_arg_t) (__typeof__ ((__x) - (__x))) (__x);   \
> >>     __arg;                                                      \
> >>   })
> >>
> >
> > Have you looked at libc-pointer-arith.h?
>
> That was my first approach, by using cast_to_integer macro. I tried to
> change its internals to zero extend pointers correctly, but I couldn't
> find a easier way without also adding the cast point suppression
> warning in this original patch.

Have you looked at sysdeps/unix/sysv/linux/x86_64/sysdep.h?

-- 
H.J.

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

* Re: [PATCH v4 04/21] nptl: x32: Fix Race conditions in pthread cancellation [BZ#12683]
  2020-04-07 13:40           ` H.J. Lu via Libc-alpha
@ 2020-04-07 13:41             ` H.J. Lu via Libc-alpha
  2020-04-07 13:55               ` Adhemerval Zanella via Libc-alpha
  0 siblings, 1 reply; 46+ messages in thread
From: H.J. Lu via Libc-alpha @ 2020-04-07 13:41 UTC (permalink / raw
  To: Adhemerval Zanella; +Cc: GNU C Library, Joseph Myers

On Tue, Apr 7, 2020 at 6:40 AM H.J. Lu <hjl.tools@gmail.com> wrote:
>
> On Tue, Apr 7, 2020 at 6:33 AM Adhemerval Zanella
> <adhemerval.zanella@linaro.org> wrote:
> >
> >
> >
> > On 07/04/2020 09:54, H.J. Lu wrote:
> > > On Tue, Apr 7, 2020 at 5:47 AM Adhemerval Zanella via Libc-alpha
> > > <libc-alpha@sourceware.org> wrote:
> > >>
> > >>
> > >>
> > >> On 03/04/2020 18:22, Joseph Myers wrote:
> > >>> On Fri, 3 Apr 2020, Adhemerval Zanella via Libc-alpha wrote:
> > >>>
> > >>>> This patches adds the x32 modification required for the BZ#12683.
> > >>>> It follows the x86_64-x32 ABI and pointers are zero-extended.
> > >>>> However, compiler may not see such cases and accuse a cast from pointer
> > >>>> to integer of different size and for such cases the warning is
> > >>>> explict disabled.
> > >>>
> > >>> MIPS n32 uses an intermediate cast to (__typeof__ ((X) - (X))), so that a
> > >>> conversion to a different size is never directly from a pointer type.
> > >>> Does something like that help here to avoid the warning without needing to
> > >>> use diagnostic pragmas?
> > >>
> > >> The intermediate cast to (__typeof__ ((X) - (X))) is not suffice for x32
> > >> (the resulting argumetn it will passed as function argument instead of
> > >> asm input).  I have replaced with:
> > >>
> > >>   #define __SSC(__x)                                              \
> > >>   ({                                                            \
> > >>     __syscall_arg_t __arg = sizeof (1 ? (__x) : 0ULL) < 8       \
> > >>       ? (unsigned long int) (uintptr_t)(__x)                    \
> > >>       : (__syscall_arg_t) (__typeof__ ((__x) - (__x))) (__x);   \
> > >>     __arg;                                                      \
> > >>   })
> > >>
> > >
> > > Have you looked at libc-pointer-arith.h?
> >
> > That was my first approach, by using cast_to_integer macro. I tried to
> > change its internals to zero extend pointers correctly, but I couldn't
> > find a easier way without also adding the cast point suppression
> > warning in this original patch.
>
> Have you looked at sysdeps/unix/sysv/linux/x86_64/sysdep.h?
>

/* Create a variable 'name' based on type 'X' to avoid explicit types.
   This is mainly used set use 64-bits arguments in x32.   */
#define TYPEFY(X, name) __typeof__ ((X) - (X)) name
/* Explicit cast the argument to avoid integer from pointer warning on
   x32.  */
#define ARGIFY(X) ((__typeof__ ((X) - (X))) (X))

-- 
H.J.

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

* Re: [PATCH v4 04/21] nptl: x32: Fix Race conditions in pthread cancellation [BZ#12683]
  2020-04-07 13:41             ` H.J. Lu via Libc-alpha
@ 2020-04-07 13:55               ` Adhemerval Zanella via Libc-alpha
  2020-04-07 13:59                 ` H.J. Lu via Libc-alpha
  0 siblings, 1 reply; 46+ messages in thread
From: Adhemerval Zanella via Libc-alpha @ 2020-04-07 13:55 UTC (permalink / raw
  To: H.J. Lu; +Cc: GNU C Library, Joseph Myers



On 07/04/2020 10:41, H.J. Lu wrote:
> On Tue, Apr 7, 2020 at 6:40 AM H.J. Lu <hjl.tools@gmail.com> wrote:
>>
>> On Tue, Apr 7, 2020 at 6:33 AM Adhemerval Zanella
>> <adhemerval.zanella@linaro.org> wrote:
>>>
>>>
>>>
>>> On 07/04/2020 09:54, H.J. Lu wrote:
>>>> On Tue, Apr 7, 2020 at 5:47 AM Adhemerval Zanella via Libc-alpha
>>>> <libc-alpha@sourceware.org> wrote:
>>>>>
>>>>>
>>>>>
>>>>> On 03/04/2020 18:22, Joseph Myers wrote:
>>>>>> On Fri, 3 Apr 2020, Adhemerval Zanella via Libc-alpha wrote:
>>>>>>
>>>>>>> This patches adds the x32 modification required for the BZ#12683.
>>>>>>> It follows the x86_64-x32 ABI and pointers are zero-extended.
>>>>>>> However, compiler may not see such cases and accuse a cast from pointer
>>>>>>> to integer of different size and for such cases the warning is
>>>>>>> explict disabled.
>>>>>>
>>>>>> MIPS n32 uses an intermediate cast to (__typeof__ ((X) - (X))), so that a
>>>>>> conversion to a different size is never directly from a pointer type.
>>>>>> Does something like that help here to avoid the warning without needing to
>>>>>> use diagnostic pragmas?
>>>>>
>>>>> The intermediate cast to (__typeof__ ((X) - (X))) is not suffice for x32
>>>>> (the resulting argumetn it will passed as function argument instead of
>>>>> asm input).  I have replaced with:
>>>>>
>>>>>   #define __SSC(__x)                                              \
>>>>>   ({                                                            \
>>>>>     __syscall_arg_t __arg = sizeof (1 ? (__x) : 0ULL) < 8       \
>>>>>       ? (unsigned long int) (uintptr_t)(__x)                    \
>>>>>       : (__syscall_arg_t) (__typeof__ ((__x) - (__x))) (__x);   \
>>>>>     __arg;                                                      \
>>>>>   })
>>>>>
>>>>
>>>> Have you looked at libc-pointer-arith.h?
>>>
>>> That was my first approach, by using cast_to_integer macro. I tried to
>>> change its internals to zero extend pointers correctly, but I couldn't
>>> find a easier way without also adding the cast point suppression
>>> warning in this original patch.
>>
>> Have you looked at sysdeps/unix/sysv/linux/x86_64/sysdep.h?
>>
> 
> /* Create a variable 'name' based on type 'X' to avoid explicit types.
>    This is mainly used set use 64-bits arguments in x32.   */
> #define TYPEFY(X, name) __typeof__ ((X) - (X)) name
> /* Explicit cast the argument to avoid integer from pointer warning on
>    x32.  */
> #define ARGIFY(X) ((__typeof__ ((X) - (X))) (X))
> 

Yes, I was the one that actually added them (78ca091cdd2). But for this
case, the issue is it requires another implicit cast on the
__syscall_cancel call itself.  The difference here is the call is not
done through an asm input anymore.

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

* Re: [PATCH v4 04/21] nptl: x32: Fix Race conditions in pthread cancellation [BZ#12683]
  2020-04-07 13:55               ` Adhemerval Zanella via Libc-alpha
@ 2020-04-07 13:59                 ` H.J. Lu via Libc-alpha
  2020-04-07 14:04                   ` Adhemerval Zanella via Libc-alpha
  0 siblings, 1 reply; 46+ messages in thread
From: H.J. Lu via Libc-alpha @ 2020-04-07 13:59 UTC (permalink / raw
  To: Adhemerval Zanella; +Cc: GNU C Library, Joseph Myers

On Tue, Apr 7, 2020 at 6:55 AM Adhemerval Zanella
<adhemerval.zanella@linaro.org> wrote:
>
>
>
> On 07/04/2020 10:41, H.J. Lu wrote:
> > On Tue, Apr 7, 2020 at 6:40 AM H.J. Lu <hjl.tools@gmail.com> wrote:
> >>
> >> On Tue, Apr 7, 2020 at 6:33 AM Adhemerval Zanella
> >> <adhemerval.zanella@linaro.org> wrote:
> >>>
> >>>
> >>>
> >>> On 07/04/2020 09:54, H.J. Lu wrote:
> >>>> On Tue, Apr 7, 2020 at 5:47 AM Adhemerval Zanella via Libc-alpha
> >>>> <libc-alpha@sourceware.org> wrote:
> >>>>>
> >>>>>
> >>>>>
> >>>>> On 03/04/2020 18:22, Joseph Myers wrote:
> >>>>>> On Fri, 3 Apr 2020, Adhemerval Zanella via Libc-alpha wrote:
> >>>>>>
> >>>>>>> This patches adds the x32 modification required for the BZ#12683.
> >>>>>>> It follows the x86_64-x32 ABI and pointers are zero-extended.
> >>>>>>> However, compiler may not see such cases and accuse a cast from pointer
> >>>>>>> to integer of different size and for such cases the warning is
> >>>>>>> explict disabled.
> >>>>>>
> >>>>>> MIPS n32 uses an intermediate cast to (__typeof__ ((X) - (X))), so that a
> >>>>>> conversion to a different size is never directly from a pointer type.
> >>>>>> Does something like that help here to avoid the warning without needing to
> >>>>>> use diagnostic pragmas?
> >>>>>
> >>>>> The intermediate cast to (__typeof__ ((X) - (X))) is not suffice for x32
> >>>>> (the resulting argumetn it will passed as function argument instead of
> >>>>> asm input).  I have replaced with:
> >>>>>
> >>>>>   #define __SSC(__x)                                              \
> >>>>>   ({                                                            \
> >>>>>     __syscall_arg_t __arg = sizeof (1 ? (__x) : 0ULL) < 8       \
> >>>>>       ? (unsigned long int) (uintptr_t)(__x)                    \
> >>>>>       : (__syscall_arg_t) (__typeof__ ((__x) - (__x))) (__x);   \
> >>>>>     __arg;                                                      \
> >>>>>   })
> >>>>>
> >>>>
> >>>> Have you looked at libc-pointer-arith.h?
> >>>
> >>> That was my first approach, by using cast_to_integer macro. I tried to
> >>> change its internals to zero extend pointers correctly, but I couldn't
> >>> find a easier way without also adding the cast point suppression
> >>> warning in this original patch.
> >>
> >> Have you looked at sysdeps/unix/sysv/linux/x86_64/sysdep.h?
> >>
> >
> > /* Create a variable 'name' based on type 'X' to avoid explicit types.
> >    This is mainly used set use 64-bits arguments in x32.   */
> > #define TYPEFY(X, name) __typeof__ ((X) - (X)) name
> > /* Explicit cast the argument to avoid integer from pointer warning on
> >    x32.  */
> > #define ARGIFY(X) ((__typeof__ ((X) - (X))) (X))
> >
>
> Yes, I was the one that actually added them (78ca091cdd2). But for this
> case, the issue is it requires another implicit cast on the
> __syscall_cancel call itself.  The difference here is the call is not
> done through an asm input anymore.

Do you have a git branch I can try?

-- 
H.J.

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

* Re: [PATCH v4 04/21] nptl: x32: Fix Race conditions in pthread cancellation [BZ#12683]
  2020-04-07 13:59                 ` H.J. Lu via Libc-alpha
@ 2020-04-07 14:04                   ` Adhemerval Zanella via Libc-alpha
  2020-04-07 15:45                     ` H.J. Lu via Libc-alpha
  0 siblings, 1 reply; 46+ messages in thread
From: Adhemerval Zanella via Libc-alpha @ 2020-04-07 14:04 UTC (permalink / raw
  To: H.J. Lu; +Cc: GNU C Library, Joseph Myers



On 07/04/2020 10:59, H.J. Lu wrote:
> On Tue, Apr 7, 2020 at 6:55 AM Adhemerval Zanella
> <adhemerval.zanella@linaro.org> wrote:
>>
>>
>>
>> On 07/04/2020 10:41, H.J. Lu wrote:
>>> On Tue, Apr 7, 2020 at 6:40 AM H.J. Lu <hjl.tools@gmail.com> wrote:
>>>>
>>>> On Tue, Apr 7, 2020 at 6:33 AM Adhemerval Zanella
>>>> <adhemerval.zanella@linaro.org> wrote:
>>>>>
>>>>>
>>>>>
>>>>> On 07/04/2020 09:54, H.J. Lu wrote:
>>>>>> On Tue, Apr 7, 2020 at 5:47 AM Adhemerval Zanella via Libc-alpha
>>>>>> <libc-alpha@sourceware.org> wrote:
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>> On 03/04/2020 18:22, Joseph Myers wrote:
>>>>>>>> On Fri, 3 Apr 2020, Adhemerval Zanella via Libc-alpha wrote:
>>>>>>>>
>>>>>>>>> This patches adds the x32 modification required for the BZ#12683.
>>>>>>>>> It follows the x86_64-x32 ABI and pointers are zero-extended.
>>>>>>>>> However, compiler may not see such cases and accuse a cast from pointer
>>>>>>>>> to integer of different size and for such cases the warning is
>>>>>>>>> explict disabled.
>>>>>>>>
>>>>>>>> MIPS n32 uses an intermediate cast to (__typeof__ ((X) - (X))), so that a
>>>>>>>> conversion to a different size is never directly from a pointer type.
>>>>>>>> Does something like that help here to avoid the warning without needing to
>>>>>>>> use diagnostic pragmas?
>>>>>>>
>>>>>>> The intermediate cast to (__typeof__ ((X) - (X))) is not suffice for x32
>>>>>>> (the resulting argumetn it will passed as function argument instead of
>>>>>>> asm input).  I have replaced with:
>>>>>>>
>>>>>>>   #define __SSC(__x)                                              \
>>>>>>>   ({                                                            \
>>>>>>>     __syscall_arg_t __arg = sizeof (1 ? (__x) : 0ULL) < 8       \
>>>>>>>       ? (unsigned long int) (uintptr_t)(__x)                    \
>>>>>>>       : (__syscall_arg_t) (__typeof__ ((__x) - (__x))) (__x);   \
>>>>>>>     __arg;                                                      \
>>>>>>>   })
>>>>>>>
>>>>>>
>>>>>> Have you looked at libc-pointer-arith.h?
>>>>>
>>>>> That was my first approach, by using cast_to_integer macro. I tried to
>>>>> change its internals to zero extend pointers correctly, but I couldn't
>>>>> find a easier way without also adding the cast point suppression
>>>>> warning in this original patch.
>>>>
>>>> Have you looked at sysdeps/unix/sysv/linux/x86_64/sysdep.h?
>>>>
>>>
>>> /* Create a variable 'name' based on type 'X' to avoid explicit types.
>>>    This is mainly used set use 64-bits arguments in x32.   */
>>> #define TYPEFY(X, name) __typeof__ ((X) - (X)) name
>>> /* Explicit cast the argument to avoid integer from pointer warning on
>>>    x32.  */
>>> #define ARGIFY(X) ((__typeof__ ((X) - (X))) (X))
>>>
>>
>> Yes, I was the one that actually added them (78ca091cdd2). But for this
>> case, the issue is it requires another implicit cast on the
>> __syscall_cancel call itself.  The difference here is the call is not
>> done through an asm input anymore.
> 
> Do you have a git branch I can try?
> 

Yes, azanella/bz12683 [1]. I just has it rebased against master.

[1] https://sourceware.org/git/?p=glibc.git;a=shortlog;h=refs/heads/azanella/bz12683

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

* Re: [PATCH v4 01/21] nptl: Do not close the pipe on tst-cancel{2,3}
  2020-04-03 20:31 ` [PATCH v4 01/21] nptl: Do not close the pipe on tst-cancel{2,3} Adhemerval Zanella via Libc-alpha
@ 2020-04-07 15:24   ` Zack Weinberg
  2020-04-07 20:07     ` Adhemerval Zanella via Libc-alpha
  0 siblings, 1 reply; 46+ messages in thread
From: Zack Weinberg @ 2020-04-07 15:24 UTC (permalink / raw
  To: Adhemerval Zanella; +Cc: GNU C Library

On Fri, Apr 3, 2020 at 4:32 PM Adhemerval Zanella via Libc-alpha
<libc-alpha@sourceware.org> wrote:
>
> This can cause a SIGPIPE before SIGCANCEL is processed, which makes
> write fail and the thread return an non expected result.

1) This is a sensible explanation for tst-cancel2.c, but tst-cancel3.c
does a read, not a write; the commit message should explain why this
is an appropriate change for both files.  Something like

# These tests cancel a thread that's supposed to be blocked while
writing or reading from a pipe.  If we close the other end of the
pipe, the closure might be reported to the thread before the
cancellation, causing a spurious failure.

2) The intention of the closes, seems to have been to prevent these
test cases blocking forever in pthread_join if the cancel isn't
delivered.  We don't actually need to do that, because the 20-second
timeout built into the test harness will suffice to make the test fail
in that case, but it might be worth adding a comment somewhere,
explaining that we're relying on the timeout.

3) I think it's no longer necessary to ignore SIGPIPE after this
change, and I think it's no longer necessary to have a loop in 'tf',
please remove that code also.

4) There's still a race in these tests; the cancellation might or
might not yet be pending when the child thread calls read/write.
Abstractly, we should be testing both a cancellation that's already
pending when we reach the cancellation point, and a cancellation
that's delivered while the thread is blocked on I/O.  It's possible to
ensure that the cancellation is already pending with a mutex, e.g.

static pthread_mutex_t prep_gate = PTHREAD_MUTEX_INITIALIZER;
static int fd[2];

static void *
tf (void *arg)
{
  /* The buffer size must be larger than the pipe size so that the
     write blocks.  */
  char buf[100000];

  /* Once we acquire this mutex, a cancellation request will be
     pending for this thread.  (pthread_mutex_(un)lock are not
     cancellation points.)  */
  pthread_mutex_lock (&prep_gate);
  pthread_mutex_unlock (&prep_gate);

  /* This write operation should be immediately cancelled.  */
  write (fd[1], buf, sizeof (buf));

  /* If control reaches this point, the test has failed;
     the parent will detect this.  */
  return arg;
}

static int
do_test (void)
{
  pthread_t th;
  void *r;

  if (pipe (fd) != 0)
    {
      puts ("pipe failed");
      return 1;
    }

  /* The child thread will wait to acquire this mutex.  */
  pthread_mutex_lock (&prep_gate);

  if (pthread_create (&th, NULL, tf, NULL) != 0)
    {
      puts ("create failed");
      return 1;
    }

  if (pthread_cancel (th) != 0)
    {
      puts ("cancel failed");
      return 1;
    }

  pthread_mutex_unlock (&prep_gate);

  // ...
}

But I don't know a good way to _guarantee_ that 'tf' is blocked on
read/write before the parent calls pthread_cancel.   Can you think of
anything?

zw

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

* Re: [PATCH v4 04/21] nptl: x32: Fix Race conditions in pthread cancellation [BZ#12683]
  2020-04-07 14:04                   ` Adhemerval Zanella via Libc-alpha
@ 2020-04-07 15:45                     ` H.J. Lu via Libc-alpha
  2020-04-07 16:16                       ` Adhemerval Zanella via Libc-alpha
  0 siblings, 1 reply; 46+ messages in thread
From: H.J. Lu via Libc-alpha @ 2020-04-07 15:45 UTC (permalink / raw
  To: Adhemerval Zanella; +Cc: GNU C Library, Joseph Myers

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

On Tue, Apr 7, 2020 at 7:04 AM Adhemerval Zanella
<adhemerval.zanella@linaro.org> wrote:
>
>
>
> On 07/04/2020 10:59, H.J. Lu wrote:
> > On Tue, Apr 7, 2020 at 6:55 AM Adhemerval Zanella
> > <adhemerval.zanella@linaro.org> wrote:
> >>
> >>
> >>
> >> On 07/04/2020 10:41, H.J. Lu wrote:
> >>> On Tue, Apr 7, 2020 at 6:40 AM H.J. Lu <hjl.tools@gmail.com> wrote:
> >>>>
> >>>> On Tue, Apr 7, 2020 at 6:33 AM Adhemerval Zanella
> >>>> <adhemerval.zanella@linaro.org> wrote:
> >>>>>
> >>>>>
> >>>>>
> >>>>> On 07/04/2020 09:54, H.J. Lu wrote:
> >>>>>> On Tue, Apr 7, 2020 at 5:47 AM Adhemerval Zanella via Libc-alpha
> >>>>>> <libc-alpha@sourceware.org> wrote:
> >>>>>>>
> >>>>>>>
> >>>>>>>
> >>>>>>> On 03/04/2020 18:22, Joseph Myers wrote:
> >>>>>>>> On Fri, 3 Apr 2020, Adhemerval Zanella via Libc-alpha wrote:
> >>>>>>>>
> >>>>>>>>> This patches adds the x32 modification required for the BZ#12683.
> >>>>>>>>> It follows the x86_64-x32 ABI and pointers are zero-extended.
> >>>>>>>>> However, compiler may not see such cases and accuse a cast from pointer
> >>>>>>>>> to integer of different size and for such cases the warning is
> >>>>>>>>> explict disabled.
> >>>>>>>>
> >>>>>>>> MIPS n32 uses an intermediate cast to (__typeof__ ((X) - (X))), so that a
> >>>>>>>> conversion to a different size is never directly from a pointer type.
> >>>>>>>> Does something like that help here to avoid the warning without needing to
> >>>>>>>> use diagnostic pragmas?
> >>>>>>>
> >>>>>>> The intermediate cast to (__typeof__ ((X) - (X))) is not suffice for x32
> >>>>>>> (the resulting argumetn it will passed as function argument instead of
> >>>>>>> asm input).  I have replaced with:
> >>>>>>>
> >>>>>>>   #define __SSC(__x)                                              \
> >>>>>>>   ({                                                            \
> >>>>>>>     __syscall_arg_t __arg = sizeof (1 ? (__x) : 0ULL) < 8       \
> >>>>>>>       ? (unsigned long int) (uintptr_t)(__x)                    \
> >>>>>>>       : (__syscall_arg_t) (__typeof__ ((__x) - (__x))) (__x);   \
> >>>>>>>     __arg;                                                      \
> >>>>>>>   })
> >>>>>>>
> >>>>>>
> >>>>>> Have you looked at libc-pointer-arith.h?
> >>>>>
> >>>>> That was my first approach, by using cast_to_integer macro. I tried to
> >>>>> change its internals to zero extend pointers correctly, but I couldn't
> >>>>> find a easier way without also adding the cast point suppression
> >>>>> warning in this original patch.
> >>>>
> >>>> Have you looked at sysdeps/unix/sysv/linux/x86_64/sysdep.h?
> >>>>
> >>>
> >>> /* Create a variable 'name' based on type 'X' to avoid explicit types.
> >>>    This is mainly used set use 64-bits arguments in x32.   */
> >>> #define TYPEFY(X, name) __typeof__ ((X) - (X)) name
> >>> /* Explicit cast the argument to avoid integer from pointer warning on
> >>>    x32.  */
> >>> #define ARGIFY(X) ((__typeof__ ((X) - (X))) (X))
> >>>
> >>
> >> Yes, I was the one that actually added them (78ca091cdd2). But for this
> >> case, the issue is it requires another implicit cast on the
> >> __syscall_cancel call itself.  The difference here is the call is not
> >> done through an asm input anymore.
> >
> > Do you have a git branch I can try?
> >
>
> Yes, azanella/bz12683 [1]. I just has it rebased against master.
>
> [1] https://sourceware.org/git/?p=glibc.git;a=shortlog;h=refs/heads/azanella/bz12683

How about these 2 patches?

-- 
H.J.

[-- Attachment #2: 0001-Add-cast_to_unsigned_integer.patch --]
[-- Type: text/x-patch, Size: 2147 bytes --]

From c00e3e1c3dac4bc4cdf70029f1fc2a2f08f133cc Mon Sep 17 00:00:00 2001
From: "H.J. Lu" <hjl.tools@gmail.com>
Date: Tue, 7 Apr 2020 08:40:56 -0700
Subject: [PATCH 1/2] Add cast_to_unsigned_integer

Cast an integer or a pointer VAL to unsigned integer with proper type.
---
 include/libc-pointer-arith.h | 20 ++++++++++++++++----
 1 file changed, 16 insertions(+), 4 deletions(-)

diff --git a/include/libc-pointer-arith.h b/include/libc-pointer-arith.h
index b4d716c727..3468c2f141 100644
--- a/include/libc-pointer-arith.h
+++ b/include/libc-pointer-arith.h
@@ -24,19 +24,31 @@
 /* 1 if 'type' is a pointer type, 0 otherwise.  */
 # 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) \
+/* INTPTR_T if P is true, or T if P is false.  */
+# define __integer_if_pointer_type_sub(T, P, INTPTR_T) \
   __typeof__ (*(0 ? (__typeof__ (0 ? (T *) 0 : (void *) (P))) 0 \
-		  : (__typeof__ (0 ? (intptr_t *) 0 : (void *) (!(P)))) 0))
+		  : (__typeof__ (0 ? (INTPTR_T *) 0 : (void *) (!(P)))) 0))
 
 /* intptr_t if EXPR has a pointer type, or the type of EXPR otherwise.  */
 # define __integer_if_pointer_type(expr) \
   __integer_if_pointer_type_sub(__typeof__ ((__typeof__ (expr)) 0), \
-				__pointer_type (__typeof__ (expr)))
+				__pointer_type (__typeof__ (expr)), \
+				intptr_t)
+
+/* uintptr_t if EXPR has a pointer type, or the type of EXPR otherwise.  */
+# define __unsigned_integer_if_pointer_type(expr) \
+  __integer_if_pointer_type_sub(__typeof__ ((__typeof__ (expr)) 0), \
+				__pointer_type (__typeof__ (expr)), \
+				uintptr_t)
 
 /* Cast an integer or a pointer VAL to integer with proper type.  */
 # define cast_to_integer(val) ((__integer_if_pointer_type (val)) (val))
 
+/* Cast an integer or a pointer VAL to unsigned integer with proper
+   type.  */
+# define cast_to_unsigned_integer(val) \
+  ((__unsigned_integer_if_pointer_type (val)) (val))
+
 /* Align a value by rounding down to closest size.
    e.g. Using size of 4096, we get this behavior:
 	{4095, 4096, 4097} = {0, 4096, 4096}.  */
-- 
2.25.2


[-- Attachment #3: 0002-x32-Use-cast_to_unsigned_integer-for-syscall-argumen.patch --]
[-- Type: text/x-patch, Size: 1238 bytes --]

From ffb514575f5689a871575847702b6e7a02e1b632 Mon Sep 17 00:00:00 2001
From: "H.J. Lu" <hjl.tools@gmail.com>
Date: Tue, 7 Apr 2020 08:43:20 -0700
Subject: [PATCH 2/2] x32: Use cast_to_unsigned_integer for syscall arguments

---
 sysdeps/unix/sysv/linux/x86_64/x32/syscall_types.h | 10 ++--------
 1 file changed, 2 insertions(+), 8 deletions(-)

diff --git a/sysdeps/unix/sysv/linux/x86_64/x32/syscall_types.h b/sysdeps/unix/sysv/linux/x86_64/x32/syscall_types.h
index fd9f14d566..b85c85b713 100644
--- a/sysdeps/unix/sysv/linux/x86_64/x32/syscall_types.h
+++ b/sysdeps/unix/sysv/linux/x86_64/x32/syscall_types.h
@@ -19,18 +19,12 @@
 #ifndef _SYSCALL_TYPES_H
 #define _SYSCALL_TYPES_H
 
-#include <libc-diag.h>
+#include <libc-pointer-arith.h>
 
 typedef long long int __syscall_arg_t;
 
 /* Syscall arguments for x32 follows x86_64 ABI, however pointers are 32 bits
    should be zero extended.  */
-#define __SSC(__x)						\
-  ({								\
-    __syscall_arg_t __arg = sizeof (1 ? (__x) : 0ULL) < 8	\
-      ? (unsigned long int) (uintptr_t)(__x) 			\
-      : (__syscall_arg_t) (__typeof__ ((__x) - (__x))) (__x);	\
-    __arg;							\
-  })
+#define __SSC(__x) ((__syscall_arg_t) cast_to_unsigned_integer (__x))
 
 #endif
-- 
2.25.2


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

* Re: [PATCH v4 04/21] nptl: x32: Fix Race conditions in pthread cancellation [BZ#12683]
  2020-04-07 15:45                     ` H.J. Lu via Libc-alpha
@ 2020-04-07 16:16                       ` Adhemerval Zanella via Libc-alpha
  0 siblings, 0 replies; 46+ messages in thread
From: Adhemerval Zanella via Libc-alpha @ 2020-04-07 16:16 UTC (permalink / raw
  To: H.J. Lu; +Cc: GNU C Library, Joseph Myers



On 07/04/2020 12:45, H.J. Lu wrote:
> On Tue, Apr 7, 2020 at 7:04 AM Adhemerval Zanella
> <adhemerval.zanella@linaro.org> wrote:
>>
>>
>>
>> On 07/04/2020 10:59, H.J. Lu wrote:
>>> On Tue, Apr 7, 2020 at 6:55 AM Adhemerval Zanella
>>> <adhemerval.zanella@linaro.org> wrote:
>>>>
>>>>
>>>>
>>>> On 07/04/2020 10:41, H.J. Lu wrote:
>>>>> On Tue, Apr 7, 2020 at 6:40 AM H.J. Lu <hjl.tools@gmail.com> wrote:
>>>>>>
>>>>>> On Tue, Apr 7, 2020 at 6:33 AM Adhemerval Zanella
>>>>>> <adhemerval.zanella@linaro.org> wrote:
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>> On 07/04/2020 09:54, H.J. Lu wrote:
>>>>>>>> On Tue, Apr 7, 2020 at 5:47 AM Adhemerval Zanella via Libc-alpha
>>>>>>>> <libc-alpha@sourceware.org> wrote:
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> On 03/04/2020 18:22, Joseph Myers wrote:
>>>>>>>>>> On Fri, 3 Apr 2020, Adhemerval Zanella via Libc-alpha wrote:
>>>>>>>>>>
>>>>>>>>>>> This patches adds the x32 modification required for the BZ#12683.
>>>>>>>>>>> It follows the x86_64-x32 ABI and pointers are zero-extended.
>>>>>>>>>>> However, compiler may not see such cases and accuse a cast from pointer
>>>>>>>>>>> to integer of different size and for such cases the warning is
>>>>>>>>>>> explict disabled.
>>>>>>>>>>
>>>>>>>>>> MIPS n32 uses an intermediate cast to (__typeof__ ((X) - (X))), so that a
>>>>>>>>>> conversion to a different size is never directly from a pointer type.
>>>>>>>>>> Does something like that help here to avoid the warning without needing to
>>>>>>>>>> use diagnostic pragmas?
>>>>>>>>>
>>>>>>>>> The intermediate cast to (__typeof__ ((X) - (X))) is not suffice for x32
>>>>>>>>> (the resulting argumetn it will passed as function argument instead of
>>>>>>>>> asm input).  I have replaced with:
>>>>>>>>>
>>>>>>>>>   #define __SSC(__x)                                              \
>>>>>>>>>   ({                                                            \
>>>>>>>>>     __syscall_arg_t __arg = sizeof (1 ? (__x) : 0ULL) < 8       \
>>>>>>>>>       ? (unsigned long int) (uintptr_t)(__x)                    \
>>>>>>>>>       : (__syscall_arg_t) (__typeof__ ((__x) - (__x))) (__x);   \
>>>>>>>>>     __arg;                                                      \
>>>>>>>>>   })
>>>>>>>>>
>>>>>>>>
>>>>>>>> Have you looked at libc-pointer-arith.h?
>>>>>>>
>>>>>>> That was my first approach, by using cast_to_integer macro. I tried to
>>>>>>> change its internals to zero extend pointers correctly, but I couldn't
>>>>>>> find a easier way without also adding the cast point suppression
>>>>>>> warning in this original patch.
>>>>>>
>>>>>> Have you looked at sysdeps/unix/sysv/linux/x86_64/sysdep.h?
>>>>>>
>>>>>
>>>>> /* Create a variable 'name' based on type 'X' to avoid explicit types.
>>>>>    This is mainly used set use 64-bits arguments in x32.   */
>>>>> #define TYPEFY(X, name) __typeof__ ((X) - (X)) name
>>>>> /* Explicit cast the argument to avoid integer from pointer warning on
>>>>>    x32.  */
>>>>> #define ARGIFY(X) ((__typeof__ ((X) - (X))) (X))
>>>>>
>>>>
>>>> Yes, I was the one that actually added them (78ca091cdd2). But for this
>>>> case, the issue is it requires another implicit cast on the
>>>> __syscall_cancel call itself.  The difference here is the call is not
>>>> done through an asm input anymore.
>>>
>>> Do you have a git branch I can try?
>>>
>>
>> Yes, azanella/bz12683 [1]. I just has it rebased against master.
>>
>> [1] https://sourceware.org/git/?p=glibc.git;a=shortlog;h=refs/heads/azanella/bz12683
> 
> How about these 2 patches?
> 

OK, I would assume libc-pointer-arith.h is a preferable solution.
Coincidently it is essentially the same strategy I used sometime
ago [1], but I don't recall exactly why I have abandoned it.

I have used you suggestion, thanks.

[1] https://sourceware.org/legacy-ml/libc-alpha/2017-12/msg00315.html

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

* Re: [PATCH v4 02/21] nptl: Fix Race conditions in pthread cancellation [BZ#12683]
  2020-04-03 20:31 ` [PATCH v4 02/21] nptl: Fix Race conditions in pthread cancellation [BZ#12683] Adhemerval Zanella via Libc-alpha
@ 2020-04-07 18:24   ` Zack Weinberg
  2020-04-08 14:13     ` Adhemerval Zanella via Libc-alpha
  0 siblings, 1 reply; 46+ messages in thread
From: Zack Weinberg @ 2020-04-07 18:24 UTC (permalink / raw
  To: Adhemerval Zanella; +Cc: GNU C Library

On Fri, Apr 3, 2020 at 4:32 PM Adhemerval Zanella via Libc-alpha
<libc-alpha@sourceware.org> wrote:
>
> This patch is the initial fix for race conditions in NPTL cancellation
> code by redefining how cancellable syscalls are defined and handled.
> The current buggy approach is to enable asynchronous cancellation
> before making the syscall and restore the previous cancellation
> type once the syscall returns.

I want to see this bug fixed.  Unfortunately I don't know the guts of
NPTL well enough to review your patches completely, but here are a few
things I noticed:

> 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).

Can we be absolutely certain that SIGCANCEL/SIGTIMER will always be
sent to a specific thread and not to a process?

> +  /* Add SIGCANCEL on ignored sigmask to avoid the handler to be called
> +     again.  */
> +  ucontext_block_sigcancel (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->canceltype == PTHREAD_CANCEL_ASYNCHRONOUS
> +      || cancellation_pc_check (ctx))
> +    __do_cancel (PTHREAD_CANCELED);

Shouldn't this check happen _before_ we block further SIGCANCELs?
If cancellation_pc_check fails, because the signal was delivered on
exit from a system call that has had side effects, don't we need to
be able to receive future SIGCANCELs in order for the next cancellation
point to trigger?

>    /* 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.  */

1) I think the third sentence of this comment has always been wrong.
2) Perhaps, if we cannot install a handler for SIGCANCEL, we should set
   a global flag which causes all calls to pthread_cancel to fail?

> +    /* Install the handle to change the threads' uid/gid.  */

Typo: handle -> handler (it was wrong before, but you may as well fix it)

> +    struct sigaction sa;
> +    __sigemptyset (&sa.sa_mask);
> +    sa.sa_sigaction = sighandler_setxid;
> +    sa.sa_flags = SA_SIGINFO | SA_RESTART;
> +    __libc_sigaction (SIGSETXID, &sa, NULL);

Unrelated preexisting bug, but I think we probably _should_ crash the
whole process if the SIGSETXID handler cannot be installed,
particularly when __libc_enable_secure is true.

> +  /* Avoid signaling when thread attempts cancel itself (pthread_kill
> +     is expensive).  */
> +  if (pd == THREAD_SELF)
> +    {
> +      if (pd->cancelstate == PTHREAD_CANCEL_ENABLE
> +         && pd->canceltype == PTHREAD_CANCEL_ASYNCHRONOUS)
> +       __pthread_exit (PTHREAD_CANCELED);
> +      return 0;

This works because __pthread_exit is actually a tiny wrapper around
__do_cancel, but I think the logic would be easier to understand,
here, if it called __do_cancel.

zw

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

* Re: [PATCH v4 01/21] nptl: Do not close the pipe on tst-cancel{2,3}
  2020-04-07 15:24   ` Zack Weinberg
@ 2020-04-07 20:07     ` Adhemerval Zanella via Libc-alpha
  0 siblings, 0 replies; 46+ messages in thread
From: Adhemerval Zanella via Libc-alpha @ 2020-04-07 20:07 UTC (permalink / raw
  To: Zack Weinberg; +Cc: GNU C Library



On 07/04/2020 12:24, Zack Weinberg wrote:
> On Fri, Apr 3, 2020 at 4:32 PM Adhemerval Zanella via Libc-alpha
> <libc-alpha@sourceware.org> wrote:
>>
>> This can cause a SIGPIPE before SIGCANCEL is processed, which makes
>> write fail and the thread return an non expected result.
> 
> 1) This is a sensible explanation for tst-cancel2.c, but tst-cancel3.c
> does a read, not a write; the commit message should explain why this
> is an appropriate change for both files.  Something like
> 
> # These tests cancel a thread that's supposed to be blocked while
> writing or reading from a pipe.  If we close the other end of the
> pipe, the closure might be reported to the thread before the
> cancellation, causing a spurious failure.

Either a read or write exercises the same issue, but I agree that
the commit message could be more comprehensive. I have added your
suggestion.

> 
> 2) The intention of the closes, seems to have been to prevent these
> test cases blocking forever in pthread_join if the cancel isn't
> delivered.  We don't actually need to do that, because the 20-second
> timeout built into the test harness will suffice to make the test fail
> in that case, but it might be worth adding a comment somewhere,
> explaining that we're relying on the timeout.

I am not sure if the close is indeed to prevent it, if the 
pthread_cancel does not cancel the thread the test will be stuck
regardless.

> 
> 3) I think it's no longer necessary to ignore SIGPIPE after this
> change, and I think it's no longer necessary to have a loop in 'tf',
> please remove that code also.

Ack.

> 
> 4) There's still a race in these tests; the cancellation might or
> might not yet be pending when the child thread calls read/write.
> Abstractly, we should be testing both a cancellation that's already
> pending when we reach the cancellation point, and a cancellation
> that's delivered while the thread is blocked on I/O.  It's possible to
> ensure that the cancellation is already pending with a mutex, e.g.

Indeed it is not intent of the patch to actually fix this race,
but I also agree that this is an opportunity to do so.

> 
> static pthread_mutex_t prep_gate = PTHREAD_MUTEX_INITIALIZER;
> static int fd[2];
> 
> static void *
> tf (void *arg)
> {
>   /* The buffer size must be larger than the pipe size so that the
>      write blocks.  */
>   char buf[100000];
> 
>   /* Once we acquire this mutex, a cancellation request will be
>      pending for this thread.  (pthread_mutex_(un)lock are not
>      cancellation points.)  */
>   pthread_mutex_lock (&prep_gate);
>   pthread_mutex_unlock (&prep_gate);
> 
>   /* This write operation should be immediately cancelled.  */
>   write (fd[1], buf, sizeof (buf));
> 
>   /* If control reaches this point, the test has failed;
>      the parent will detect this.  */
>   return arg;
> }
> 
> static int
> do_test (void)
> {
>   pthread_t th;
>   void *r;
> 
>   if (pipe (fd) != 0)
>     {
>       puts ("pipe failed");
>       return 1;
>     }
> 
>   /* The child thread will wait to acquire this mutex.  */
>   pthread_mutex_lock (&prep_gate);
> 
>   if (pthread_create (&th, NULL, tf, NULL) != 0)
>     {
>       puts ("create failed");
>       return 1;
>     }
> 
>   if (pthread_cancel (th) != 0)
>     {
>       puts ("cancel failed");
>       return 1;
>     }
> 
>   pthread_mutex_unlock (&prep_gate);
> 
>   // ...
> }
> 
> But I don't know a good way to _guarantee_ that 'tf' is blocked on
> read/write before the parent calls pthread_cancel.   Can you think of
> anything?
> 
> zw

I think we cance use the support_process_state_wait on the thread ID 
and check for support_process_state_sleeping (meaning that the process is
blocked on the syscall).

For the write operation with new cancellation it might require a second
write to actually acts on the pending cancellation (since kernel might
write some partial data on internal pipe buffer since it is larger 
than PIPE_BUF).

Update patch based in your comments below.

--

nptl: Do not close the pipe on tst-cancel{2,3}

These tests cancel a thread that is supposed to be blocked while
writing or reading from a pipe.  If we close the other end of the
pipe, the closure might be reported to the thread before the
cancellation, causing a spurious failure.

For the write operation, pthread_cancel might not act on the call
since kernel might write some partial data on pipe internal buffer.
This requires a second write call to act on pending cancellation.

Also, to avoid a race between pthread_cancel and the read/write
operation the master thread wait the target thread reach a sleeping
state prior starting the cancellation.

Checked on x86_64-linux-gnu and powerpc64le-linux-gnu.
---
 nptl/tst-cancel2.c | 89 ++++++++++++++++++++--------------------------
 nptl/tst-cancel3.c | 83 +++++++++++++++---------------------------
 2 files changed, 68 insertions(+), 104 deletions(-)

diff --git a/nptl/tst-cancel2.c b/nptl/tst-cancel2.c
index 1e86711596..860085c1f9 100644
--- a/nptl/tst-cancel2.c
+++ b/nptl/tst-cancel2.c
@@ -18,21 +18,39 @@
 
 #include <pthread.h>
 #include <signal.h>
-#include <stdio.h>
-#include <unistd.h>
+#include <fcntl.h>
 
+#include <support/xunistd.h>
+#include <support/xthread.h>
+#include <support/check.h>
+#include <support/process_state.h>
 
+
+/* The pipe will be used pass the thread TID to master thread.  */
+static int tidfd[2];
+/* The pipe will be used to check the cancellation.  */
 static int fd[2];
 
 
 static void *
 tf (void *arg)
 {
+  int pipesz = fcntl(fd[1], F_GETPIPE_SZ);
+  TEST_VERIFY (pipesz != -1);
+
+  pid_t tid = gettid ();
+  TEST_COMPARE (write (tidfd[1], &tid, sizeof (tid)), sizeof (tid));
+
   /* The buffer size must be larger than the pipe size so that the
      write blocks.  */
-  char buf[100000];
+  char buf[pipesz + 1];
 
-  while (write (fd[1], buf, sizeof (buf)) > 0);
+  /* When cancellation acts, first write might return if kernel fill
+     the socket buffer with partial data.  */
+  TEST_COMPARE (write (fd[1], buf, sizeof (buf)), pipesz);
+
+  /* This will act on the pending cancellation.  */
+  write (fd[1], buf, sizeof (buf));
 
   return (void *) 42l;
 }
@@ -43,53 +61,24 @@ do_test (void)
 {
   pthread_t th;
   void *r;
-  struct sigaction sa;
-
-  sa.sa_handler = SIG_IGN;
-  sigemptyset (&sa.sa_mask);
-  sa.sa_flags = 0;
-
-  if (sigaction (SIGPIPE, &sa, NULL) != 0)
-    {
-      puts ("sigaction failed");
-      return 1;
-    }
-
-  if (pipe (fd) != 0)
-    {
-      puts ("pipe failed");
-      return 1;
-    }
-
-  if (pthread_create (&th, NULL, tf, NULL) != 0)
-    {
-      puts ("create failed");
-      return 1;
-    }
-
-  if (pthread_cancel (th) != 0)
-    {
-      puts ("cancel failed");
-      return 1;
-    }
-
-  /* This will cause the write in the child to return.  */
-  close (fd[0]);
-
-  if (pthread_join (th, &r) != 0)
-    {
-      puts ("join failed");
-      return 1;
-    }
-
-  if (r != PTHREAD_CANCELED)
-    {
-      printf ("result is wrong: expected %p, got %p\n", PTHREAD_CANCELED, r);
-      return 1;
-    }
+
+  xpipe (tidfd);
+  xpipe (fd);
+
+  th = xpthread_create (NULL, tf, NULL);
+
+  pid_t tid;
+  TEST_COMPARE (read (tidfd[0], &tid, sizeof (tid)), sizeof (tid));
+
+  support_process_state_wait (tid, support_process_state_sleeping);
+
+  xpthread_cancel (th);
+
+  r = xpthread_join (th);
+
+  TEST_VERIFY (r == PTHREAD_CANCELED);
 
   return 0;
 }
 
-#define TEST_FUNCTION do_test ()
-#include "../test-skeleton.c"
+#include <support/test-driver.c>
diff --git a/nptl/tst-cancel3.c b/nptl/tst-cancel3.c
index 0a531dbcdb..cf810aef09 100644
--- a/nptl/tst-cancel3.c
+++ b/nptl/tst-cancel3.c
@@ -18,23 +18,27 @@
 
 #include <pthread.h>
 #include <signal.h>
-#include <stdio.h>
-#include <unistd.h>
 
+#include <support/xunistd.h>
+#include <support/xthread.h>
+#include <support/check.h>
+#include <support/process_state.h>
 
+
+/* The pipe will be used pass the thread TID to master thread.  */
+static int tidfd[2];
+/* The pipe will be used to check the cancellation.  */
 static int fd[2];
 
 
 static void *
 tf (void *arg)
 {
-  char buf[100];
+  pid_t tid = gettid ();
+  TEST_COMPARE (write (tidfd[1], &tid, sizeof (tid)), sizeof (tid));
 
-  if (read (fd[0], buf, sizeof (buf)) == sizeof (buf))
-    {
-      puts ("read succeeded");
-      return (void *) 1l;
-    }
+  char buf[100];
+  read (fd[0], buf, sizeof (buf));
 
   return NULL;
 }
@@ -45,53 +49,24 @@ do_test (void)
 {
   pthread_t th;
   void *r;
-  struct sigaction sa;
-
-  sa.sa_handler = SIG_IGN;
-  sigemptyset (&sa.sa_mask);
-  sa.sa_flags = 0;
-
-  if (sigaction (SIGPIPE, &sa, NULL) != 0)
-    {
-      puts ("sigaction failed");
-      return 1;
-    }
-
-  if (pipe (fd) != 0)
-    {
-      puts ("pipe failed");
-      return 1;
-    }
-
-  if (pthread_create (&th, NULL, tf, NULL) != 0)
-    {
-      puts ("create failed");
-      return 1;
-    }
-
-  if (pthread_cancel (th) != 0)
-    {
-      puts ("cancel failed");
-      return 1;
-    }
-
-  /* This will cause the read in the child to return.  */
-  close (fd[0]);
-
-  if (pthread_join (th, &r) != 0)
-    {
-      puts ("join failed");
-      return 1;
-    }
-
-  if (r != PTHREAD_CANCELED)
-    {
-      puts ("result is wrong");
-      return 1;
-    }
+
+  xpipe (tidfd);
+  xpipe (fd);
+
+  th = xpthread_create (NULL, tf, NULL);
+
+  pid_t tid;
+  TEST_COMPARE (read (tidfd[0], &tid, sizeof (tid)), sizeof (tid));
+
+  support_process_state_wait (tid, support_process_state_sleeping);
+
+  xpthread_cancel (th);
+
+  r = xpthread_join (th);
+
+  TEST_VERIFY (r == PTHREAD_CANCELED);
 
   return 0;
 }
 
-#define TEST_FUNCTION do_test ()
-#include "../test-skeleton.c"
+#include <support/test-driver.c>

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

* Re: [PATCH v4 02/21] nptl: Fix Race conditions in pthread cancellation [BZ#12683]
  2020-04-07 18:24   ` Zack Weinberg
@ 2020-04-08 14:13     ` Adhemerval Zanella via Libc-alpha
  0 siblings, 0 replies; 46+ messages in thread
From: Adhemerval Zanella via Libc-alpha @ 2020-04-08 14:13 UTC (permalink / raw
  To: Zack Weinberg; +Cc: GNU C Library



On 07/04/2020 15:24, Zack Weinberg wrote:
> On Fri, Apr 3, 2020 at 4:32 PM Adhemerval Zanella via Libc-alpha
> <libc-alpha@sourceware.org> wrote:
>>
>> This patch is the initial fix for race conditions in NPTL cancellation
>> code by redefining how cancellable syscalls are defined and handled.
>> The current buggy approach is to enable asynchronous cancellation
>> before making the syscall and restore the previous cancellation
>> type once the syscall returns.
> 
> I want to see this bug fixed.  Unfortunately I don't know the guts of
> NPTL well enough to review your patches completely, but here are a few
> things I noticed:

Thanks.

> 
>> 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).
> 
> Can we be absolutely certain that SIGCANCEL/SIGTIMER will always be
> sent to a specific thread and not to a process?

With this patch pthread_cancel calls __pthread_kill_internal and
in turn it will use tgkill with process's pid and struct pthread tid.

And Linux timer_create does use the helper thread tid as the target one
(line 148).

> 
>> +  /* Add SIGCANCEL on ignored sigmask to avoid the handler to be called
>> +     again.  */
>> +  ucontext_block_sigcancel (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->canceltype == PTHREAD_CANCEL_ASYNCHRONOUS
>> +      || cancellation_pc_check (ctx))
>> +    __do_cancel (PTHREAD_CANCELED);
> 
> Shouldn't this check happen _before_ we block further SIGCANCELs?
> If cancellation_pc_check fails, because the signal was delivered on
> exit from a system call that has had side effects, don't we need to
> be able to receive future SIGCANCELs in order for the next cancellation
> point to trigger?

For this case the cancellation will happen on next cancellation entrypoint
since pthread_cancel has already set the CANCELED_BIT on the target 
struct pthread cancelhandling member and it will be checked on every 
cancellation entrypoint prior issuing the syscall.

> 
>>    /* 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.  */
> 
> 1) I think the third sentence of this comment has always been wrong.
> 2) Perhaps, if we cannot install a handler for SIGCANCEL, we should set
>    a global flag which causes all calls to pthread_cancel to fail?
> 

The cases I see it might fail are if kernel or some filter (seccomp, bpf,
etc.) explicit disables it. And I am not sure if is up to glibc to actually
handle it, since it would require to:

  1. Set a global flag stating that *asynchronous* thread cancellation is
     not supported at runtime, as you noted.

  2. The pthread_setcanceltype should the check this flag and fail for 
     PTHREAD_CANCEL_ASYNCHRONOUS.

  3. We will need to adjust the code on thread start (START_THREAD_DEFN)
     which set PTHREAD_CANCEL_ASYNCHRONOUS (and as Florian noted, this
     code might be unnecessary).

  4. We will also need to adjust on how to handle
     pthread_cleanup_push_defer_np since __pthread_register_cancel_defer
     also set and reset cancellation type to PTHREAD_CANCEL_ASYNCHRONOUS.

So I am not sure which would be better: 

  1. Do nothing (currently).

  2. Abort in case of an handler installation error.

  3. Disable asynchronous cancellation at runtime.

In any case I think we should discuss in in another thread.

>> +    /* Install the handle to change the threads' uid/gid.  */
> 
> Typo: handle -> handler (it was wrong before, but you may as well fix it)

Ack.

> 
>> +    struct sigaction sa;
>> +    __sigemptyset (&sa.sa_mask);
>> +    sa.sa_sigaction = sighandler_setxid;
>> +    sa.sa_flags = SA_SIGINFO | SA_RESTART;
>> +    __libc_sigaction (SIGSETXID, &sa, NULL);
> 
> Unrelated preexisting bug, but I think we probably _should_ crash the
> whole process if the SIGSETXID handler cannot be installed,
> particularly when __libc_enable_secure is true.

I tend to agree, but is there a real scenario where sigaction syscall
might fail here?

> 
>> +  /* Avoid signaling when thread attempts cancel itself (pthread_kill
>> +     is expensive).  */
>> +  if (pd == THREAD_SELF)
>> +    {
>> +      if (pd->cancelstate == PTHREAD_CANCEL_ENABLE
>> +         && pd->canceltype == PTHREAD_CANCEL_ASYNCHRONOUS)
>> +       __pthread_exit (PTHREAD_CANCELED);
>> +      return 0;
> 
> This works because __pthread_exit is actually a tiny wrapper around
> __do_cancel, but I think the logic would be easier to understand,
> here, if it called __do_cancel.

The idea is eventually just remove __do_cancel and use __pthread_exit
instead internally.  I didn't do it on this patch because it would 
require first to move __pthread_exit to libc.so.

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

* Re: [PATCH v4 08/21] nptl: aarch64: Fix Race conditions in pthread cancellation [BZ#12683]
  2020-04-03 20:31 ` [PATCH v4 08/21] nptl: aarch64: " Adhemerval Zanella via Libc-alpha
@ 2020-04-12 15:29   ` Stepan Golosunov
  2020-04-15 14:30     ` Adhemerval Zanella via Libc-alpha
  0 siblings, 1 reply; 46+ messages in thread
From: Stepan Golosunov @ 2020-04-12 15:29 UTC (permalink / raw
  To: Adhemerval Zanella; +Cc: libc-alpha

03.04.2020 в 17:31:48 -0300 Adhemerval Zanella написал:
> 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.
> ---
>  sysdeps/aarch64/nptl/tcb-offsets.sym          |  3 +
>  .../unix/sysv/linux/aarch64/syscall_cancel.S  | 59 +++++++++++++++++++
>  2 files changed, 62 insertions(+)
>  create mode 100644 sysdeps/unix/sysv/linux/aarch64/syscall_cancel.S

> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/aarch64/syscall_cancel.S
> @@ -0,0 +1,59 @@
> +/* Cancellable syscall wrapper.  Linux/AArch64 version.
> +   Copyright (C) 2020 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])  */

Looks like this comment was copypasted from 32-bit arm.  Texts in
square brackets obviously do not correspond to reality.  Starting
from the fact that they imply that sizeof (long int) == 4.

> +
> +ENTRY (__syscall_cancel_arch)
> +
> +	.globl __syscall_cancel_arch_start
> +__syscall_cancel_arch_start:
> +
> +	/* if (*cancelhandling & CANCELED_BITMASK)
> +	     __syscall_do_cancel()  */
> +	ldr	w0, [x0]
> +	tbnz    w0, TCB_CANCELED_BIT, 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
> +__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] 46+ messages in thread

* Re: [PATCH v4 12/21] nptl: sparc: Fix Race conditions in pthread cancellation [BZ#12683]
  2020-04-03 20:31 ` [PATCH v4 12/21] nptl: sparc: " Adhemerval Zanella via Libc-alpha
@ 2020-04-12 15:33   ` Stepan Golosunov
  2020-04-14 16:54     ` Stepan Golosunov
  0 siblings, 1 reply; 46+ messages in thread
From: Stepan Golosunov @ 2020-04-12 15:33 UTC (permalink / raw
  To: Adhemerval Zanella; +Cc: libc-alpha

03.04.2020 в 17:31:52 -0300 Adhemerval Zanella написал:
> 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.

s/ppool/ppoll/

> 
> Checked on sparc64-linux-gnu and sparcv9-linux-gnu.
> 
> [1] https://www.spinics.net/lists/sparclinux/msg05037.html
> ---
>  sysdeps/sparc/nptl/tcb-offsets.sym            |  3 +
>  .../sysv/linux/sparc/cancellation-sigmask.h   | 39 ++++++++++
>  .../sysv/linux/sparc/sparc32/syscall_cancel.S | 71 ++++++++++++++++++
>  sysdeps/unix/sysv/linux/sparc/sparc64/pause.c | 25 +++++++
>  .../sysv/linux/sparc/sparc64/syscall_cancel.S | 74 +++++++++++++++++++
>  5 files changed, 212 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

> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/sparc/sparc64/pause.c
> @@ -0,0 +1,25 @@
> +/* Linux pause syscall implementation.  Linux/sparc64.
> +   Copyright (C) 2020 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.  */

ditto

> +#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

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

* Re: [PATCH v4 14/21] nptl: m68k: Fix Race conditions in pthread cancellation [BZ#12683]
  2020-04-03 20:31 ` [PATCH v4 14/21] nptl: m68k: " Adhemerval Zanella via Libc-alpha
  2020-04-03 21:34   ` Andreas Schwab
@ 2020-04-12 15:42   ` Stepan Golosunov
  2020-04-15 14:51     ` Adhemerval Zanella via Libc-alpha
  1 sibling, 1 reply; 46+ messages in thread
From: Stepan Golosunov @ 2020-04-12 15:42 UTC (permalink / raw
  To: Adhemerval Zanella; +Cc: libc-alpha

03.04.2020 в 17:31:54 -0300 Adhemerval Zanella написал:
> This patch adds the m68k modifications required for the BZ#12683 fix
> by adding the arch-specific cancellation syscall bridge.
> 
> Checked on m68k-linux-gnu.
> ---
>  sysdeps/m68k/nptl/tcb-offsets.sym             |  3 +
>  sysdeps/unix/sysv/linux/m68k/syscall_cancel.S | 85 +++++++++++++++++++
>  2 files changed, 88 insertions(+)
>  create mode 100644 sysdeps/unix/sysv/linux/m68k/syscall_cancel.S

> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/m68k/syscall_cancel.S
> @@ -0,0 +1,85 @@
> +/* Cancellable syscall wrapper.  Linux/m68k version.
> +   Copyright (C) 2020 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)  */

Is #define for HAVE_CANCELABLE_SYSCALL_WITH_7_ARGS missing?
More likely the comment is wrong though.
Same issue in the alpha patch.

> +
> +
> +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
> +__syscall_cancel_arch_start:
> +
> +	move.l	20(%sp),%a0
> +	move.l	(%a0),%d0
> +#ifdef __mcoldfire__
> +	move.w	%d0,%ccr
> +	jeq	1f
> +#else
> +	btst	#TCB_CANCELED_BIT,%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
> +__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)

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

* Re: [PATCH v4 12/21] nptl: sparc: Fix Race conditions in pthread cancellation [BZ#12683]
  2020-04-12 15:33   ` Stepan Golosunov
@ 2020-04-14 16:54     ` Stepan Golosunov
  2020-04-15 14:48       ` Adhemerval Zanella via Libc-alpha
  0 siblings, 1 reply; 46+ messages in thread
From: Stepan Golosunov @ 2020-04-14 16:54 UTC (permalink / raw
  To: Adhemerval Zanella; +Cc: libc-alpha

12.04.2020 в 19:33:21 +0400 Stepan Golosunov написал:
> 03.04.2020 в 17:31:52 -0300 Adhemerval Zanella написал:
> > 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.
> 
> s/ppool/ppoll/
> 
> > 
> > Checked on sparc64-linux-gnu and sparcv9-linux-gnu.
> > 
> > [1] https://www.spinics.net/lists/sparclinux/msg05037.html
> > ---
> >  sysdeps/sparc/nptl/tcb-offsets.sym            |  3 +
> >  .../sysv/linux/sparc/cancellation-sigmask.h   | 39 ++++++++++
> >  .../sysv/linux/sparc/sparc32/syscall_cancel.S | 71 ++++++++++++++++++
> >  sysdeps/unix/sysv/linux/sparc/sparc64/pause.c | 25 +++++++
> >  .../sysv/linux/sparc/sparc64/syscall_cancel.S | 74 +++++++++++++++++++
> >  5 files changed, 212 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
> 
> > --- /dev/null
> > +++ b/sysdeps/unix/sysv/linux/sparc/sparc64/pause.c
> > @@ -0,0 +1,25 @@
> > +/* Linux pause syscall implementation.  Linux/sparc64.
> > +   Copyright (C) 2020 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.  */
> 
> ditto
> 
> > +#undef __NR_pause
> > +#include <sysdeps/unix/sysv/linux/pause.c>

But sysdeps/unix/sysv/linux/sparc/kernel-features.h already contains

#ifdef __arch64__
/* sparc64 defines __NR_pause,  however it is not supported (ENOSYS).
   Undefine so pause.c can use a correct alternative.  */
# undef __NR_pause
#endif

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

* Re: [PATCH v4 08/21] nptl: aarch64: Fix Race conditions in pthread cancellation [BZ#12683]
  2020-04-12 15:29   ` Stepan Golosunov
@ 2020-04-15 14:30     ` Adhemerval Zanella via Libc-alpha
  0 siblings, 0 replies; 46+ messages in thread
From: Adhemerval Zanella via Libc-alpha @ 2020-04-15 14:30 UTC (permalink / raw
  To: Stepan Golosunov; +Cc: libc-alpha



On 12/04/2020 12:29, Stepan Golosunov wrote:
> 03.04.2020 в 17:31:48 -0300 Adhemerval Zanella написал:
>> 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.
>> ---
>>  sysdeps/aarch64/nptl/tcb-offsets.sym          |  3 +
>>  .../unix/sysv/linux/aarch64/syscall_cancel.S  | 59 +++++++++++++++++++
>>  2 files changed, 62 insertions(+)
>>  create mode 100644 sysdeps/unix/sysv/linux/aarch64/syscall_cancel.S
> 
>> --- /dev/null
>> +++ b/sysdeps/unix/sysv/linux/aarch64/syscall_cancel.S
>> @@ -0,0 +1,59 @@
>> +/* Cancellable syscall wrapper.  Linux/AArch64 version.
>> +   Copyright (C) 2020 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])  */
> 
> Looks like this comment was copypasted from 32-bit arm.  Texts in
> square brackets obviously do not correspond to reality.  Starting
> from the fact that they imply that sizeof (long int) == 4.

Ack, I have fixed the comment to the expected aarch64 ABI.  Thanks
for spotting it.

> 
>> +
>> +ENTRY (__syscall_cancel_arch)
>> +
>> +	.globl __syscall_cancel_arch_start
>> +__syscall_cancel_arch_start:
>> +
>> +	/* if (*cancelhandling & CANCELED_BITMASK)
>> +	     __syscall_do_cancel()  */
>> +	ldr	w0, [x0]
>> +	tbnz    w0, TCB_CANCELED_BIT, 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
>> +__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] 46+ messages in thread

* Re: [PATCH v4 12/21] nptl: sparc: Fix Race conditions in pthread cancellation [BZ#12683]
  2020-04-14 16:54     ` Stepan Golosunov
@ 2020-04-15 14:48       ` Adhemerval Zanella via Libc-alpha
  0 siblings, 0 replies; 46+ messages in thread
From: Adhemerval Zanella via Libc-alpha @ 2020-04-15 14:48 UTC (permalink / raw
  To: Stepan Golosunov; +Cc: libc-alpha



On 14/04/2020 13:54, Stepan Golosunov wrote:
> 12.04.2020 в 19:33:21 +0400 Stepan Golosunov написал:
>> 03.04.2020 в 17:31:52 -0300 Adhemerval Zanella написал:
>>> 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.
>>
>> s/ppool/ppoll/
>>
>>>
>>> Checked on sparc64-linux-gnu and sparcv9-linux-gnu.
>>>
>>> [1] https://www.spinics.net/lists/sparclinux/msg05037.html
>>> ---
>>>  sysdeps/sparc/nptl/tcb-offsets.sym            |  3 +
>>>  .../sysv/linux/sparc/cancellation-sigmask.h   | 39 ++++++++++
>>>  .../sysv/linux/sparc/sparc32/syscall_cancel.S | 71 ++++++++++++++++++
>>>  sysdeps/unix/sysv/linux/sparc/sparc64/pause.c | 25 +++++++
>>>  .../sysv/linux/sparc/sparc64/syscall_cancel.S | 74 +++++++++++++++++++
>>>  5 files changed, 212 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
>>
>>> --- /dev/null
>>> +++ b/sysdeps/unix/sysv/linux/sparc/sparc64/pause.c
>>> @@ -0,0 +1,25 @@
>>> +/* Linux pause syscall implementation.  Linux/sparc64.
>>> +   Copyright (C) 2020 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.  */
>>
>> ditto
>>
>>> +#undef __NR_pause
>>> +#include <sysdeps/unix/sysv/linux/pause.c>
> 
> But sysdeps/unix/sysv/linux/sparc/kernel-features.h already contains
> 
> #ifdef __arch64__
> /* sparc64 defines __NR_pause,  however it is not supported (ENOSYS).
>    Undefine so pause.c can use a correct alternative.  */
> # undef __NR_pause
> #endif
> 

Indeed, I already has pushed this fix on generic implementation. I have
removed the new pause implementation and fixed the commit message
accordingly.

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

* Re: [PATCH v4 14/21] nptl: m68k: Fix Race conditions in pthread cancellation [BZ#12683]
  2020-04-12 15:42   ` Stepan Golosunov
@ 2020-04-15 14:51     ` Adhemerval Zanella via Libc-alpha
  0 siblings, 0 replies; 46+ messages in thread
From: Adhemerval Zanella via Libc-alpha @ 2020-04-15 14:51 UTC (permalink / raw
  To: Stepan Golosunov; +Cc: libc-alpha



On 12/04/2020 12:42, Stepan Golosunov wrote:
> 03.04.2020 в 17:31:54 -0300 Adhemerval Zanella написал:
>> This patch adds the m68k modifications required for the BZ#12683 fix
>> by adding the arch-specific cancellation syscall bridge.
>>
>> Checked on m68k-linux-gnu.
>> ---
>>  sysdeps/m68k/nptl/tcb-offsets.sym             |  3 +
>>  sysdeps/unix/sysv/linux/m68k/syscall_cancel.S | 85 +++++++++++++++++++
>>  2 files changed, 88 insertions(+)
>>  create mode 100644 sysdeps/unix/sysv/linux/m68k/syscall_cancel.S
> 
>> --- /dev/null
>> +++ b/sysdeps/unix/sysv/linux/m68k/syscall_cancel.S
>> @@ -0,0 +1,85 @@
>> +/* Cancellable syscall wrapper.  Linux/m68k version.
>> +   Copyright (C) 2020 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)  */
> 
> Is #define for HAVE_CANCELABLE_SYSCALL_WITH_7_ARGS missing?
> More likely the comment is wrong though.
> Same issue in the alpha patch.

No, on both cases the comment is wrong. I have fixed both.

> 
>> +
>> +
>> +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
>> +__syscall_cancel_arch_start:
>> +
>> +	move.l	20(%sp),%a0
>> +	move.l	(%a0),%d0
>> +#ifdef __mcoldfire__
>> +	move.w	%d0,%ccr
>> +	jeq	1f
>> +#else
>> +	btst	#TCB_CANCELED_BIT,%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
>> +__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)

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

end of thread, other threads:[~2020-04-15 14:51 UTC | newest]

Thread overview: 46+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2020-04-03 20:31 [PATCH v4 00/21] nptl: Fix Race conditions in pthread cancellation [BZ#12683] Adhemerval Zanella via Libc-alpha
2020-04-03 20:31 ` [PATCH v4 01/21] nptl: Do not close the pipe on tst-cancel{2,3} Adhemerval Zanella via Libc-alpha
2020-04-07 15:24   ` Zack Weinberg
2020-04-07 20:07     ` Adhemerval Zanella via Libc-alpha
2020-04-03 20:31 ` [PATCH v4 02/21] nptl: Fix Race conditions in pthread cancellation [BZ#12683] Adhemerval Zanella via Libc-alpha
2020-04-07 18:24   ` Zack Weinberg
2020-04-08 14:13     ` Adhemerval Zanella via Libc-alpha
2020-04-03 20:31 ` [PATCH v4 03/21] nptl: x86_64: " Adhemerval Zanella via Libc-alpha
2020-04-03 20:31 ` [PATCH v4 04/21] nptl: x32: " Adhemerval Zanella via Libc-alpha
2020-04-03 21:22   ` Joseph Myers
2020-04-07 12:47     ` Adhemerval Zanella via Libc-alpha
2020-04-07 12:54       ` H.J. Lu via Libc-alpha
2020-04-07 13:33         ` Adhemerval Zanella via Libc-alpha
2020-04-07 13:40           ` H.J. Lu via Libc-alpha
2020-04-07 13:41             ` H.J. Lu via Libc-alpha
2020-04-07 13:55               ` Adhemerval Zanella via Libc-alpha
2020-04-07 13:59                 ` H.J. Lu via Libc-alpha
2020-04-07 14:04                   ` Adhemerval Zanella via Libc-alpha
2020-04-07 15:45                     ` H.J. Lu via Libc-alpha
2020-04-07 16:16                       ` Adhemerval Zanella via Libc-alpha
2020-04-03 20:31 ` [PATCH v4 05/21] nptl: i386: " Adhemerval Zanella via Libc-alpha
2020-04-03 20:31 ` [PATCH v4 06/21] nptl: ia64: " Adhemerval Zanella via Libc-alpha
2020-04-03 20:31 ` [PATCH v4 07/21] nptl: mips: " Adhemerval Zanella via Libc-alpha
2020-04-03 20:31 ` [PATCH v4 08/21] nptl: aarch64: " Adhemerval Zanella via Libc-alpha
2020-04-12 15:29   ` Stepan Golosunov
2020-04-15 14:30     ` Adhemerval Zanella via Libc-alpha
2020-04-03 20:31 ` [PATCH v4 09/21] nptl: arm: " Adhemerval Zanella via Libc-alpha
2020-04-03 20:31 ` [PATCH v4 10/21] nptl: powerpc: " Adhemerval Zanella via Libc-alpha
2020-04-03 20:31 ` [PATCH v4 11/21] nptl: microblaze: " Adhemerval Zanella via Libc-alpha
2020-04-03 20:31 ` [PATCH v4 12/21] nptl: sparc: " Adhemerval Zanella via Libc-alpha
2020-04-12 15:33   ` Stepan Golosunov
2020-04-14 16:54     ` Stepan Golosunov
2020-04-15 14:48       ` Adhemerval Zanella via Libc-alpha
2020-04-03 20:31 ` [PATCH v4 13/21] nptl: hppa: " Adhemerval Zanella via Libc-alpha
2020-04-03 20:31 ` [PATCH v4 14/21] nptl: m68k: " Adhemerval Zanella via Libc-alpha
2020-04-03 21:34   ` Andreas Schwab
2020-04-07 12:46     ` Adhemerval Zanella via Libc-alpha
2020-04-12 15:42   ` Stepan Golosunov
2020-04-15 14:51     ` Adhemerval Zanella via Libc-alpha
2020-04-03 20:31 ` [PATCH v4 15/21] nptl: alpha: " Adhemerval Zanella via Libc-alpha
2020-04-03 20:31 ` [PATCH v4 16/21] nptl: sh: " Adhemerval Zanella via Libc-alpha
2020-04-03 20:31 ` [PATCH v4 17/21] nptl: riscv: " Adhemerval Zanella via Libc-alpha
2020-04-03 20:31 ` [PATCH v4 18/21] nptl: s390: " Adhemerval Zanella via Libc-alpha
2020-04-03 20:31 ` [PATCH v4 19/21] nptl: nios2: " Adhemerval Zanella via Libc-alpha
2020-04-03 20:32 ` [PATCH v4 20/21] nptl: csky: " Adhemerval Zanella via Libc-alpha
2020-04-03 20:32 ` [PATCH v4 21/21] Linux: Remove sysdep-cancel header Adhemerval Zanella via Libc-alpha

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).