Commit bd0c5661bfd5d665f3e733b6724406b5a0ca1403
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
Showing
2 changed files
with
90 additions
and
0 deletions
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 "brlapi support $brlapi" |
| 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 "#include \"../config-host.h\"" >> $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 "$target_cpu" 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 "$target_user_only" = "yes" -a "$bflt" = "yes"; 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: | ... | ... |