linux-user: support timerfd_{create, gettime, settime} syscalls

Adds support for the timerfd_create, timerfd_gettime & timerfd_settime
syscalls, allowing use of timerfds by target programs.

v2: By Riku - added configure check for timerfd and ifdefs
for benefit of old distributions like RHEL5.

Signed-off-by: Paul Burton <paul@archlinuxmips.org>
Signed-off-by: Riku Voipio <riku.voipio@linaro.org>
This commit is contained in:
Riku Voipio 2014-06-22 11:25:42 +01:00
parent f17f4989fa
commit 518343413f
3 changed files with 71 additions and 0 deletions

17
configure vendored
View file

@ -3456,6 +3456,20 @@ if compile_prog "" "" ; then
sendfile=yes
fi
# check for timerfd support (glibc 2.8 and newer)
timerfd=no
cat > $TMPC << EOF
#include <sys/timerfd.h>
int main(void)
{
return(timerfd_create(CLOCK_REALTIME, 0));
}
EOF
if compile_prog "" "" ; then
timerfd=yes
fi
# Check if tools are available to build documentation.
if test "$docs" != "no" ; then
if has makeinfo && has pod2man; then
@ -4524,6 +4538,9 @@ fi
if test "$sendfile" = "yes" ; then
echo "CONFIG_SENDFILE=y" >> $config_host_mak
fi
if test "$timerfd" = "yes" ; then
echo "CONFIG_TIMERFD=y" >> $config_host_mak
fi
if test "$inotify" = "yes" ; then
echo "CONFIG_INOTIFY=y" >> $config_host_mak
fi

View file

@ -1404,6 +1404,15 @@
#ifdef TARGET_NR_timer_settime
{ TARGET_NR_timer_settime, "timer_settime" , NULL, NULL, NULL },
#endif
#ifdef TARGET_NR_timerfd_create
{ TARGET_NR_timerfd_create, "timerfd_create" , NULL, NULL, NULL },
#endif
#ifdef TARGET_NR_timerfd_gettime
{ TARGET_NR_timerfd_gettime, "timerfd_gettime" , NULL, NULL, NULL },
#endif
#ifdef TARGET_NR_timerfd_settime
{ TARGET_NR_timerfd_settime, "timerfd_settime" , NULL, NULL, NULL },
#endif
#ifdef TARGET_NR_times
{ TARGET_NR_times, "times" , NULL, NULL, NULL },
#endif

View file

@ -58,6 +58,7 @@ int __clone2(int (*fn)(void *), void *child_stack_base,
#include <sys/shm.h>
#include <sys/sem.h>
#include <sys/statfs.h>
#include <sys/timerfd.h>
#include <utime.h>
#include <sys/sysinfo.h>
//#include <sys/user.h>
@ -9547,6 +9548,50 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
}
#endif
#if defined(TARGET_NR_timerfd_create) && defined(CONFIG_TIMERFD)
case TARGET_NR_timerfd_create:
ret = get_errno(timerfd_create(arg1,
target_to_host_bitmask(arg2, fcntl_flags_tbl)));
break;
#endif
#if defined(TARGET_NR_timerfd_gettime) && defined(CONFIG_TIMERFD)
case TARGET_NR_timerfd_gettime:
{
struct itimerspec its_curr;
ret = get_errno(timerfd_gettime(arg1, &its_curr));
if (arg2 && host_to_target_itimerspec(arg2, &its_curr)) {
goto efault;
}
}
break;
#endif
#if defined(TARGET_NR_timerfd_settime) && defined(CONFIG_TIMERFD)
case TARGET_NR_timerfd_settime:
{
struct itimerspec its_new, its_old, *p_new;
if (arg3) {
if (target_to_host_itimerspec(&its_new, arg3)) {
goto efault;
}
p_new = &its_new;
} else {
p_new = NULL;
}
ret = get_errno(timerfd_settime(arg1, arg2, p_new, &its_old));
if (arg4 && host_to_target_itimerspec(arg4, &its_old)) {
goto efault;
}
}
break;
#endif
default:
unimplemented:
gemu_log("qemu: Unsupported syscall: %d\n", num);