qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [4616] NPTL host detection and futex syscall passthrough.


From: Paul Brook
Subject: [Qemu-devel] [4616] NPTL host detection and futex syscall passthrough.
Date: Thu, 29 May 2008 14:34:12 +0000

Revision: 4616
          http://svn.sv.gnu.org/viewvc/?view=rev&root=qemu&revision=4616
Author:   pbrook
Date:     2008-05-29 14:34:11 +0000 (Thu, 29 May 2008)

Log Message:
-----------
NPTL host detection and futex syscall passthrough.

Modified Paths:
--------------
    trunk/configure
    trunk/linux-user/syscall.c

Modified: trunk/configure
===================================================================
--- trunk/configure     2008-05-29 13:56:10 UTC (rev 4615)
+++ trunk/configure     2008-05-29 14:34:11 UTC (rev 4616)
@@ -112,6 +112,7 @@
 build_docs="no"
 uname_release=""
 curses="yes"
+nptl="yes"
 
 # OS specific
 targetos=`uname -s`
@@ -331,6 +332,8 @@
   ;;
   --disable-curses) curses="no"
   ;;
+  --disable-nptl) nptl="no"
+  ;;
   *) echo "ERROR: unknown option $opt"; show_help="yes"
   ;;
   esac
@@ -424,6 +427,7 @@
 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 @@
 }
 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 "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 @@
 
 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 @@
     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 @@
   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

Modified: trunk/linux-user/syscall.c
===================================================================
--- trunk/linux-user/syscall.c  2008-05-29 13:56:10 UTC (rev 4615)
+++ trunk/linux-user/syscall.c  2008-05-29 14:34:11 UTC (rev 4616)
@@ -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 @@
 #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 @@
 _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 @@
     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 @@
     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 @@
         }
        break;
 #endif
+#if defined(USE_NPTL)
+    case TARGET_NR_futex:
+        ret = do_futex(arg1, arg2, arg3, arg4, arg5, arg6);
+        break;
+#endif
 
     default:
     unimplemented:






reply via email to

[Prev in Thread] Current Thread [Next in Thread]