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:
parent
b5fc909e02
commit
bd0c5661bf
29
configure
vendored
29
configure
vendored
@ -112,6 +112,7 @@ darwin_user="no"
|
|||||||
build_docs="no"
|
build_docs="no"
|
||||||
uname_release=""
|
uname_release=""
|
||||||
curses="yes"
|
curses="yes"
|
||||||
|
nptl="yes"
|
||||||
|
|
||||||
# OS specific
|
# OS specific
|
||||||
targetos=`uname -s`
|
targetos=`uname -s`
|
||||||
@ -331,6 +332,8 @@ for opt do
|
|||||||
;;
|
;;
|
||||||
--disable-curses) curses="no"
|
--disable-curses) curses="no"
|
||||||
;;
|
;;
|
||||||
|
--disable-nptl) nptl="no"
|
||||||
|
;;
|
||||||
*) echo "ERROR: unknown option $opt"; show_help="yes"
|
*) echo "ERROR: unknown option $opt"; show_help="yes"
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
@ -424,6 +427,7 @@ echo " --enable-dsound enable DirectSound audio driver"
|
|||||||
echo " --disable-brlapi disable BrlAPI"
|
echo " --disable-brlapi disable BrlAPI"
|
||||||
echo " --disable-vnc-tls disable TLS encryption for VNC server"
|
echo " --disable-vnc-tls disable TLS encryption for VNC server"
|
||||||
echo " --disable-curses disable curses output"
|
echo " --disable-curses disable curses output"
|
||||||
|
echo " --disable-nptl disable usermode NPTL support"
|
||||||
echo " --enable-system enable all system emulation targets"
|
echo " --enable-system enable all system emulation targets"
|
||||||
echo " --disable-system disable all system emulation targets"
|
echo " --disable-system disable all system emulation targets"
|
||||||
echo " --enable-linux-user enable all linux usermode emulation targets"
|
echo " --enable-linux-user enable all linux usermode emulation targets"
|
||||||
@ -641,6 +645,24 @@ int main(void) {
|
|||||||
}
|
}
|
||||||
EOF
|
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
|
# SDL probe
|
||||||
|
|
||||||
@ -839,6 +861,7 @@ echo "brlapi support $brlapi"
|
|||||||
echo "Documentation $build_docs"
|
echo "Documentation $build_docs"
|
||||||
[ ! -z "$uname_release" ] && \
|
[ ! -z "$uname_release" ] && \
|
||||||
echo "uname -r $uname_release"
|
echo "uname -r $uname_release"
|
||||||
|
echo "NPTL support $nptl"
|
||||||
|
|
||||||
if test $sdl_too_old = "yes"; then
|
if test $sdl_too_old = "yes"; then
|
||||||
echo "-> Your SDL version is too old - please upgrade to have SDL support"
|
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"
|
bflt="no"
|
||||||
elfload32="no"
|
elfload32="no"
|
||||||
|
target_nptl="no"
|
||||||
interp_prefix1=`echo "$interp_prefix" | sed "s/%M/$target_cpu/g"`
|
interp_prefix1=`echo "$interp_prefix" | sed "s/%M/$target_cpu/g"`
|
||||||
echo "#define CONFIG_QEMU_PREFIX \"$interp_prefix1\"" >> $config_h
|
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_ARCH \"arm\"" >> $config_h
|
||||||
echo "#define TARGET_ARM 1" >> $config_h
|
echo "#define TARGET_ARM 1" >> $config_h
|
||||||
bflt="yes"
|
bflt="yes"
|
||||||
|
target_nptl="yes"
|
||||||
;;
|
;;
|
||||||
cris)
|
cris)
|
||||||
echo "TARGET_ARCH=cris" >> $config_mak
|
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 "TARGET_HAS_BFLT=yes" >> $config_mak
|
||||||
echo "#define TARGET_HAS_BFLT 1" >> $config_h
|
echo "#define TARGET_HAS_BFLT 1" >> $config_h
|
||||||
fi
|
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?
|
# 32 bit ELF loader in addition to native 64 bit loader?
|
||||||
if test "$target_user_only" = "yes" -a "$elfload32" = "yes"; then
|
if test "$target_user_only" = "yes" -a "$elfload32" = "yes"; then
|
||||||
echo "TARGET_HAS_ELFLOAD32=yes" >> $config_mak
|
echo "TARGET_HAS_ELFLOAD32=yes" >> $config_mak
|
||||||
|
@ -52,6 +52,9 @@
|
|||||||
//#include <sys/user.h>
|
//#include <sys/user.h>
|
||||||
#include <netinet/ip.h>
|
#include <netinet/ip.h>
|
||||||
#include <netinet/tcp.h>
|
#include <netinet/tcp.h>
|
||||||
|
#if defined(USE_NPTL)
|
||||||
|
#include <sys/futex.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#define termios host_termios
|
#define termios host_termios
|
||||||
#define winsize host_winsize
|
#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_tkill __NR_tkill
|
||||||
#define __NR_sys_unlinkat __NR_unlinkat
|
#define __NR_sys_unlinkat __NR_unlinkat
|
||||||
#define __NR_sys_utimensat __NR_utimensat
|
#define __NR_sys_utimensat __NR_utimensat
|
||||||
|
#define __NR_sys_futex __NR_futex
|
||||||
|
|
||||||
#if defined(__alpha__) || defined (__ia64__) || defined(__x86_64__)
|
#if defined(__alpha__) || defined (__ia64__) || defined(__x86_64__)
|
||||||
#define __NR__llseek __NR_lseek
|
#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,
|
_syscall4(int,sys_utimensat,int,dirfd,const char *,pathname,
|
||||||
const struct timespec *,tsp,int,flags)
|
const struct timespec *,tsp,int,flags)
|
||||||
#endif
|
#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 personality(int);
|
||||||
extern int flock(int, int);
|
extern int flock(int, int);
|
||||||
@ -2718,6 +2727,14 @@ int do_fork(CPUState *env, unsigned int flags, abi_ulong newsp)
|
|||||||
CPUState *new_env;
|
CPUState *new_env;
|
||||||
|
|
||||||
if (flags & CLONE_VM) {
|
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);
|
ts = malloc(sizeof(TaskState) + NEW_STACK_SIZE);
|
||||||
memset(ts, 0, sizeof(TaskState));
|
memset(ts, 0, sizeof(TaskState));
|
||||||
new_stack = ts->stack;
|
new_stack = ts->stack;
|
||||||
@ -3056,6 +3073,45 @@ static inline abi_long host_to_target_timespec(abi_ulong target_addr,
|
|||||||
return 0;
|
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)
|
int get_osversion(void)
|
||||||
{
|
{
|
||||||
static int osversion;
|
static int osversion;
|
||||||
@ -5614,6 +5670,11 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
|
#if defined(USE_NPTL)
|
||||||
|
case TARGET_NR_futex:
|
||||||
|
ret = do_futex(arg1, arg2, arg3, arg4, arg5, arg6);
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
|
||||||
default:
|
default:
|
||||||
unimplemented:
|
unimplemented:
|
||||||
|
Loading…
Reference in New Issue
Block a user