Commit bd0c5661bfd5d665f3e733b6724406b5a0ca1403

Authored by pbrook
1 parent b5fc909e

NPTL host detection and futex syscall passthrough.


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4616 c046a42c-6fe2-441c-8c8c-71466251a162
configure
... ... @@ -112,6 +112,7 @@ darwin_user="no"
112 112 build_docs="no"
113 113 uname_release=""
114 114 curses="yes"
  115 +nptl="yes"
115 116  
116 117 # OS specific
117 118 targetos=`uname -s`
... ... @@ -331,6 +332,8 @@ for opt do
331 332 ;;
332 333 --disable-curses) curses="no"
333 334 ;;
  335 + --disable-nptl) nptl="no"
  336 + ;;
334 337 *) echo "ERROR: unknown option $opt"; show_help="yes"
335 338 ;;
336 339 esac
... ... @@ -424,6 +427,7 @@ echo " --enable-dsound enable DirectSound audio driver"
424 427 echo " --disable-brlapi disable BrlAPI"
425 428 echo " --disable-vnc-tls disable TLS encryption for VNC server"
426 429 echo " --disable-curses disable curses output"
  430 +echo " --disable-nptl disable usermode NPTL support"
427 431 echo " --enable-system enable all system emulation targets"
428 432 echo " --disable-system disable all system emulation targets"
429 433 echo " --enable-linux-user enable all linux usermode emulation targets"
... ... @@ -641,6 +645,24 @@ int main(void) {
641 645 }
642 646 EOF
643 647  
  648 +# Check host NPTL support
  649 +cat > $TMPC <<EOF
  650 +#include <sched.h>
  651 +#include <sys/futex.h>
  652 +void foo()
  653 +{
  654 +#if !defined(CLONE_SETTLS) || !defined(FUTEX_WAIT)
  655 +#error bork
  656 +#endif
  657 +}
  658 +EOF
  659 +
  660 +if $cc $ARCH_CFLAGS -c -o $TMPO $TMPC 2> /dev/null ; then
  661 + :
  662 +else
  663 + nptl="no"
  664 +fi
  665 +
644 666 ##########################################
645 667 # SDL probe
646 668  
... ... @@ -839,6 +861,7 @@ echo &quot;brlapi support $brlapi&quot;
839 861 echo "Documentation $build_docs"
840 862 [ ! -z "$uname_release" ] && \
841 863 echo "uname -r $uname_release"
  864 +echo "NPTL support $nptl"
842 865  
843 866 if test $sdl_too_old = "yes"; then
844 867 echo "-> Your SDL version is too old - please upgrade to have SDL support"
... ... @@ -1190,6 +1213,7 @@ echo &quot;#include \&quot;../config-host.h\&quot;&quot; &gt;&gt; $config_h
1190 1213  
1191 1214 bflt="no"
1192 1215 elfload32="no"
  1216 +target_nptl="no"
1193 1217 interp_prefix1=`echo "$interp_prefix" | sed "s/%M/$target_cpu/g"`
1194 1218 echo "#define CONFIG_QEMU_PREFIX \"$interp_prefix1\"" >> $config_h
1195 1219  
... ... @@ -1232,6 +1256,7 @@ case &quot;$target_cpu&quot; in
1232 1256 echo "#define TARGET_ARCH \"arm\"" >> $config_h
1233 1257 echo "#define TARGET_ARM 1" >> $config_h
1234 1258 bflt="yes"
  1259 + target_nptl="yes"
1235 1260 ;;
1236 1261 cris)
1237 1262 echo "TARGET_ARCH=cris" >> $config_mak
... ... @@ -1379,6 +1404,10 @@ if test &quot;$target_user_only&quot; = &quot;yes&quot; -a &quot;$bflt&quot; = &quot;yes&quot;; then
1379 1404 echo "TARGET_HAS_BFLT=yes" >> $config_mak
1380 1405 echo "#define TARGET_HAS_BFLT 1" >> $config_h
1381 1406 fi
  1407 +if test "$target_user_only" = "yes" \
  1408 + -a "$nptl" = "yes" -a "$target_nptl" = "yes"; then
  1409 + echo "#define USE_NPTL 1" >> $config_h
  1410 +fi
1382 1411 # 32 bit ELF loader in addition to native 64 bit loader?
1383 1412 if test "$target_user_only" = "yes" -a "$elfload32" = "yes"; then
1384 1413 echo "TARGET_HAS_ELFLOAD32=yes" >> $config_mak
... ...
linux-user/syscall.c
... ... @@ -52,6 +52,9 @@
52 52 //#include <sys/user.h>
53 53 #include <netinet/ip.h>
54 54 #include <netinet/tcp.h>
  55 +#if defined(USE_NPTL)
  56 +#include <sys/futex.h>
  57 +#endif
55 58  
56 59 #define termios host_termios
57 60 #define winsize host_winsize
... ... @@ -160,6 +163,7 @@ type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5,type6 arg6) \
160 163 #define __NR_sys_tkill __NR_tkill
161 164 #define __NR_sys_unlinkat __NR_unlinkat
162 165 #define __NR_sys_utimensat __NR_utimensat
  166 +#define __NR_sys_futex __NR_futex
163 167  
164 168 #if defined(__alpha__) || defined (__ia64__) || defined(__x86_64__)
165 169 #define __NR__llseek __NR_lseek
... ... @@ -241,6 +245,11 @@ _syscall3(int,sys_unlinkat,int,dirfd,const char *,pathname,int,flags)
241 245 _syscall4(int,sys_utimensat,int,dirfd,const char *,pathname,
242 246 const struct timespec *,tsp,int,flags)
243 247 #endif
  248 +#if defined(TARGET_NR_futex) && defined(__NR_futex)
  249 +_syscall6(int,sys_futex,int *,uaddr,int,op,int,val,
  250 + const struct timespec *,timeout,int *,uaddr2,int,val3)
  251 +
  252 +#endif
244 253  
245 254 extern int personality(int);
246 255 extern int flock(int, int);
... ... @@ -2718,6 +2727,14 @@ int do_fork(CPUState *env, unsigned int flags, abi_ulong newsp)
2718 2727 CPUState *new_env;
2719 2728  
2720 2729 if (flags & CLONE_VM) {
  2730 +#if defined(USE_NPTL)
  2731 + /* qemu is not threadsafe. Bail out immediately if application
  2732 + tries to create a thread. */
  2733 + if (!(flags & CLONE_VFORK)) {
  2734 + gemu_log ("clone(CLONE_VM) not supported\n");
  2735 + return -EINVAL;
  2736 + }
  2737 +#endif
2721 2738 ts = malloc(sizeof(TaskState) + NEW_STACK_SIZE);
2722 2739 memset(ts, 0, sizeof(TaskState));
2723 2740 new_stack = ts->stack;
... ... @@ -3056,6 +3073,45 @@ static inline abi_long host_to_target_timespec(abi_ulong target_addr,
3056 3073 return 0;
3057 3074 }
3058 3075  
  3076 +#if defined(USE_NPTL)
  3077 +/* ??? Using host futex calls even when target atomic operations
  3078 + are not really atomic probably breaks things. However implementing
  3079 + futexes locally would make futexes shared between multiple processes
  3080 + tricky. However they're probably useless because guest atomic
  3081 + operations won't work either. */
  3082 +int do_futex(target_ulong uaddr, int op, int val, target_ulong timeout,
  3083 + target_ulong uaddr2, int val3)
  3084 +{
  3085 + struct timespec ts, *pts;
  3086 +
  3087 + /* ??? We assume FUTEX_* constants are the same on both host
  3088 + and target. */
  3089 + switch (op) {
  3090 + case FUTEX_WAIT:
  3091 + if (timeout) {
  3092 + pts = &ts;
  3093 + target_to_host_timespec(pts, timeout);
  3094 + } else {
  3095 + pts = NULL;
  3096 + }
  3097 + return get_errno(sys_futex(g2h(uaddr), FUTEX_WAIT, tswap32(val),
  3098 + pts, NULL, 0));
  3099 + case FUTEX_WAKE:
  3100 + return get_errno(sys_futex(g2h(uaddr), FUTEX_WAKE, val, NULL, NULL, 0));
  3101 + case FUTEX_FD:
  3102 + return get_errno(sys_futex(g2h(uaddr), FUTEX_FD, val, NULL, NULL, 0));
  3103 + case FUTEX_REQUEUE:
  3104 + return get_errno(sys_futex(g2h(uaddr), FUTEX_REQUEUE, val,
  3105 + NULL, g2h(uaddr2), 0));
  3106 + case FUTEX_CMP_REQUEUE:
  3107 + return get_errno(sys_futex(g2h(uaddr), FUTEX_CMP_REQUEUE, val,
  3108 + NULL, g2h(uaddr2), tswap32(val3)));
  3109 + default:
  3110 + return -TARGET_ENOSYS;
  3111 + }
  3112 +}
  3113 +#endif
  3114 +
3059 3115 int get_osversion(void)
3060 3116 {
3061 3117 static int osversion;
... ... @@ -5614,6 +5670,11 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
5614 5670 }
5615 5671 break;
5616 5672 #endif
  5673 +#if defined(USE_NPTL)
  5674 + case TARGET_NR_futex:
  5675 + ret = do_futex(arg1, arg2, arg3, arg4, arg5, arg6);
  5676 + break;
  5677 +#endif
5617 5678  
5618 5679 default:
5619 5680 unimplemented:
... ...