Le 25/08/2020 à 00:30, Filip Bozuta a écrit : > This patch introduces functionality for following time64 syscalls: > > *utimensat_time64() > > int utimensat(int dirfd, const char *pathname, > const struct timespec times[2], int flags); > -- change file timestamps with nanosecond precision -- > man page: https://man7.org/linux/man-pages/man2/utimensat.2.html > > *semtimedop_time64() > > int semtimedop(int semid, struct sembuf *sops, size_t nsops, > const struct timespec *timeout); > -- System V semaphore operations -- > man page: https://www.man7.org/linux/man-pages/man2/semtimedop.2.html > > Implementation notes: > > Syscall 'utimensat_time64()' is implemented in similar way as its > regular variants only difference being that time64 converting function > is used to convert values of 'struct timespec' between host and target > ('target_to_host_timespec64()'). > > For syscall 'semtimedop_time64()' and additional argument is added > in function 'do_semtimedop()' through which the aproppriate 'struct > timespec' > converting function is called (false for regular target_to_host_timespec() > and true for target_to_host_timespec64()). For 'do_ipc()' a > check was added as that additional argument: 'TARGET_ABI_BITS == 64'. > > Signed-off-by: Filip Bozuta <filip.boz...@syrmia.com> > Reviewed-by: Laurent Vivier <laur...@vivier.eu> > --- > linux-user/syscall.c | 60 ++++++++++++++++++++++++++++++++++++-------- > 1 file changed, 50 insertions(+), 10 deletions(-) > > diff --git a/linux-user/syscall.c b/linux-user/syscall.c > index fc6a6e32e4..4d460af744 100644 > --- a/linux-user/syscall.c > +++ b/linux-user/syscall.c > @@ -1253,7 +1253,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) || > \ > - defined(TARGET_NR_pselect6_time64) || defined(TARGET_NR_ppoll_time64) > + defined(TARGET_NR_pselect6_time64) || defined(TARGET_NR_ppoll_time64) || > \ > + defined(TARGET_NR_utimensat_time64) || > defined(TARGET_NR_semtimedop_time64) > static inline abi_long target_to_host_timespec64(struct timespec *host_ts, > abi_ulong target_addr) > { > @@ -4117,7 +4118,7 @@ static inline abi_long target_to_host_sembuf(struct > sembuf *host_sembuf, > } > > #if defined(TARGET_NR_ipc) || defined(TARGET_NR_semop) || \ > - defined(TARGET_NR_semtimedop) > + defined(TARGET_NR_semtimedop) || defined(TARGET_NR_semtimedop_time64) > > /* > * This macro is required to handle the s390 variants, which passes the > @@ -4134,7 +4135,7 @@ static inline abi_long target_to_host_sembuf(struct > sembuf *host_sembuf, > static inline abi_long do_semtimedop(int semid, > abi_long ptr, > unsigned nsops, > - abi_long timeout) > + abi_long timeout, bool time64) > { > struct sembuf sops[nsops]; > struct timespec ts, *pts = NULL; > @@ -4142,8 +4143,14 @@ static inline abi_long do_semtimedop(int semid, > > if (timeout) { > pts = &ts; > - if (target_to_host_timespec(pts, timeout)) { > - return -TARGET_EFAULT; > + if (time64) { > + if (target_to_host_timespec64(pts, timeout)) { > + return -TARGET_EFAULT; > + } > + } else { > + if (target_to_host_timespec(pts, timeout)) { > + return -TARGET_EFAULT; > + } > } > } > > @@ -4657,7 +4664,7 @@ static abi_long do_ipc(CPUArchState *cpu_env, > > switch (call) { > case IPCOP_semop: > - ret = do_semtimedop(first, ptr, second, 0); > + ret = do_semtimedop(first, ptr, second, 0, false); > break; > case IPCOP_semtimedop: > /* > @@ -4667,9 +4674,9 @@ static abi_long do_ipc(CPUArchState *cpu_env, > * to a struct timespec where the generic variant uses fifth parameter. > */ > #if defined(TARGET_S390X) > - ret = do_semtimedop(first, ptr, second, third); > + ret = do_semtimedop(first, ptr, second, third, TARGET_ABI_BITS == > 64); > #else > - ret = do_semtimedop(first, ptr, second, fifth); > + ret = do_semtimedop(first, ptr, second, fifth, TARGET_ABI_BITS == > 64); > #endif > break; > > @@ -9887,11 +9894,15 @@ static abi_long do_syscall1(void *cpu_env, int num, > abi_long arg1, > #endif > #ifdef TARGET_NR_semop > case TARGET_NR_semop: > - return do_semtimedop(arg1, arg2, arg3, 0); > + return do_semtimedop(arg1, arg2, arg3, 0, false); > #endif > #ifdef TARGET_NR_semtimedop > case TARGET_NR_semtimedop: > - return do_semtimedop(arg1, arg2, arg3, arg4); > + return do_semtimedop(arg1, arg2, arg3, arg4, false); > +#endif > +#ifdef TARGET_NR_semtimedop_time64 > + case TARGET_NR_semtimedop_time64: > + return do_semtimedop(arg1, arg2, arg3, arg4, true); > #endif > #ifdef TARGET_NR_semctl > case TARGET_NR_semctl: > @@ -11938,6 +11949,35 @@ static abi_long do_syscall1(void *cpu_env, int num, > abi_long arg1, > } > return ret; > #endif > +#ifdef TARGET_NR_utimensat_time64 > + case TARGET_NR_utimensat_time64: > + { > + struct timespec *tsp, ts[2]; > + if (!arg3) { > + tsp = NULL; > + } else { > + if (target_to_host_timespec64(ts, arg3)) { > + return -TARGET_EFAULT; > + } > + if (target_to_host_timespec64(ts + 1, arg3 + > + sizeof(struct > target__kernel_timespec))) { > + return -TARGET_EFAULT; > + } > + tsp = ts; > + } > + if (!arg2) > + ret = get_errno(sys_utimensat(arg1, NULL, tsp, arg4)); > + else { > + p = lock_user_string(arg2); > + if (!p) { > + return -TARGET_EFAULT; > + } > + ret = get_errno(sys_utimensat(arg1, path(p), tsp, arg4)); > + unlock_user(p, arg2, 0); > + } > + } > + return ret; > +#endif > #ifdef TARGET_NR_futex > case TARGET_NR_futex: > return do_futex(arg1, arg2, arg3, arg4, arg5, arg6); >
Applied to my linux-user-for-5.2 branch. Thanks, Laurent