NPTL host detection and futex syscall passthrough.

git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4616 c046a42c-6fe2-441c-8c8c-71466251a162
This commit is contained in:
pbrook 2008-05-29 14:34:11 +00:00
parent b5fc909e02
commit bd0c5661bf
2 changed files with 90 additions and 0 deletions

29
configure vendored
View File

@ -112,6 +112,7 @@ darwin_user="no"
build_docs="no"
uname_release=""
curses="yes"
nptl="yes"
# OS specific
targetos=`uname -s`
@ -331,6 +332,8 @@ for opt do
;;
--disable-curses) curses="no"
;;
--disable-nptl) nptl="no"
;;
*) echo "ERROR: unknown option $opt"; show_help="yes"
;;
esac
@ -424,6 +427,7 @@ echo " --enable-dsound enable DirectSound audio driver"
echo " --disable-brlapi disable BrlAPI"
echo " --disable-vnc-tls disable TLS encryption for VNC server"
echo " --disable-curses disable curses output"
echo " --disable-nptl disable usermode NPTL support"
echo " --enable-system enable all system emulation targets"
echo " --disable-system disable all system emulation targets"
echo " --enable-linux-user enable all linux usermode emulation targets"
@ -641,6 +645,24 @@ int main(void) {
}
EOF
# Check host NPTL support
cat > $TMPC <<EOF
#include <sched.h>
#include <sys/futex.h>
void foo()
{
#if !defined(CLONE_SETTLS) || !defined(FUTEX_WAIT)
#error bork
#endif
}
EOF
if $cc $ARCH_CFLAGS -c -o $TMPO $TMPC 2> /dev/null ; then
:
else
nptl="no"
fi
##########################################
# SDL probe
@ -839,6 +861,7 @@ echo "brlapi support $brlapi"
echo "Documentation $build_docs"
[ ! -z "$uname_release" ] && \
echo "uname -r $uname_release"
echo "NPTL support $nptl"
if test $sdl_too_old = "yes"; then
echo "-> Your SDL version is too old - please upgrade to have SDL support"
@ -1190,6 +1213,7 @@ echo "#include \"../config-host.h\"" >> $config_h
bflt="no"
elfload32="no"
target_nptl="no"
interp_prefix1=`echo "$interp_prefix" | sed "s/%M/$target_cpu/g"`
echo "#define CONFIG_QEMU_PREFIX \"$interp_prefix1\"" >> $config_h
@ -1232,6 +1256,7 @@ case "$target_cpu" in
echo "#define TARGET_ARCH \"arm\"" >> $config_h
echo "#define TARGET_ARM 1" >> $config_h
bflt="yes"
target_nptl="yes"
;;
cris)
echo "TARGET_ARCH=cris" >> $config_mak
@ -1379,6 +1404,10 @@ if test "$target_user_only" = "yes" -a "$bflt" = "yes"; then
echo "TARGET_HAS_BFLT=yes" >> $config_mak
echo "#define TARGET_HAS_BFLT 1" >> $config_h
fi
if test "$target_user_only" = "yes" \
-a "$nptl" = "yes" -a "$target_nptl" = "yes"; then
echo "#define USE_NPTL 1" >> $config_h
fi
# 32 bit ELF loader in addition to native 64 bit loader?
if test "$target_user_only" = "yes" -a "$elfload32" = "yes"; then
echo "TARGET_HAS_ELFLOAD32=yes" >> $config_mak

View File

@ -52,6 +52,9 @@
//#include <sys/user.h>
#include <netinet/ip.h>
#include <netinet/tcp.h>
#if defined(USE_NPTL)
#include <sys/futex.h>
#endif
#define termios host_termios
#define winsize host_winsize
@ -160,6 +163,7 @@ type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5,type6 arg6) \
#define __NR_sys_tkill __NR_tkill
#define __NR_sys_unlinkat __NR_unlinkat
#define __NR_sys_utimensat __NR_utimensat
#define __NR_sys_futex __NR_futex
#if defined(__alpha__) || defined (__ia64__) || defined(__x86_64__)
#define __NR__llseek __NR_lseek
@ -241,6 +245,11 @@ _syscall3(int,sys_unlinkat,int,dirfd,const char *,pathname,int,flags)
_syscall4(int,sys_utimensat,int,dirfd,const char *,pathname,
const struct timespec *,tsp,int,flags)
#endif
#if defined(TARGET_NR_futex) && defined(__NR_futex)
_syscall6(int,sys_futex,int *,uaddr,int,op,int,val,
const struct timespec *,timeout,int *,uaddr2,int,val3)
#endif
extern int personality(int);
extern int flock(int, int);
@ -2718,6 +2727,14 @@ int do_fork(CPUState *env, unsigned int flags, abi_ulong newsp)
CPUState *new_env;
if (flags & CLONE_VM) {
#if defined(USE_NPTL)
/* qemu is not threadsafe. Bail out immediately if application
tries to create a thread. */
if (!(flags & CLONE_VFORK)) {
gemu_log ("clone(CLONE_VM) not supported\n");
return -EINVAL;
}
#endif
ts = malloc(sizeof(TaskState) + NEW_STACK_SIZE);
memset(ts, 0, sizeof(TaskState));
new_stack = ts->stack;
@ -3056,6 +3073,45 @@ static inline abi_long host_to_target_timespec(abi_ulong target_addr,
return 0;
}
#if defined(USE_NPTL)
/* ??? Using host futex calls even when target atomic operations
are not really atomic probably breaks things. However implementing
futexes locally would make futexes shared between multiple processes
tricky. However they're probably useless because guest atomic
operations won't work either. */
int do_futex(target_ulong uaddr, int op, int val, target_ulong timeout,
target_ulong uaddr2, int val3)
{
struct timespec ts, *pts;
/* ??? We assume FUTEX_* constants are the same on both host
and target. */
switch (op) {
case FUTEX_WAIT:
if (timeout) {
pts = &ts;
target_to_host_timespec(pts, timeout);
} else {
pts = NULL;
}
return get_errno(sys_futex(g2h(uaddr), FUTEX_WAIT, tswap32(val),
pts, NULL, 0));
case FUTEX_WAKE:
return get_errno(sys_futex(g2h(uaddr), FUTEX_WAKE, val, NULL, NULL, 0));
case FUTEX_FD:
return get_errno(sys_futex(g2h(uaddr), FUTEX_FD, val, NULL, NULL, 0));
case FUTEX_REQUEUE:
return get_errno(sys_futex(g2h(uaddr), FUTEX_REQUEUE, val,
NULL, g2h(uaddr2), 0));
case FUTEX_CMP_REQUEUE:
return get_errno(sys_futex(g2h(uaddr), FUTEX_CMP_REQUEUE, val,
NULL, g2h(uaddr2), tswap32(val3)));
default:
return -TARGET_ENOSYS;
}
}
#endif
int get_osversion(void)
{
static int osversion;
@ -5614,6 +5670,11 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
}
break;
#endif
#if defined(USE_NPTL)
case TARGET_NR_futex:
ret = do_futex(arg1, arg2, arg3, arg4, arg5, arg6);
break;
#endif
default:
unimplemented: