Re: [PATCH v9 3/4] linux-user: Support futex_time64

2020-03-26 Thread Alistair Francis
On Wed, Mar 25, 2020 at 11:22 PM Laurent Vivier  wrote:
>
> Le 25/03/2020 à 18:41, Alistair Francis a écrit :
> > On Wed, Mar 18, 2020 at 3:54 PM Alistair Francis
> >  wrote:
> >>
> >> Add support for host and target futex_time64. If futex_time64 exists on
> >> the host we try that first before falling back to the standard futux
> >> syscall.
> >>
> >> Signed-off-by: Alistair Francis 
> >
> > @Laurent did you see this?
> >
> > I guess it's a little late for 5.0 but it would be nice to support.
>
> Yes, I've seen your patch.
>
> I think it can go into 5.0 RC because it's a bug fix and it is really
> needed because the 32bit futex will be broken if host timespec uses
> 64bit field.
>
> But I need to review and test before.

Thanks!

Alistair

>
> Thanks,
> Laurent



Re: [PATCH v9 3/4] linux-user: Support futex_time64

2020-03-26 Thread Laurent Vivier
Le 25/03/2020 à 18:41, Alistair Francis a écrit :
> On Wed, Mar 18, 2020 at 3:54 PM Alistair Francis
>  wrote:
>>
>> Add support for host and target futex_time64. If futex_time64 exists on
>> the host we try that first before falling back to the standard futux
>> syscall.
>>
>> Signed-off-by: Alistair Francis 
> 
> @Laurent did you see this?
> 
> I guess it's a little late for 5.0 but it would be nice to support.

Yes, I've seen your patch.

I think it can go into 5.0 RC because it's a bug fix and it is really
needed because the 32bit futex will be broken if host timespec uses
64bit field.

But I need to review and test before.

Thanks,
Laurent



Re: [PATCH v9 3/4] linux-user: Support futex_time64

2020-03-25 Thread Alistair Francis
On Wed, Mar 18, 2020 at 3:54 PM Alistair Francis
 wrote:
>
> Add support for host and target futex_time64. If futex_time64 exists on
> the host we try that first before falling back to the standard futux
> syscall.
>
> Signed-off-by: Alistair Francis 

@Laurent did you see this?

I guess it's a little late for 5.0 but it would be nice to support.

Alistair

> ---
>  linux-user/syscall.c | 144 +++
>  1 file changed, 131 insertions(+), 13 deletions(-)
>
> diff --git a/linux-user/syscall.c b/linux-user/syscall.c
> index 60fd775d9c..3354f41bb2 100644
> --- a/linux-user/syscall.c
> +++ b/linux-user/syscall.c
> @@ -245,7 +245,12 @@ static type name (type1 arg1,type2 arg2,type3 arg3,type4 
> arg4,type5 arg5,  \
>  #define __NR_sys_rt_sigqueueinfo __NR_rt_sigqueueinfo
>  #define __NR_sys_rt_tgsigqueueinfo __NR_rt_tgsigqueueinfo
>  #define __NR_sys_syslog __NR_syslog
> -#define __NR_sys_futex __NR_futex
> +#if defined(__NR_futex)
> +# define __NR_sys_futex __NR_futex
> +#endif
> +#if defined(__NR_futex_time64)
> +# define __NR_sys_futex_time64 __NR_futex_time64
> +#endif
>  #define __NR_sys_inotify_init __NR_inotify_init
>  #define __NR_sys_inotify_add_watch __NR_inotify_add_watch
>  #define __NR_sys_inotify_rm_watch __NR_inotify_rm_watch
> @@ -295,10 +300,16 @@ _syscall1(int,exit_group,int,error_code)
>  #if defined(TARGET_NR_set_tid_address) && defined(__NR_set_tid_address)
>  _syscall1(int,set_tid_address,int *,tidptr)
>  #endif
> -#if defined(TARGET_NR_futex) && defined(__NR_futex)
> +#if (defined(TARGET_NR_futex) && defined(__NR_futex)) || \
> +(defined(TARGET_NR_futex_time64) && \
> +(HOST_LONG_BITS == 64 && defined(__NR_futex)))
>  _syscall6(int,sys_futex,int *,uaddr,int,op,int,val,
>const struct timespec *,timeout,int *,uaddr2,int,val3)
>  #endif
> +#if defined(__NR_futex_time64)
> +_syscall6(int,sys_futex_time64,int *,uaddr,int,op,int,val,
> +  const struct timespec *,timeout,int *,uaddr2,int,val3)
> +#endif
>  #define __NR_sys_sched_getaffinity __NR_sched_getaffinity
>  _syscall3(int, sys_sched_getaffinity, pid_t, pid, unsigned int, len,
>unsigned long *, user_mask_ptr);
> @@ -762,10 +773,14 @@ safe_syscall5(int, ppoll, struct pollfd *, ufds, 
> unsigned int, nfds,
>  safe_syscall6(int, epoll_pwait, int, epfd, struct epoll_event *, events,
>int, maxevents, int, timeout, const sigset_t *, sigmask,
>size_t, sigsetsize)
> -#ifdef TARGET_NR_futex
> +#if defined(__NR_futex)
>  safe_syscall6(int,futex,int *,uaddr,int,op,int,val, \
>const struct timespec *,timeout,int *,uaddr2,int,val3)
>  #endif
> +#if defined(__NR_futex_time64)
> +safe_syscall6(int,futex_time64,int *,uaddr,int,op,int,val, \
> +  const struct timespec *,timeout,int *,uaddr2,int,val3)
> +#endif
>  safe_syscall2(int, rt_sigsuspend, sigset_t *, newset, size_t, sigsetsize)
>  safe_syscall2(int, kill, pid_t, pid, int, sig)
>  safe_syscall2(int, tkill, int, tid, int, sig)
> @@ -1229,7 +1244,7 @@ static inline abi_long target_to_host_timespec(struct 
> timespec *host_ts,
>  }
>  #endif
>
> -#if defined(TARGET_NR_clock_settime64)
> +#if defined(TARGET_NR_clock_settime64) || defined(TARGET_NR_futex_time64)
>  static inline abi_long target_to_host_timespec64(struct timespec *host_ts,
>   abi_ulong target_addr)
>  {
> @@ -6890,6 +6905,55 @@ static inline abi_long host_to_target_statx(struct 
> target_statx *host_stx,
>  }
>  #endif
>
> +static int do_sys_futex(int *uaddr, int op, int val,
> + const struct timespec *timeout, int *uaddr2,
> + int val3)
> +{
> +#if HOST_LONG_BITS == 64
> +#if defined(__NR_futex)
> +/* always a 64-bit time_t, it doesn't define _time64 version  */
> +return sys_futex(uaddr, op, val, timeout, uaddr2, val3);
> +
> +#endif
> +#else /* HOST_LONG_BITS == 64 */
> +#if defined(__NR_futex_time64)
> +if (sizeof(timeout->tv_sec) == 8) {
> +/* _time64 function on 32bit arch */
> +return sys_futex_time64(uaddr, op, val, timeout, uaddr2, val3);
> +}
> +#endif
> +#if defined(__NR_futex)
> +/* old function on 32bit arch */
> +return sys_futex(uaddr, op, val, timeout, uaddr2, val3);
> +#endif
> +#endif /* HOST_LONG_BITS == 64 */
> +g_assert_not_reached();
> +}
> +
> +static int do_safe_futex(int *uaddr, int op, int val,
> + const struct timespec *timeout, int *uaddr2,
> + int val3)
> +{
> +#if HOST_LONG_BITS == 64
> +#if defined(__NR_futex)
> +/* always a 64-bit time_t, it doesn't define _time64 version  */
> +return get_errno(safe_futex(uaddr, op, val, timeout, uaddr2, val3));
> +#endif
> +#else /* HOST_LONG_BITS == 64 */
> +#if defined(__NR_futex_time64)
> +if (sizeof(timeout->tv_sec) == 8) {
> +/* _time64 function on 32bit arch */
> +return get_errno(safe_futex_time64(uaddr, op, val, 

[PATCH v9 3/4] linux-user: Support futex_time64

2020-03-18 Thread Alistair Francis
Add support for host and target futex_time64. If futex_time64 exists on
the host we try that first before falling back to the standard futux
syscall.

Signed-off-by: Alistair Francis 
---
 linux-user/syscall.c | 144 +++
 1 file changed, 131 insertions(+), 13 deletions(-)

diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 60fd775d9c..3354f41bb2 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -245,7 +245,12 @@ static type name (type1 arg1,type2 arg2,type3 arg3,type4 
arg4,type5 arg5,  \
 #define __NR_sys_rt_sigqueueinfo __NR_rt_sigqueueinfo
 #define __NR_sys_rt_tgsigqueueinfo __NR_rt_tgsigqueueinfo
 #define __NR_sys_syslog __NR_syslog
-#define __NR_sys_futex __NR_futex
+#if defined(__NR_futex)
+# define __NR_sys_futex __NR_futex
+#endif
+#if defined(__NR_futex_time64)
+# define __NR_sys_futex_time64 __NR_futex_time64
+#endif
 #define __NR_sys_inotify_init __NR_inotify_init
 #define __NR_sys_inotify_add_watch __NR_inotify_add_watch
 #define __NR_sys_inotify_rm_watch __NR_inotify_rm_watch
@@ -295,10 +300,16 @@ _syscall1(int,exit_group,int,error_code)
 #if defined(TARGET_NR_set_tid_address) && defined(__NR_set_tid_address)
 _syscall1(int,set_tid_address,int *,tidptr)
 #endif
-#if defined(TARGET_NR_futex) && defined(__NR_futex)
+#if (defined(TARGET_NR_futex) && defined(__NR_futex)) || \
+(defined(TARGET_NR_futex_time64) && \
+(HOST_LONG_BITS == 64 && defined(__NR_futex)))
 _syscall6(int,sys_futex,int *,uaddr,int,op,int,val,
   const struct timespec *,timeout,int *,uaddr2,int,val3)
 #endif
+#if defined(__NR_futex_time64)
+_syscall6(int,sys_futex_time64,int *,uaddr,int,op,int,val,
+  const struct timespec *,timeout,int *,uaddr2,int,val3)
+#endif
 #define __NR_sys_sched_getaffinity __NR_sched_getaffinity
 _syscall3(int, sys_sched_getaffinity, pid_t, pid, unsigned int, len,
   unsigned long *, user_mask_ptr);
@@ -762,10 +773,14 @@ safe_syscall5(int, ppoll, struct pollfd *, ufds, unsigned 
int, nfds,
 safe_syscall6(int, epoll_pwait, int, epfd, struct epoll_event *, events,
   int, maxevents, int, timeout, const sigset_t *, sigmask,
   size_t, sigsetsize)
-#ifdef TARGET_NR_futex
+#if defined(__NR_futex)
 safe_syscall6(int,futex,int *,uaddr,int,op,int,val, \
   const struct timespec *,timeout,int *,uaddr2,int,val3)
 #endif
+#if defined(__NR_futex_time64)
+safe_syscall6(int,futex_time64,int *,uaddr,int,op,int,val, \
+  const struct timespec *,timeout,int *,uaddr2,int,val3)
+#endif
 safe_syscall2(int, rt_sigsuspend, sigset_t *, newset, size_t, sigsetsize)
 safe_syscall2(int, kill, pid_t, pid, int, sig)
 safe_syscall2(int, tkill, int, tid, int, sig)
@@ -1229,7 +1244,7 @@ static inline abi_long target_to_host_timespec(struct 
timespec *host_ts,
 }
 #endif
 
-#if defined(TARGET_NR_clock_settime64)
+#if defined(TARGET_NR_clock_settime64) || defined(TARGET_NR_futex_time64)
 static inline abi_long target_to_host_timespec64(struct timespec *host_ts,
  abi_ulong target_addr)
 {
@@ -6890,6 +6905,55 @@ static inline abi_long host_to_target_statx(struct 
target_statx *host_stx,
 }
 #endif
 
+static int do_sys_futex(int *uaddr, int op, int val,
+ const struct timespec *timeout, int *uaddr2,
+ int val3)
+{
+#if HOST_LONG_BITS == 64
+#if defined(__NR_futex)
+/* always a 64-bit time_t, it doesn't define _time64 version  */
+return sys_futex(uaddr, op, val, timeout, uaddr2, val3);
+
+#endif
+#else /* HOST_LONG_BITS == 64 */
+#if defined(__NR_futex_time64)
+if (sizeof(timeout->tv_sec) == 8) {
+/* _time64 function on 32bit arch */
+return sys_futex_time64(uaddr, op, val, timeout, uaddr2, val3);
+}
+#endif
+#if defined(__NR_futex)
+/* old function on 32bit arch */
+return sys_futex(uaddr, op, val, timeout, uaddr2, val3);
+#endif
+#endif /* HOST_LONG_BITS == 64 */
+g_assert_not_reached();
+}
+
+static int do_safe_futex(int *uaddr, int op, int val,
+ const struct timespec *timeout, int *uaddr2,
+ int val3)
+{
+#if HOST_LONG_BITS == 64
+#if defined(__NR_futex)
+/* always a 64-bit time_t, it doesn't define _time64 version  */
+return get_errno(safe_futex(uaddr, op, val, timeout, uaddr2, val3));
+#endif
+#else /* HOST_LONG_BITS == 64 */
+#if defined(__NR_futex_time64)
+if (sizeof(timeout->tv_sec) == 8) {
+/* _time64 function on 32bit arch */
+return get_errno(safe_futex_time64(uaddr, op, val, timeout, uaddr2,
+   val3));
+}
+#endif
+#if defined(__NR_futex)
+/* old function on 32bit arch */
+return get_errno(safe_futex(uaddr, op, val, timeout, uaddr2, val3));
+#endif
+#endif /* HOST_LONG_BITS == 64 */
+return -TARGET_ENOSYS;
+}
 
 /* ??? Using host futex calls even when target atomic operations
are not really atomic