* [PATCH v2 0/2] Introducing functionality for a group of 4 time64 syscalls @ 2020-07-27 11:23 Filip Bozuta 2020-07-27 11:23 ` [PATCH v2 1/2] linux-user: Add support for two 'clock_nanosleep_time64()' and 'clock_adjtime64()' Filip Bozuta 2020-07-27 11:23 ` [PATCH v2 2/2] linux-user: Add support for 'rt_sigtimedwait_time64()' and 'sched_rr_get_interval_time64()' Filip Bozuta 0 siblings, 2 replies; 5+ messages in thread From: Filip Bozuta @ 2020-07-27 11:23 UTC (permalink / raw) To: qemu-devel; +Cc: Riku Voipio, Laurent Vivier, Filip Bozuta This two patch series introduces functionality for a group of 4 2038 safe syscalls. The list of implemented syscalls and implementation details can be found in the patch commit messages. Testing method: The implementation of the implemented syscalls was tested using already existing tests from LTP test suite which was built inside chroot. *v2: -Added check for 'clock_nanosleep_time64()' which returns '-TARGET_EFAULT' if conversion of 'struct timespec64' between host and target fails -Removed unnecesary special errno handling for 'PPC' Filip Bozuta (2): linux-user: Add support for two 'clock_nanosleep_time64()' and 'clock_adjtime64()' linux-user: Add support for 'rt_sigtimedwait_time64()' and 'sched_rr_get_interval_time64()' linux-user/syscall.c | 192 +++++++++++++++++++++++++++++++++++++- linux-user/syscall_defs.h | 31 ++++++ 2 files changed, 221 insertions(+), 2 deletions(-) -- 2.25.1 ^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH v2 1/2] linux-user: Add support for two 'clock_nanosleep_time64()' and 'clock_adjtime64()' 2020-07-27 11:23 [PATCH v2 0/2] Introducing functionality for a group of 4 time64 syscalls Filip Bozuta @ 2020-07-27 11:23 ` Filip Bozuta 2020-08-24 16:40 ` Laurent Vivier 2020-07-27 11:23 ` [PATCH v2 2/2] linux-user: Add support for 'rt_sigtimedwait_time64()' and 'sched_rr_get_interval_time64()' Filip Bozuta 1 sibling, 1 reply; 5+ messages in thread From: Filip Bozuta @ 2020-07-27 11:23 UTC (permalink / raw) To: qemu-devel; +Cc: Riku Voipio, Laurent Vivier, Filip Bozuta This patch implements functionality for following time64 syscall: *clock_nanosleep_time64() This is a year 2038 safe vairant of syscall: int clock_nanosleep(clockid_t clockid, int flags, const struct timespec *request, struct timespec *remain) --high-resolution sleep with specifiable clock-- man page: https://man7.org/linux/man-pages/man2/clock_nanosleep.2.html *clock_adjtime64() This is a year 2038 safe variant of syscall: int clock_adjtime(clockid_t clk_id, struct timex *buf) --tune kernel clock-- man page: https://man7.org/linux/man-pages/man2/clock_adjtime.2.html Implementation notes: Syscall 'clock_nanosleep_time64()' was implemented similarly to syscall 'clock_nanosleep()' except that 'host_to_target_timespec64()' and 'target_to_host_timespec64()' were used instead of the regular 'host_to_target_timespec()' and 'target_to_host_timespec()'. For 'clock_adjtime64()' a 64-bit target kernel version of 'struct timex' was defined in 'syscall_defs.h': 'struct target__kernel_timex'. This type was used to convert the values of 64-bit timex type between host and target. For this purpose a 64-bit timex converting functions 'target_to_host_timex64()' and 'host_to_target_timex64()'. An existing function 'copy_to_user_timeval64()' was used to convert the field 'time' which if of type 'struct timeval' from host to target. Function 'copy_from_user_timveal64()' was added in this patch and used to convert the 'time' field from target to host. Signed-off-by: Filip Bozuta <Filip.Bozuta@syrmia.com> --- linux-user/syscall.c | 139 +++++++++++++++++++++++++++++++++++++- linux-user/syscall_defs.h | 31 +++++++++ 2 files changed, 168 insertions(+), 2 deletions(-) diff --git a/linux-user/syscall.c b/linux-user/syscall.c index 05f03919ff..c1b36ea698 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -809,7 +809,8 @@ safe_syscall4(int, accept4, int, fd, struct sockaddr *, addr, socklen_t *, len, safe_syscall2(int, nanosleep, const struct timespec *, req, struct timespec *, rem) #endif -#ifdef TARGET_NR_clock_nanosleep +#if defined(TARGET_NR_clock_nanosleep) || \ + defined(TARGET_NR_clock_nanosleep_time64) safe_syscall4(int, clock_nanosleep, const clockid_t, clock, int, flags, const struct timespec *, req, struct timespec *, rem) #endif @@ -1205,8 +1206,25 @@ static inline abi_long copy_to_user_timeval(abi_ulong target_tv_addr, return 0; } +static inline abi_long copy_from_user_timeval64(struct timeval *tv, + abi_ulong target_tv_addr) +{ + struct target__kernel_sock_timeval *target_tv; + + if (!lock_user_struct(VERIFY_READ, target_tv, target_tv_addr, 1)) { + return -TARGET_EFAULT; + } + + __get_user(tv->tv_sec, &target_tv->tv_sec); + __get_user(tv->tv_usec, &target_tv->tv_usec); + + unlock_user_struct(target_tv, target_tv_addr, 0); + + return 0; +} + static inline abi_long copy_to_user_timeval64(abi_ulong target_tv_addr, - const struct timeval *tv) + const struct timeval *tv) { struct target__kernel_sock_timeval *target_tv; @@ -6771,6 +6789,87 @@ static inline abi_long host_to_target_timex(abi_long target_addr, } #endif + +#if defined(TARGET_NR_clock_adjtime64) && defined(CONFIG_CLOCK_ADJTIME) +static inline abi_long target_to_host_timex64(struct timex *host_tx, + abi_long target_addr) +{ + struct target__kernel_timex *target_tx; + + if (copy_from_user_timeval64(&host_tx->time, target_addr + + offsetof(struct target__kernel_timex, + time))) { + return -TARGET_EFAULT; + } + + if (!lock_user_struct(VERIFY_READ, target_tx, target_addr, 1)) { + return -TARGET_EFAULT; + } + + __get_user(host_tx->modes, &target_tx->modes); + __get_user(host_tx->offset, &target_tx->offset); + __get_user(host_tx->freq, &target_tx->freq); + __get_user(host_tx->maxerror, &target_tx->maxerror); + __get_user(host_tx->esterror, &target_tx->esterror); + __get_user(host_tx->status, &target_tx->status); + __get_user(host_tx->constant, &target_tx->constant); + __get_user(host_tx->precision, &target_tx->precision); + __get_user(host_tx->tolerance, &target_tx->tolerance); + __get_user(host_tx->tick, &target_tx->tick); + __get_user(host_tx->ppsfreq, &target_tx->ppsfreq); + __get_user(host_tx->jitter, &target_tx->jitter); + __get_user(host_tx->shift, &target_tx->shift); + __get_user(host_tx->stabil, &target_tx->stabil); + __get_user(host_tx->jitcnt, &target_tx->jitcnt); + __get_user(host_tx->calcnt, &target_tx->calcnt); + __get_user(host_tx->errcnt, &target_tx->errcnt); + __get_user(host_tx->stbcnt, &target_tx->stbcnt); + __get_user(host_tx->tai, &target_tx->tai); + + unlock_user_struct(target_tx, target_addr, 0); + return 0; +} + +static inline abi_long host_to_target_timex64(abi_long target_addr, + struct timex *host_tx) +{ + struct target__kernel_timex *target_tx; + + if (copy_to_user_timeval64(target_addr + + offsetof(struct target__kernel_timex, time), + &host_tx->time)) { + return -TARGET_EFAULT; + } + + if (!lock_user_struct(VERIFY_WRITE, target_tx, target_addr, 0)) { + return -TARGET_EFAULT; + } + + __put_user(host_tx->modes, &target_tx->modes); + __put_user(host_tx->offset, &target_tx->offset); + __put_user(host_tx->freq, &target_tx->freq); + __put_user(host_tx->maxerror, &target_tx->maxerror); + __put_user(host_tx->esterror, &target_tx->esterror); + __put_user(host_tx->status, &target_tx->status); + __put_user(host_tx->constant, &target_tx->constant); + __put_user(host_tx->precision, &target_tx->precision); + __put_user(host_tx->tolerance, &target_tx->tolerance); + __put_user(host_tx->tick, &target_tx->tick); + __put_user(host_tx->ppsfreq, &target_tx->ppsfreq); + __put_user(host_tx->jitter, &target_tx->jitter); + __put_user(host_tx->shift, &target_tx->shift); + __put_user(host_tx->stabil, &target_tx->stabil); + __put_user(host_tx->jitcnt, &target_tx->jitcnt); + __put_user(host_tx->calcnt, &target_tx->calcnt); + __put_user(host_tx->errcnt, &target_tx->errcnt); + __put_user(host_tx->stbcnt, &target_tx->stbcnt); + __put_user(host_tx->tai, &target_tx->tai); + + unlock_user_struct(target_tx, target_addr, 1); + return 0; +} +#endif + static inline abi_long target_to_host_sigevent(struct sigevent *host_sevp, abi_ulong target_addr) { @@ -9726,6 +9825,23 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1, } } return ret; +#endif +#if defined(TARGET_NR_clock_adjtime64) && defined(CONFIG_CLOCK_ADJTIME) + case TARGET_NR_clock_adjtime64: + { + struct timex htx, *phtx = &htx; + + if (target_to_host_timex64(phtx, arg2) != 0) { + return -TARGET_EFAULT; + } + ret = get_errno(clock_adjtime(arg1, phtx)); + if (!is_error(ret) && phtx) { + if (host_to_target_timex64(arg2, phtx) != 0) { + return -TARGET_EFAULT; + } + } + } + return ret; #endif case TARGET_NR_getpgid: return get_errno(getpgid(arg1)); @@ -11684,6 +11800,25 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1, return ret; } #endif +#ifdef TARGET_NR_clock_nanosleep_time64 + case TARGET_NR_clock_nanosleep_time64: + { + struct timespec ts; + + if (target_to_host_timespec64(&ts, arg3)) { + return -TARGET_EFAULT; + } + + ret = get_errno(safe_clock_nanosleep(arg1, arg2, + &ts, arg4 ? &ts : NULL)); + + if (ret == -TARGET_EINTR && arg4 && arg2 != TIMER_ABSTIME && + host_to_target_timespec64(arg4, &ts)) { + return -TARGET_EFAULT; + } + return ret; + } +#endif #if defined(TARGET_NR_set_tid_address) && defined(__NR_set_tid_address) case TARGET_NR_set_tid_address: diff --git a/linux-user/syscall_defs.h b/linux-user/syscall_defs.h index 152ec637cb..3783c5a07e 100644 --- a/linux-user/syscall_defs.h +++ b/linux-user/syscall_defs.h @@ -287,6 +287,37 @@ struct target_timex { abi_int:32; abi_int:32; abi_int:32; }; +struct target__kernel_timex { + abi_uint modes; /* Mode selector */ + abi_int: 32; /* pad */ + abi_llong offset; /* Time offset */ + abi_llong freq; /* Frequency offset */ + abi_llong maxerror; /* Maximum error (microseconds) */ + abi_llong esterror; /* Estimated error (microseconds) */ + abi_int status; /* Clock command/status */ + abi_int: 32; /* pad */ + abi_llong constant; /* PLL (phase-locked loop) time constant */ + abi_llong precision; /* Clock precision (microseconds, ro) */ + abi_llong tolerance; /* Clock freq. tolerance (ppm, ro) */ + struct target__kernel_sock_timeval time; /* Current time */ + abi_llong tick; /* Microseconds between clock ticks */ + abi_llong ppsfreq; /* PPS (pulse per second) frequency */ + abi_llong jitter; /* PPS jitter (ro); nanoseconds */ + abi_int shift; /* PPS interval duration (seconds) */ + abi_int: 32; /* pad */ + abi_llong stabil; /* PPS stability */ + abi_llong jitcnt; /* PPS jitter limit exceeded (ro) */ + abi_llong calcnt; /* PPS calibration intervals */ + abi_llong errcnt; /* PPS calibration errors */ + abi_llong stbcnt; /* PPS stability limit exceeded */ + abi_int tai; /* TAI offset */ + + /* Further padding bytes to allow for future expansion */ + abi_int:32; abi_int:32; abi_int:32; abi_int:32; + abi_int:32; abi_int:32; abi_int:32; abi_int:32; + abi_int:32; abi_int:32; abi_int:32; +}; + typedef abi_long target_clock_t; #define TARGET_HZ 100 -- 2.25.1 ^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: [PATCH v2 1/2] linux-user: Add support for two 'clock_nanosleep_time64()' and 'clock_adjtime64()' 2020-07-27 11:23 ` [PATCH v2 1/2] linux-user: Add support for two 'clock_nanosleep_time64()' and 'clock_adjtime64()' Filip Bozuta @ 2020-08-24 16:40 ` Laurent Vivier 0 siblings, 0 replies; 5+ messages in thread From: Laurent Vivier @ 2020-08-24 16:40 UTC (permalink / raw) To: Filip Bozuta, qemu-devel; +Cc: Riku Voipio Le 27/07/2020 à 13:23, Filip Bozuta a écrit : > This patch implements functionality for following time64 syscall: > > *clock_nanosleep_time64() > > This is a year 2038 safe vairant of syscall: > int clock_nanosleep(clockid_t clockid, int flags, > const struct timespec *request, > struct timespec *remain) > --high-resolution sleep with specifiable clock-- > man page: https://man7.org/linux/man-pages/man2/clock_nanosleep.2.html > > *clock_adjtime64() > > This is a year 2038 safe variant of syscall: > int clock_adjtime(clockid_t clk_id, struct timex *buf) > --tune kernel clock-- > man page: https://man7.org/linux/man-pages/man2/clock_adjtime.2.html > > Implementation notes: > > Syscall 'clock_nanosleep_time64()' was implemented similarly > to syscall 'clock_nanosleep()' except that 'host_to_target_timespec64()' > and 'target_to_host_timespec64()' were used instead of the regular > 'host_to_target_timespec()' and 'target_to_host_timespec()'. > > For 'clock_adjtime64()' a 64-bit target kernel version of 'struct timex' > was defined in 'syscall_defs.h': 'struct target__kernel_timex'. > This type was used to convert the values of 64-bit timex type between > host and target. For this purpose a 64-bit timex converting functions > 'target_to_host_timex64()' and 'host_to_target_timex64()'. An existing > function 'copy_to_user_timeval64()' was used to convert the field > 'time' which if of type 'struct timeval' from host to target. > Function 'copy_from_user_timveal64()' was added in this patch and > used to convert the 'time' field from target to host. > > Signed-off-by: Filip Bozuta <Filip.Bozuta@syrmia.com> > --- > linux-user/syscall.c | 139 +++++++++++++++++++++++++++++++++++++- > linux-user/syscall_defs.h | 31 +++++++++ > 2 files changed, 168 insertions(+), 2 deletions(-) > > diff --git a/linux-user/syscall.c b/linux-user/syscall.c > index 05f03919ff..c1b36ea698 100644 > --- a/linux-user/syscall.c > +++ b/linux-user/syscall.c > @@ -809,7 +809,8 @@ safe_syscall4(int, accept4, int, fd, struct sockaddr *, addr, socklen_t *, len, > safe_syscall2(int, nanosleep, const struct timespec *, req, > struct timespec *, rem) > #endif > -#ifdef TARGET_NR_clock_nanosleep > +#if defined(TARGET_NR_clock_nanosleep) || \ > + defined(TARGET_NR_clock_nanosleep_time64) > safe_syscall4(int, clock_nanosleep, const clockid_t, clock, int, flags, > const struct timespec *, req, struct timespec *, rem) > #endif > @@ -1205,8 +1206,25 @@ static inline abi_long copy_to_user_timeval(abi_ulong target_tv_addr, > return 0; > } > > +static inline abi_long copy_from_user_timeval64(struct timeval *tv, > + abi_ulong target_tv_addr) > +{ > + struct target__kernel_sock_timeval *target_tv; > + > + if (!lock_user_struct(VERIFY_READ, target_tv, target_tv_addr, 1)) { > + return -TARGET_EFAULT; > + } > + > + __get_user(tv->tv_sec, &target_tv->tv_sec); > + __get_user(tv->tv_usec, &target_tv->tv_usec); > + > + unlock_user_struct(target_tv, target_tv_addr, 0); > + > + return 0; > +} > + > static inline abi_long copy_to_user_timeval64(abi_ulong target_tv_addr, > - const struct timeval *tv) > + const struct timeval *tv) > { > struct target__kernel_sock_timeval *target_tv; > > @@ -6771,6 +6789,87 @@ static inline abi_long host_to_target_timex(abi_long target_addr, > } > #endif > > + > +#if defined(TARGET_NR_clock_adjtime64) && defined(CONFIG_CLOCK_ADJTIME) > +static inline abi_long target_to_host_timex64(struct timex *host_tx, > + abi_long target_addr) > +{ > + struct target__kernel_timex *target_tx; > + > + if (copy_from_user_timeval64(&host_tx->time, target_addr + > + offsetof(struct target__kernel_timex, > + time))) { > + return -TARGET_EFAULT; > + } > + > + if (!lock_user_struct(VERIFY_READ, target_tx, target_addr, 1)) { > + return -TARGET_EFAULT; > + } > + > + __get_user(host_tx->modes, &target_tx->modes); > + __get_user(host_tx->offset, &target_tx->offset); > + __get_user(host_tx->freq, &target_tx->freq); > + __get_user(host_tx->maxerror, &target_tx->maxerror); > + __get_user(host_tx->esterror, &target_tx->esterror); > + __get_user(host_tx->status, &target_tx->status); > + __get_user(host_tx->constant, &target_tx->constant); > + __get_user(host_tx->precision, &target_tx->precision); > + __get_user(host_tx->tolerance, &target_tx->tolerance); > + __get_user(host_tx->tick, &target_tx->tick); > + __get_user(host_tx->ppsfreq, &target_tx->ppsfreq); > + __get_user(host_tx->jitter, &target_tx->jitter); > + __get_user(host_tx->shift, &target_tx->shift); > + __get_user(host_tx->stabil, &target_tx->stabil); > + __get_user(host_tx->jitcnt, &target_tx->jitcnt); > + __get_user(host_tx->calcnt, &target_tx->calcnt); > + __get_user(host_tx->errcnt, &target_tx->errcnt); > + __get_user(host_tx->stbcnt, &target_tx->stbcnt); > + __get_user(host_tx->tai, &target_tx->tai); > + > + unlock_user_struct(target_tx, target_addr, 0); > + return 0; > +} > + > +static inline abi_long host_to_target_timex64(abi_long target_addr, > + struct timex *host_tx) > +{ > + struct target__kernel_timex *target_tx; > + > + if (copy_to_user_timeval64(target_addr + > + offsetof(struct target__kernel_timex, time), > + &host_tx->time)) { > + return -TARGET_EFAULT; > + } > + > + if (!lock_user_struct(VERIFY_WRITE, target_tx, target_addr, 0)) { > + return -TARGET_EFAULT; > + } > + > + __put_user(host_tx->modes, &target_tx->modes); > + __put_user(host_tx->offset, &target_tx->offset); > + __put_user(host_tx->freq, &target_tx->freq); > + __put_user(host_tx->maxerror, &target_tx->maxerror); > + __put_user(host_tx->esterror, &target_tx->esterror); > + __put_user(host_tx->status, &target_tx->status); > + __put_user(host_tx->constant, &target_tx->constant); > + __put_user(host_tx->precision, &target_tx->precision); > + __put_user(host_tx->tolerance, &target_tx->tolerance); > + __put_user(host_tx->tick, &target_tx->tick); > + __put_user(host_tx->ppsfreq, &target_tx->ppsfreq); > + __put_user(host_tx->jitter, &target_tx->jitter); > + __put_user(host_tx->shift, &target_tx->shift); > + __put_user(host_tx->stabil, &target_tx->stabil); > + __put_user(host_tx->jitcnt, &target_tx->jitcnt); > + __put_user(host_tx->calcnt, &target_tx->calcnt); > + __put_user(host_tx->errcnt, &target_tx->errcnt); > + __put_user(host_tx->stbcnt, &target_tx->stbcnt); > + __put_user(host_tx->tai, &target_tx->tai); > + > + unlock_user_struct(target_tx, target_addr, 1); > + return 0; > +} > +#endif > + > static inline abi_long target_to_host_sigevent(struct sigevent *host_sevp, > abi_ulong target_addr) > { > @@ -9726,6 +9825,23 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1, > } > } > return ret; > +#endif > +#if defined(TARGET_NR_clock_adjtime64) && defined(CONFIG_CLOCK_ADJTIME) > + case TARGET_NR_clock_adjtime64: > + { > + struct timex htx, *phtx = &htx; I know you have copied the code from TARGET_NR_clock_adjtime, but I think phtx is totally useless. > + > + if (target_to_host_timex64(phtx, arg2) != 0) { > + return -TARGET_EFAULT; > + } > + ret = get_errno(clock_adjtime(arg1, phtx)); > + if (!is_error(ret) && phtx) { value of phtx doesn't change. No need to check. > + if (host_to_target_timex64(arg2, phtx) != 0) { > + return -TARGET_EFAULT; > + } > + } > + } > + return ret; > #endif > case TARGET_NR_getpgid: > return get_errno(getpgid(arg1)); Thanks, Laurent ^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH v2 2/2] linux-user: Add support for 'rt_sigtimedwait_time64()' and 'sched_rr_get_interval_time64()' 2020-07-27 11:23 [PATCH v2 0/2] Introducing functionality for a group of 4 time64 syscalls Filip Bozuta 2020-07-27 11:23 ` [PATCH v2 1/2] linux-user: Add support for two 'clock_nanosleep_time64()' and 'clock_adjtime64()' Filip Bozuta @ 2020-07-27 11:23 ` Filip Bozuta 2020-08-24 16:43 ` Laurent Vivier 1 sibling, 1 reply; 5+ messages in thread From: Filip Bozuta @ 2020-07-27 11:23 UTC (permalink / raw) To: qemu-devel; +Cc: Riku Voipio, Laurent Vivier, Filip Bozuta This patch implements functionality for following time64 syscalls: *rt_sigtimedwait_time64() This is a year 2038 safe variant of syscall: int rt_sigtimedwait(const sigset_t *set, siginfo_t *info, const struct timespec *timeout, size_t sigsetsize) --synchronously wait for queued signals-- man page: https://man7.org/linux/man-pages/man2/rt_sigtimedwait.2.html *sched_rr_get_interval_time64() This is a year 2038 safe variant of syscall: int sched_rr_get_interval(pid_t pid, struct timespec *tp) --get the SCHED_RR interval for the named process-- man page: https://man7.org/linux/man-pages/man2/sched_rr_get_interval.2.html Implementation notes: These syscalls were implemented in similar ways like 'rt_sigtimedwait()' and 'sched_rr_get_interval()' except that functions 'target_to_host_timespec64()' and 'host_to_target_timespec64()' were used to convert values of 'struct timespec' between host and target. Signed-off-by: Filip Bozuta <Filip.Bozuta@syrmia.com> --- linux-user/syscall.c | 53 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) diff --git a/linux-user/syscall.c b/linux-user/syscall.c index c1b36ea698..35f6dded81 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -8831,6 +8831,48 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1, } } return ret; +#endif +#ifdef TARGET_NR_rt_sigtimedwait_time64 + case TARGET_NR_rt_sigtimedwait_time64: + { + sigset_t set; + struct timespec uts, *puts; + siginfo_t uinfo; + + if (arg4 != sizeof(target_sigset_t)) { + return -TARGET_EINVAL; + } + + p = lock_user(VERIFY_READ, arg1, sizeof(target_sigset_t), 1); + if (!p) { + return -TARGET_EFAULT; + } + target_to_host_sigset(&set, p); + unlock_user(p, arg1, 0); + if (arg3) { + puts = &uts; + if (target_to_host_timespec64(puts, arg3)) { + return -TARGET_EFAULT; + } + } else { + puts = NULL; + } + ret = get_errno(safe_rt_sigtimedwait(&set, &uinfo, puts, + SIGSET_T_SIZE)); + if (!is_error(ret)) { + if (arg2) { + p = lock_user(VERIFY_WRITE, arg2, + sizeof(target_siginfo_t), 0); + if (!p) { + return -TARGET_EFAULT; + } + host_to_target_siginfo(p, &uinfo); + unlock_user(p, arg2, sizeof(target_siginfo_t)); + } + ret = host_to_target_signal(ret); + } + } + return ret; #endif case TARGET_NR_rt_sigqueueinfo: { @@ -10353,6 +10395,17 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1, } return ret; #endif +#ifdef TARGET_NR_sched_rr_get_interval_time64 + case TARGET_NR_sched_rr_get_interval_time64: + { + struct timespec ts; + ret = get_errno(sched_rr_get_interval(arg1, &ts)); + if (!is_error(ret)) { + ret = host_to_target_timespec64(arg2, &ts); + } + } + return ret; +#endif #if defined(TARGET_NR_nanosleep) case TARGET_NR_nanosleep: { -- 2.25.1 ^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: [PATCH v2 2/2] linux-user: Add support for 'rt_sigtimedwait_time64()' and 'sched_rr_get_interval_time64()' 2020-07-27 11:23 ` [PATCH v2 2/2] linux-user: Add support for 'rt_sigtimedwait_time64()' and 'sched_rr_get_interval_time64()' Filip Bozuta @ 2020-08-24 16:43 ` Laurent Vivier 0 siblings, 0 replies; 5+ messages in thread From: Laurent Vivier @ 2020-08-24 16:43 UTC (permalink / raw) To: Filip Bozuta, qemu-devel; +Cc: Riku Voipio Le 27/07/2020 à 13:23, Filip Bozuta a écrit : > This patch implements functionality for following time64 syscalls: > > *rt_sigtimedwait_time64() > > This is a year 2038 safe variant of syscall: > > int rt_sigtimedwait(const sigset_t *set, siginfo_t *info, > const struct timespec *timeout, size_t sigsetsize) > --synchronously wait for queued signals-- > man page: https://man7.org/linux/man-pages/man2/rt_sigtimedwait.2.html > > *sched_rr_get_interval_time64() > > This is a year 2038 safe variant of syscall: > > int sched_rr_get_interval(pid_t pid, struct timespec *tp) > --get the SCHED_RR interval for the named process-- > man page: https://man7.org/linux/man-pages/man2/sched_rr_get_interval.2.html > > Implementation notes: > > These syscalls were implemented in similar ways like > 'rt_sigtimedwait()' and 'sched_rr_get_interval()' except > that functions 'target_to_host_timespec64()' and > 'host_to_target_timespec64()' were used to convert values > of 'struct timespec' between host and target. > > Signed-off-by: Filip Bozuta <Filip.Bozuta@syrmia.com> > --- > linux-user/syscall.c | 53 ++++++++++++++++++++++++++++++++++++++++++++ > 1 file changed, 53 insertions(+) > > diff --git a/linux-user/syscall.c b/linux-user/syscall.c > index c1b36ea698..35f6dded81 100644 > --- a/linux-user/syscall.c > +++ b/linux-user/syscall.c > @@ -8831,6 +8831,48 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1, > } > } > return ret; > +#endif > +#ifdef TARGET_NR_rt_sigtimedwait_time64 > + case TARGET_NR_rt_sigtimedwait_time64: > + { > + sigset_t set; > + struct timespec uts, *puts; > + siginfo_t uinfo; > + > + if (arg4 != sizeof(target_sigset_t)) { > + return -TARGET_EINVAL; > + } > + > + p = lock_user(VERIFY_READ, arg1, sizeof(target_sigset_t), 1); > + if (!p) { > + return -TARGET_EFAULT; > + } > + target_to_host_sigset(&set, p); > + unlock_user(p, arg1, 0); > + if (arg3) { > + puts = &uts; > + if (target_to_host_timespec64(puts, arg3)) { > + return -TARGET_EFAULT; > + } > + } else { > + puts = NULL; > + } > + ret = get_errno(safe_rt_sigtimedwait(&set, &uinfo, puts, > + SIGSET_T_SIZE)); > + if (!is_error(ret)) { > + if (arg2) { > + p = lock_user(VERIFY_WRITE, arg2, > + sizeof(target_siginfo_t), 0); > + if (!p) { > + return -TARGET_EFAULT; > + } > + host_to_target_siginfo(p, &uinfo); > + unlock_user(p, arg2, sizeof(target_siginfo_t)); > + } > + ret = host_to_target_signal(ret); > + } > + } > + return ret; > #endif > case TARGET_NR_rt_sigqueueinfo: > { > @@ -10353,6 +10395,17 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1, > } > return ret; > #endif > +#ifdef TARGET_NR_sched_rr_get_interval_time64 > + case TARGET_NR_sched_rr_get_interval_time64: > + { > + struct timespec ts; > + ret = get_errno(sched_rr_get_interval(arg1, &ts)); > + if (!is_error(ret)) { > + ret = host_to_target_timespec64(arg2, &ts); > + } > + } > + return ret; > +#endif > #if defined(TARGET_NR_nanosleep) > case TARGET_NR_nanosleep: > { > Reviewed-by: Laurent Vivier <laurent@vivier.eu> ^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2020-08-24 16:45 UTC | newest] Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2020-07-27 11:23 [PATCH v2 0/2] Introducing functionality for a group of 4 time64 syscalls Filip Bozuta 2020-07-27 11:23 ` [PATCH v2 1/2] linux-user: Add support for two 'clock_nanosleep_time64()' and 'clock_adjtime64()' Filip Bozuta 2020-08-24 16:40 ` Laurent Vivier 2020-07-27 11:23 ` [PATCH v2 2/2] linux-user: Add support for 'rt_sigtimedwait_time64()' and 'sched_rr_get_interval_time64()' Filip Bozuta 2020-08-24 16:43 ` Laurent Vivier
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.