qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH 0/2] support for pselect in linux-user
@ 2010-02-16 10:31 Michael Casadevall
  2010-02-16 10:31 ` [Qemu-devel] [PATCH 1/2] This patch adds support for the pselect syscall in linux-user emulation and also adds several support functions required to translate the timespec structs between the target and the host Michael Casadevall
  0 siblings, 1 reply; 4+ messages in thread
From: Michael Casadevall @ 2010-02-16 10:31 UTC (permalink / raw)
  To: qemu-devel; +Cc: Michael Casadevall

The attached patches here add support for pselect call emulation in linux-user
and also add the proper entry to the ARM architecture syscall lists.

There is some code duplication between do_select() and do_pselect() to handle
copying the file descriptors over from the target to host; this could be 
refactored into two common functions; if desired, I'll resubmit the patch with
said refactoring in place.

Michael Casadevall (2):
  This patch adds support for the pselect syscall in linux-user
    emulation and     also adds several support functions required to
    translate the timespec structs     between the target and the host.
  Add the syscall id for pselect6 on ARM as this is now supported in
    newer     linux kernels.

 linux-user/arm/syscall_nr.h |    2 +-
 linux-user/syscall.c        |  119 +++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 120 insertions(+), 1 deletions(-)

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

* [Qemu-devel] [PATCH 1/2] This patch adds support for the pselect syscall in linux-user emulation and also adds several support functions required to translate the timespec structs between the target and the host.
  2010-02-16 10:31 [Qemu-devel] [PATCH 0/2] support for pselect in linux-user Michael Casadevall
@ 2010-02-16 10:31 ` Michael Casadevall
  2010-02-16 10:31   ` [Qemu-devel] [PATCH 2/2] Add the syscall id for pselect6 on ARM as this is now supported in newer linux kernels Michael Casadevall
  2010-02-17 15:10   ` [Qemu-devel] [PATCH 1/2] This patch adds support for the pselect syscall in linux-user emulation and also adds several support functions required to translate the timespec structs between the target and the host Riku Voipio
  0 siblings, 2 replies; 4+ messages in thread
From: Michael Casadevall @ 2010-02-16 10:31 UTC (permalink / raw)
  To: qemu-devel; +Cc: Michael Casadevall

Signed-off-by: Michael Casadevall <mcasadevall@ubuntu.com>
---
 linux-user/syscall.c |  119 ++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 119 insertions(+), 0 deletions(-)

diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 9fb493f..3663451 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -850,6 +850,38 @@ static inline abi_long copy_to_user_timeval(abi_ulong target_tv_addr,
     return 0;
 }
 
+static inline abi_long copy_from_user_timespec(struct timespec *ts,
+                                              abi_ulong target_ts_addr)
+{
+    struct target_timespec *target_ts;
+
+    if (!lock_user_struct(VERIFY_READ, target_ts, target_ts_addr, 1))
+        return -TARGET_EFAULT;
+
+    __get_user(ts->tv_sec, &target_ts->tv_sec);
+    __get_user(ts->tv_nsec, &target_ts->tv_nsec);
+
+    unlock_user_struct(target_ts, target_ts_addr, 0);
+
+    return 0;
+}
+
+
+static inline abi_long copy_to_user_timespec(abi_ulong target_ts_addr,
+                                            const struct timespec *ts)
+{
+    struct target_timespec *target_ts;
+
+    if (!lock_user_struct(VERIFY_WRITE, target_ts, target_ts_addr, 0))
+        return -TARGET_EFAULT;
+
+    __put_user(ts->tv_sec, &target_ts->tv_sec);
+    __put_user(ts->tv_nsec, &target_ts->tv_nsec);
+
+    unlock_user_struct(target_ts, target_ts_addr, 1);
+
+    return 0;
+}
 #if defined(TARGET_NR_mq_open) && defined(__NR_mq_open)
 #include <mqueue.h>
 
@@ -949,6 +981,75 @@ static abi_long do_select(int n,
     return ret;
 }
 
+#ifdef TARGET_NR_pselect6
+/* do_pselect() must return target values and target errnos. */
+static abi_long do_pselect(int n,
+                          abi_ulong rfd_addr, abi_ulong wfd_addr,
+                          abi_ulong efd_addr, abi_ulong target_tv_addr,
+                          abi_ulong set_addr)
+{
+    fd_set rfds, wfds, efds;
+    fd_set *rfds_ptr, *wfds_ptr, *efds_ptr;
+    struct timespec tv, *tv_ptr;
+    sigset_t set, *set_ptr;
+    abi_long ret;
+
+    if (rfd_addr) {
+        if (copy_from_user_fdset(&rfds, rfd_addr, n))
+            return -TARGET_EFAULT;
+        rfds_ptr = &rfds;
+    } else {
+        rfds_ptr = NULL;
+    }
+    if (wfd_addr) {
+        if (copy_from_user_fdset(&wfds, wfd_addr, n))
+            return -TARGET_EFAULT;
+        wfds_ptr = &wfds;
+    } else {
+        wfds_ptr = NULL;
+    }
+    if (efd_addr) {
+        if (copy_from_user_fdset(&efds, efd_addr, n))
+            return -TARGET_EFAULT;
+        efds_ptr = &efds;
+    } else {
+        efds_ptr = NULL;
+    }
+
+    if (target_tv_addr) {
+        if (copy_from_user_timespec(&tv, target_tv_addr))
+            return -TARGET_EFAULT;
+        tv_ptr = &tv;
+    } else {
+        tv_ptr = NULL;
+    }
+
+    /* We don't need to return sigmask to target */
+    if (set_addr) {
+        target_to_host_old_sigset(&set, &set_addr);
+        set_ptr = &set;
+    } else {
+        set_ptr = NULL;
+    }
+
+    ret = get_errno(pselect(n, rfds_ptr, wfds_ptr, efds_ptr, tv_ptr, set_ptr));
+
+    if (!is_error(ret)) {
+        if (rfd_addr && copy_to_user_fdset(rfd_addr, &rfds, n))
+            return -TARGET_EFAULT;
+        if (wfd_addr && copy_to_user_fdset(wfd_addr, &wfds, n))
+            return -TARGET_EFAULT;
+        if (efd_addr && copy_to_user_fdset(efd_addr, &efds, n))
+            return -TARGET_EFAULT;
+
+        if (target_tv_addr && copy_to_user_timespec(target_tv_addr, &tv))
+            return -TARGET_EFAULT;
+    }
+
+    return ret;
+}
+#endif
+
 static abi_long do_pipe2(int host_pipe[], int flags)
 {
 #ifdef CONFIG_PIPE2
@@ -5136,6 +5237,24 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
         }
         break;
 #endif
+
+#ifdef TARGET_NR_pselect6
+    case TARGET_NR_pselect6:
+        {
+            abi_ulong inp, outp, exp, tvp, set;
+            long nsel;
+
+            nsel = tswapl(arg1);
+            inp = tswapl(arg2);
+            outp = tswapl(arg3);
+            exp = tswapl(arg4);
+            tvp = tswapl(arg5);
+            set = tswapl(arg6);
+
+            ret = do_pselect(nsel, inp, outp, exp, tvp, set);
+        }
+        break;
+#endif
     case TARGET_NR_symlink:
         {
             void *p2;
-- 
1.6.6.1

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

* [Qemu-devel] [PATCH 2/2] Add the syscall id for pselect6 on ARM as this is now supported in newer linux kernels.
  2010-02-16 10:31 ` [Qemu-devel] [PATCH 1/2] This patch adds support for the pselect syscall in linux-user emulation and also adds several support functions required to translate the timespec structs between the target and the host Michael Casadevall
@ 2010-02-16 10:31   ` Michael Casadevall
  2010-02-17 15:10   ` [Qemu-devel] [PATCH 1/2] This patch adds support for the pselect syscall in linux-user emulation and also adds several support functions required to translate the timespec structs between the target and the host Riku Voipio
  1 sibling, 0 replies; 4+ messages in thread
From: Michael Casadevall @ 2010-02-16 10:31 UTC (permalink / raw)
  To: qemu-devel; +Cc: Michael Casadevall

Signed-off-by: Michael Casadevall <mcasadevall@ubuntu.com>
---
 linux-user/arm/syscall_nr.h |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/linux-user/arm/syscall_nr.h b/linux-user/arm/syscall_nr.h
index b1db341..79a216a 100644
--- a/linux-user/arm/syscall_nr.h
+++ b/linux-user/arm/syscall_nr.h
@@ -338,7 +338,7 @@
 #define TARGET_NR_readlinkat			(332)
 #define TARGET_NR_fchmodat			(333)
 #define TARGET_NR_faccessat			(334)
-					/* 335 for pselect6 */
+#define TARGET_NR_pselect6			(335)
 					/* 336 for ppoll */
 #define TARGET_NR_unshare			(337)
 #define TARGET_NR_set_robust_list		(338)
-- 
1.6.6.1

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

* Re: [Qemu-devel] [PATCH 1/2] This patch adds support for the pselect syscall in linux-user emulation and also adds several support functions required to translate the timespec structs between the target and the host.
  2010-02-16 10:31 ` [Qemu-devel] [PATCH 1/2] This patch adds support for the pselect syscall in linux-user emulation and also adds several support functions required to translate the timespec structs between the target and the host Michael Casadevall
  2010-02-16 10:31   ` [Qemu-devel] [PATCH 2/2] Add the syscall id for pselect6 on ARM as this is now supported in newer linux kernels Michael Casadevall
@ 2010-02-17 15:10   ` Riku Voipio
  1 sibling, 0 replies; 4+ messages in thread
From: Riku Voipio @ 2010-02-17 15:10 UTC (permalink / raw)
  To: Michael Casadevall; +Cc: qemu-devel

On Tue, Feb 16, 2010 at 05:31:19AM -0500, Michael Casadevall wrote:
> Signed-off-by: Michael Casadevall <mcasadevall@ubuntu.com>

Looks correct and passes ltp tests, thanks. Will include these patches
in the next linux-user pull request.

Next time you might want to separate the commit title and message instead
of having all in the first line.

> ---
>  linux-user/syscall.c |  119 ++++++++++++++++++++++++++++++++++++++++++++++++++
>  1 files changed, 119 insertions(+), 0 deletions(-)
> 
> diff --git a/linux-user/syscall.c b/linux-user/syscall.c
> index 9fb493f..3663451 100644
> --- a/linux-user/syscall.c
> +++ b/linux-user/syscall.c
> @@ -850,6 +850,38 @@ static inline abi_long copy_to_user_timeval(abi_ulong target_tv_addr,
>      return 0;
>  }
>  
> +static inline abi_long copy_from_user_timespec(struct timespec *ts,
> +                                              abi_ulong target_ts_addr)
> +{
> +    struct target_timespec *target_ts;
> +
> +    if (!lock_user_struct(VERIFY_READ, target_ts, target_ts_addr, 1))
> +        return -TARGET_EFAULT;
> +
> +    __get_user(ts->tv_sec, &target_ts->tv_sec);
> +    __get_user(ts->tv_nsec, &target_ts->tv_nsec);
> +
> +    unlock_user_struct(target_ts, target_ts_addr, 0);
> +
> +    return 0;
> +}
> +
> +
> +static inline abi_long copy_to_user_timespec(abi_ulong target_ts_addr,
> +                                            const struct timespec *ts)
> +{
> +    struct target_timespec *target_ts;
> +
> +    if (!lock_user_struct(VERIFY_WRITE, target_ts, target_ts_addr, 0))
> +        return -TARGET_EFAULT;
> +
> +    __put_user(ts->tv_sec, &target_ts->tv_sec);
> +    __put_user(ts->tv_nsec, &target_ts->tv_nsec);
> +
> +    unlock_user_struct(target_ts, target_ts_addr, 1);
> +
> +    return 0;
> +}
>  #if defined(TARGET_NR_mq_open) && defined(__NR_mq_open)
>  #include <mqueue.h>
>  
> @@ -949,6 +981,75 @@ static abi_long do_select(int n,
>      return ret;
>  }
>  
> +#ifdef TARGET_NR_pselect6
> +/* do_pselect() must return target values and target errnos. */
> +static abi_long do_pselect(int n,
> +                          abi_ulong rfd_addr, abi_ulong wfd_addr,
> +                          abi_ulong efd_addr, abi_ulong target_tv_addr,
> +                          abi_ulong set_addr)
> +{
> +    fd_set rfds, wfds, efds;
> +    fd_set *rfds_ptr, *wfds_ptr, *efds_ptr;
> +    struct timespec tv, *tv_ptr;
> +    sigset_t set, *set_ptr;
> +    abi_long ret;
> +
> +    if (rfd_addr) {
> +        if (copy_from_user_fdset(&rfds, rfd_addr, n))
> +            return -TARGET_EFAULT;
> +        rfds_ptr = &rfds;
> +    } else {
> +        rfds_ptr = NULL;
> +    }
> +    if (wfd_addr) {
> +        if (copy_from_user_fdset(&wfds, wfd_addr, n))
> +            return -TARGET_EFAULT;
> +        wfds_ptr = &wfds;
> +    } else {
> +        wfds_ptr = NULL;
> +    }
> +    if (efd_addr) {
> +        if (copy_from_user_fdset(&efds, efd_addr, n))
> +            return -TARGET_EFAULT;
> +        efds_ptr = &efds;
> +    } else {
> +        efds_ptr = NULL;
> +    }
> +
> +    if (target_tv_addr) {
> +        if (copy_from_user_timespec(&tv, target_tv_addr))
> +            return -TARGET_EFAULT;
> +        tv_ptr = &tv;
> +    } else {
> +        tv_ptr = NULL;
> +    }
> +
> +    /* We don't need to return sigmask to target */
> +    if (set_addr) {
> +        target_to_host_old_sigset(&set, &set_addr);
> +        set_ptr = &set;
> +    } else {
> +        set_ptr = NULL;
> +    }
> +
> +    ret = get_errno(pselect(n, rfds_ptr, wfds_ptr, efds_ptr, tv_ptr, set_ptr));
> +
> +    if (!is_error(ret)) {
> +        if (rfd_addr && copy_to_user_fdset(rfd_addr, &rfds, n))
> +            return -TARGET_EFAULT;
> +        if (wfd_addr && copy_to_user_fdset(wfd_addr, &wfds, n))
> +            return -TARGET_EFAULT;
> +        if (efd_addr && copy_to_user_fdset(efd_addr, &efds, n))
> +            return -TARGET_EFAULT;
> +
> +        if (target_tv_addr && copy_to_user_timespec(target_tv_addr, &tv))
> +            return -TARGET_EFAULT;
> +    }
> +
> +    return ret;
> +}
> +#endif
> +
>  static abi_long do_pipe2(int host_pipe[], int flags)
>  {
>  #ifdef CONFIG_PIPE2
> @@ -5136,6 +5237,24 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
>          }
>          break;
>  #endif
> +
> +#ifdef TARGET_NR_pselect6
> +    case TARGET_NR_pselect6:
> +        {
> +            abi_ulong inp, outp, exp, tvp, set;
> +            long nsel;
> +
> +            nsel = tswapl(arg1);
> +            inp = tswapl(arg2);
> +            outp = tswapl(arg3);
> +            exp = tswapl(arg4);
> +            tvp = tswapl(arg5);
> +            set = tswapl(arg6);
> +
> +            ret = do_pselect(nsel, inp, outp, exp, tvp, set);
> +        }
> +        break;
> +#endif
>      case TARGET_NR_symlink:
>          {
>              void *p2;
> -- 
> 1.6.6.1
> 
> 

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

end of thread, other threads:[~2010-02-17 15:10 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-02-16 10:31 [Qemu-devel] [PATCH 0/2] support for pselect in linux-user Michael Casadevall
2010-02-16 10:31 ` [Qemu-devel] [PATCH 1/2] This patch adds support for the pselect syscall in linux-user emulation and also adds several support functions required to translate the timespec structs between the target and the host Michael Casadevall
2010-02-16 10:31   ` [Qemu-devel] [PATCH 2/2] Add the syscall id for pselect6 on ARM as this is now supported in newer linux kernels Michael Casadevall
2010-02-17 15:10   ` [Qemu-devel] [PATCH 1/2] This patch adds support for the pselect syscall in linux-user emulation and also adds several support functions required to translate the timespec structs between the target and the host Riku Voipio

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 NNTP newsgroup(s).