From: Laurent Vivier <laurent@vivier.eu>
To: Filip Bozuta <Filip.Bozuta@syrmia.com>, qemu-devel@nongnu.org
Cc: Riku Voipio <riku.voipio@iki.fi>
Subject: Re: [PATCH v2 1/2] linux-user: Add support for two 'clock_nanosleep_time64()' and 'clock_adjtime64()'
Date: Mon, 24 Aug 2020 18:40:48 +0200 [thread overview]
Message-ID: <f35b45d9-289b-75c1-c01f-7fabc59e2fa7@vivier.eu> (raw)
In-Reply-To: <20200727112307.343608-2-Filip.Bozuta@syrmia.com>
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
next prev parent reply other threads:[~2020-08-24 16:43 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
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 [this message]
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
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=f35b45d9-289b-75c1-c01f-7fabc59e2fa7@vivier.eu \
--to=laurent@vivier.eu \
--cc=Filip.Bozuta@syrmia.com \
--cc=qemu-devel@nongnu.org \
--cc=riku.voipio@iki.fi \
/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 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).