[01/23] linux: Remove INTERNAL_SYSCALL_ERRNO

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

Commit Message

Michael Hudson-Doyle via Libc-alpha Nov. 9, 2020, 8:18 p.m.
All architectures now returns the error code on the INTERNAL_SYSCALL
value and follow the Linux de-facto ABI (error are signaled with a
value between -4096UL and -1UL).  This make the INTERNAL_SYSCALL_ERRNO
superflous and some implementations already checks for either values
different than 0 or for an specific errno in the failure case.

Checked on x86_64-linux-gnu and powerpc64le-linux-gnu.
---
 nptl/allocatestack.c                                   |  2 +-
 nptl/nptl-init.c                                       |  2 +-
 nptl/pthread_cancel.c                                  |  2 +-
 nptl/pthread_getaffinity.c                             |  2 +-
 nptl/pthread_mutex_trylock.c                           |  3 +--
 nptl/pthread_setaffinity.c                             |  2 +-
 nptl/pthread_sigmask.c                                 |  2 +-
 sysdeps/nptl/lowlevellock-futex.h                      |  2 +-
 sysdeps/unix/sysv/linux/createthread.c                 |  2 +-
 sysdeps/unix/sysv/linux/dl-write.c                     |  5 +----
 sysdeps/unix/sysv/linux/fcntl_nocancel.c               |  3 +--
 sysdeps/unix/sysv/linux/libc_fatal.c                   |  3 +--
 sysdeps/unix/sysv/linux/mq_unlink.c                    |  7 +++----
 sysdeps/unix/sysv/linux/not-errno.h                    |  4 ++--
 sysdeps/unix/sysv/linux/personality.c                  | 10 +---------
 sysdeps/unix/sysv/linux/posix_fadvise.c                |  4 +---
 sysdeps/unix/sysv/linux/posix_fadvise64.c              |  4 +---
 sysdeps/unix/sysv/linux/posix_fallocate.c              |  4 ++--
 sysdeps/unix/sysv/linux/posix_fallocate64.c            |  4 ++--
 sysdeps/unix/sysv/linux/posix_madvise.c                |  3 +--
 sysdeps/unix/sysv/linux/pthread_kill.c                 |  3 +--
 sysdeps/unix/sysv/linux/pthread_sigqueue.c             |  3 +--
 sysdeps/unix/sysv/linux/s390/s390-32/posix_fadvise64.c |  4 +---
 sysdeps/unix/sysv/linux/shmat.c                        |  2 +-
 sysdeps/unix/sysv/linux/sysdep-vdso.h                  |  4 ++--
 sysdeps/unix/sysv/linux/sysdep.h                       |  5 +----
 sysdeps/unix/sysv/linux/timer_create.c                 |  2 +-
 sysdeps/unix/sysv/linux/times.c                        |  2 +-
 28 files changed, 34 insertions(+), 61 deletions(-)

-- 
2.25.1

Comments

Michael Hudson-Doyle via Libc-alpha Nov. 10, 2020, 11:11 a.m. | #1
* Adhemerval Zanella via Libc-alpha:

> diff --git a/sysdeps/unix/sysv/linux/posix_fadvise.c b/sysdeps/unix/sysv/linux/posix_fadvise.c

> index bada96b697..1191ab3db5 100644

> --- a/sysdeps/unix/sysv/linux/posix_fadvise.c

> +++ b/sysdeps/unix/sysv/linux/posix_fadvise.c

> @@ -60,8 +60,6 @@ posix_fadvise (int fd, off_t offset, off_t len, int advise)

>  				   SYSCALL_LL (len), advise);

>  #  endif

>  # endif

> -  if (INTERNAL_SYSCALL_ERROR_P (ret))

> -    return INTERNAL_SYSCALL_ERRNO (ret);

> -  return 0;

> +  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 9787ab4c7c..e3726a6a8a 100644

> --- a/sysdeps/unix/sysv/linux/posix_fadvise64.c

> +++ b/sysdeps/unix/sysv/linux/posix_fadvise64.c

> @@ -48,9 +48,7 @@ __posix_fadvise64_l64 (int fd, off64_t offset, off64_t len, int advise)

>  				   __ALIGNMENT_ARG SYSCALL_LL64 (offset),

>  				   SYSCALL_LL64 (len), advise);

>  #endif

> -  if (!INTERNAL_SYSCALL_ERROR_P (ret))

> -    return 0;

> -  return INTERNAL_SYSCALL_ERRNO (ret);

> +  return INTERNAL_SYSCALL_ERROR_P (ret) ? -ret : 0;

>  }

>  

>  /* The type of the len argument was changed from size_t to off_t in


These two could just use -ret, I think.  The kernel returns 0 for
success, right?

> diff --git a/sysdeps/unix/sysv/linux/posix_fallocate.c b/sysdeps/unix/sysv/linux/posix_fallocate.c

> index 7238b00038..87532668cd 100644

> --- a/sysdeps/unix/sysv/linux/posix_fallocate.c

> +++ b/sysdeps/unix/sysv/linux/posix_fallocate.c

> @@ -30,7 +30,7 @@ posix_fallocate (int fd, __off_t offset, __off_t len)

>  				   SYSCALL_LL (offset), SYSCALL_LL (len));

>    if (! INTERNAL_SYSCALL_ERROR_P (res))

>      return 0;

> -  if (INTERNAL_SYSCALL_ERRNO (res) != EOPNOTSUPP)

> -    return INTERNAL_SYSCALL_ERRNO (res);

> +  if (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 2de63ac277..0340357e57 100644

> --- a/sysdeps/unix/sysv/linux/posix_fallocate64.c

> +++ b/sysdeps/unix/sysv/linux/posix_fallocate64.c

> @@ -32,8 +32,8 @@ __posix_fallocate64_l64 (int fd, __off64_t offset, __off64_t len)

>  				   SYSCALL_LL64 (offset), SYSCALL_LL64 (len));

>    if (! INTERNAL_SYSCALL_ERROR_P (res))

>      return 0;

> -  if (INTERNAL_SYSCALL_ERRNO (res) != EOPNOTSUPP)

> -    return INTERNAL_SYSCALL_ERRNO (res);

> +  if (-res != EOPNOTSUPP)

> +    return -res;

>    return internal_fallocate64 (fd, offset, len);

>  }

>  libc_hidden_def (__posix_fallocate64_l64)


-res == EOPNOTSUPP is inconsistent with the rest of the patch.

> diff --git a/sysdeps/unix/sysv/linux/pthread_sigqueue.c b/sysdeps/unix/sysv/linux/pthread_sigqueue.c

> index 4b32be2d64..fbbd9fee20 100644

> --- a/sysdeps/unix/sysv/linux/pthread_sigqueue.c

> +++ b/sysdeps/unix/sysv/linux/pthread_sigqueue.c

> @@ -63,8 +63,7 @@ pthread_sigqueue (pthread_t threadid, int signo, const union sigval 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)

> -	  ? INTERNAL_SYSCALL_ERRNO (val) : 0);

> +  return INTERNAL_SYSCALL_ERROR_P (val) ? -val : 0;

>  #else

>    return ENOSYS;

>  #endif


This could use plain -val.

> 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 b556a6caae..6199589307 100644

> --- a/sysdeps/unix/sysv/linux/s390/s390-32/posix_fadvise64.c

> +++ b/sysdeps/unix/sysv/linux/s390/s390-32/posix_fadvise64.c

> @@ -43,9 +43,7 @@ __posix_fadvise64_l64 (int fd, off64_t offset, off64_t len, int advise)

>    parameters.len = len;

>    parameters.advise = advise;

>    int ret = INTERNAL_SYSCALL_CALL (fadvise64_64, &parameters);

> -  if (!INTERNAL_SYSCALL_ERROR_P (ret))

> -    return 0;

> -  return INTERNAL_SYSCALL_ERRNO (ret);

> +  return INTERNAL_SYSCALL_ERROR_P (ret) ? -ret : 0;

>  }

>  

>  #include <shlib-compat.h>


See above, plain -ret should be okay.


The patch relies on a GCC extension because in the error case, -res is a
large unsigned value which cannot be represented in an int.  But I think
this is okay.

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:21 p.m. | #2
On 10/11/2020 08:11, Florian Weimer wrote:
> * Adhemerval Zanella via Libc-alpha:

> 

>> diff --git a/sysdeps/unix/sysv/linux/posix_fadvise.c b/sysdeps/unix/sysv/linux/posix_fadvise.c

>> index bada96b697..1191ab3db5 100644

>> --- a/sysdeps/unix/sysv/linux/posix_fadvise.c

>> +++ b/sysdeps/unix/sysv/linux/posix_fadvise.c

>> @@ -60,8 +60,6 @@ posix_fadvise (int fd, off_t offset, off_t len, int advise)

>>  				   SYSCALL_LL (len), advise);

>>  #  endif

>>  # endif

>> -  if (INTERNAL_SYSCALL_ERROR_P (ret))

>> -    return INTERNAL_SYSCALL_ERRNO (ret);

>> -  return 0;

>> +  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 9787ab4c7c..e3726a6a8a 100644

>> --- a/sysdeps/unix/sysv/linux/posix_fadvise64.c

>> +++ b/sysdeps/unix/sysv/linux/posix_fadvise64.c

>> @@ -48,9 +48,7 @@ __posix_fadvise64_l64 (int fd, off64_t offset, off64_t len, int advise)

>>  				   __ALIGNMENT_ARG SYSCALL_LL64 (offset),

>>  				   SYSCALL_LL64 (len), advise);

>>  #endif

>> -  if (!INTERNAL_SYSCALL_ERROR_P (ret))

>> -    return 0;

>> -  return INTERNAL_SYSCALL_ERRNO (ret);

>> +  return INTERNAL_SYSCALL_ERROR_P (ret) ? -ret : 0;

>>  }

>>  

>>  /* The type of the len argument was changed from size_t to off_t in

> 

> These two could just use -ret, I think.  The kernel returns 0 for

> success, right?

> 


Yes, I make this change on the the subsequent patch where I remove the
INTERNAL_SYSCALL_ERROR_P macro.  

>> diff --git a/sysdeps/unix/sysv/linux/posix_fallocate.c b/sysdeps/unix/sysv/linux/posix_fallocate.c

>> index 7238b00038..87532668cd 100644

>> --- a/sysdeps/unix/sysv/linux/posix_fallocate.c

>> +++ b/sysdeps/unix/sysv/linux/posix_fallocate.c

>> @@ -30,7 +30,7 @@ posix_fallocate (int fd, __off_t offset, __off_t len)

>>  				   SYSCALL_LL (offset), SYSCALL_LL (len));

>>    if (! INTERNAL_SYSCALL_ERROR_P (res))

>>      return 0;

>> -  if (INTERNAL_SYSCALL_ERRNO (res) != EOPNOTSUPP)

>> -    return INTERNAL_SYSCALL_ERRNO (res);

>> +  if (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 2de63ac277..0340357e57 100644

>> --- a/sysdeps/unix/sysv/linux/posix_fallocate64.c

>> +++ b/sysdeps/unix/sysv/linux/posix_fallocate64.c

>> @@ -32,8 +32,8 @@ __posix_fallocate64_l64 (int fd, __off64_t offset, __off64_t len)

>>  				   SYSCALL_LL64 (offset), SYSCALL_LL64 (len));

>>    if (! INTERNAL_SYSCALL_ERROR_P (res))

>>      return 0;

>> -  if (INTERNAL_SYSCALL_ERRNO (res) != EOPNOTSUPP)

>> -    return INTERNAL_SYSCALL_ERRNO (res);

>> +  if (-res != EOPNOTSUPP)

>> +    return -res;

>>    return internal_fallocate64 (fd, offset, len);

>>  }

>>  libc_hidden_def (__posix_fallocate64_l64)

> 

> -res == EOPNOTSUPP is inconsistent with the rest of the patch.


Do you mean change to 'res == -EOPNOTSUPP) ?

> 

>> diff --git a/sysdeps/unix/sysv/linux/pthread_sigqueue.c b/sysdeps/unix/sysv/linux/pthread_sigqueue.c

>> index 4b32be2d64..fbbd9fee20 100644

>> --- a/sysdeps/unix/sysv/linux/pthread_sigqueue.c

>> +++ b/sysdeps/unix/sysv/linux/pthread_sigqueue.c

>> @@ -63,8 +63,7 @@ pthread_sigqueue (pthread_t threadid, int signo, const union sigval 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)

>> -	  ? INTERNAL_SYSCALL_ERRNO (val) : 0);

>> +  return INTERNAL_SYSCALL_ERROR_P (val) ? -val : 0;

>>  #else

>>    return ENOSYS;

>>  #endif

> 

> This could use plain -val.

> 

>> 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 b556a6caae..6199589307 100644

>> --- a/sysdeps/unix/sysv/linux/s390/s390-32/posix_fadvise64.c

>> +++ b/sysdeps/unix/sysv/linux/s390/s390-32/posix_fadvise64.c

>> @@ -43,9 +43,7 @@ __posix_fadvise64_l64 (int fd, off64_t offset, off64_t len, int advise)

>>    parameters.len = len;

>>    parameters.advise = advise;

>>    int ret = INTERNAL_SYSCALL_CALL (fadvise64_64, &parameters);

>> -  if (!INTERNAL_SYSCALL_ERROR_P (ret))

>> -    return 0;

>> -  return INTERNAL_SYSCALL_ERRNO (ret);

>> +  return INTERNAL_SYSCALL_ERROR_P (ret) ? -ret : 0;

>>  }

>>  

>>  #include <shlib-compat.h>

> 

> See above, plain -ret should be okay.

> 

> 

> The patch relies on a GCC extension because in the error case, -res is a

> large unsigned value which cannot be represented in an int.  But I think

> this is okay.


I think with subsequent patches where it moves towards inline functions with
a more well typed interface should make the internal syscall interface more
well-defined.

Patch

diff --git a/nptl/allocatestack.c b/nptl/allocatestack.c
index 4b45f8c884..a9e9d39354 100644
--- a/nptl/allocatestack.c
+++ b/nptl/allocatestack.c
@@ -1174,7 +1174,7 @@  __nptl_setxid (struct xid_command *cmdp)
   int error = 0;
   if (__glibc_unlikely (INTERNAL_SYSCALL_ERROR_P (result)))
     {
-      error = INTERNAL_SYSCALL_ERRNO (result);
+      error = -result;
       __set_errno (error);
       result = -1;
     }
diff --git a/nptl/nptl-init.c b/nptl/nptl-init.c
index 95c60a524a..8aef4c83b5 100644
--- a/nptl/nptl-init.c
+++ b/nptl/nptl-init.c
@@ -192,7 +192,7 @@  sighandler_setxid (int sig, siginfo_t *si, void *ctx)
 				 __xidcmd->id[1], __xidcmd->id[2]);
   int error = 0;
   if (__glibc_unlikely (INTERNAL_SYSCALL_ERROR_P (result)))
-    error = INTERNAL_SYSCALL_ERRNO (result);
+    error = -result;
   __nptl_setxid_error (__xidcmd, error);
 
   /* Reset the SETXID flag.  */
diff --git a/nptl/pthread_cancel.c b/nptl/pthread_cancel.c
index 88c1ab8f6a..7daf4f8c15 100644
--- a/nptl/pthread_cancel.c
+++ b/nptl/pthread_cancel.c
@@ -70,7 +70,7 @@  __pthread_cancel (pthread_t th)
 	  int val = INTERNAL_SYSCALL_CALL (tgkill, pid, pd->tid,
 					   SIGCANCEL);
 	  if (INTERNAL_SYSCALL_ERROR_P (val))
-	    result = INTERNAL_SYSCALL_ERRNO (val);
+	    result = -val;
 
 	  break;
 	}
diff --git a/nptl/pthread_getaffinity.c b/nptl/pthread_getaffinity.c
index 6ebd1ded2d..ffeb878c7c 100644
--- a/nptl/pthread_getaffinity.c
+++ b/nptl/pthread_getaffinity.c
@@ -34,7 +34,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))
-    return INTERNAL_SYSCALL_ERRNO (res);
+    return -res;
 
   /* Clean the rest of the memory the kernel didn't do.  */
   memset ((char *) cpuset + res, '\0', cpusetsize - res);
diff --git a/nptl/pthread_mutex_trylock.c b/nptl/pthread_mutex_trylock.c
index 2130f52529..5c294a3eea 100644
--- a/nptl/pthread_mutex_trylock.c
+++ b/nptl/pthread_mutex_trylock.c
@@ -301,8 +301,7 @@  __pthread_mutex_trylock (pthread_mutex_t *mutex)
 					   __lll_private_flag (FUTEX_TRYLOCK_PI,
 							       private), 0, 0);
 
-	    if (INTERNAL_SYSCALL_ERROR_P (e)
-		&& INTERNAL_SYSCALL_ERRNO (e) == EWOULDBLOCK)
+	    if (INTERNAL_SYSCALL_ERROR_P (e) && 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 b0bd90c324..aaaa4f0194 100644
--- a/nptl/pthread_setaffinity.c
+++ b/nptl/pthread_setaffinity.c
@@ -34,7 +34,7 @@  __pthread_setaffinity_new (pthread_t th, size_t cpusetsize,
 			       cpuset);
 
   return (INTERNAL_SYSCALL_ERROR_P (res)
-	  ? INTERNAL_SYSCALL_ERRNO (res)
+	  ? -res
 	  : 0);
 }
 versioned_symbol (libpthread, __pthread_setaffinity_new,
diff --git a/nptl/pthread_sigmask.c b/nptl/pthread_sigmask.c
index 7b65ae1f27..1d6d753af4 100644
--- a/nptl/pthread_sigmask.c
+++ b/nptl/pthread_sigmask.c
@@ -42,7 +42,7 @@  __pthread_sigmask (int how, const sigset_t *newmask, sigset_t *oldmask)
 				      oldmask, __NSIG_BYTES);
 
   return (INTERNAL_SYSCALL_ERROR_P (result)
-	  ? INTERNAL_SYSCALL_ERRNO (result)
+	  ? -result
 	  : 0);
 }
 libc_hidden_def (__pthread_sigmask)
diff --git a/sysdeps/nptl/lowlevellock-futex.h b/sysdeps/nptl/lowlevellock-futex.h
index 2209ca76a1..dd36997021 100644
--- a/sysdeps/nptl/lowlevellock-futex.h
+++ b/sysdeps/nptl/lowlevellock-futex.h
@@ -70,7 +70,7 @@ 
     long int __ret = INTERNAL_SYSCALL (futex, nargs, futexp, op, 	\
 				       __VA_ARGS__);                    \
     (__glibc_unlikely (INTERNAL_SYSCALL_ERROR_P (__ret))         	\
-     ? -INTERNAL_SYSCALL_ERRNO (__ret) : 0);                     	\
+     ? __ret : 0);                     					\
   })
 
 /* For most of these macros, the return value is never really used.
diff --git a/sysdeps/unix/sysv/linux/createthread.c b/sysdeps/unix/sysv/linux/createthread.c
index 6588893ba5..01cf2ff42a 100644
--- a/sysdeps/unix/sysv/linux/createthread.c
+++ b/sysdeps/unix/sysv/linux/createthread.c
@@ -132,7 +132,7 @@  create_thread (struct pthread *pd, const struct pthread_attr *attr,
 	      pid_t pid = __getpid ();
 	      INTERNAL_SYSCALL_CALL (tgkill, pid, pd->tid, SIGCANCEL);
 
-	      return INTERNAL_SYSCALL_ERRNO (res);
+	      return -res;
 	    }
 	}
 
diff --git a/sysdeps/unix/sysv/linux/dl-write.c b/sysdeps/unix/sysv/linux/dl-write.c
index 1c6298fb41..cce5a55e68 100644
--- a/sysdeps/unix/sysv/linux/dl-write.c
+++ b/sysdeps/unix/sysv/linux/dl-write.c
@@ -23,8 +23,5 @@ 
 ssize_t
 _dl_write (int fd, const void *buffer, size_t length)
 {
-  long int r = INTERNAL_SYSCALL_CALL (write, fd, buffer, length);
-  if (INTERNAL_SYSCALL_ERROR_P (r))
-    r = - INTERNAL_SYSCALL_ERRNO (r);
-  return r;
+  return INTERNAL_SYSCALL_CALL (write, fd, buffer, length);
 }
diff --git a/sysdeps/unix/sysv/linux/fcntl_nocancel.c b/sysdeps/unix/sysv/linux/fcntl_nocancel.c
index ed9211001f..1bf3030f75 100644
--- a/sysdeps/unix/sysv/linux/fcntl_nocancel.c
+++ b/sysdeps/unix/sysv/linux/fcntl_nocancel.c
@@ -56,8 +56,7 @@  __fcntl64_nocancel_adjusted (int fd, int cmd, void *arg)
       if (!INTERNAL_SYSCALL_ERROR_P (res))
 	return fex.type == F_OWNER_GID ? -fex.pid : fex.pid;
 
-      return INLINE_SYSCALL_ERROR_RETURN_VALUE
-        (INTERNAL_SYSCALL_ERRNO (res));
+      return INLINE_SYSCALL_ERROR_RETURN_VALUE (-res);
     }
 
   return INLINE_SYSCALL_CALL (fcntl64, fd, cmd, (void *) arg);
diff --git a/sysdeps/unix/sysv/linux/libc_fatal.c b/sysdeps/unix/sysv/linux/libc_fatal.c
index 7e22c0fc32..35a20ca0fd 100644
--- a/sysdeps/unix/sysv/linux/libc_fatal.c
+++ b/sysdeps/unix/sysv/linux/libc_fatal.c
@@ -25,8 +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)
-         && INTERNAL_SYSCALL_ERRNO (cnt) == EINTR);
+  while (INTERNAL_SYSCALL_ERROR_P (cnt) && cnt == -EINTR);
   return cnt == total;
 }
 #define WRITEV_FOR_FATAL	writev_for_fatal
diff --git a/sysdeps/unix/sysv/linux/mq_unlink.c b/sysdeps/unix/sysv/linux/mq_unlink.c
index 85fb5d0951..ed7858dc9d 100644
--- a/sysdeps/unix/sysv/linux/mq_unlink.c
+++ b/sysdeps/unix/sysv/linux/mq_unlink.c
@@ -32,10 +32,9 @@  mq_unlink (const char *name)
      return just EACCES.  */
   if (__glibc_unlikely (INTERNAL_SYSCALL_ERROR_P (ret)))
     {
-      ret = INTERNAL_SYSCALL_ERRNO (ret);
-      if (ret == EPERM)
-	ret = EACCES;
-      return INLINE_SYSCALL_ERROR_RETURN_VALUE (ret);
+      if (ret == -EPERM)
+	ret = -EACCES;
+      return INLINE_SYSCALL_ERROR_RETURN_VALUE (-ret);
     }
 
   return ret;
diff --git a/sysdeps/unix/sysv/linux/not-errno.h b/sysdeps/unix/sysv/linux/not-errno.h
index 394dabeb93..fc0eda09d9 100644
--- a/sysdeps/unix/sysv/linux/not-errno.h
+++ b/sysdeps/unix/sysv/linux/not-errno.h
@@ -32,7 +32,7 @@  __access_noerrno (const char *pathname, int mode)
   res = INTERNAL_SYSCALL_CALL (faccessat, AT_FDCWD, pathname, mode);
 #endif
   if (INTERNAL_SYSCALL_ERROR_P (res))
-    return INTERNAL_SYSCALL_ERRNO (res);
+    return -res;
   return 0;
 }
 
@@ -42,6 +42,6 @@  __kill_noerrno (pid_t pid, int sig)
   int res;
   res = INTERNAL_SYSCALL_CALL (kill, pid, sig);
   if (INTERNAL_SYSCALL_ERROR_P (res))
-    return INTERNAL_SYSCALL_ERRNO (res);
+    return -res;
   return 0;
 }
diff --git a/sysdeps/unix/sysv/linux/personality.c b/sysdeps/unix/sysv/linux/personality.c
index e45fffa1c2..75f9d0adb2 100644
--- a/sysdeps/unix/sysv/linux/personality.c
+++ b/sysdeps/unix/sysv/linux/personality.c
@@ -35,14 +35,6 @@  __personality (unsigned long persona)
   persona = (unsigned int) persona;
 #endif
 
-  long int ret = INTERNAL_SYSCALL_CALL (personality, persona);
-
-  /* Starting with kernel commit v2.6.29-6609-g11d06b2, the personality syscall
-     never fails.  However, 32-bit kernels might flag valid values as errors, so
-     we need to reverse the error setting.  We can't use the raw result as some
-     arches split the return/error values.  */
-  if (__glibc_unlikely (INTERNAL_SYSCALL_ERROR_P (ret)))
-    ret = -INTERNAL_SYSCALL_ERRNO (ret);
-  return ret;
+  return INTERNAL_SYSCALL_CALL (personality, persona);
 }
 weak_alias (__personality, personality)
diff --git a/sysdeps/unix/sysv/linux/posix_fadvise.c b/sysdeps/unix/sysv/linux/posix_fadvise.c
index bada96b697..1191ab3db5 100644
--- a/sysdeps/unix/sysv/linux/posix_fadvise.c
+++ b/sysdeps/unix/sysv/linux/posix_fadvise.c
@@ -60,8 +60,6 @@  posix_fadvise (int fd, off_t offset, off_t len, int advise)
 				   SYSCALL_LL (len), advise);
 #  endif
 # endif
-  if (INTERNAL_SYSCALL_ERROR_P (ret))
-    return INTERNAL_SYSCALL_ERRNO (ret);
-  return 0;
+  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 9787ab4c7c..e3726a6a8a 100644
--- a/sysdeps/unix/sysv/linux/posix_fadvise64.c
+++ b/sysdeps/unix/sysv/linux/posix_fadvise64.c
@@ -48,9 +48,7 @@  __posix_fadvise64_l64 (int fd, off64_t offset, off64_t len, int advise)
 				   __ALIGNMENT_ARG SYSCALL_LL64 (offset),
 				   SYSCALL_LL64 (len), advise);
 #endif
-  if (!INTERNAL_SYSCALL_ERROR_P (ret))
-    return 0;
-  return INTERNAL_SYSCALL_ERRNO (ret);
+  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 7238b00038..87532668cd 100644
--- a/sysdeps/unix/sysv/linux/posix_fallocate.c
+++ b/sysdeps/unix/sysv/linux/posix_fallocate.c
@@ -30,7 +30,7 @@  posix_fallocate (int fd, __off_t offset, __off_t len)
 				   SYSCALL_LL (offset), SYSCALL_LL (len));
   if (! INTERNAL_SYSCALL_ERROR_P (res))
     return 0;
-  if (INTERNAL_SYSCALL_ERRNO (res) != EOPNOTSUPP)
-    return INTERNAL_SYSCALL_ERRNO (res);
+  if (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 2de63ac277..0340357e57 100644
--- a/sysdeps/unix/sysv/linux/posix_fallocate64.c
+++ b/sysdeps/unix/sysv/linux/posix_fallocate64.c
@@ -32,8 +32,8 @@  __posix_fallocate64_l64 (int fd, __off64_t offset, __off64_t len)
 				   SYSCALL_LL64 (offset), SYSCALL_LL64 (len));
   if (! INTERNAL_SYSCALL_ERROR_P (res))
     return 0;
-  if (INTERNAL_SYSCALL_ERRNO (res) != EOPNOTSUPP)
-    return INTERNAL_SYSCALL_ERRNO (res);
+  if (-res != EOPNOTSUPP)
+    return -res;
   return internal_fallocate64 (fd, offset, len);
 }
 libc_hidden_def (__posix_fallocate64_l64)
diff --git a/sysdeps/unix/sysv/linux/posix_madvise.c b/sysdeps/unix/sysv/linux/posix_madvise.c
index 0e49f3b7ac..5fe2e5f653 100644
--- a/sysdeps/unix/sysv/linux/posix_madvise.c
+++ b/sysdeps/unix/sysv/linux/posix_madvise.c
@@ -31,6 +31,5 @@  posix_madvise (void *addr, size_t len, int advice)
   if (advice == POSIX_MADV_DONTNEED)
     return 0;
 
-  int result = INTERNAL_SYSCALL_CALL (madvise, addr, len, advice);
-  return INTERNAL_SYSCALL_ERRNO (result);
+  return -INTERNAL_SYSCALL_CALL (madvise, addr, len, advice);
 }
diff --git a/sysdeps/unix/sysv/linux/pthread_kill.c b/sysdeps/unix/sysv/linux/pthread_kill.c
index 4dfe08ffcd..defdeaecac 100644
--- a/sysdeps/unix/sysv/linux/pthread_kill.c
+++ b/sysdeps/unix/sysv/linux/pthread_kill.c
@@ -51,7 +51,6 @@  __pthread_kill (pthread_t threadid, int signo)
   pid_t pid = __getpid ();
 
   int val = INTERNAL_SYSCALL_CALL (tgkill, pid, tid, signo);
-  return (INTERNAL_SYSCALL_ERROR_P (val)
-	  ? INTERNAL_SYSCALL_ERRNO (val) : 0);
+  return INTERNAL_SYSCALL_ERROR_P (val) ? -val : 0;
 }
 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 4b32be2d64..fbbd9fee20 100644
--- a/sysdeps/unix/sysv/linux/pthread_sigqueue.c
+++ b/sysdeps/unix/sysv/linux/pthread_sigqueue.c
@@ -63,8 +63,7 @@  pthread_sigqueue (pthread_t threadid, int signo, const union sigval 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)
-	  ? INTERNAL_SYSCALL_ERRNO (val) : 0);
+  return INTERNAL_SYSCALL_ERROR_P (val) ? -val : 0;
 #else
   return ENOSYS;
 #endif
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 b556a6caae..6199589307 100644
--- a/sysdeps/unix/sysv/linux/s390/s390-32/posix_fadvise64.c
+++ b/sysdeps/unix/sysv/linux/s390/s390-32/posix_fadvise64.c
@@ -43,9 +43,7 @@  __posix_fadvise64_l64 (int fd, off64_t offset, off64_t len, int advise)
   parameters.len = len;
   parameters.advise = advise;
   int ret = INTERNAL_SYSCALL_CALL (fadvise64_64, &parameters);
-  if (!INTERNAL_SYSCALL_ERROR_P (ret))
-    return 0;
-  return INTERNAL_SYSCALL_ERRNO (ret);
+  return INTERNAL_SYSCALL_ERROR_P (ret) ? -ret : 0;
 }
 
 #include <shlib-compat.h>
diff --git a/sysdeps/unix/sysv/linux/shmat.c b/sysdeps/unix/sysv/linux/shmat.c
index 89df350d84..d5a65c06c1 100644
--- a/sysdeps/unix/sysv/linux/shmat.c
+++ b/sysdeps/unix/sysv/linux/shmat.c
@@ -36,7 +36,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))
-    return (void *) INLINE_SYSCALL_ERROR_RETURN_VALUE (INTERNAL_SYSCALL_ERRNO (resultvar));
+    return (void *) INLINE_SYSCALL_ERROR_RETURN_VALUE (-resultvar);
 
   return raddr;
 #endif
diff --git a/sysdeps/unix/sysv/linux/sysdep-vdso.h b/sysdeps/unix/sysv/linux/sysdep-vdso.h
index a9215494dc..88db076184 100644
--- a/sysdeps/unix/sysv/linux/sysdep-vdso.h
+++ b/sysdeps/unix/sysv/linux/sysdep-vdso.h
@@ -38,7 +38,7 @@ 
 	sc_ret = INTERNAL_VSYSCALL_CALL (vdsop, nr, ##args);	      	      \
 	if (!INTERNAL_SYSCALL_ERROR_P (sc_ret))			      	      \
 	  goto out;							      \
-	if (INTERNAL_SYSCALL_ERRNO (sc_ret) != ENOSYS)		      	      \
+	if (sc_ret != -ENOSYS)		      	      			      \
 	  goto iserr;							      \
       }									      \
 									      \
@@ -46,7 +46,7 @@ 
     if (INTERNAL_SYSCALL_ERROR_P (sc_ret))			      	      \
       {									      \
       iserr:								      \
-        __set_errno (INTERNAL_SYSCALL_ERRNO (sc_ret));		      	      \
+        __set_errno (-sc_ret);		      	      			      \
         sc_ret = -1L;							      \
       }									      \
   out:									      \
diff --git a/sysdeps/unix/sysv/linux/sysdep.h b/sysdeps/unix/sysv/linux/sysdep.h
index 5e7b6c5765..4e25e51470 100644
--- a/sysdeps/unix/sysv/linux/sysdep.h
+++ b/sysdeps/unix/sysv/linux/sysdep.h
@@ -42,13 +42,10 @@ 
   ({									\
     long int sc_ret = INTERNAL_SYSCALL (name, nr, args);		\
     __glibc_unlikely (INTERNAL_SYSCALL_ERROR_P (sc_ret))		\
-    ? SYSCALL_ERROR_LABEL (INTERNAL_SYSCALL_ERRNO (sc_ret))		\
+    ? SYSCALL_ERROR_LABEL (-sc_ret)					\
     : sc_ret;								\
   })
 
-#undef INTERNAL_SYSCALL_ERRNO
-#define INTERNAL_SYSCALL_ERRNO(val)     (-(val))
-
 /* Set error number and return -1.  A target may choose to return the
    internal function, __syscall_error, which sets errno and returns -1.
    We use -1l, instead of -1, so that it can be casted to (void *).  */
diff --git a/sysdeps/unix/sysv/linux/timer_create.c b/sysdeps/unix/sysv/linux/timer_create.c
index 18fb00c6e6..d8289d1dc7 100644
--- a/sysdeps/unix/sysv/linux/timer_create.c
+++ b/sysdeps/unix/sysv/linux/timer_create.c
@@ -127,7 +127,7 @@  timer_create (clockid_t clock_id, struct sigevent *evp, timer_t *timerid)
 	if (INTERNAL_SYSCALL_ERROR_P (res))
 	  {
 	    free (newp);
-	    __set_errno (INTERNAL_SYSCALL_ERRNO (res));
+	    __set_errno (-res);
 	    return -1;
 	  }
 
diff --git a/sysdeps/unix/sysv/linux/times.c b/sysdeps/unix/sysv/linux/times.c
index e3db9cb400..b5eb6404c9 100644
--- a/sysdeps/unix/sysv/linux/times.c
+++ b/sysdeps/unix/sysv/linux/times.c
@@ -25,7 +25,7 @@  __times (struct tms *buf)
 {
   clock_t ret = INTERNAL_SYSCALL_CALL (times, buf);
   if (INTERNAL_SYSCALL_ERROR_P (ret)
-      && __glibc_unlikely (INTERNAL_SYSCALL_ERRNO (ret) == EFAULT)
+      && __glibc_unlikely (ret == -EFAULT)
       && buf)
     {
       /* This might be an error or not.  For architectures which have no