[02/23] linux: Replace INTERNAL_SYSCALL_ERROR_P macro with a inline function

Message ID 20201109201826.120534-3-adhemerval.zanella@linaro.org
State New
Headers show
Series
  • Simplify internal Linux syscall
Related show

Commit Message

Michael Hudson-Doyle via Libc-alpha Nov. 9, 2020, 8:18 p.m.
It also allows simplify some posix and pthread implementations.

Checked on x86_64-linux-gnu and i686-linux-gnu.
---
 nptl/allocatestack.c                            |  4 ++--
 nptl/nptl-init.c                                |  4 ++--
 nptl/pthread_cancel.c                           |  2 +-
 nptl/pthread_getaffinity.c                      |  2 +-
 nptl/pthread_mutex_trylock.c                    |  2 +-
 nptl/pthread_setaffinity.c                      |  9 ++-------
 nptl/pthread_sigmask.c                          |  8 ++------
 sysdeps/arc/nptl/tls.h                          |  2 +-
 sysdeps/csky/nptl/tls.h                         |  2 +-
 sysdeps/m68k/nptl/tls.h                         |  2 +-
 sysdeps/mips/nptl/tls.h                         |  2 +-
 sysdeps/nptl/lowlevellock-futex.h               |  7 +------
 sysdeps/powerpc/nofpu/sfp-machine.h             |  2 +-
 sysdeps/unix/sysv/linux/arm/tls.h               |  2 +-
 sysdeps/unix/sysv/linux/clock_nanosleep.c       |  2 +-
 sysdeps/unix/sysv/linux/createthread.c          |  4 ++--
 sysdeps/unix/sysv/linux/dl-origin.c             |  2 +-
 sysdeps/unix/sysv/linux/fcntl_nocancel.c        |  2 +-
 sysdeps/unix/sysv/linux/fstatat.c               |  2 +-
 sysdeps/unix/sysv/linux/fstatat64.c             |  2 +-
 sysdeps/unix/sysv/linux/generic/dl-origin.c     |  2 +-
 sysdeps/unix/sysv/linux/hppa/____longjmp_chk.c  |  2 +-
 sysdeps/unix/sysv/linux/libc_fatal.c            |  2 +-
 sysdeps/unix/sysv/linux/m68k/____longjmp_chk.c  |  2 +-
 sysdeps/unix/sysv/linux/m68k/getpagesize.c      |  2 +-
 sysdeps/unix/sysv/linux/mq_unlink.c             |  2 +-
 sysdeps/unix/sysv/linux/not-errno.h             | 14 +++-----------
 sysdeps/unix/sysv/linux/nscd_setup_thread.c     |  2 +-
 sysdeps/unix/sysv/linux/posix_fadvise.c         | 17 ++++++++---------
 sysdeps/unix/sysv/linux/posix_fadvise64.c       | 11 +++++------
 sysdeps/unix/sysv/linux/posix_fallocate.c       |  4 +---
 sysdeps/unix/sysv/linux/posix_fallocate64.c     |  4 +---
 sysdeps/unix/sysv/linux/pthread_kill.c          |  3 +--
 sysdeps/unix/sysv/linux/pthread_sigqueue.c      |  4 +---
 sysdeps/unix/sysv/linux/riscv/syscall.c         |  2 +-
 .../sysv/linux/s390/s390-32/____longjmp_chk.c   |  2 +-
 .../sysv/linux/s390/s390-32/posix_fadvise64.c   |  3 +--
 .../sysv/linux/s390/s390-64/____longjmp_chk.c   |  2 +-
 sysdeps/unix/sysv/linux/shmat.c                 |  2 +-
 sysdeps/unix/sysv/linux/sysdep-vdso.h           |  4 ++--
 sysdeps/unix/sysv/linux/sysdep.h                | 14 ++++++++++----
 sysdeps/unix/sysv/linux/timer_create.c          |  2 +-
 sysdeps/unix/sysv/linux/times.c                 |  5 ++++-
 sysdeps/unix/sysv/linux/x86_64/x32/times.c      |  9 ++++++---
 44 files changed, 80 insertions(+), 100 deletions(-)

-- 
2.25.1

Comments

Michael Hudson-Doyle via Libc-alpha Nov. 10, 2020, 11:27 a.m. | #1
I believe this leads to a miscompilation of lseek on x86-64 x32.  The
generic syscall_error will ignore top half of the lseek system call
result there.

I suspect that many of the conditions could be changed to ret == 0 or
ret < 0 (using a signed type for ret, i.e. not what comes from
INTERNAL_SYSCALL_CALL), resulting in better code.

Thanks,
Florian
-- 
Red Hat GmbH, https://de.redhat.com/ , Registered seat: Grasbrunn,
Commercial register: Amtsgericht Muenchen, HRB 153243,
Managing Directors: Charles Cachera, Brian Klemm, Laurie Krebs, Michael O'Neill
Michael Hudson-Doyle via Libc-alpha Nov. 11, 2020, 4:30 p.m. | #2
On 10/11/2020 08:27, Florian Weimer wrote:
> I believe this leads to a miscompilation of lseek on x86-64 x32.  The

> generic syscall_error will ignore top half of the lseek system call

> result there.


The x32 lseek is provided by the arch-specific inloine assembly:

  sysdeps/unix/sysv/linux/x86_64/x32/lseek.S

I have a patchset that moves a lot of assembly implementations that issues
syscalls to C counter-parts and I think since lseek is an outlier it would
be better to provide a arch-specific implementation than parametrize
the generic internal syscall interface to return a 64-bit value for x32
(which might pessimize code generation).

> 

> I suspect that many of the conditions could be changed to ret == 0 or

> ret < 0 (using a signed type for ret, i.e. not what comes from

> INTERNAL_SYSCALL_CALL), resulting in better code.


I do agree and I was doubtful that syscall_error is indeed useful.
In the end I decided to make this change more mechanical and thus
add a direct replacement for INTERNAL_YSCALL_ERROR_P.

Maybe it would be better to just check for 'ret' value directly
instead of using an auxiliary value.

Patch

diff --git a/nptl/allocatestack.c b/nptl/allocatestack.c
index a9e9d39354..1e34623a86 100644
--- a/nptl/allocatestack.c
+++ b/nptl/allocatestack.c
@@ -1043,7 +1043,7 @@  setxid_signal_thread (struct xid_command *cmdp, struct pthread *t)
   val = INTERNAL_SYSCALL_CALL (tgkill, pid, t->tid, SIGSETXID);
 
   /* If this failed, it must have had not started yet or else exited.  */
-  if (!INTERNAL_SYSCALL_ERROR_P (val))
+  if (!syscall_error (val))
     {
       atomic_increment (&cmdp->cntr);
       return 1;
@@ -1172,7 +1172,7 @@  __nptl_setxid (struct xid_command *cmdp)
   result = INTERNAL_SYSCALL_NCS (cmdp->syscall_no, 3,
 				 cmdp->id[0], cmdp->id[1], cmdp->id[2]);
   int error = 0;
-  if (__glibc_unlikely (INTERNAL_SYSCALL_ERROR_P (result)))
+  if (__glibc_unlikely (syscall_error (result)))
     {
       error = -result;
       __set_errno (error);
diff --git a/nptl/nptl-init.c b/nptl/nptl-init.c
index 8aef4c83b5..38a3bbea56 100644
--- a/nptl/nptl-init.c
+++ b/nptl/nptl-init.c
@@ -191,7 +191,7 @@  sighandler_setxid (int sig, siginfo_t *si, void *ctx)
   result = INTERNAL_SYSCALL_NCS (__xidcmd->syscall_no, 3, __xidcmd->id[0],
 				 __xidcmd->id[1], __xidcmd->id[2]);
   int error = 0;
-  if (__glibc_unlikely (INTERNAL_SYSCALL_ERROR_P (result)))
+  if (__glibc_unlikely (syscall_error (result)))
     error = -result;
   __nptl_setxid_error (__xidcmd, error);
 
@@ -243,7 +243,7 @@  __pthread_initialize_minimal_internal (void)
 						__data.__list.__next));
     int res = INTERNAL_SYSCALL_CALL (set_robust_list, &pd->robust_head,
 				     sizeof (struct robust_list_head));
-    if (INTERNAL_SYSCALL_ERROR_P (res))
+    if (syscall_error (res))
       set_robust_list_not_avail ();
   }
 
diff --git a/nptl/pthread_cancel.c b/nptl/pthread_cancel.c
index 7daf4f8c15..855ecef87b 100644
--- a/nptl/pthread_cancel.c
+++ b/nptl/pthread_cancel.c
@@ -69,7 +69,7 @@  __pthread_cancel (pthread_t th)
 
 	  int val = INTERNAL_SYSCALL_CALL (tgkill, pid, pd->tid,
 					   SIGCANCEL);
-	  if (INTERNAL_SYSCALL_ERROR_P (val))
+	  if (syscall_error (val))
 	    result = -val;
 
 	  break;
diff --git a/nptl/pthread_getaffinity.c b/nptl/pthread_getaffinity.c
index ffeb878c7c..a9e7071e62 100644
--- a/nptl/pthread_getaffinity.c
+++ b/nptl/pthread_getaffinity.c
@@ -33,7 +33,7 @@  __pthread_getaffinity_np (pthread_t th, size_t cpusetsize, cpu_set_t *cpuset)
 
   int res = INTERNAL_SYSCALL_CALL (sched_getaffinity, pd->tid,
 				   MIN (INT_MAX, cpusetsize), cpuset);
-  if (INTERNAL_SYSCALL_ERROR_P (res))
+  if (syscall_error (res))
     return -res;
 
   /* Clean the rest of the memory the kernel didn't do.  */
diff --git a/nptl/pthread_mutex_trylock.c b/nptl/pthread_mutex_trylock.c
index 5c294a3eea..492f011cae 100644
--- a/nptl/pthread_mutex_trylock.c
+++ b/nptl/pthread_mutex_trylock.c
@@ -301,7 +301,7 @@  __pthread_mutex_trylock (pthread_mutex_t *mutex)
 					   __lll_private_flag (FUTEX_TRYLOCK_PI,
 							       private), 0, 0);
 
-	    if (INTERNAL_SYSCALL_ERROR_P (e) && e == -EWOULDBLOCK)
+	    if (e == -EWOULDBLOCK)
 	      {
 		/* The kernel has not yet finished the mutex owner death.
 		   We do not need to ensure ordering wrt another memory
diff --git a/nptl/pthread_setaffinity.c b/nptl/pthread_setaffinity.c
index aaaa4f0194..bcf8ac1376 100644
--- a/nptl/pthread_setaffinity.c
+++ b/nptl/pthread_setaffinity.c
@@ -28,14 +28,9 @@  __pthread_setaffinity_new (pthread_t th, size_t cpusetsize,
 			   const cpu_set_t *cpuset)
 {
   const struct pthread *pd = (const struct pthread *) th;
-  int res;
 
-  res = INTERNAL_SYSCALL_CALL (sched_setaffinity, pd->tid, cpusetsize,
-			       cpuset);
-
-  return (INTERNAL_SYSCALL_ERROR_P (res)
-	  ? -res
-	  : 0);
+  return -INTERNAL_SYSCALL_CALL (sched_setaffinity, pd->tid, cpusetsize,
+				 cpuset);
 }
 versioned_symbol (libpthread, __pthread_setaffinity_new,
 		  pthread_setaffinity_np, GLIBC_2_3_4);
diff --git a/nptl/pthread_sigmask.c b/nptl/pthread_sigmask.c
index 1d6d753af4..7939a6cfe6 100644
--- a/nptl/pthread_sigmask.c
+++ b/nptl/pthread_sigmask.c
@@ -38,12 +38,8 @@  __pthread_sigmask (int how, const sigset_t *newmask, sigset_t *oldmask)
     }
 
   /* We know that realtime signals are available if NPTL is used.  */
-  int result = INTERNAL_SYSCALL_CALL (rt_sigprocmask, how, newmask,
-				      oldmask, __NSIG_BYTES);
-
-  return (INTERNAL_SYSCALL_ERROR_P (result)
-	  ? -result
-	  : 0);
+  return -INTERNAL_SYSCALL_CALL (rt_sigprocmask, how, newmask, oldmask,
+				 __NSIG_BYTES);
 }
 libc_hidden_def (__pthread_sigmask)
 
diff --git a/sysdeps/arc/nptl/tls.h b/sysdeps/arc/nptl/tls.h
index 184b550ab5..de9cd9c3ca 100644
--- a/sysdeps/arc/nptl/tls.h
+++ b/sysdeps/arc/nptl/tls.h
@@ -81,7 +81,7 @@  typedef struct
 	long result_var;					\
 	__builtin_set_thread_pointer (tcbp);     		\
 	result_var = INTERNAL_SYSCALL_CALL (arc_settls, (tcbp));\
-	INTERNAL_SYSCALL_ERROR_P (result_var)			\
+	syscall_error (result_var)				\
 	  ? "settls syscall error" : NULL;			\
    })
 
diff --git a/sysdeps/csky/nptl/tls.h b/sysdeps/csky/nptl/tls.h
index bcca9674a1..dd864cdc7c 100644
--- a/sysdeps/csky/nptl/tls.h
+++ b/sysdeps/csky/nptl/tls.h
@@ -99,7 +99,7 @@  typedef struct
   ({ long int result_var;						\
      result_var = INTERNAL_SYSCALL_CALL (set_thread_area, 		\
                     (char *) (tcbp) + TLS_TCB_OFFSET);			\
-     INTERNAL_SYSCALL_ERROR_P (result_var)				\
+     syscall_error (result_var)						\
        ? "unknown error" : NULL; })
 
 /* Return the address of the dtv for the current thread.  */
diff --git a/sysdeps/m68k/nptl/tls.h b/sysdeps/m68k/nptl/tls.h
index 68ea952e79..77b7afe67f 100644
--- a/sysdeps/m68k/nptl/tls.h
+++ b/sysdeps/m68k/nptl/tls.h
@@ -99,7 +99,7 @@  typedef struct
 									\
     _sys_result = INTERNAL_SYSCALL_CALL (set_thread_area, 		\
 				    ((void *) (tcbp)) + TLS_TCB_OFFSET); \
-    INTERNAL_SYSCALL_ERROR_P (_sys_result) ? "unknown error" : NULL; })
+    syscall_error (_sys_result) ? "unknown error" : NULL; })
 
 # define TLS_DEFINE_INIT_TP(tp, pd) \
   void *tp = (void *) (pd) + TLS_TCB_OFFSET + TLS_PRE_TCB_SIZE
diff --git a/sysdeps/mips/nptl/tls.h b/sysdeps/mips/nptl/tls.h
index 8b55f19c37..e91c0074e8 100644
--- a/sysdeps/mips/nptl/tls.h
+++ b/sysdeps/mips/nptl/tls.h
@@ -123,7 +123,7 @@  typedef struct
   ({ long int result_var;						\
      result_var = INTERNAL_SYSCALL_CALL (set_thread_area, 		\
 				    (char *) (tcbp) + TLS_TCB_OFFSET);	\
-     INTERNAL_SYSCALL_ERROR_P (result_var)				\
+     syscall_error (result_var)						\
        ? "unknown error" : NULL; })
 
 /* Value passed to 'clone' for initialization of the thread register.  */
diff --git a/sysdeps/nptl/lowlevellock-futex.h b/sysdeps/nptl/lowlevellock-futex.h
index dd36997021..c6a0908ff1 100644
--- a/sysdeps/nptl/lowlevellock-futex.h
+++ b/sysdeps/nptl/lowlevellock-futex.h
@@ -66,12 +66,7 @@ 
 # endif
 
 # define lll_futex_syscall(nargs, futexp, op, ...)                      \
-  ({                                                                    \
-    long int __ret = INTERNAL_SYSCALL (futex, nargs, futexp, op, 	\
-				       __VA_ARGS__);                    \
-    (__glibc_unlikely (INTERNAL_SYSCALL_ERROR_P (__ret))         	\
-     ? __ret : 0);                     					\
-  })
+  INTERNAL_SYSCALL (futex, nargs, futexp, op, __VA_ARGS__)
 
 /* For most of these macros, the return value is never really used.
    Nevertheless, the protocol is that each one returns a negated errno
diff --git a/sysdeps/powerpc/nofpu/sfp-machine.h b/sysdeps/powerpc/nofpu/sfp-machine.h
index 8489c0f1c0..110a3bf547 100644
--- a/sysdeps/powerpc/nofpu/sfp-machine.h
+++ b/sysdeps/powerpc/nofpu/sfp-machine.h
@@ -70,7 +70,7 @@  libc_hidden_proto (__feraiseexcept_soft)
 									\
       _spefscr = fegetenv_register ();					\
       _r = INTERNAL_SYSCALL_CALL (prctl, PR_GET_FPEXC, &_ftrapex);	\
-      if (INTERNAL_SYSCALL_ERROR_P (_r))				\
+      if (syscall_error (_r))						\
 	_ftrapex = 0;							\
     }									\
   while (0)
diff --git a/sysdeps/unix/sysv/linux/arm/tls.h b/sysdeps/unix/sysv/linux/arm/tls.h
index 57b583dbd8..4155d6c030 100644
--- a/sysdeps/unix/sysv/linux/arm/tls.h
+++ b/sysdeps/unix/sysv/linux/arm/tls.h
@@ -33,7 +33,7 @@ 
 # define TLS_INIT_TP(tcbp) \
   ({ long int result_var;						\
      result_var = INTERNAL_SYSCALL_CALL (set_tls, (tcbp));		\
-     INTERNAL_SYSCALL_ERROR_P (result_var)				\
+     syscall_error (result_var)						\
        ? "unknown error" : NULL; })
 
 #endif /* __ASSEMBLER__ */
diff --git a/sysdeps/unix/sysv/linux/clock_nanosleep.c b/sysdeps/unix/sysv/linux/clock_nanosleep.c
index 6ad3321435..ace1191d90 100644
--- a/sysdeps/unix/sysv/linux/clock_nanosleep.c
+++ b/sysdeps/unix/sysv/linux/clock_nanosleep.c
@@ -57,7 +57,7 @@  __clock_nanosleep_time64 (clockid_t clock_id, int flags, const struct __timespec
   struct timespec ts32 = valid_timespec64_to_timespec (*req);
   r = INTERNAL_SYSCALL_CANCEL (clock_nanosleep, clock_id, flags,
                                &ts32, &tr32);
-  if (INTERNAL_SYSCALL_ERROR_P (r))
+  if (syscall_error (r))
     {
       if (r == -EINTR && rem != NULL && (flags & TIMER_ABSTIME) == 0)
 	*rem = valid_timespec_to_timespec64 (tr32);
diff --git a/sysdeps/unix/sysv/linux/createthread.c b/sysdeps/unix/sysv/linux/createthread.c
index 01cf2ff42a..1c224155f8 100644
--- a/sysdeps/unix/sysv/linux/createthread.c
+++ b/sysdeps/unix/sysv/linux/createthread.c
@@ -123,7 +123,7 @@  create_thread (struct pthread *pd, const struct pthread_attr *attr,
 				       attr->extension->cpusetsize,
 				       attr->extension->cpuset);
 
-	  if (__glibc_unlikely (INTERNAL_SYSCALL_ERROR_P (res)))
+	  if (__glibc_unlikely (syscall_error (res)))
 	  err_out:
 	    {
 	      /* The operation failed.  We have to kill the thread.
@@ -144,7 +144,7 @@  create_thread (struct pthread *pd, const struct pthread_attr *attr,
 	  res = INTERNAL_SYSCALL_CALL (sched_setscheduler, pd->tid,
 				       pd->schedpolicy, &pd->schedparam);
 
-	  if (__glibc_unlikely (INTERNAL_SYSCALL_ERROR_P (res)))
+	  if (__glibc_unlikely (syscall_error (res)))
 	    goto err_out;
 	}
     }
diff --git a/sysdeps/unix/sysv/linux/dl-origin.c b/sysdeps/unix/sysv/linux/dl-origin.c
index 515ed6fc8c..00cba11495 100644
--- a/sysdeps/unix/sysv/linux/dl-origin.c
+++ b/sysdeps/unix/sysv/linux/dl-origin.c
@@ -40,7 +40,7 @@  _dl_get_origin (void)
 
   len = INTERNAL_SYSCALL_CALL (readlink, "/proc/self/exe", linkval,
 			       sizeof (linkval));
-  if (! INTERNAL_SYSCALL_ERROR_P (len) && len > 0 && linkval[0] != '[')
+  if (! syscall_error (len) && len > 0 && linkval[0] != '[')
     {
       /* We can use this value.  */
       assert (linkval[0] == '/');
diff --git a/sysdeps/unix/sysv/linux/fcntl_nocancel.c b/sysdeps/unix/sysv/linux/fcntl_nocancel.c
index 1bf3030f75..a16fc75cb7 100644
--- a/sysdeps/unix/sysv/linux/fcntl_nocancel.c
+++ b/sysdeps/unix/sysv/linux/fcntl_nocancel.c
@@ -53,7 +53,7 @@  __fcntl64_nocancel_adjusted (int fd, int cmd, void *arg)
     {
       struct f_owner_ex fex;
       int res = INTERNAL_SYSCALL_CALL (fcntl64, fd, F_GETOWN_EX, &fex);
-      if (!INTERNAL_SYSCALL_ERROR_P (res))
+      if (!syscall_error (res))
 	return fex.type == F_OWNER_GID ? -fex.pid : fex.pid;
 
       return INLINE_SYSCALL_ERROR_RETURN_VALUE (-res);
diff --git a/sysdeps/unix/sysv/linux/fstatat.c b/sysdeps/unix/sysv/linux/fstatat.c
index db49e3155c..a61fffa6e7 100644
--- a/sysdeps/unix/sysv/linux/fstatat.c
+++ b/sysdeps/unix/sysv/linux/fstatat.c
@@ -80,7 +80,7 @@  __fstatat (int fd, const char *file, struct stat *buf, int flag)
 #  endif /* __nr_fstatat64  */
 # endif /* STAT_IS_KERNEL_STAT  */
 
-  return INTERNAL_SYSCALL_ERROR_P (r)
+  return syscall_error (r)
 	 ? INLINE_SYSCALL_ERROR_RETURN_VALUE (-r)
 	 : 0;
 }
diff --git a/sysdeps/unix/sysv/linux/fstatat64.c b/sysdeps/unix/sysv/linux/fstatat64.c
index 44347603b4..6e12cf2456 100644
--- a/sysdeps/unix/sysv/linux/fstatat64.c
+++ b/sysdeps/unix/sysv/linux/fstatat64.c
@@ -102,7 +102,7 @@  __fstatat64_time64 (int fd, const char *file, struct __stat64_t64 *buf,
 # endif
 #endif
 
-  return INTERNAL_SYSCALL_ERROR_P (r)
+  return syscall_error (r)
 	 ? INLINE_SYSCALL_ERROR_RETURN_VALUE (-r)
 	 : 0;
 }
diff --git a/sysdeps/unix/sysv/linux/generic/dl-origin.c b/sysdeps/unix/sysv/linux/generic/dl-origin.c
index 1ab02bbf10..f90b59b1ef 100644
--- a/sysdeps/unix/sysv/linux/generic/dl-origin.c
+++ b/sysdeps/unix/sysv/linux/generic/dl-origin.c
@@ -41,7 +41,7 @@  _dl_get_origin (void)
 
   len = INTERNAL_SYSCALL_CALL (readlinkat, AT_FDCWD, "/proc/self/exe",
 			       linkval, sizeof (linkval));
-  if (! INTERNAL_SYSCALL_ERROR_P (len) && len > 0 && linkval[0] != '[')
+  if (! syscall_error (len) && len > 0 && linkval[0] != '[')
     {
       /* We can use this value.  */
       assert (linkval[0] == '/');
diff --git a/sysdeps/unix/sysv/linux/hppa/____longjmp_chk.c b/sysdeps/unix/sysv/linux/hppa/____longjmp_chk.c
index eae0a7fe31..541c05fcf4 100644
--- a/sysdeps/unix/sysv/linux/hppa/____longjmp_chk.c
+++ b/sysdeps/unix/sysv/linux/hppa/____longjmp_chk.c
@@ -35,7 +35,7 @@ 
 	   that we are jumping *out* of the alternate stack. Note that	\
 	   the check for that is the same as that for _STACK_GROWS_UP	\
 	   as for _STACK_GROWS_DOWN.  */				\
-        if (!INTERNAL_SYSCALL_ERROR_P (result)				\
+        if (!syscall_error (result)					\
             && ((oss.ss_flags & SS_ONSTACK) == 0			\
                 || ((unsigned long) oss.ss_sp + oss.ss_size		\
                     - (unsigned long) (sp)) < oss.ss_size))		\
diff --git a/sysdeps/unix/sysv/linux/libc_fatal.c b/sysdeps/unix/sysv/linux/libc_fatal.c
index 35a20ca0fd..52fcd9761b 100644
--- a/sysdeps/unix/sysv/linux/libc_fatal.c
+++ b/sysdeps/unix/sysv/linux/libc_fatal.c
@@ -25,7 +25,7 @@  writev_for_fatal (int fd, const struct iovec *iov, size_t niov, size_t total)
   ssize_t cnt;
   do
     cnt = INTERNAL_SYSCALL_CALL (writev, fd, iov, niov);
-  while (INTERNAL_SYSCALL_ERROR_P (cnt) && cnt == -EINTR);
+  while (syscall_error (cnt) && cnt == -EINTR);
   return cnt == total;
 }
 #define WRITEV_FOR_FATAL	writev_for_fatal
diff --git a/sysdeps/unix/sysv/linux/m68k/____longjmp_chk.c b/sysdeps/unix/sysv/linux/m68k/____longjmp_chk.c
index 1e9c5259ab..7a3ed27a5c 100644
--- a/sysdeps/unix/sysv/linux/m68k/____longjmp_chk.c
+++ b/sysdeps/unix/sysv/linux/m68k/____longjmp_chk.c
@@ -26,7 +26,7 @@ 
       {									      \
 	stack_t oss;							      \
 	int result = INTERNAL_SYSCALL_CALL (sigaltstack, NULL, &oss);         \
-	if (!INTERNAL_SYSCALL_ERROR_P (result)				      \
+	if (!syscall_error (result)					      \
 	    && ((oss.ss_flags & SS_ONSTACK) == 0			      \
 		|| ((unsigned long) oss.ss_sp + oss.ss_size		      \
 		    - (unsigned long) (sp)) < oss.ss_size))		      \
diff --git a/sysdeps/unix/sysv/linux/m68k/getpagesize.c b/sysdeps/unix/sysv/linux/m68k/getpagesize.c
index 99c83313d2..99ab5772b3 100644
--- a/sysdeps/unix/sysv/linux/m68k/getpagesize.c
+++ b/sysdeps/unix/sysv/linux/m68k/getpagesize.c
@@ -35,7 +35,7 @@  __getpagesize (void)
 
   result = INTERNAL_SYSCALL_CALL (getpagesize);
   /* The only possible error is ENOSYS.  */
-  if (!INTERNAL_SYSCALL_ERROR_P (result))
+  if (!syscall_error (result))
     return result;
 
   return 4096;
diff --git a/sysdeps/unix/sysv/linux/mq_unlink.c b/sysdeps/unix/sysv/linux/mq_unlink.c
index ed7858dc9d..4964eb9028 100644
--- a/sysdeps/unix/sysv/linux/mq_unlink.c
+++ b/sysdeps/unix/sysv/linux/mq_unlink.c
@@ -30,7 +30,7 @@  mq_unlink (const char *name)
 
   /* While unlink can return either EPERM or EACCES, mq_unlink should
      return just EACCES.  */
-  if (__glibc_unlikely (INTERNAL_SYSCALL_ERROR_P (ret)))
+  if (__glibc_unlikely (syscall_error (ret)))
     {
       if (ret == -EPERM)
 	ret = -EACCES;
diff --git a/sysdeps/unix/sysv/linux/not-errno.h b/sysdeps/unix/sysv/linux/not-errno.h
index fc0eda09d9..07330a83ca 100644
--- a/sysdeps/unix/sysv/linux/not-errno.h
+++ b/sysdeps/unix/sysv/linux/not-errno.h
@@ -25,23 +25,15 @@ 
 static inline int
 __access_noerrno (const char *pathname, int mode)
 {
-  int res;
 #ifdef __NR_access
-  res = INTERNAL_SYSCALL_CALL (access, pathname, mode);
+  return -INTERNAL_SYSCALL_CALL (access, pathname, mode);
 #else
-  res = INTERNAL_SYSCALL_CALL (faccessat, AT_FDCWD, pathname, mode);
+  return -INTERNAL_SYSCALL_CALL (faccessat, AT_FDCWD, pathname, mode);
 #endif
-  if (INTERNAL_SYSCALL_ERROR_P (res))
-    return -res;
-  return 0;
 }
 
 static inline int
 __kill_noerrno (pid_t pid, int sig)
 {
-  int res;
-  res = INTERNAL_SYSCALL_CALL (kill, pid, sig);
-  if (INTERNAL_SYSCALL_ERROR_P (res))
-    return -res;
-  return 0;
+  return -INTERNAL_SYSCALL_CALL (kill, pid, sig);
 }
diff --git a/sysdeps/unix/sysv/linux/nscd_setup_thread.c b/sysdeps/unix/sysv/linux/nscd_setup_thread.c
index 2ba64ebea5..fe70da0b5e 100644
--- a/sysdeps/unix/sysv/linux/nscd_setup_thread.c
+++ b/sysdeps/unix/sysv/linux/nscd_setup_thread.c
@@ -36,7 +36,7 @@  setup_thread (struct database_dyn *db)
      since none of the threads ever terminates.  */
   int r = INTERNAL_SYSCALL_CALL (set_tid_address,
 				 &db->head->nscd_certainly_running);
-  if (!INTERNAL_SYSCALL_ERROR_P (r))
+  if (!syscall_error (r))
     /* We know the kernel can reset this field when nscd terminates.
        So, set the field to a nonzero value which indicates that nscd
        is certainly running and clients can skip the test.  */
diff --git a/sysdeps/unix/sysv/linux/posix_fadvise.c b/sysdeps/unix/sysv/linux/posix_fadvise.c
index 1191ab3db5..3d6bf4b972 100644
--- a/sysdeps/unix/sysv/linux/posix_fadvise.c
+++ b/sysdeps/unix/sysv/linux/posix_fadvise.c
@@ -42,24 +42,23 @@  int
 posix_fadvise (int fd, off_t offset, off_t len, int advise)
 {
 # if defined (__NR_fadvise64) && !defined (__ASSUME_FADVISE64_AS_64_64)
-  int ret = INTERNAL_SYSCALL_CALL (fadvise64, fd,
-				   __ALIGNMENT_ARG SYSCALL_LL (offset),
-				   len, advise);
+  return -INTERNAL_SYSCALL_CALL (fadvise64, fd,
+				 __ALIGNMENT_ARG SYSCALL_LL (offset),
+				 len, advise);
 # else
 #  ifdef __ASSUME_FADVISE64_64_6ARG
-  int ret = INTERNAL_SYSCALL_CALL (fadvise64_64, fd, advise,
-				   SYSCALL_LL (offset), SYSCALL_LL (len));
+  return -INTERNAL_SYSCALL_CALL (fadvise64_64, fd, advise,
+				 SYSCALL_LL (offset), SYSCALL_LL (len));
 #  else
 
 #   ifndef __NR_fadvise64_64
 #    define __NR_fadvise64_64 __NR_fadvise64
 #   endif
 
-  int ret = INTERNAL_SYSCALL_CALL (fadvise64_64, fd,
-				   __ALIGNMENT_ARG SYSCALL_LL (offset),
-				   SYSCALL_LL (len), advise);
+  return -INTERNAL_SYSCALL_CALL (fadvise64_64, fd,
+				 __ALIGNMENT_ARG SYSCALL_LL (offset),
+				 SYSCALL_LL (len), advise);
 #  endif
 # endif
-  return INTERNAL_SYSCALL_ERROR_P (ret) ? -ret : 0;
 }
 #endif /* __OFF_T_MATCHES_OFF64_T  */
diff --git a/sysdeps/unix/sysv/linux/posix_fadvise64.c b/sysdeps/unix/sysv/linux/posix_fadvise64.c
index e3726a6a8a..6ef425cf22 100644
--- a/sysdeps/unix/sysv/linux/posix_fadvise64.c
+++ b/sysdeps/unix/sysv/linux/posix_fadvise64.c
@@ -41,14 +41,13 @@  int
 __posix_fadvise64_l64 (int fd, off64_t offset, off64_t len, int advise)
 {
 #ifdef __ASSUME_FADVISE64_64_6ARG
-  int ret = INTERNAL_SYSCALL_CALL (fadvise64_64, fd, advise,
-				   SYSCALL_LL64 (offset), SYSCALL_LL64 (len));
+  return -INTERNAL_SYSCALL_CALL (fadvise64_64, fd, advise,
+				 SYSCALL_LL64 (offset), SYSCALL_LL64 (len));
 #else
-  int ret = INTERNAL_SYSCALL_CALL (fadvise64_64, fd,
-				   __ALIGNMENT_ARG SYSCALL_LL64 (offset),
-				   SYSCALL_LL64 (len), advise);
+  return -INTERNAL_SYSCALL_CALL (fadvise64_64, fd,
+				 __ALIGNMENT_ARG SYSCALL_LL64 (offset),
+				 SYSCALL_LL64 (len), advise);
 #endif
-  return INTERNAL_SYSCALL_ERROR_P (ret) ? -ret : 0;
 }
 
 /* The type of the len argument was changed from size_t to off_t in
diff --git a/sysdeps/unix/sysv/linux/posix_fallocate.c b/sysdeps/unix/sysv/linux/posix_fallocate.c
index 87532668cd..3c8f7cafeb 100644
--- a/sysdeps/unix/sysv/linux/posix_fallocate.c
+++ b/sysdeps/unix/sysv/linux/posix_fallocate.c
@@ -28,9 +28,7 @@  posix_fallocate (int fd, __off_t offset, __off_t len)
 {
   int res = INTERNAL_SYSCALL_CALL (fallocate, fd, 0,
 				   SYSCALL_LL (offset), SYSCALL_LL (len));
-  if (! INTERNAL_SYSCALL_ERROR_P (res))
-    return 0;
-  if (res != -EOPNOTSUPP)
+  if (! syscall_error (res) || -res != EOPNOTSUPP)
     return -res;
   return internal_fallocate (fd, offset, len);
 }
diff --git a/sysdeps/unix/sysv/linux/posix_fallocate64.c b/sysdeps/unix/sysv/linux/posix_fallocate64.c
index 0340357e57..910f83384c 100644
--- a/sysdeps/unix/sysv/linux/posix_fallocate64.c
+++ b/sysdeps/unix/sysv/linux/posix_fallocate64.c
@@ -30,9 +30,7 @@  __posix_fallocate64_l64 (int fd, __off64_t offset, __off64_t len)
 {
   int res = INTERNAL_SYSCALL_CALL (fallocate, fd, 0,
 				   SYSCALL_LL64 (offset), SYSCALL_LL64 (len));
-  if (! INTERNAL_SYSCALL_ERROR_P (res))
-    return 0;
-  if (-res != EOPNOTSUPP)
+  if (! syscall_error (res) || -res != EOPNOTSUPP)
     return -res;
   return internal_fallocate64 (fd, offset, len);
 }
diff --git a/sysdeps/unix/sysv/linux/pthread_kill.c b/sysdeps/unix/sysv/linux/pthread_kill.c
index defdeaecac..525383f960 100644
--- a/sysdeps/unix/sysv/linux/pthread_kill.c
+++ b/sysdeps/unix/sysv/linux/pthread_kill.c
@@ -50,7 +50,6 @@  __pthread_kill (pthread_t threadid, int signo)
   /* We have a special syscall to do the work.  */
   pid_t pid = __getpid ();
 
-  int val = INTERNAL_SYSCALL_CALL (tgkill, pid, tid, signo);
-  return INTERNAL_SYSCALL_ERROR_P (val) ? -val : 0;
+  return -INTERNAL_SYSCALL_CALL (tgkill, pid, tid, signo);
 }
 strong_alias (__pthread_kill, pthread_kill)
diff --git a/sysdeps/unix/sysv/linux/pthread_sigqueue.c b/sysdeps/unix/sysv/linux/pthread_sigqueue.c
index fbbd9fee20..814f449b63 100644
--- a/sysdeps/unix/sysv/linux/pthread_sigqueue.c
+++ b/sysdeps/unix/sysv/linux/pthread_sigqueue.c
@@ -61,9 +61,7 @@  pthread_sigqueue (pthread_t threadid, int signo, const union sigval value)
   info.si_value = value;
 
   /* We have a special syscall to do the work.  */
-  int val = INTERNAL_SYSCALL_CALL (rt_tgsigqueueinfo, pid, tid, signo,
-				   &info);
-  return INTERNAL_SYSCALL_ERROR_P (val) ? -val : 0;
+  return -INTERNAL_SYSCALL_CALL (rt_tgsigqueueinfo, pid, tid, signo, &info);
 #else
   return ENOSYS;
 #endif
diff --git a/sysdeps/unix/sysv/linux/riscv/syscall.c b/sysdeps/unix/sysv/linux/riscv/syscall.c
index a99375c054..4ebb759b72 100644
--- a/sysdeps/unix/sysv/linux/riscv/syscall.c
+++ b/sysdeps/unix/sysv/linux/riscv/syscall.c
@@ -27,7 +27,7 @@  syscall (long int syscall_number, long int arg1, long int arg2, long int arg3,
   ret = INTERNAL_SYSCALL_NCS (syscall_number, 7, arg1, arg2, arg3, arg4,
 			      arg5, arg6, arg7);
 
-  if (INTERNAL_SYSCALL_ERROR_P (ret))
+  if (syscall_error (ret))
     return __syscall_error (ret);
 
   return ret;
diff --git a/sysdeps/unix/sysv/linux/s390/s390-32/____longjmp_chk.c b/sysdeps/unix/sysv/linux/s390/s390-32/____longjmp_chk.c
index 1f214173fe..7cb3a69e90 100644
--- a/sysdeps/unix/sysv/linux/s390/s390-32/____longjmp_chk.c
+++ b/sysdeps/unix/sysv/linux/s390/s390-32/____longjmp_chk.c
@@ -40,7 +40,7 @@ 
 	{								\
 	  stack_t oss;							\
 	  int res = INTERNAL_SYSCALL_CALL (sigaltstack, NULL, &oss);	\
-	  if (!INTERNAL_SYSCALL_ERROR_P (res))				\
+	  if (!syscall_error (res))					\
 	    {								\
 	      if ((oss.ss_flags & SS_ONSTACK) == 0			\
 		  || ((uintptr_t) (oss.ss_sp + oss.ss_size) - new_sp	\
diff --git a/sysdeps/unix/sysv/linux/s390/s390-32/posix_fadvise64.c b/sysdeps/unix/sysv/linux/s390/s390-32/posix_fadvise64.c
index 6199589307..75c1318d83 100644
--- a/sysdeps/unix/sysv/linux/s390/s390-32/posix_fadvise64.c
+++ b/sysdeps/unix/sysv/linux/s390/s390-32/posix_fadvise64.c
@@ -42,8 +42,7 @@  __posix_fadvise64_l64 (int fd, off64_t offset, off64_t len, int advise)
   parameters.offset = offset;
   parameters.len = len;
   parameters.advise = advise;
-  int ret = INTERNAL_SYSCALL_CALL (fadvise64_64, &parameters);
-  return INTERNAL_SYSCALL_ERROR_P (ret) ? -ret : 0;
+  return -INTERNAL_SYSCALL_CALL (fadvise64_64, &parameters);
 }
 
 #include <shlib-compat.h>
diff --git a/sysdeps/unix/sysv/linux/s390/s390-64/____longjmp_chk.c b/sysdeps/unix/sysv/linux/s390/s390-64/____longjmp_chk.c
index bc74408135..84c6d13655 100644
--- a/sysdeps/unix/sysv/linux/s390/s390-64/____longjmp_chk.c
+++ b/sysdeps/unix/sysv/linux/s390/s390-64/____longjmp_chk.c
@@ -40,7 +40,7 @@ 
 	{								\
 	  stack_t oss;							\
 	  int res = INTERNAL_SYSCALL_CALL (sigaltstack, NULL, &oss);	\
-	  if (!INTERNAL_SYSCALL_ERROR_P (res))				\
+	  if (!syscall_error (res))					\
 	    {								\
 	      if ((oss.ss_flags & SS_ONSTACK) == 0			\
 		  || ((uintptr_t) (oss.ss_sp + oss.ss_size) - new_sp	\
diff --git a/sysdeps/unix/sysv/linux/shmat.c b/sysdeps/unix/sysv/linux/shmat.c
index d5a65c06c1..98291fe972 100644
--- a/sysdeps/unix/sysv/linux/shmat.c
+++ b/sysdeps/unix/sysv/linux/shmat.c
@@ -35,7 +35,7 @@  shmat (int shmid, const void *shmaddr, int shmflg)
 
   resultvar = INTERNAL_SYSCALL_CALL (ipc, IPCOP_shmat, shmid, shmflg,
 				     &raddr, shmaddr);
-  if (INTERNAL_SYSCALL_ERROR_P (resultvar))
+  if (syscall_error (resultvar))
     return (void *) INLINE_SYSCALL_ERROR_RETURN_VALUE (-resultvar);
 
   return raddr;
diff --git a/sysdeps/unix/sysv/linux/sysdep-vdso.h b/sysdeps/unix/sysv/linux/sysdep-vdso.h
index 88db076184..7c578808c6 100644
--- a/sysdeps/unix/sysv/linux/sysdep-vdso.h
+++ b/sysdeps/unix/sysv/linux/sysdep-vdso.h
@@ -36,14 +36,14 @@ 
     if (vdsop != NULL)							      \
       {									      \
 	sc_ret = INTERNAL_VSYSCALL_CALL (vdsop, nr, ##args);	      	      \
-	if (!INTERNAL_SYSCALL_ERROR_P (sc_ret))			      	      \
+	if (!syscall_error (sc_ret))					      \
 	  goto out;							      \
 	if (sc_ret != -ENOSYS)		      	      			      \
 	  goto iserr;							      \
       }									      \
 									      \
     sc_ret = INTERNAL_SYSCALL_CALL (name, ##args);		      	      \
-    if (INTERNAL_SYSCALL_ERROR_P (sc_ret))			      	      \
+    if (syscall_error (sc_ret))					      	      \
       {									      \
       iserr:								      \
         __set_errno (-sc_ret);		      	      			      \
diff --git a/sysdeps/unix/sysv/linux/sysdep.h b/sysdeps/unix/sysv/linux/sysdep.h
index 4e25e51470..3fa29dd588 100644
--- a/sysdeps/unix/sysv/linux/sysdep.h
+++ b/sysdeps/unix/sysv/linux/sysdep.h
@@ -22,9 +22,13 @@ 
 #include <kernel-features.h>
 #include <errno.h>
 
-#undef INTERNAL_SYSCALL_ERROR_P
-#define INTERNAL_SYSCALL_ERROR_P(val) \
-  ((unsigned long int) (val) > -4096UL)
+#ifndef __ASSEMBLER__
+static inline _Bool
+syscall_error (unsigned long int val)
+{
+  return val > -4096UL;
+}
+#endif
 
 #ifndef SYSCALL_ERROR_LABEL
 # define SYSCALL_ERROR_LABEL(sc_err)					\
@@ -34,6 +38,7 @@ 
   })
 #endif
 
+#ifndef __ASSEMBLER__
 /* Define a macro which expands into the inline wrapper code for a system
    call.  It sets the errno and returns -1 on a failure, or the syscall
    return value otherwise.  */
@@ -41,10 +46,11 @@ 
 #define INLINE_SYSCALL(name, nr, args...)				\
   ({									\
     long int sc_ret = INTERNAL_SYSCALL (name, nr, args);		\
-    __glibc_unlikely (INTERNAL_SYSCALL_ERROR_P (sc_ret))		\
+    __glibc_unlikely (syscall_error (sc_ret))				\
     ? SYSCALL_ERROR_LABEL (-sc_ret)					\
     : sc_ret;								\
   })
+#endif
 
 /* Set error number and return -1.  A target may choose to return the
    internal function, __syscall_error, which sets errno and returns -1.
diff --git a/sysdeps/unix/sysv/linux/timer_create.c b/sysdeps/unix/sysv/linux/timer_create.c
index d8289d1dc7..1f5f2b95da 100644
--- a/sysdeps/unix/sysv/linux/timer_create.c
+++ b/sysdeps/unix/sysv/linux/timer_create.c
@@ -124,7 +124,7 @@  timer_create (clockid_t clock_id, struct sigevent *evp, timer_t *timerid)
 	int res;
 	res = INTERNAL_SYSCALL_CALL (timer_create, syscall_clockid, &sev,
 				     &newp->ktimerid);
-	if (INTERNAL_SYSCALL_ERROR_P (res))
+	if (syscall_error (res))
 	  {
 	    free (newp);
 	    __set_errno (-res);
diff --git a/sysdeps/unix/sysv/linux/times.c b/sysdeps/unix/sysv/linux/times.c
index b5eb6404c9..0b47979bfd 100644
--- a/sysdeps/unix/sysv/linux/times.c
+++ b/sysdeps/unix/sysv/linux/times.c
@@ -19,12 +19,15 @@ 
 #include <sys/times.h>
 #include <sysdep.h>
 
+#ifndef SYSCALL_ERROR
+# define SYSCALL_ERROR(__val) syscall_error(__val)
+#endif
 
 clock_t
 __times (struct tms *buf)
 {
   clock_t ret = INTERNAL_SYSCALL_CALL (times, buf);
-  if (INTERNAL_SYSCALL_ERROR_P (ret)
+  if (syscall_error (ret)
       && __glibc_unlikely (ret == -EFAULT)
       && buf)
     {
diff --git a/sysdeps/unix/sysv/linux/x86_64/x32/times.c b/sysdeps/unix/sysv/linux/x86_64/x32/times.c
index 864c123117..f540447b0a 100644
--- a/sysdeps/unix/sysv/linux/x86_64/x32/times.c
+++ b/sysdeps/unix/sysv/linux/x86_64/x32/times.c
@@ -33,8 +33,11 @@ 
     (long long int) resultvar;						\
 })
 
-#undef INTERNAL_SYSCALL_ERROR_P
-#define INTERNAL_SYSCALL_ERROR_P(val) \
-  ((unsigned long long int) (val) >= -4095LL)
+static inline _Bool
+syscall_error_u64 (unsigned long long int val)
+{
+  return val > -4096ULL;
+}
+#define SYSCALL_ERROR(__val) syscall_error_u64 (__val)
 
 #include <sysdeps/unix/sysv/linux/times.c>