Message ID | 20160922165712.79809-3-aleksandar.markovic@rt-rk.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
On Thu, Sep 22, 2016 at 06:56:51PM +0200, Aleksandar Markovic wrote: > From: Aleksandar Markovic <aleksandar.markovic@imgtec.com> > > This patch implements Qemu user mode clock_adjtime() syscall support. > > The implementation is based on invocation of host's clock_adjtime(), and is > very similar to the implementation of adjtimex() syscall support. The main > difference is the presence of "clockid_t" argument in clock_adjtime(). > Signed-off-by: Aleksandar Rikalo <aleksandar.rikalo@imgtec.com> > Signed-off-by: Aleksandar Markovic <aleksandar.markovic@imgtec.com> > --- > linux-user/strace.c | 76 ++++++++++++++++++++++++++++++++++++++++++++++++++ > linux-user/strace.list | 3 ++ > linux-user/syscall.c | 17 +++++++++++ > 3 files changed, 96 insertions(+) > > diff --git a/linux-user/strace.c b/linux-user/strace.c > index f37b386..a61717d 100644 > --- a/linux-user/strace.c > +++ b/linux-user/strace.c > @@ -435,6 +435,69 @@ print_fdset(int n, abi_ulong target_fds_addr) > } > #endif > > +#ifdef TARGET_NR_clock_adjtime > +/* IDs of the various system clocks */ > +#define TARGET_CLOCK_REALTIME 0 > +#define TARGET_CLOCK_MONOTONIC 1 > +#define TARGET_CLOCK_PROCESS_CPUTIME_ID 2 > +#define TARGET_CLOCK_THREAD_CPUTIME_ID 3 > +#define TARGET_CLOCK_MONOTONIC_RAW 4 > +#define TARGET_CLOCK_REALTIME_COARSE 5 > +#define TARGET_CLOCK_MONOTONIC_COARSE 6 > +#define TARGET_CLOCK_BOOTTIME 7 > +#define TARGET_CLOCK_REALTIME_ALARM 8 > +#define TARGET_CLOCK_BOOTTIME_ALARM 9 > +#define TARGET_CLOCK_SGI_CYCLE 10 > +#define TARGET_CLOCK_TAI 11 > + > +static void > +print_clockid(int clockid, int last) > +{ > + switch (clockid) { > + case TARGET_CLOCK_REALTIME: > + gemu_log("CLOCK_REALTIME"); > + break; > + case TARGET_CLOCK_MONOTONIC: > + gemu_log("CLOCK_MONOTONIC"); > + break; > + case TARGET_CLOCK_PROCESS_CPUTIME_ID: > + gemu_log("CLOCK_PROCESS_CPUTIME_ID"); > + break; > + case TARGET_CLOCK_THREAD_CPUTIME_ID: > + gemu_log("CLOCK_THREAD_CPUTIME_ID"); > + break; > + case TARGET_CLOCK_MONOTONIC_RAW: > + gemu_log("CLOCK_MONOTONIC_RAW"); > + break; > + case TARGET_CLOCK_REALTIME_COARSE: > + gemu_log("CLOCK_REALTIME_COARSE"); > + break; > + case TARGET_CLOCK_MONOTONIC_COARSE: > + gemu_log("CLOCK_MONOTONIC_COARSE"); > + break; > + case TARGET_CLOCK_BOOTTIME: > + gemu_log("CLOCK_BOOTTIME"); > + break; > + case TARGET_CLOCK_REALTIME_ALARM: > + gemu_log("CLOCK_REALTIME_ALARM"); > + break; > + case TARGET_CLOCK_BOOTTIME_ALARM: > + gemu_log("CLOCK_BOOTTIME_ALARM"); > + break; > + case TARGET_CLOCK_SGI_CYCLE: > + gemu_log("CLOCK_SGI_CYCLE"); > + break; > + case TARGET_CLOCK_TAI: > + gemu_log("CLOCK_TAI"); > + break; > + default: > + gemu_log("%d", clockid); > + break; > + } > + gemu_log("%s", get_comma(last)); > +} > +#endif > + > /* > * Sysycall specific output functions > */ > @@ -1096,6 +1159,19 @@ print_chmod(const struct syscallname *name, > } > #endif > > +#ifdef TARGET_NR_clock_adjtime > +static void > +print_clock_adjtime(const struct syscallname *name, > + abi_long arg0, abi_long arg1, abi_long arg2, > + abi_long arg3, abi_long arg4, abi_long arg5) > +{ > + print_syscall_prologue(name); > + print_clockid(arg0, 0); > + print_pointer(arg1, 1); > + print_syscall_epilogue(name); > +} > +#endif > + > #ifdef TARGET_NR_clone > static void do_print_clone(unsigned int flags, abi_ulong newsp, > abi_ulong parent_tidptr, target_ulong newtls, > diff --git a/linux-user/strace.list b/linux-user/strace.list > index 44e8322..01aecfc 100644 > --- a/linux-user/strace.list > +++ b/linux-user/strace.list > @@ -73,6 +73,9 @@ > #ifdef TARGET_NR_chroot > { TARGET_NR_chroot, "chroot" , NULL, NULL, NULL }, > #endif > +#ifdef TARGET_NR_clock_adjtime > +{ TARGET_NR_clock_adjtime, "clock_adjtime" , NULL, print_clock_adjtime, NULL }, > +#endif > #ifdef TARGET_NR_clock_getres > { TARGET_NR_clock_getres, "clock_getres" , NULL, NULL, NULL }, > #endif > diff --git a/linux-user/syscall.c b/linux-user/syscall.c > index 7ad5b96..9f11ca2 100644 > --- a/linux-user/syscall.c > +++ b/linux-user/syscall.c > @@ -9623,6 +9623,23 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, > } > } > break; > +#if defined(TARGET_NR_clock_adjtime) > + case TARGET_NR_clock_adjtime: > + { > + struct timex host_buf; > + > + if (target_to_host_timex(&host_buf, arg2) != 0) { > + goto efault; > + } > + ret = get_errno(clock_adjtime(arg1, &host_buf)); When compiling on SuSe11: linux-user/syscall.o: In function `do_syscall': /work/linux-user/syscall.c:9710: undefined reference to `clock_adjtime' The syscall is new enough that it needs a CONFIG_CLOCK_ADJTIME test in configure. > + if (!is_error(ret)) { > + if (host_to_target_timex(arg2, &host_buf) != 0) { > + goto efault; > + } > + } > + } > + break; > +#endif > #ifdef TARGET_NR_create_module > case TARGET_NR_create_module: > #endif > -- > 2.9.3 > >
diff --git a/linux-user/strace.c b/linux-user/strace.c index f37b386..a61717d 100644 --- a/linux-user/strace.c +++ b/linux-user/strace.c @@ -435,6 +435,69 @@ print_fdset(int n, abi_ulong target_fds_addr) } #endif +#ifdef TARGET_NR_clock_adjtime +/* IDs of the various system clocks */ +#define TARGET_CLOCK_REALTIME 0 +#define TARGET_CLOCK_MONOTONIC 1 +#define TARGET_CLOCK_PROCESS_CPUTIME_ID 2 +#define TARGET_CLOCK_THREAD_CPUTIME_ID 3 +#define TARGET_CLOCK_MONOTONIC_RAW 4 +#define TARGET_CLOCK_REALTIME_COARSE 5 +#define TARGET_CLOCK_MONOTONIC_COARSE 6 +#define TARGET_CLOCK_BOOTTIME 7 +#define TARGET_CLOCK_REALTIME_ALARM 8 +#define TARGET_CLOCK_BOOTTIME_ALARM 9 +#define TARGET_CLOCK_SGI_CYCLE 10 +#define TARGET_CLOCK_TAI 11 + +static void +print_clockid(int clockid, int last) +{ + switch (clockid) { + case TARGET_CLOCK_REALTIME: + gemu_log("CLOCK_REALTIME"); + break; + case TARGET_CLOCK_MONOTONIC: + gemu_log("CLOCK_MONOTONIC"); + break; + case TARGET_CLOCK_PROCESS_CPUTIME_ID: + gemu_log("CLOCK_PROCESS_CPUTIME_ID"); + break; + case TARGET_CLOCK_THREAD_CPUTIME_ID: + gemu_log("CLOCK_THREAD_CPUTIME_ID"); + break; + case TARGET_CLOCK_MONOTONIC_RAW: + gemu_log("CLOCK_MONOTONIC_RAW"); + break; + case TARGET_CLOCK_REALTIME_COARSE: + gemu_log("CLOCK_REALTIME_COARSE"); + break; + case TARGET_CLOCK_MONOTONIC_COARSE: + gemu_log("CLOCK_MONOTONIC_COARSE"); + break; + case TARGET_CLOCK_BOOTTIME: + gemu_log("CLOCK_BOOTTIME"); + break; + case TARGET_CLOCK_REALTIME_ALARM: + gemu_log("CLOCK_REALTIME_ALARM"); + break; + case TARGET_CLOCK_BOOTTIME_ALARM: + gemu_log("CLOCK_BOOTTIME_ALARM"); + break; + case TARGET_CLOCK_SGI_CYCLE: + gemu_log("CLOCK_SGI_CYCLE"); + break; + case TARGET_CLOCK_TAI: + gemu_log("CLOCK_TAI"); + break; + default: + gemu_log("%d", clockid); + break; + } + gemu_log("%s", get_comma(last)); +} +#endif + /* * Sysycall specific output functions */ @@ -1096,6 +1159,19 @@ print_chmod(const struct syscallname *name, } #endif +#ifdef TARGET_NR_clock_adjtime +static void +print_clock_adjtime(const struct syscallname *name, + abi_long arg0, abi_long arg1, abi_long arg2, + abi_long arg3, abi_long arg4, abi_long arg5) +{ + print_syscall_prologue(name); + print_clockid(arg0, 0); + print_pointer(arg1, 1); + print_syscall_epilogue(name); +} +#endif + #ifdef TARGET_NR_clone static void do_print_clone(unsigned int flags, abi_ulong newsp, abi_ulong parent_tidptr, target_ulong newtls, diff --git a/linux-user/strace.list b/linux-user/strace.list index 44e8322..01aecfc 100644 --- a/linux-user/strace.list +++ b/linux-user/strace.list @@ -73,6 +73,9 @@ #ifdef TARGET_NR_chroot { TARGET_NR_chroot, "chroot" , NULL, NULL, NULL }, #endif +#ifdef TARGET_NR_clock_adjtime +{ TARGET_NR_clock_adjtime, "clock_adjtime" , NULL, print_clock_adjtime, NULL }, +#endif #ifdef TARGET_NR_clock_getres { TARGET_NR_clock_getres, "clock_getres" , NULL, NULL, NULL }, #endif diff --git a/linux-user/syscall.c b/linux-user/syscall.c index 7ad5b96..9f11ca2 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -9623,6 +9623,23 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, } } break; +#if defined(TARGET_NR_clock_adjtime) + case TARGET_NR_clock_adjtime: + { + struct timex host_buf; + + if (target_to_host_timex(&host_buf, arg2) != 0) { + goto efault; + } + ret = get_errno(clock_adjtime(arg1, &host_buf)); + if (!is_error(ret)) { + if (host_to_target_timex(arg2, &host_buf) != 0) { + goto efault; + } + } + } + break; +#endif #ifdef TARGET_NR_create_module case TARGET_NR_create_module: #endif