All of lore.kernel.org
 help / color / mirror / Atom feed
From: Filip Bozuta <Filip.Bozuta@syrmia.com>
To: qemu-devel@nongnu.org
Cc: Laurent Vivier <laurent@vivier.eu>,
	Filip Bozuta <Filip.Bozuta@syrmia.com>
Subject: [PATCH 1/2] linux-user: Add support for 'ppoll_time64()' and 'pselect6_time64()'
Date: Wed, 12 Aug 2020 15:57:02 +0200	[thread overview]
Message-ID: <20200812135703.39404-2-Filip.Bozuta@syrmia.com> (raw)
In-Reply-To: <20200812135703.39404-1-Filip.Bozuta@syrmia.com>

This patch introduces functionality for following time64 syscalls:

*ppoll_time64

    This is a year 2038 safe variant of:

    int poll(struct pollfd *fds, nfds_t nfds, int timeout)
    -- wait for some event on a file descriptor --
    man page: https://man7.org/linux/man-pages/man2/ppoll.2.html

*pselect6_time64

    This is a year 2038 safe variant of:

    int pselect6(int nfds, fd_set *readfds, fd_set *writefds,
                 fd_set *exceptfds, const struct timespec *timeout,
                 const sigset_t *sigmask);
    -- synchronous I/O multiplexing --
    man page: https://man7.org/linux/man-pages/man2/pselect6.2.html

Implementation notes:

    Year 2038 safe syscalls in this patch were implemented
    with the same code as their regular variants (ppoll() and pselect()).
    A switch/case statement was used to call an apropriate converting
    function for 'struct timespec' between target and host.
    (target_to_host/host_to_target_timespec() for regular and
     target_to_host/host_to_target_timespec64() for time64 variants)

Signed-off-by: Filip Bozuta <Filip.Bozuta@syrmia.com>
---
 linux-user/syscall.c | 101 ++++++++++++++++++++++++++++++++++++-------
 1 file changed, 86 insertions(+), 15 deletions(-)

diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 1211e759c2..8f63a46f58 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -397,7 +397,7 @@ static int sys_getcwd1(char *buf, size_t size)
   return strlen(buf)+1;
 }
 
-#ifdef TARGET_NR_utimensat
+#if defined(TARGET_NR_utimensat)
 #if defined(__NR_utimensat)
 #define __NR_sys_utimensat __NR_utimensat
 _syscall4(int,sys_utimensat,int,dirfd,const char *,pathname,
@@ -763,11 +763,11 @@ safe_syscall5(int, waitid, idtype_t, idtype, id_t, id, siginfo_t *, infop, \
               int, options, struct rusage *, rusage)
 safe_syscall3(int, execve, const char *, filename, char **, argv, char **, envp)
 #if defined(TARGET_NR_select) || defined(TARGET_NR__newselect) || \
-    defined(TARGET_NR_pselect6)
+    defined(TARGET_NR_pselect6) || defined(TARGET_NR_pselect6_time64)
 safe_syscall6(int, pselect6, int, nfds, fd_set *, readfds, fd_set *, writefds, \
               fd_set *, exceptfds, struct timespec *, timeout, void *, sig)
 #endif
-#if defined(TARGET_NR_ppoll) || defined(TARGET_NR_poll)
+#if defined(TARGET_NR_ppoll) || defined(TARGET_NR_ppoll_time64)
 safe_syscall5(int, ppoll, struct pollfd *, ufds, unsigned int, nfds,
               struct timespec *, tsp, const sigset_t *, sigmask,
               size_t, sigsetsize)
@@ -984,7 +984,7 @@ abi_long do_brk(abi_ulong new_brk)
 }
 
 #if defined(TARGET_NR_select) || defined(TARGET_NR__newselect) || \
-    defined(TARGET_NR_pselect6)
+    defined(TARGET_NR_pselect6) || defined(TARGET_NR_pselect6_time64)
 static inline abi_long copy_from_user_fdset(fd_set *fds,
                                             abi_ulong target_fds_addr,
                                             int n)
@@ -1252,7 +1252,8 @@ static inline abi_long target_to_host_timespec(struct timespec *host_ts,
 }
 #endif
 
-#if defined(TARGET_NR_clock_settime64) || defined(TARGET_NR_futex_time64)
+#if defined(TARGET_NR_clock_settime64) || defined(TARGET_NR_futex_time64) || \
+    defined(TARGET_NR_pselect6_time64) || defined(TARGET_NR_ppoll_time64)
 static inline abi_long target_to_host_timespec64(struct timespec *host_ts,
                                                  abi_ulong target_addr)
 {
@@ -9043,8 +9044,13 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
 #endif
         return ret;
 #endif
+#if defined(TARGET_NR_pselect6) || defined(TARGET_NR_pselect6_time64)
 #ifdef TARGET_NR_pselect6
     case TARGET_NR_pselect6:
+#endif
+#ifdef TARGET_NR_pselect6_time64
+    case TARGET_NR_pselect6_time64:
+#endif
         {
             abi_long rfd_addr, wfd_addr, efd_addr, n, ts_addr;
             fd_set rfds, wfds, efds;
@@ -9088,8 +9094,21 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
              * use the do_select() helper ...
              */
             if (ts_addr) {
-                if (target_to_host_timespec(&ts, ts_addr)) {
-                    return -TARGET_EFAULT;
+                switch (num) {
+#ifdef TARGET_NR_pselect6
+                case TARGET_NR_pselect6:
+                    if (target_to_host_timespec(&ts, ts_addr)) {
+                        return -TARGET_EFAULT;
+                    }
+                    break;
+#endif
+#ifdef TARGET_NR_pselect6_time64
+                case TARGET_NR_pselect6_time64:
+                    if (target_to_host_timespec64(&ts, ts_addr)) {
+                        return -TARGET_EFAULT;
+                    }
+                    break;
+#endif
                 }
                 ts_ptr = &ts;
             } else {
@@ -9140,8 +9159,22 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
                 if (efd_addr && copy_to_user_fdset(efd_addr, &efds, n))
                     return -TARGET_EFAULT;
 
-                if (ts_addr && host_to_target_timespec(ts_addr, &ts))
-                    return -TARGET_EFAULT;
+                switch (num) {
+#ifdef TARGET_NR_pselect6
+                case TARGET_NR_pselect6:
+                    if (ts_addr && host_to_target_timespec(ts_addr, &ts)) {
+                        return -TARGET_EFAULT;
+                    }
+                break;
+#endif
+#ifdef TARGET_NR_pselect6_time64
+                case TARGET_NR_pselect6_time64:
+                    if (ts_addr && host_to_target_timespec64(ts_addr, &ts)) {
+                        return -TARGET_EFAULT;
+                    }
+                break;
+#endif
+                }
             }
         }
         return ret;
@@ -10076,12 +10109,16 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
     case TARGET_NR__newselect:
         return do_select(arg1, arg2, arg3, arg4, arg5);
 #endif
-#if defined(TARGET_NR_poll) || defined(TARGET_NR_ppoll)
+#if defined(TARGET_NR_poll) || defined(TARGET_NR_ppoll) || \
+    defined(TARGET_NR_ppoll_time64)
 # ifdef TARGET_NR_poll
     case TARGET_NR_poll:
 # endif
 # ifdef TARGET_NR_ppoll
     case TARGET_NR_ppoll:
+# endif
+# ifdef TARGET_NR_ppoll_time64
+    case TARGET_NR_ppoll_time64:
 # endif
         {
             struct target_pollfd *target_pfd;
@@ -10110,17 +10147,38 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
             }
 
             switch (num) {
-# ifdef TARGET_NR_ppoll
+#if defined(TARGET_NR_ppoll) || defined(TARGET_NR_ppoll_time64)
+#ifdef TARGET_NR_ppoll
             case TARGET_NR_ppoll:
+#endif
+#ifdef TARGET_NR_ppoll_time64
+            case TARGET_NR_ppoll_time64:
+#endif
             {
                 struct timespec _timeout_ts, *timeout_ts = &_timeout_ts;
                 target_sigset_t *target_set;
                 sigset_t _set, *set = &_set;
 
                 if (arg3) {
-                    if (target_to_host_timespec(timeout_ts, arg3)) {
-                        unlock_user(target_pfd, arg1, 0);
-                        return -TARGET_EFAULT;
+                    switch (num) {
+#ifdef TARGET_NR_ppoll
+                    case TARGET_NR_ppoll:
+                        if (target_to_host_timespec(timeout_ts, arg3)) {
+                            unlock_user(target_pfd, arg1, 0);
+                            return -TARGET_EFAULT;
+                        }
+                    break;
+#endif
+#ifdef TARGET_NR_ppoll_time64
+                    case TARGET_NR_ppoll_time64:
+                        if (target_to_host_timespec64(timeout_ts, arg3)) {
+                            unlock_user(target_pfd, arg1, 0);
+                            return -TARGET_EFAULT;
+                        }
+                    break;
+#endif
+                    default:
+                        g_assert_not_reached();
                     }
                 } else {
                     timeout_ts = NULL;
@@ -10146,7 +10204,20 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
                                            set, SIGSET_T_SIZE));
 
                 if (!is_error(ret) && arg3) {
-                    host_to_target_timespec(arg3, timeout_ts);
+                    switch (num) {
+#ifdef TARGET_NR_ppoll
+                    case TARGET_NR_ppoll:
+                        host_to_target_timespec(arg3, timeout_ts);
+                        break;
+#endif
+#ifdef TARGET_NR_ppoll_time64
+                    case TARGET_NR_ppoll_time64:
+                        host_to_target_timespec64(arg3, timeout_ts);
+                        break;
+#endif
+                    default:
+                        g_assert_not_reached();
+                    }
                 }
                 if (arg4) {
                     unlock_user(target_set, arg4, 0);
-- 
2.25.1



  reply	other threads:[~2020-08-12 13:58 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-08-12 13:57 [PATCH 0/2] linux-user: Adding support for a group of 4 time64 syscalls Filip Bozuta
2020-08-12 13:57 ` Filip Bozuta [this message]
2020-08-24 17:12   ` [PATCH 1/2] linux-user: Add support for 'ppoll_time64()' and 'pselect6_time64()' Laurent Vivier
2020-08-12 13:57 ` [PATCH 2/2] linux-user: Add support for 'utimensat_time64()' and 'semtimedop_time64()' Filip Bozuta
2020-08-24 17:20   ` Laurent Vivier

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20200812135703.39404-2-Filip.Bozuta@syrmia.com \
    --to=filip.bozuta@syrmia.com \
    --cc=laurent@vivier.eu \
    --cc=qemu-devel@nongnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.