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: | ... | ... |