Index: emulators/qemu-devel/Makefile =================================================================== --- emulators/qemu-devel/Makefile (revision 374226) +++ emulators/qemu-devel/Makefile (working copy) @@ -3,7 +3,7 @@ PORTNAME= qemu PORTVERSION= 2.0.2 -PORTREVISION= 10 +PORTREVISION= 11 CATEGORIES= emulators MASTER_SITES= http://wiki.qemu.org/download/:release \ LOCAL/nox:snapshot @@ -97,6 +97,19 @@ EXTRA_PATCHES+= ${FILESDIR}/extra-patch-72f0a64c7d EXTRA_PATCHES+= ${FILESDIR}/extra-patch-9ed0e07e2e07791858339874eb4d20daca858c8a EXTRA_PATCHES+= ${FILESDIR}/extra-patch-a8dc4de7f73bc6f8363c0fc81c4c6e53733c444b EXTRA_PATCHES+= ${FILESDIR}/extra-patch-bsd-user-freebsd-os-socket.h + +EXTRA_PATCHES+= ${FILESDIR}/extra-patch-7aea4e8d72cab81a102686eb639530c78d555315 +# XXX 9.x doesn't have struct _umtx_time: +EXTRA_PATCHES+= ${FILESDIR}/extra-patch-7b9ddce757fee0edf23982be98530a5556ee1b17 + +EXTRA_PATCHES+= ${FILESDIR}/extra-patch-bf8de490b6a42d2ef504072cdc0899638091196a +EXTRA_PATCHES+= ${FILESDIR}/extra-patch-41006748ffe0fbd7bfc5180adf09c3a01563202b +EXTRA_PATCHES+= ${FILESDIR}/extra-patch-cabfcd6c231c9425b9ac27c9ecca983786c5eff1 +EXTRA_PATCHES+= ${FILESDIR}/extra-patch-c9ff14ece1eab3efeb683b1e9752f5f7fb6b3870 + +EXTRA_PATCHES+= ${FILESDIR}/extra-patch-9650cd6e2499a6e5f8a6382032fa1636e4b93e6e +EXTRA_PATCHES+= ${FILESDIR}/extra-patch-cfd5876b814e70e95df84620b8d130a36be32edc + EXTRA_PATCHES+= ${FILESDIR}/extra-patch-cab0d36ffd4e70b1879dc2cf860c975a7965afc3 EXTRA_PATCHES+= ${FILESDIR}/extra-patch-8267ad2cb92b106bb16e91234f04abc49ab32036 EXTRA_PATCHES+= ${FILESDIR}/extra-patch-290a6e398b9d132a673e1f95954fc7d9a86c3baa @@ -106,6 +119,19 @@ EXTRA_PATCHES+= ${FILESDIR}/extra-patch-a72c668c8a EXTRA_PATCHES+= ${FILESDIR}/extra-patch-d5c3fb7b75b4ea80e09bf3cb7ff6dd1061968d6e EXTRA_PATCHES+= ${FILESDIR}/extra-patch-f4319eb1a3a8393930570f061bdac6abe007b2bb EXTRA_PATCHES+= ${FILESDIR}/extra-patch-f254372f13ab5cd8f25bd1ca8641ce6d67bff3fe +EXTRA_PATCHES+= ${FILESDIR}/extra-patch-e41ec268589bd572b170b4f360928265f8472b2c +EXTRA_PATCHES+= ${FILESDIR}/extra-patch-fc128b9c49bb87d22772a74829c802117c3ef94f +EXTRA_PATCHES+= ${FILESDIR}/extra-patch-b43b3fe91c85201399f8b2248da267337342a869 +EXTRA_PATCHES+= ${FILESDIR}/extra-patch-b8cf8682d4542d08864c4af069b235a151a10300 + +EXTRA_PATCHES+= ${FILESDIR}/extra-patch-1ec9ed3be8ac887486354c69c988cd1ee0edcaca +EXTRA_PATCHES+= ${FILESDIR}/extra-patch-ea04e4628070f31ca8c00b8a3cbdd4bd25c19465 + +EXTRA_PATCHES+= ${FILESDIR}/extra-patch-32b747b24b7c6b7b071121459ddd2fc15b242a8a + +EXTRA_PATCHES+= ${FILESDIR}/extra-patch-9ec60058f0445120f26324970fce6f9f5e30d82f +EXTRA_PATCHES+= ${FILESDIR}/extra-patch-89daa490c97173cfcb6bf071ef923a0b30be43ab +EXTRA_PATCHES+= ${FILESDIR}/extra-patch-2b6c52c4195be39678a4a2eafb8dc11b2e040762 .endif CONFIGURE_ARGS+= --localstatedir=/var Index: emulators/qemu-devel/files/extra-patch-1ec9ed3be8ac887486354c69c988cd1ee0edcaca =================================================================== --- emulators/qemu-devel/files/extra-patch-1ec9ed3be8ac887486354c69c988cd1ee0edcaca (revision 0) +++ emulators/qemu-devel/files/extra-patch-1ec9ed3be8ac887486354c69c988cd1ee0edcaca (working copy) @@ -0,0 +1,131 @@ +From 1ec9ed3be8ac887486354c69c988cd1ee0edcaca Mon Sep 17 00:00:00 2001 +From: Stacey Son +Date: Mon, 8 Dec 2014 18:53:26 +0000 +Subject: [PATCH] Clean up _umtx_op(.., UMTX_OP_NWAKE_PRIVATE, ...) syscall + support. + +This changes support _umtx_op(.., UMTX_OP_NWAKE_PRIVATE, ...) so +it only has to make one system call (the way NWAKE should work) +instead of a system call for each deferred waiter in the list. +--- + bsd-user/freebsd/os-thread.c | 59 ++++++++++++++++++++++++++++++++++++++------ + bsd-user/freebsd/os-thread.h | 20 +-------------- + 2 files changed, 53 insertions(+), 26 deletions(-) + +diff --git a/bsd-user/freebsd/os-thread.c b/bsd-user/freebsd/os-thread.c +index 6f8fee3..535a5b9 100644 +--- a/bsd-user/freebsd/os-thread.c ++++ b/bsd-user/freebsd/os-thread.c +@@ -35,6 +35,7 @@ + #include "target_arch_thread.h" + + // #define DEBUG_UMTX(...) fprintf(stderr, __VA_ARGS__) ++// #define DEBUG_UMTX(...) qemu_log(__VA_ARGS__) + #define DEBUG_UMTX(...) + + #define NEW_STACK_SIZE 0x40000 +@@ -186,8 +187,9 @@ abi_long freebsd_umtx_wait_uint_private(abi_ulong obj, uint32_t val, + size_t utsz, struct _umtx_time *ut) + { + +- DEBUG_UMTX(" %s: _umtx_op(%p, %d, 0x%x, %d, %p)\n", +- __func__, g2h(obj), UMTX_OP_WAIT_UINT_PRIVATE, val, (int)utsz, ut); ++ DEBUG_UMTX(" %s: _umtx_op(%p (%u), %d, 0x%x, %d, %p)\n", ++ __func__, g2h(obj), *(uint32_t *)g2h(obj), UMTX_OP_WAIT_UINT_PRIVATE, ++ val, (int)utsz, ut); + return get_errno(_umtx_op(g2h(obj), UMTX_OP_WAIT_UINT_PRIVATE, val, + (void *)utsz, ut)); + } +@@ -202,13 +204,56 @@ abi_long freebsd_umtx_wake_private(abi_ulong obj, uint32_t val) + + #if defined(__FreeBSD_version) && __FreeBSD_version > 900000 + #if defined(UMTX_OP_NWAKE_PRIVATE) +-abi_long freebsd_umtx_nwake_private(abi_ulong obj, uint32_t val) ++abi_long freebsd_umtx_nwake_private(abi_ulong target_array_addr, uint32_t num) + { ++#if 0 ++ int i; ++ abi_ulong *uaddr; ++ abi_long ret = 0; ++ ++ DEBUG_UMTX(" %s: _umtx_op(%p, %d, %d, NULL, NULL) Waking: ", ++ __func__, g2h(target_array_addr), UMTX_OP_NWAKE_PRIVATE, num); ++ if (!access_ok(VERIFY_READ, target_array_addr, num * sizeof(abi_ulong))) { ++ return -TARGET_EFAULT; ++ } ++ uaddr = (abi_ulong *)g2h(target_array_addr); ++ for (i = 0; i < (int32_t)num; i++) { ++ DEBUG_UMTX("%p ", g2h(tswapal(uaddr[ii]))); ++ ret = get_errno(_umtx_op(g2h(tswapal(uaddr[i])), UMTX_OP_WAKE_PRIVATE, ++ INT_MAX, NULL, NULL)); ++ if (is_error(ret)) { ++ DEBUG_UMTX("\n"); ++ return ret; ++ } ++ } ++ DEBUG_UMTX("\n"); ++ return ret; ++ ++#else ++ ++ uint32_t i; ++ abi_ulong *target_array; ++ void **array; ++ ++ ++ array = alloca(num * sizeof(void *)); ++ ++ target_array = lock_user(VERIFY_READ, target_array_addr, ++ num * sizeof(abi_ulong), 1); ++ if (target_array == NULL) { ++ return -TARGET_EFAULT; ++ } ++ DEBUG_UMTX(" %s: _umtx_op(%p, %d, %d, NULL, NULL) Waking: ", ++ __func__, g2h(target_array_addr), UMTX_OP_NWAKE_PRIVATE, num); ++ for(i = 0; i < num; i++) { ++ array[i] = g2h(tswapal(target_array[i])); ++ DEBUG_UMTX("%p ", array[i]); ++ } ++ DEBUG_UMTX("\n"); ++ unlock_user(target_array, target_array_addr, 0); + +- DEBUG_UMTX(" %s: _umtx_op(%p, %d, 0x%x, NULL, NULL)\n", +- __func__, g2h(obj), UMTX_OP_NWAKE_PRIVATE, val); +- return get_errno(_umtx_op(g2h(obj), UMTX_OP_NWAKE_PRIVATE, val, NULL, +- NULL)); ++ return get_errno(_umtx_op(array, UMTX_OP_NWAKE_PRIVATE, num, NULL, NULL)); ++#endif /* #if 0 */ + } + #endif /* UMTX_OP_NWAKE_PRIVATE */ + +diff --git a/bsd-user/freebsd/os-thread.h b/bsd-user/freebsd/os-thread.h +index a41fde5..9ed4f6d 100644 +--- a/bsd-user/freebsd/os-thread.h ++++ b/bsd-user/freebsd/os-thread.h +@@ -493,25 +493,7 @@ static inline abi_long do_freebsd__umtx_op(abi_ulong obj, int op, abi_ulong val, + + #ifdef UMTX_OP_NWAKE_PRIVATE + case TARGET_UMTX_OP_NWAKE_PRIVATE: +- { +- int i; +- abi_ulong *uaddr; +- uint32_t imax = tswap32(INT_MAX); +- +- if (!access_ok(VERIFY_READ, obj, val * sizeof(uint32_t))) { +- return -TARGET_EFAULT; +- } +- ret = freebsd_umtx_nwake_private(obj, val); +- +- uaddr = (abi_ulong *)g2h(obj); +- ret = 0; +- for (i = 0; i < (int32_t)val; i++) { +- ret = freebsd_umtx_wake_private(tswapal(uaddr[i]), imax); +- if (is_error(ret)) { +- break; +- } +- } +- } ++ ret = freebsd_umtx_nwake_private(obj, val); + break; + #endif /* UMTX_OP_NWAKE_PRIVATE */ + Property changes on: emulators/qemu-devel/files/extra-patch-1ec9ed3be8ac887486354c69c988cd1ee0edcaca ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property Added: fbsd:nokeywords ## -0,0 +1 ## +yes \ No newline at end of property Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Index: emulators/qemu-devel/files/extra-patch-2b6c52c4195be39678a4a2eafb8dc11b2e040762 =================================================================== --- emulators/qemu-devel/files/extra-patch-2b6c52c4195be39678a4a2eafb8dc11b2e040762 (revision 0) +++ emulators/qemu-devel/files/extra-patch-2b6c52c4195be39678a4a2eafb8dc11b2e040762 (working copy) @@ -0,0 +1,173 @@ +From 2b6c52c4195be39678a4a2eafb8dc11b2e040762 Mon Sep 17 00:00:00 2001 +From: Stacey Son +Date: Thu, 11 Dec 2014 05:15:49 +0000 +Subject: [PATCH] Add a sleep count for freebsd_umtx_sem2_wait/wake(). + +This change adds a sleep count for freebsd_umtx_sem2_wait() and +freebsd_umtx_sem2_wake() by using the unused upper 30 bits of the +_flag field of the semaphore struct. The lock count is used to +know when to clear the USEM_HAS_WAITERS bit in the count field. +--- + bsd-user/freebsd/os-thread.c | 111 ++++++++++++++++++++++++++++--------------- + 1 file changed, 72 insertions(+), 39 deletions(-) + +diff --git a/bsd-user/freebsd/os-thread.c b/bsd-user/freebsd/os-thread.c +index 2d395eb..2809358 100644 +--- a/bsd-user/freebsd/os-thread.c ++++ b/bsd-user/freebsd/os-thread.c +@@ -39,7 +39,7 @@ + #define DEBUG_UMTX(...) + + #define DETECT_DEADLOCK 0 +-#define DEADLOCK_TO 30 ++#define DEADLOCK_TO 100 + + #define NEW_STACK_SIZE 0x40000 + +@@ -438,75 +438,108 @@ abi_long freebsd_umtx_sem2_wait(abi_ulong obj, size_t utsz, + struct _umtx_time *ut) + { + struct target__usem2 *t__usem2; +- uint32_t count; ++ uint32_t count, cnt; + uint32_t flags; /* either THREAD_SHARE (0 _private) or AUTO_SHARE (1) */ ++ abi_long ret; + + pthread_mutex_lock(&umtx_sem_lck); + if (!lock_user_struct(VERIFY_WRITE, t__usem2, obj, 0)) { + pthread_mutex_unlock(&umtx_sem_lck); + return -TARGET_EFAULT; + } +- do { +- __get_user(count, &t__usem2->_count); +- } while (!tcmpset_32(&t__usem2->_count, count, count | USEM_HAS_WAITERS)); ++ ++ for (;;) { ++ __get_user(count, &t__usem2->_count); ++ if (USEM_COUNT(count) != 0) { ++ pthread_mutex_unlock(&umtx_sem_lck); ++ return 0; ++ } ++ if (count == USEM_HAS_WAITERS) { ++ break; ++ } ++ if (tcmpset_32(&t__usem2->_count, 0, USEM_HAS_WAITERS)) { ++ break; ++ } ++ } ++ ++ /* Get the flags and increment the sleep count (upper 30 bits in _flags). */ ++ __get_user(flags, &t__usem2->_flags); ++ cnt = flags >> 2; ++ if (cnt < 0x40000000) ++ cnt++; ++ flags = (flags & 0x3) | (cnt << 2); ++ __put_user(flags, &t__usem2->_flags); ++ + unlock_user_struct(t__usem2, obj, 1); + pthread_mutex_unlock(&umtx_sem_lck); + +- __get_user(flags, &t__usem2->_flags); + + DEBUG_UMTX(" %s: _umtx_op(%p, %d, flags=%d , 0x%x, %d, %p)\n", + __func__, &t__usem2->_count, UMTX_OP_WAIT_UINT, + t__usem2->_flags, t__usem2->_count, (int)utsz, ut); + +- if (USEM_COUNT(count) != 0) +- return (0); +- if (!flags) { +- return _umtx_wait_uint_private(&t__usem2->_count, +- tswap32(count | USEM_HAS_WAITERS), utsz, ut); ++ if (flags & 1) { ++ ret = _umtx_wait_uint_private(&t__usem2->_count, ++ tswap32(USEM_HAS_WAITERS), utsz, ut); + } else { +- return _umtx_wait_uint(&t__usem2->_count, +- tswap32(count | USEM_HAS_WAITERS), utsz, ut); ++ ret = _umtx_wait_uint(&t__usem2->_count, ++ tswap32(USEM_HAS_WAITERS), utsz, ut); + } ++ ++ pthread_mutex_lock(&umtx_sem_lck); ++ if (!lock_user_struct(VERIFY_WRITE, t__usem2, obj, 0)) { ++ pthread_mutex_unlock(&umtx_sem_lck); ++ return -TARGET_EFAULT; ++ } ++ /* Decrement the sleep count. */ ++ __get_user(flags, &t__usem2->_flags); ++ cnt = flags >> 2; ++ if (cnt != 0) ++ cnt--; ++ flags = (flags & 0x3) | (cnt << 2); ++ __put_user(flags, &t__usem2->_flags); ++ unlock_user_struct(t__usem2, obj, 1); ++ pthread_mutex_unlock(&umtx_sem_lck); ++ ++ return ret; + } + + abi_long freebsd_umtx_sem2_wake(abi_ulong obj, uint32_t val) + { + struct target__usem2 *t__usem2; +- uint32_t count, flags; ++ uint32_t count, cnt, flags; ++ abi_long ret; + + pthread_mutex_lock(&umtx_sem_lck); +- if (!lock_user_struct(VERIFY_WRITE, t__usem2, obj, 0)) { ++ if (!lock_user_struct(VERIFY_READ, t__usem2, obj, 1)) { + pthread_mutex_unlock(&umtx_sem_lck); + return -TARGET_EFAULT; + } +-again: +- __get_user(count, &t__usem2->_count); +- if (USEM_COUNT(count) > 0) { +- if (USEM_COUNT(count) == 1) { +- if (!tcmpset_32(&t__usem2->_count, count, USEM_COUNT(count))) { +- /* count has changed, try again. */ +- goto again; +- } +- } +- __get_user(count, &t__usem2->_count); +- __get_user(flags, &t__usem2->_flags); +- unlock_user_struct(t__usem2, obj, 1); +- pthread_mutex_unlock(&umtx_sem_lck); + ++ __get_user(flags, &t__usem2->_flags); ++ if (flags & 1) { + DEBUG_UMTX(" %s: _umtx_op(%p, %d, %d, NULL, NULL)\n", +- __func__, &t__usem2->_count, UMTX_OP_WAKE, INT_MAX); +- +- if (!flags) { +- return get_errno(_umtx_op(&t__usem2->_count, UMTX_OP_WAKE_PRIVATE, +- INT_MAX /* USEM_COUNT(count) */, NULL, NULL)); +- } else { +- return get_errno(_umtx_op(&t__usem2->_count, UMTX_OP_WAKE, +- INT_MAX /* USEM_COUNT(count) */, NULL, NULL)); +- } ++ __func__, &t__usem2->_count, UMTX_OP_WAKE_PRIVATE, 1); ++ ret = get_errno(_umtx_op(&t__usem2->_count, UMTX_OP_WAKE_PRIVATE, ++ INT_MAX /* 1 */, NULL, NULL)); ++ } else { ++ DEBUG_UMTX(" %s: _umtx_op(%p, %d, %d, NULL, NULL)\n", ++ __func__, &t__usem2->_count, UMTX_OP_WAKE, 1); ++ ret = get_errno(_umtx_op(&t__usem2->_count, UMTX_OP_WAKE, ++ INT_MAX /* 1 */, NULL, NULL)); + } +- unlock_user_struct(t__usem2, obj, 1); ++ /* If this was the last sleeping thread then clear USEM_HAS_WAITERS. */ ++ cnt = flags >> 2; ++ if (cnt == 1) { ++ do { ++ __get_user(count, &t__usem2->_count); ++ } while (!tcmpset_32(&t__usem2->_count, count, ++ count & ~USEM_HAS_WAITERS)); ++ } ++ unlock_user_struct(t__usem2, obj, 0); + pthread_mutex_unlock(&umtx_sem_lck); +- return (0); ++ ++ return ret; + } + #endif /* ! __FreeBSD_version > 1100000 */ + Property changes on: emulators/qemu-devel/files/extra-patch-2b6c52c4195be39678a4a2eafb8dc11b2e040762 ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property Added: fbsd:nokeywords ## -0,0 +1 ## +yes \ No newline at end of property Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Index: emulators/qemu-devel/files/extra-patch-32b747b24b7c6b7b071121459ddd2fc15b242a8a =================================================================== --- emulators/qemu-devel/files/extra-patch-32b747b24b7c6b7b071121459ddd2fc15b242a8a (revision 0) +++ emulators/qemu-devel/files/extra-patch-32b747b24b7c6b7b071121459ddd2fc15b242a8a (working copy) @@ -0,0 +1,389 @@ +From 32b747b24b7c6b7b071121459ddd2fc15b242a8a Mon Sep 17 00:00:00 2001 +From: Stacey Son +Date: Tue, 9 Dec 2014 20:03:51 +0000 +Subject: [PATCH] Add some simple deadlock detection for uwait. + +Added some simple deadlock dectection for uwait to help find why +some things are hanging. This is currently "on" by default. +--- + bsd-user/freebsd/os-thread.c | 230 ++++++++++++++++++++++++++++++++----------- + 1 file changed, 171 insertions(+), 59 deletions(-) + +diff --git a/bsd-user/freebsd/os-thread.c b/bsd-user/freebsd/os-thread.c +index 535a5b9..194b166 100644 +--- a/bsd-user/freebsd/os-thread.c ++++ b/bsd-user/freebsd/os-thread.c +@@ -38,6 +38,9 @@ + // #define DEBUG_UMTX(...) qemu_log(__VA_ARGS__) + #define DEBUG_UMTX(...) + ++#define DETECT_DEADLOCK 1 ++#define DEADLOCK_TO 30 ++ + #define NEW_STACK_SIZE 0x40000 + + /* sys/_umtx.h */ +@@ -173,31 +176,159 @@ static int tcmpset_32(uint32_t *addr, uint32_t a, uint32_t b) + return atomic_cmpset_acq_32(addr, current, new); + } + +-abi_long freebsd_umtx_wait_uint(abi_ulong obj, uint32_t val, ++static abi_long _umtx_wait_uint(uint32_t *addr, uint32_t target_val, ++ size_t utsz, struct _umtx_time *ut) ++{ ++#if DETECT_DEADLOCK ++ abi_long ret; ++ long cnt = 0; ++ ++ /* target_val has already been tswap'ed. */ ++ if (ut == NULL) { ++ struct timespec ts; ++ ++ ts.tv_sec = 1; ++ ts.tv_nsec = 0; ++ ++ do { ++ if (target_val != *addr) { ++ return 0; ++ } ++ ret = get_errno(_umtx_op(addr, UMTX_OP_WAIT_UINT, target_val, ++ NULL, &ts)); ++ if (ret != -TARGET_ETIMEDOUT) { ++ return ret; ++ } ++ if (cnt++ > DEADLOCK_TO) { ++ fprintf(stderr, "Deadlock in %s\n", __func__); ++ return -TARGET_ETIMEDOUT; ++ } ++ } while (1); ++ } else ++#endif ++ return get_errno(_umtx_op(addr, UMTX_OP_WAIT_UINT, target_val, ++ (void *)utsz, ut)); ++} ++ ++abi_long freebsd_umtx_wait_uint(abi_ulong obj, uint32_t target_val, + size_t utsz, struct _umtx_time *ut) + { ++ /* target_val has already been tswap'ed. */ + + DEBUG_UMTX(" %s: _umtx_op(%p, %d, 0x%x, %d, %p)\n", +- __func__, g2h(obj), UMTX_OP_WAIT_UINT, val, (int)utsz, ut); +- return get_errno(_umtx_op(g2h(obj), UMTX_OP_WAIT_UINT, val, +- (void *)utsz, ut)); ++ __func__, g2h(obj), UMTX_OP_WAIT_UINT, target_val, (int)utsz, ut); ++ return _umtx_wait_uint(g2h(obj), target_val, utsz, ut); + } + +-abi_long freebsd_umtx_wait_uint_private(abi_ulong obj, uint32_t val, ++static abi_long _umtx_wait_uint_private(uint32_t *addr, uint32_t target_val, + size_t utsz, struct _umtx_time *ut) + { ++#if DETECT_DEADLOCK ++ abi_long ret; ++ long cnt = 0; ++ ++ /* target_val has already been tswap'ed. */ ++ ++ if (ut == NULL) { ++ struct timespec ts; ++ ++ ts.tv_sec = 1; ++ ts.tv_nsec = 0; ++ ++ do { ++ if (target_val != *addr) { ++ return 0; ++ } ++ ret = get_errno(_umtx_op(addr, UMTX_OP_WAIT_UINT_PRIVATE, target_val, ++ NULL, &ts)); ++ if (ret != -TARGET_ETIMEDOUT) { ++ return ret; ++ } ++ if (cnt++ > DEADLOCK_TO) { ++ fprintf(stderr, "Deadlock in %s\n", __func__); ++ return -TARGET_ETIMEDOUT; ++ } ++ } while (1); ++ } else ++#endif /* DETECT_DEADLOCK */ ++ return get_errno(_umtx_op(addr, UMTX_OP_WAIT_UINT_PRIVATE, target_val, ++ (void *)utsz, ut)); ++} + ++abi_long freebsd_umtx_wait_uint_private(abi_ulong obj, uint32_t target_val, ++ size_t utsz, struct _umtx_time *ut) ++{ + DEBUG_UMTX(" %s: _umtx_op(%p (%u), %d, 0x%x, %d, %p)\n", +- __func__, g2h(obj), *(uint32_t *)g2h(obj), UMTX_OP_WAIT_UINT_PRIVATE, +- val, (int)utsz, ut); +- return get_errno(_umtx_op(g2h(obj), UMTX_OP_WAIT_UINT_PRIVATE, val, +- (void *)utsz, ut)); ++ __func__, g2h(obj), *(uint32_t *)g2h(obj), UMTX_OP_WAIT_UINT_PRIVATE, ++ target_val, (int)utsz, ut); ++ return _umtx_wait_uint_private(g2h(obj), target_val, utsz, ut); + } + ++static abi_long _umtx_wait(abi_ulong *addr, abi_ulong target_val, ++ size_t utsz, struct _umtx_time *ut) ++{ ++#if DETECT_DEADLOCK ++ abi_long ret; ++ long cnt = 0; ++ ++ /* target_val has already been tswap'ed. */ ++ ++ if (ut == NULL) { ++ struct timespec ts; ++ ++ ts.tv_sec = 1; ++ ts.tv_nsec = 0; ++ ++ ++ do { ++ if (target_val != *addr) { ++ return 0; ++ } ++#ifdef TARGET_ABI32 ++ ret = get_errno(_umtx_op(addr, UMTX_OP_WAIT_UINT, target_val, ++ NULL, &ts)); ++#else ++ ret = get_errno(_umtx_op(addr, UMTX_OP_WAIT, target_val, ++ NULL, &ts)); ++#endif ++ if (ret != -TARGET_ETIMEDOUT) { ++ return ret; ++ } ++ if (cnt++ > DEADLOCK_TO) { ++ fprintf(stderr, "Deadlock in %s\n", __func__); ++ return -TARGET_ETIMEDOUT; ++ } ++ } while (1); ++ } else ++#endif /* DETECT_DEADLOCK */ ++#ifdef TARGET_ABI32 ++ return get_errno(_umtx_op(addr, UMTX_OP_WAIT_UINT, target_val, (void *)utsz, ut)); ++#else ++ return get_errno(_umtx_op(addr, UMTX_OP_WAIT, target_val, (void *)utsz, ut)); ++#endif ++} ++ ++abi_long freebsd_umtx_wait(abi_ulong targ_addr, abi_ulong target_id, ++ size_t utsz, struct _umtx_time *ut) ++{ ++ ++ /* target_id has already been tswap'ed. */ ++ ++ /* We want to check the user memory but not lock it. We might sleep. */ ++ if (!access_ok(VERIFY_READ, targ_addr, sizeof(abi_ulong))) { ++ return -TARGET_EFAULT; ++ } ++ ++ DEBUG_UMTX(" %s: _umtx_op(%p, %d, 0x%llx, %d, %p)\n", ++ __func__, g2h(targ_addr), UMTX_OP_WAIT, (long long)target_id, (int)utsz, ut); ++ return _umtx_wait(g2h(targ_addr), target_id, utsz, ut); ++} ++ ++ + abi_long freebsd_umtx_wake_private(abi_ulong obj, uint32_t val) + { + +- DEBUG_UMTX(" %s: _umtx_op(%p, %d, 0x%x, NULL, NULL)\n", ++ DEBUG_UMTX(" %s: _umtx_op(%p, %d, %u, NULL, NULL)\n", + __func__, g2h(obj), UMTX_OP_WAKE_PRIVATE, val); + return get_errno(_umtx_op(g2h(obj), UMTX_OP_WAKE_PRIVATE, val, NULL, NULL)); + } +@@ -206,7 +337,7 @@ abi_long freebsd_umtx_wake_private(abi_ulong obj, uint32_t val) + #if defined(UMTX_OP_NWAKE_PRIVATE) + abi_long freebsd_umtx_nwake_private(abi_ulong target_array_addr, uint32_t num) + { +-#if 0 ++#if 1 + int i; + abi_ulong *uaddr; + abi_long ret = 0; +@@ -219,6 +350,7 @@ abi_long freebsd_umtx_nwake_private(abi_ulong target_array_addr, uint32_t num) + uaddr = (abi_ulong *)g2h(target_array_addr); + for (i = 0; i < (int32_t)num; i++) { + DEBUG_UMTX("%p ", g2h(tswapal(uaddr[ii]))); ++_umtx_op(g2h(tswapal(uaddr[i])), UMTX_OP_WAKE, INT_MAX, NULL, NULL); + ret = get_errno(_umtx_op(g2h(tswapal(uaddr[i])), UMTX_OP_WAKE_PRIVATE, + INT_MAX, NULL, NULL)); + if (is_error(ret)) { +@@ -287,7 +419,7 @@ abi_long freebsd_umtx_sem2_wait(abi_ulong obj, size_t utsz, + return -TARGET_EFAULT; + } + do { +- __get_user(count, &t__usem2->_count); ++ __get_user(count, &t__usem2->_count); + } while (!tcmpset_32(&t__usem2->_count, count, count | USEM_HAS_WAITERS)); + unlock_user_struct(t__usem2, obj, 1); + pthread_mutex_unlock(&umtx_sem_lck); +@@ -301,11 +433,11 @@ abi_long freebsd_umtx_sem2_wait(abi_ulong obj, size_t utsz, + if (USEM_COUNT(count) != 0) + return (0); + if (!flags) { +- return get_errno(_umtx_op(&t__usem2->_count, UMTX_OP_WAIT_UINT_PRIVATE, +- tswap32(count | USEM_HAS_WAITERS), (void *)utsz, ut)); ++ return _umtx_wait_uint_private(&t__usem2->_count, ++ tswap32(count | USEM_HAS_WAITERS), utsz, ut); + } else { +- return get_errno(_umtx_op(&t__usem2->_count, UMTX_OP_WAIT_UINT, +- tswap32(count | USEM_HAS_WAITERS), (void *)utsz, ut)); ++ return _umtx_wait_uint(&t__usem2->_count, ++ tswap32(count | USEM_HAS_WAITERS), utsz, ut); + } + } + +@@ -361,8 +493,7 @@ abi_long freebsd_umtx_sem_wait(abi_ulong obj, size_t utsz, + return (0); + } + +- return get_errno(_umtx_op(&t__usem->_count, UMTX_OP_WAIT_UINT, tswap32(count), +- (void *)utsz, ut)); ++ return _umtx_wait_uint(&t__usem->_count, tswap32(count), utsz, ut); + } + + abi_long freebsd_umtx_sem_wake(abi_ulong obj, uint32_t val) +@@ -467,13 +598,7 @@ abi_long freebsd_lock_umtx(abi_ulong target_addr, abi_long id, + owner = tswapal(owner); + DEBUG_UMTX(" %s: _umtx_op(%p, %d, 0x%llx, NULL, NULL)\n", + __func__, g2h(target_addr), UMTX_OP_WAIT, (long long)owner); +-#ifdef TARGET_ABI32 +- ret = get_errno(_umtx_op(g2h(target_addr), UMTX_OP_WAIT_UINT, owner, +- (void *)utsz, ut)); +-#else +- ret = get_errno(_umtx_op(g2h(target_addr), UMTX_OP_WAIT, owner, +- (void *)utsz, ut)); +-#endif ++ ret = _umtx_wait(g2h(target_addr), owner, utsz, ut); + if (is_error(ret)) { + return ret; + } +@@ -513,25 +638,6 @@ abi_long freebsd_unlock_umtx(abi_ulong target_addr, abi_long id) + return 0; + } + +-abi_long freebsd_umtx_wait(abi_ulong targ_addr, abi_ulong id, +- size_t utsz, struct _umtx_time *ut) +-{ +- +- /* We want to check the user memory but not lock it. We might sleep. */ +- if (!access_ok(VERIFY_READ, targ_addr, sizeof(abi_ulong))) { +- return -TARGET_EFAULT; +- } +- +- DEBUG_UMTX(" %s: _umtx_op(%p, %d, 0x%llx, %d, %p)\n", +- __func__, g2h(targ_addr), UMTX_OP_WAIT, (long long)id, (int)utsz, ut); +-#ifdef TARGET_ABI32 +- return get_errno(_umtx_op(g2h(targ_addr), UMTX_OP_WAIT_UINT, id, +- (void *)utsz, ut)); +-#else +- return get_errno(_umtx_op(g2h(targ_addr), UMTX_OP_WAIT, id, (void *)utsz, ut)); +-#endif +-} +- + abi_long freebsd_umtx_wake(abi_ulong target_addr, uint32_t n_wake) + { + +@@ -703,25 +809,20 @@ abi_long freebsd_cv_wait(abi_ulong target_ucond_addr, + { + abi_long ret; + long tid; ++ struct target_ucond *target_ucond; + +- if (!access_ok(VERIFY_WRITE, target_ucond_addr, +- sizeof(struct target_ucond))) { ++ if (!lock_user_struct(VERIFY_WRITE, target_ucond, target_ucond_addr, 0)) { + return -TARGET_EFAULT; + } + + /* Check the clock ID if needed. */ + if ((wflags & TARGET_CVWAIT_CLOCKID) != 0) { +- struct target_ucond *target_ucond; + uint32_t clockid; + +- if (!lock_user_struct(VERIFY_WRITE, target_ucond, target_ucond_addr, +- 0)) { +- return -TARGET_EFAULT; +- } + __get_user(clockid, &target_ucond->c_clockid); +- unlock_user_struct(target_ucond, target_ucond_addr, 1); + if (clockid >= CLOCK_THREAD_CPUTIME_ID) { + /* Only HW clock id will work. */ ++ unlock_user_struct(target_ucond, target_ucond_addr, 1); + return -TARGET_EINVAL; + } + } +@@ -731,19 +832,31 @@ abi_long freebsd_cv_wait(abi_ulong target_ucond_addr, + /* Lock the _cv_mutex so we can safely unlock the user mutex */ + _umtx_op(&_cv_mutex, UMTX_OP_MUTEX_LOCK, 0, NULL, NULL); + ++ /* Set c_has_waiters before releasing the user mutex! */ ++ __put_user(1, &target_ucond->c_has_waiters); ++ + /* unlock the user mutex */ + ret = freebsd_unlock_umutex(target_umtx_addr, tid); + if (is_error(ret)) { + _umtx_op(&_cv_mutex, UMTX_OP_MUTEX_UNLOCK, 0, NULL, NULL); ++ unlock_user_struct(target_ucond, target_ucond_addr, 1); + return ret; + } + + /* UMTX_OP_CV_WAIT unlocks _cv_mutex */ +- DEBUG_UMTX(" %s: _umtx_op(%p, %d, 0x%x, %p, NULL)\n", ++ DEBUG_UMTX(" %s: _umtx_op(%p, %d, 0x%x, %p, NULL)\n", + __func__, g2h(target_ucond_addr), UMTX_OP_CV_WAIT, wflags, + &_cv_mutex); + ret = get_errno(_umtx_op(g2h(target_ucond_addr), UMTX_OP_CV_WAIT, wflags, + &_cv_mutex, ts)); ++ if (is_error(ret)) { ++ _umtx_op(&_cv_mutex, UMTX_OP_MUTEX_UNLOCK, 0, NULL, NULL); ++ unlock_user_struct(target_ucond, target_ucond_addr, 1); ++ return ret; ++ } ++ ret = freebsd_lock_umutex(target_umtx_addr, tid, NULL, TARGET_UMUTEX_TRY); ++ _umtx_op(&_cv_mutex, UMTX_OP_MUTEX_UNLOCK, 0, NULL, NULL); ++ unlock_user_struct(target_ucond, target_ucond_addr, 1); + + return ret; + } +@@ -759,7 +872,7 @@ abi_long freebsd_cv_signal(abi_ulong target_ucond_addr) + + /* Lock the _cv_mutex to prevent a race in do_cv_wait(). */ + _umtx_op(&_cv_mutex, UMTX_OP_MUTEX_LOCK, 0, NULL, NULL); +- DEBUG_UMTX(" %s: _umtx_op(%p, %d, 0x%x, NULL, NULL)\n", ++ DEBUG_UMTX(" %s: _umtx_op(%p, %d, 0x%x, NULL, NULL)\n", + __func__, g2h(target_ucond_addr), UMTX_OP_CV_SIGNAL, 0); + ret = get_errno(_umtx_op(g2h(target_ucond_addr), UMTX_OP_CV_SIGNAL, 0, + NULL, NULL)); +@@ -779,7 +892,7 @@ abi_long freebsd_cv_broadcast(abi_ulong target_ucond_addr) + + /* Lock the _cv_mutex to prevent a race in do_cv_wait(). */ + _umtx_op(&_cv_mutex, UMTX_OP_MUTEX_LOCK, 0, NULL, NULL); +- DEBUG_UMTX(" %s: _umtx_op(%p, %d, 0x%x, NULL, NULL)\n", ++ DEBUG_UMTX(" %s: _umtx_op(%p, %d, 0x%x, NULL, NULL)\n", + __func__, g2h(target_ucond_addr), UMTX_OP_CV_BROADCAST, 0); + ret = get_errno(_umtx_op(g2h(target_ucond_addr), UMTX_OP_CV_BROADCAST, 0, + NULL, NULL)); +@@ -847,8 +960,7 @@ abi_long freebsd_rw_rdlock(abi_ulong target_addr, long fflag, + __func__, &target_urwlock->rw_state, + UMTX_OP_WAIT_UINT, tswap32(state), + target_urwlock->rw_state); +- ret = get_errno(_umtx_op(&target_urwlock->rw_state, +- UMTX_OP_WAIT_UINT, tswap32(state), (void *)utsz, ut)); ++ ret = _umtx_wait_uint(&target_urwlock->rw_state, tswap32(state), utsz, ut); + if (is_error(ret)) { + return ret; + } +@@ -939,8 +1051,8 @@ abi_long freebsd_rw_wrlock(abi_ulong target_addr, long fflag, + __func__, &target_urwlock->rw_blocked_writers, + UMTX_OP_WAIT_UINT, tswap32(state), + target_urwlock->rw_state); +- ret = get_errno(_umtx_op(&target_urwlock->rw_state, +- UMTX_OP_WAIT_UINT, tswap32(state), (void *)utsz, ut)); ++ ret = _umtx_wait_uint(&target_urwlock->rw_state, ++ tswap32(state), utsz, ut); + if (is_error(ret)) { + return ret; + } Property changes on: emulators/qemu-devel/files/extra-patch-32b747b24b7c6b7b071121459ddd2fc15b242a8a ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property Added: fbsd:nokeywords ## -0,0 +1 ## +yes \ No newline at end of property Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Index: emulators/qemu-devel/files/extra-patch-41006748ffe0fbd7bfc5180adf09c3a01563202b =================================================================== --- emulators/qemu-devel/files/extra-patch-41006748ffe0fbd7bfc5180adf09c3a01563202b (revision 0) +++ emulators/qemu-devel/files/extra-patch-41006748ffe0fbd7bfc5180adf09c3a01563202b (working copy) @@ -0,0 +1,166 @@ +From 41006748ffe0fbd7bfc5180adf09c3a01563202b Mon Sep 17 00:00:00 2001 +From: Stacey Son +Date: Tue, 18 Nov 2014 16:09:52 +0000 +Subject: [PATCH] More struct timespec to struct _umtx_time changes. + +--- + bsd-user/freebsd/os-thread.c | 14 +++++++------- + bsd-user/freebsd/os-thread.h | 29 +++++++++++++++++++---------- + bsd-user/qemu.h | 6 +++--- + 3 files changed, 29 insertions(+), 20 deletions(-) + +diff --git a/bsd-user/freebsd/os-thread.c b/bsd-user/freebsd/os-thread.c +index 9ac1219..2ea3495 100644 +--- a/bsd-user/freebsd/os-thread.c ++++ b/bsd-user/freebsd/os-thread.c +@@ -358,7 +358,7 @@ abi_long h2t_freebsd_rtprio(abi_ulong target_addr, struct rtprio *host_rtp) + } + + abi_long freebsd_lock_umtx(abi_ulong target_addr, abi_long id, +- struct timespec *timeout) ++ size_t utsz, struct _umtx_time *ut) + { + abi_long ret; + abi_long owner; +@@ -411,10 +411,10 @@ abi_long freebsd_lock_umtx(abi_ulong target_addr, abi_long id, + __func__, g2h(target_addr), UMTX_OP_WAIT, (long long)owner); + #ifdef TARGET_ABI32 + ret = get_errno(_umtx_op(g2h(target_addr), UMTX_OP_WAIT_UINT, owner, +- NULL, timeout)); ++ (void *)utsz, ut)); + #else + ret = get_errno(_umtx_op(g2h(target_addr), UMTX_OP_WAIT, owner, +- NULL, timeout)); ++ (void *)utsz, ut)); + #endif + if (is_error(ret)) { + return ret; +@@ -731,7 +731,7 @@ abi_long freebsd_cv_broadcast(abi_ulong target_ucond_addr) + } + + abi_long freebsd_rw_rdlock(abi_ulong target_addr, long fflag, +- struct timespec *ts) ++ size_t utsz, struct _umtx_time *ut) + { + struct target_urwlock *target_urwlock; + uint32_t flags, wrflags; +@@ -790,7 +790,7 @@ abi_long freebsd_rw_rdlock(abi_ulong target_addr, long fflag, + UMTX_OP_WAIT_UINT, tswap32(state), + target_urwlock->rw_state); + ret = get_errno(_umtx_op(&target_urwlock->rw_state, +- UMTX_OP_WAIT_UINT, tswap32(state), NULL, ts)); ++ UMTX_OP_WAIT_UINT, tswap32(state), (void *)utsz, ut)); + if (is_error(ret)) { + return ret; + } +@@ -819,7 +819,7 @@ abi_long freebsd_rw_rdlock(abi_ulong target_addr, long fflag, + } + + abi_long freebsd_rw_wrlock(abi_ulong target_addr, long fflag, +- struct timespec *ts) ++ size_t utsz, struct _umtx_time *ut) + { + struct target_urwlock *target_urwlock; + uint32_t blocked_readers, blocked_writers; +@@ -882,7 +882,7 @@ abi_long freebsd_rw_wrlock(abi_ulong target_addr, long fflag, + UMTX_OP_WAIT_UINT, tswap32(state), + target_urwlock->rw_state); + ret = get_errno(_umtx_op(&target_urwlock->rw_state, +- UMTX_OP_WAIT_UINT, tswap32(state), NULL, ts)); ++ UMTX_OP_WAIT_UINT, tswap32(state), (void *)utsz, ut)); + if (is_error(ret)) { + return ret; + } +diff --git a/bsd-user/freebsd/os-thread.h b/bsd-user/freebsd/os-thread.h +index 9844b91..eef58fb 100644 +--- a/bsd-user/freebsd/os-thread.h ++++ b/bsd-user/freebsd/os-thread.h +@@ -243,7 +243,7 @@ static inline abi_long do_freebsd__umtx_lock(abi_ulong target_addr) + if (is_error(ret)) { + return ret; + } +- return freebsd_lock_umtx(target_addr, tid, NULL); ++ return freebsd_lock_umtx(target_addr, tid, 0, NULL); + } + + /* undocumented _umtx_unlock() */ +@@ -276,12 +276,15 @@ static inline abi_long do_freebsd__umtx_op(abi_ulong obj, int op, abi_ulong val, + return ret; + } + if (target_time != 0) { +- if (t2h_freebsd_timespec(&ts, target_time)) { ++ ut._clockid = CLOCK_REALTIME; ++ ut._flags = UMTX_ABSTIME; ++ if (t2h_freebsd_timespec(&ut._timeout, target_time + ++ offsetof(struct target__umtx_time, _timeout))) { + return -TARGET_EFAULT; + } +- ret = freebsd_lock_umtx(obj, tid, &ts); ++ ret = freebsd_lock_umtx(obj, tid, sizeof(ut), &ut); + } else { +- ret = freebsd_lock_umtx(obj, tid, NULL); ++ ret = freebsd_lock_umtx(obj, tid, 0, NULL); + } + break; + +@@ -451,23 +454,29 @@ static inline abi_long do_freebsd__umtx_op(abi_ulong obj, int op, abi_ulong val, + + case TARGET_UMTX_OP_RW_RDLOCK: + if (target_time != 0) { +- if (t2h_freebsd_timespec(&ts, target_time)) { ++ ut._clockid = CLOCK_REALTIME; ++ ut._flags = UMTX_ABSTIME; ++ if (t2h_freebsd_timespec(&ut._timeout, target_time + ++ offsetof(struct target__umtx_time, _timeout))) { + return -TARGET_EFAULT; + } +- ret = freebsd_rw_rdlock(obj, val, &ts); ++ ret = freebsd_rw_rdlock(obj, val, sizeof(ut), &ut); + } else { +- ret = freebsd_rw_rdlock(obj, val, NULL); ++ ret = freebsd_rw_rdlock(obj, val, 0, NULL); + } + break; + + case TARGET_UMTX_OP_RW_WRLOCK: + if (target_time != 0) { +- if (t2h_freebsd_timespec(&ts, target_time)) { ++ ut._clockid = CLOCK_REALTIME; ++ ut._flags = UMTX_ABSTIME; ++ if (t2h_freebsd_timespec(&ut._timeout, target_time + ++ offsetof(struct target__umtx_time, _timeout))) { + return -TARGET_EFAULT; + } +- ret = freebsd_rw_wrlock(obj, val, &ts); ++ ret = freebsd_rw_wrlock(obj, val, sizeof(ut), &ut); + } else { +- ret = freebsd_rw_wrlock(obj, val, NULL); ++ ret = freebsd_rw_wrlock(obj, val, 0, NULL); + } + break; + +diff --git a/bsd-user/qemu.h b/bsd-user/qemu.h +index c6a0833..8a31517 100644 +--- a/bsd-user/qemu.h ++++ b/bsd-user/qemu.h +@@ -277,7 +277,7 @@ abi_long do_freebsd_sysarch(void *cpu_env, abi_long arg1, abi_long arg2); + extern pthread_mutex_t *new_freebsd_thread_lock_ptr; + void *new_freebsd_thread_start(void *arg); + abi_long freebsd_lock_umtx(abi_ulong target_addr, abi_long tid, +- struct timespec *timeout); ++ size_t utsz, struct _umtx_time *ut); + abi_long freebsd_unlock_umtx(abi_ulong target_addr, abi_long id); + abi_long freebsd_umtx_wait(abi_ulong targ_addr, abi_ulong id, + size_t utsz, struct _umtx_time *ut); +@@ -306,9 +306,9 @@ abi_long freebsd_cv_wait(abi_ulong target_ucond_addr, + abi_long freebsd_cv_signal(abi_ulong target_ucond_addr); + abi_long freebsd_cv_broadcast(abi_ulong target_ucond_addr); + abi_long freebsd_rw_rdlock(abi_ulong target_addr, long fflag, +- struct timespec *ts); ++ size_t utsz, struct _umtx_time *ut); + abi_long freebsd_rw_wrlock(abi_ulong target_addr, long fflag, +- struct timespec *ts); ++ size_t utsz, struct _umtx_time *ut); + abi_long freebsd_rw_unlock(abi_ulong target_addr); + + Property changes on: emulators/qemu-devel/files/extra-patch-41006748ffe0fbd7bfc5180adf09c3a01563202b ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property Added: fbsd:nokeywords ## -0,0 +1 ## +yes \ No newline at end of property Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Index: emulators/qemu-devel/files/extra-patch-7aea4e8d72cab81a102686eb639530c78d555315 =================================================================== --- emulators/qemu-devel/files/extra-patch-7aea4e8d72cab81a102686eb639530c78d555315 (revision 0) +++ emulators/qemu-devel/files/extra-patch-7aea4e8d72cab81a102686eb639530c78d555315 (working copy) @@ -0,0 +1,105 @@ +From 7aea4e8d72cab81a102686eb639530c78d555315 Mon Sep 17 00:00:00 2001 +From: Stacey Son +Date: Mon, 17 Nov 2014 18:15:40 +0000 +Subject: [PATCH] Bug fix: _umtx_sem_{wait, wake} should use legacy op code. + +This change uses the legacy UMTX_OP_SEM_WAKE and UMTX_OP_SEM_WAIT +op codes for _umtx_sem_wake() and _umtx_sem_wait() given that sem2 +uses a different structure that is passed into the kernel. I am not +convinced yet this work work for a big endian target yet. +--- + bsd-user/freebsd/os-thread.c | 8 +++----- + bsd-user/freebsd/os-thread.h | 19 +++++++++++++++---- + bsd-user/qemu.h | 4 ++++ + 3 files changed, 22 insertions(+), 9 deletions(-) + +diff --git a/bsd-user/freebsd/os-thread.c b/bsd-user/freebsd/os-thread.c +index baec878..313d8fe 100644 +--- a/bsd-user/freebsd/os-thread.c ++++ b/bsd-user/freebsd/os-thread.c +@@ -226,7 +226,7 @@ abi_long freebsd_umtx_mutex_wake2(abi_ulong target_addr, + #endif /* UMTX_OP_MUTEX_WAKE2 */ + + #if defined(__FreeBSD_version) && __FreeBSD_version > 1100000 +-abi_long freebsd_umtx_sem_wait(abi_ulong obj, struct timespec *timeout) ++abi_long freebsd_umtx_sem2_wait(abi_ulong obj, struct timespec *timeout) + { + + /* XXX Assumes struct _usem is opauque to the user */ +@@ -236,13 +236,12 @@ abi_long freebsd_umtx_sem_wait(abi_ulong obj, struct timespec *timeout) + return get_errno(_umtx_op(g2h(obj), UMTX_OP_SEM2_WAIT, 0, NULL, timeout)); + } + +-abi_long freebsd_umtx_sem_wake(abi_ulong obj, uint32_t val) ++abi_long freebsd_umtx_sem2_wake(abi_ulong obj, uint32_t val) + { + + return get_errno(_umtx_op(g2h(obj), UMTX_OP_SEM2_WAKE, val, NULL, NULL)); + } +- +-#else /* ! __FreeBSD_version > 1100000 */ ++#endif /* ! __FreeBSD_version > 1100000 */ + + abi_long freebsd_umtx_sem_wait(abi_ulong obj, struct timespec *timeout) + { +@@ -259,7 +258,6 @@ abi_long freebsd_umtx_sem_wake(abi_ulong obj, uint32_t val) + + return get_errno(_umtx_op(g2h(obj), UMTX_OP_SEM_WAKE, val, NULL, NULL)); + } +-#endif /* ! __FreeBSD_version > 110000 */ + #endif /* ! __FreeBSD_version > 900000 */ + + abi_long t2h_freebsd_rtprio(struct rtprio *host_rtp, abi_ulong target_addr) +diff --git a/bsd-user/freebsd/os-thread.h b/bsd-user/freebsd/os-thread.h +index 8157e85..3adcee5 100644 +--- a/bsd-user/freebsd/os-thread.h ++++ b/bsd-user/freebsd/os-thread.h +@@ -486,8 +486,22 @@ static inline abi_long do_freebsd__umtx_op(abi_ulong obj, int op, abi_ulong val, + break; + #endif /* UMTX_OP_NWAKE_PRIVATE */ + +-#if defined(__FreeBSD_version) && __FreeBSD_version > 1100000 ++#if __FreeBSD_version > 1100000 + case TARGET_UMTX_OP_SEM2_WAIT: ++ if (target_ts != 0) { ++ if (t2h_freebsd_timespec(&ts, target_ts)) { ++ return -TARGET_EFAULT; ++ } ++ ret = freebsd_umtx_sem2_wait(obj, &ts); ++ } else { ++ ret = freebsd_umtx_sem2_wait(obj, NULL); ++ } ++ break; ++ ++ case TARGET_UMTX_OP_SEM2_WAKE: ++ /* Don't need to do access_ok(). */ ++ ret = freebsd_umtx_sem2_wake(obj, val); ++ break; + #endif + case TARGET_UMTX_OP_SEM_WAIT: + if (target_ts != 0) { +@@ -500,9 +514,6 @@ static inline abi_long do_freebsd__umtx_op(abi_ulong obj, int op, abi_ulong val, + } + break; + +-#if defined(__FreeBSD_version) && __FreeBSD_version > 1100000 +- case TARGET_UMTX_OP_SEM2_WAKE: +-#endif + case TARGET_UMTX_OP_SEM_WAKE: + /* Don't need to do access_ok(). */ + ret = freebsd_umtx_sem_wake(obj, val); +diff --git a/bsd-user/qemu.h b/bsd-user/qemu.h +index 0731c64..8c84c06 100644 +--- a/bsd-user/qemu.h ++++ b/bsd-user/qemu.h +@@ -291,6 +291,10 @@ abi_long freebsd_umtx_wake_private(abi_ulong obj, uint32_t val); + #if defined(__FreeBSD_version) && __FreeBSD_version > 900000 + abi_long freebsd_umtx_nwake_private(abi_ulong obj, uint32_t val); + abi_long freebsd_umtx_mutex_wake2(abi_ulong obj, uint32_t val); ++#if __FreeBSD_version > 1100000 ++abi_long freebsd_umtx_sem2_wait(abi_ulong obj, struct timespec *timeout); ++abi_long freebsd_umtx_sem2_wake(abi_ulong obj, uint32_t val); ++#endif + abi_long freebsd_umtx_sem_wait(abi_ulong obj, struct timespec *timeout); + abi_long freebsd_umtx_sem_wake(abi_ulong obj, uint32_t val); + #endif Property changes on: emulators/qemu-devel/files/extra-patch-7aea4e8d72cab81a102686eb639530c78d555315 ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property Added: fbsd:nokeywords ## -0,0 +1 ## +yes \ No newline at end of property Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Index: emulators/qemu-devel/files/extra-patch-7b9ddce757fee0edf23982be98530a5556ee1b17 =================================================================== --- emulators/qemu-devel/files/extra-patch-7b9ddce757fee0edf23982be98530a5556ee1b17 (revision 0) +++ emulators/qemu-devel/files/extra-patch-7b9ddce757fee0edf23982be98530a5556ee1b17 (working copy) @@ -0,0 +1,387 @@ +From 7b9ddce757fee0edf23982be98530a5556ee1b17 Mon Sep 17 00:00:00 2001 +From: Stacey Son +Date: Tue, 18 Nov 2014 01:44:22 +0000 +Subject: [PATCH] Use _umtx_time for the umtx wait system calls (_umtx_op()). + +The emulation for _umtx_op(..., *_WAIT*,...) family of umtx +operations was using struct timespec instead struct _umtx_time for +the timeout which is incorrect. +--- + bsd-user/freebsd/os-thread.c | 51 +++++++++++++---------- + bsd-user/freebsd/os-thread.h | 98 ++++++++++++++++++++++++++++---------------- + bsd-user/qemu.h | 14 +++---- + 3 files changed, 100 insertions(+), 63 deletions(-) + +diff --git a/bsd-user/freebsd/os-thread.c b/bsd-user/freebsd/os-thread.c +index 313d8fe..88fcc51 100644 +--- a/bsd-user/freebsd/os-thread.c ++++ b/bsd-user/freebsd/os-thread.c +@@ -1,7 +1,7 @@ + /* + * FreeBSD thr emulation support code + * +- * Copyright (c) 2013 Stacey D. Son ++ * Copyright (c) 2013-14 Stacey D. Son + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by +@@ -72,6 +72,11 @@ struct target__usem { + uint32_t _flags; + }; + ++struct target__usem2 { ++ uint32_t _count; ++ uint32_t _flags; ++}; ++ + static pthread_mutex_t new_thread_lock = PTHREAD_MUTEX_INITIALIZER; + pthread_mutex_t *new_freebsd_thread_lock_ptr = &new_thread_lock; + +@@ -170,22 +175,23 @@ static int tcmpset_32(uint32_t *addr, uint32_t a, uint32_t b) + } + + abi_long freebsd_umtx_wait_uint(abi_ulong obj, uint32_t val, +- struct timespec *timeout) ++ size_t utsz, struct _umtx_time *ut) + { + +- DEBUG_UMTX(" %s: _umtx_op(%p, %d, 0x%x, NULL, %p)\n", +- __func__, g2h(obj), UMTX_OP_WAIT_UINT, val, timeout); +- return get_errno(_umtx_op(g2h(obj), UMTX_OP_WAIT_UINT, val, NULL, timeout)); ++ DEBUG_UMTX(" %s: _umtx_op(%p, %d, 0x%x, %d, %p)\n", ++ __func__, g2h(obj), UMTX_OP_WAIT_UINT, val, (int)utsz, ut); ++ return get_errno(_umtx_op(g2h(obj), UMTX_OP_WAIT_UINT, val, ++ (void *)utsz, ut)); + } + + abi_long freebsd_umtx_wait_uint_private(abi_ulong obj, uint32_t val, +- struct timespec *timeout) ++ size_t utsz, struct _umtx_time *ut) + { + +- DEBUG_UMTX(" %s: _umtx_op(%p, %d, 0x%x, NULL, %p)\n", +- __func__, g2h(obj), UMTX_OP_WAIT_UINT_PRIVATE, val, timeout); +- return get_errno(_umtx_op(g2h(obj), UMTX_OP_WAIT_UINT_PRIVATE, val, NULL, +- timeout)); ++ DEBUG_UMTX(" %s: _umtx_op(%p, %d, 0x%x, %d, %p)\n", ++ __func__, g2h(obj), UMTX_OP_WAIT_UINT_PRIVATE, val, (int)utsz, ut); ++ return get_errno(_umtx_op(g2h(obj), UMTX_OP_WAIT_UINT_PRIVATE, val, ++ (void *)utsz, ut)); + } + + abi_long freebsd_umtx_wake_private(abi_ulong obj, uint32_t val) +@@ -226,14 +232,16 @@ abi_long freebsd_umtx_mutex_wake2(abi_ulong target_addr, + #endif /* UMTX_OP_MUTEX_WAKE2 */ + + #if defined(__FreeBSD_version) && __FreeBSD_version > 1100000 +-abi_long freebsd_umtx_sem2_wait(abi_ulong obj, struct timespec *timeout) ++abi_long freebsd_umtx_sem2_wait(abi_ulong obj, size_t utsz, ++ struct _umtx_time *ut) + { + + /* XXX Assumes struct _usem is opauque to the user */ +- if (!access_ok(VERIFY_WRITE, obj, sizeof(struct target__usem))) { ++ if (!access_ok(VERIFY_WRITE, obj, sizeof(struct target__usem2))) { + return -TARGET_EFAULT; + } +- return get_errno(_umtx_op(g2h(obj), UMTX_OP_SEM2_WAIT, 0, NULL, timeout)); ++ return get_errno(_umtx_op(g2h(obj), UMTX_OP_SEM2_WAIT, 0, (void *)utsz, ++ ut)); + } + + abi_long freebsd_umtx_sem2_wake(abi_ulong obj, uint32_t val) +@@ -243,14 +251,14 @@ abi_long freebsd_umtx_sem2_wake(abi_ulong obj, uint32_t val) + } + #endif /* ! __FreeBSD_version > 1100000 */ + +-abi_long freebsd_umtx_sem_wait(abi_ulong obj, struct timespec *timeout) ++abi_long freebsd_umtx_sem_wait(abi_ulong obj, size_t utsz, ++ struct _umtx_time *ut) + { +- + /* XXX Assumes struct _usem is opauque to the user */ + if (!access_ok(VERIFY_WRITE, obj, sizeof(struct target__usem))) { + return -TARGET_EFAULT; + } +- return get_errno(_umtx_op(g2h(obj), UMTX_OP_SEM_WAIT, 0, NULL, timeout)); ++ return get_errno(_umtx_op(g2h(obj), UMTX_OP_SEM_WAIT, 0, (void *)utsz, ut)); + } + + abi_long freebsd_umtx_sem_wake(abi_ulong obj, uint32_t val) +@@ -385,7 +393,7 @@ abi_long freebsd_unlock_umtx(abi_ulong target_addr, abi_long id) + } + + abi_long freebsd_umtx_wait(abi_ulong targ_addr, abi_ulong id, +- struct timespec *ts) ++ size_t utsz, struct _umtx_time *ut) + { + + /* We want to check the user memory but not lock it. We might sleep. */ +@@ -393,12 +401,13 @@ abi_long freebsd_umtx_wait(abi_ulong targ_addr, abi_ulong id, + return -TARGET_EFAULT; + } + +- DEBUG_UMTX(" %s: _umtx_op(%p, %d, 0x%llx, NULL, NULL)\n", +- __func__, g2h(targ_addr), UMTX_OP_WAIT, (long long)id); ++ DEBUG_UMTX(" %s: _umtx_op(%p, %d, 0x%llx, %d, %p)\n", ++ __func__, g2h(targ_addr), UMTX_OP_WAIT, (long long)id, (int)utsz, ut); + #ifdef TARGET_ABI32 +- return get_errno(_umtx_op(g2h(targ_addr), UMTX_OP_WAIT_UINT, id, NULL, ts)); ++ return get_errno(_umtx_op(g2h(targ_addr), UMTX_OP_WAIT_UINT, id, ++ (void *)utsz, ut)); + #else +- return get_errno(_umtx_op(g2h(targ_addr), UMTX_OP_WAIT, id, NULL, ts)); ++ return get_errno(_umtx_op(g2h(targ_addr), UMTX_OP_WAIT, id, (void *)utsz, ut)); + #endif + } + +diff --git a/bsd-user/freebsd/os-thread.h b/bsd-user/freebsd/os-thread.h +index 3adcee5..9844b91 100644 +--- a/bsd-user/freebsd/os-thread.h ++++ b/bsd-user/freebsd/os-thread.h +@@ -23,8 +23,15 @@ + #include + #include + ++#include "qemu.h" + #include "qemu-os.h" + ++struct target__umtx_time { ++ struct target_freebsd_timespec _timeout; ++ uint32_t _flags; ++ uint32_t _clockid; ++}; ++ + static abi_long do_freebsd_thr_create(CPUArchState *env, abi_ulong target_ctx, + abi_ulong target_id, int flags) + { +@@ -253,12 +260,13 @@ static inline abi_long do_freebsd__umtx_unlock(abi_ulong target_addr) + } + + /* undocumented _umtx_op(void *obj, int op, u_long val, void *uaddr, +- void *target_ts); */ ++ void *target_time); */ + static inline abi_long do_freebsd__umtx_op(abi_ulong obj, int op, abi_ulong val, +- abi_ulong uaddr, abi_ulong target_ts) ++ abi_ulong uaddr, abi_ulong target_time) + { + abi_long ret; + struct timespec ts; ++ struct _umtx_time ut; + long tid; + + switch (op) { +@@ -267,8 +275,8 @@ static inline abi_long do_freebsd__umtx_op(abi_ulong obj, int op, abi_ulong val, + if (is_error(ret)) { + return ret; + } +- if (target_ts != 0) { +- if (t2h_freebsd_timespec(&ts, target_ts)) { ++ if (target_time != 0) { ++ if (t2h_freebsd_timespec(&ts, target_time)) { + return -TARGET_EFAULT; + } + ret = freebsd_lock_umtx(obj, tid, &ts); +@@ -286,14 +294,17 @@ static inline abi_long do_freebsd__umtx_op(abi_ulong obj, int op, abi_ulong val, + break; + + case TARGET_UMTX_OP_WAIT: +- /* args: obj *, val, ts * */ +- if (target_ts != 0) { +- if (t2h_freebsd_timespec(&ts, target_ts)) { ++ /* args: obj *, val, (void *)sizeof(ut), ut * */ ++ if (target_time != 0) { ++ ut._clockid = CLOCK_REALTIME; ++ ut._flags = UMTX_ABSTIME; ++ if (t2h_freebsd_timespec(&ut._timeout, target_time + ++ offsetof(struct target__umtx_time, _timeout))) { + return -TARGET_EFAULT; + } +- ret = freebsd_umtx_wait(obj, tswapal(val), &ts); ++ ret = freebsd_umtx_wait(obj, tswapal(val), sizeof(ut), &ut); + } else { +- ret = freebsd_umtx_wait(obj, tswapal(val), NULL); ++ ret = freebsd_umtx_wait(obj, tswapal(val), 0, NULL); + } + break; + +@@ -307,8 +318,8 @@ static inline abi_long do_freebsd__umtx_op(abi_ulong obj, int op, abi_ulong val, + if (is_error(ret)) { + return ret; + } +- if (target_ts) { +- if (t2h_freebsd_timespec(&ts, target_ts)) { ++ if (target_time) { ++ if (t2h_freebsd_timespec(&ts, target_time)) { + return -TARGET_EFAULT; + } + ret = freebsd_lock_umutex(obj, tid, &ts, 0); +@@ -338,8 +349,8 @@ static inline abi_long do_freebsd__umtx_op(abi_ulong obj, int op, abi_ulong val, + if (is_error(ret)) { + return ret; + } +- if (target_ts != 0) { +- if (t2h_freebsd_timespec(&ts, target_ts)) { ++ if (target_time != 0) { ++ if (t2h_freebsd_timespec(&ts, target_time)) { + return -TARGET_EFAULT; + } + ret = freebsd_lock_umutex(obj, tid, &ts, TARGET_UMUTEX_WAIT); +@@ -362,8 +373,8 @@ static inline abi_long do_freebsd__umtx_op(abi_ulong obj, int op, abi_ulong val, + * Initialization of the struct conv is done by + * bzero'ing everything in userland. + */ +- if (target_ts != 0) { +- if (t2h_freebsd_timespec(&ts, target_ts)) { ++ if (target_time != 0) { ++ if (t2h_freebsd_timespec(&ts, target_time)) { + return -TARGET_EFAULT; + } + ret = freebsd_cv_wait(obj, uaddr, &ts, val); +@@ -398,13 +409,18 @@ static inline abi_long do_freebsd__umtx_op(abi_ulong obj, int op, abi_ulong val, + if (!access_ok(VERIFY_READ, obj, sizeof(abi_ulong))) { + return -TARGET_EFAULT; + } +- if (target_ts != 0) { +- if (t2h_freebsd_timespec(&ts, target_ts)) { ++ /* args: obj *, val, (void *)sizeof(ut), ut * */ ++ if (target_time != 0) { ++ ut._clockid = CLOCK_REALTIME; ++ ut._flags = UMTX_ABSTIME; ++ if (t2h_freebsd_timespec(&ut._timeout, target_time + ++ offsetof(struct target__umtx_time, _timeout))) { + return -TARGET_EFAULT; + } +- ret = freebsd_umtx_wait_uint(obj, tswap32((uint32_t)val), &ts); ++ ret = freebsd_umtx_wait_uint(obj, tswap32((uint32_t)val), ++ sizeof(ut), &ut); + } else { +- ret = freebsd_umtx_wait_uint(obj, tswap32((uint32_t)val), NULL); ++ ret = freebsd_umtx_wait_uint(obj, tswap32((uint32_t)val), 0, NULL); + } + break; + +@@ -412,15 +428,19 @@ static inline abi_long do_freebsd__umtx_op(abi_ulong obj, int op, abi_ulong val, + if (!access_ok(VERIFY_READ, obj, sizeof(abi_ulong))) { + return -TARGET_EFAULT; + } +- if (target_ts != 0) { +- if (t2h_freebsd_timespec(&ts, target_ts)) { ++ /* args: obj *, val, (void *)sizeof(ut), ut * */ ++ if (target_time != 0) { ++ ut._clockid = CLOCK_REALTIME; ++ ut._flags = UMTX_ABSTIME; ++ if (t2h_freebsd_timespec(&ut._timeout, target_time + ++ offsetof(struct target__umtx_time, _timeout))) { + return -TARGET_EFAULT; + } + ret = freebsd_umtx_wait_uint_private(obj, tswap32((uint32_t)val), +- &ts); ++ sizeof(ut), &ut); + } else { + ret = freebsd_umtx_wait_uint_private(obj, tswap32((uint32_t)val), +- NULL); ++ 0, NULL); + } + break; + +@@ -430,8 +450,8 @@ static inline abi_long do_freebsd__umtx_op(abi_ulong obj, int op, abi_ulong val, + break; + + case TARGET_UMTX_OP_RW_RDLOCK: +- if (target_ts != 0) { +- if (t2h_freebsd_timespec(&ts, target_ts)) { ++ if (target_time != 0) { ++ if (t2h_freebsd_timespec(&ts, target_time)) { + return -TARGET_EFAULT; + } + ret = freebsd_rw_rdlock(obj, val, &ts); +@@ -441,8 +461,8 @@ static inline abi_long do_freebsd__umtx_op(abi_ulong obj, int op, abi_ulong val, + break; + + case TARGET_UMTX_OP_RW_WRLOCK: +- if (target_ts != 0) { +- if (t2h_freebsd_timespec(&ts, target_ts)) { ++ if (target_time != 0) { ++ if (t2h_freebsd_timespec(&ts, target_time)) { + return -TARGET_EFAULT; + } + ret = freebsd_rw_wrlock(obj, val, &ts); +@@ -488,13 +508,17 @@ static inline abi_long do_freebsd__umtx_op(abi_ulong obj, int op, abi_ulong val, + + #if __FreeBSD_version > 1100000 + case TARGET_UMTX_OP_SEM2_WAIT: +- if (target_ts != 0) { +- if (t2h_freebsd_timespec(&ts, target_ts)) { ++ /* args: obj *, val, (void *)sizeof(ut), ut * */ ++ if (target_time != 0) { ++ ut._clockid = CLOCK_REALTIME; ++ ut._flags = UMTX_ABSTIME; ++ if (t2h_freebsd_timespec(&ut._timeout, target_time + ++ offsetof(struct target__umtx_time, _timeout))) { + return -TARGET_EFAULT; + } +- ret = freebsd_umtx_sem2_wait(obj, &ts); ++ ret = freebsd_umtx_sem2_wait(obj, sizeof(ut), &ut); + } else { +- ret = freebsd_umtx_sem2_wait(obj, NULL); ++ ret = freebsd_umtx_sem2_wait(obj, 0, NULL); + } + break; + +@@ -504,13 +528,17 @@ static inline abi_long do_freebsd__umtx_op(abi_ulong obj, int op, abi_ulong val, + break; + #endif + case TARGET_UMTX_OP_SEM_WAIT: +- if (target_ts != 0) { +- if (t2h_freebsd_timespec(&ts, target_ts)) { ++ /* args: obj *, val, (void *)sizeof(ut), ut * */ ++ if (target_time != 0) { ++ ut._clockid = CLOCK_REALTIME; ++ ut._flags = UMTX_ABSTIME; ++ if (t2h_freebsd_timespec(&ut._timeout, target_time + ++ offsetof(struct target__umtx_time, _timeout))) { + return -TARGET_EFAULT; + } +- ret = freebsd_umtx_sem_wait(obj, &ts); ++ ret = freebsd_umtx_sem_wait(obj, sizeof(ut), &ut); + } else { +- ret = freebsd_umtx_sem_wait(obj, NULL); ++ ret = freebsd_umtx_sem_wait(obj, 0, NULL); + } + break; + +diff --git a/bsd-user/qemu.h b/bsd-user/qemu.h +index 8c84c06..c6a0833 100644 +--- a/bsd-user/qemu.h ++++ b/bsd-user/qemu.h +@@ -280,22 +280,22 @@ abi_long freebsd_lock_umtx(abi_ulong target_addr, abi_long tid, + struct timespec *timeout); + abi_long freebsd_unlock_umtx(abi_ulong target_addr, abi_long id); + abi_long freebsd_umtx_wait(abi_ulong targ_addr, abi_ulong id, +- struct timespec *ts); ++ size_t utsz, struct _umtx_time *ut); + abi_long freebsd_umtx_wake(abi_ulong target_addr, uint32_t n_wake); + abi_long freebsd_umtx_mutex_wake(abi_ulong target_addr, abi_long val); +-abi_long freebsd_umtx_wait_uint(abi_ulong obj, uint32_t val, +- struct timespec *timeout); +-abi_long freebsd_umtx_wait_uint_private(abi_ulong obj, uint32_t val, +- struct timespec *timeout); ++abi_long freebsd_umtx_wait_uint(abi_ulong obj, uint32_t val, size_t utsz, ++ struct _umtx_time *ut); ++abi_long freebsd_umtx_wait_uint_private(abi_ulong obj, uint32_t val, size_t utsz, ++ struct _umtx_time *ut); + abi_long freebsd_umtx_wake_private(abi_ulong obj, uint32_t val); + #if defined(__FreeBSD_version) && __FreeBSD_version > 900000 + abi_long freebsd_umtx_nwake_private(abi_ulong obj, uint32_t val); + abi_long freebsd_umtx_mutex_wake2(abi_ulong obj, uint32_t val); + #if __FreeBSD_version > 1100000 +-abi_long freebsd_umtx_sem2_wait(abi_ulong obj, struct timespec *timeout); ++abi_long freebsd_umtx_sem2_wait(abi_ulong obj, size_t utsz, struct _umtx_time *ut); + abi_long freebsd_umtx_sem2_wake(abi_ulong obj, uint32_t val); + #endif +-abi_long freebsd_umtx_sem_wait(abi_ulong obj, struct timespec *timeout); ++abi_long freebsd_umtx_sem_wait(abi_ulong obj, size_t utsz, struct _umtx_time *ut); + abi_long freebsd_umtx_sem_wake(abi_ulong obj, uint32_t val); + #endif + abi_long freebsd_lock_umutex(abi_ulong target_addr, uint32_t id, Property changes on: emulators/qemu-devel/files/extra-patch-7b9ddce757fee0edf23982be98530a5556ee1b17 ___________________________________________________________________ Added: fbsd:nokeywords ## -0,0 +1 ## +yes \ No newline at end of property Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property Index: emulators/qemu-devel/files/extra-patch-89daa490c97173cfcb6bf071ef923a0b30be43ab =================================================================== --- emulators/qemu-devel/files/extra-patch-89daa490c97173cfcb6bf071ef923a0b30be43ab (revision 0) +++ emulators/qemu-devel/files/extra-patch-89daa490c97173cfcb6bf071ef923a0b30be43ab (working copy) @@ -0,0 +1,61 @@ +From 89daa490c97173cfcb6bf071ef923a0b30be43ab Mon Sep 17 00:00:00 2001 +From: Stacey Son +Date: Wed, 10 Dec 2014 19:41:05 +0000 +Subject: [PATCH] Fix some obvious deadlock problems with + freebsd_umtx_sem2_wait/wake(). + +This change fixes a couple of deadlock problems. First, the hold +on the lock should be dropped if it returns on an error. Second, +the non-shared (private) wake should be used depending on the flag +setting. +--- + bsd-user/freebsd/os-thread.c | 12 ++++++++++-- + 1 file changed, 10 insertions(+), 2 deletions(-) + +diff --git a/bsd-user/freebsd/os-thread.c b/bsd-user/freebsd/os-thread.c +index d143ab8..2d395eb 100644 +--- a/bsd-user/freebsd/os-thread.c ++++ b/bsd-user/freebsd/os-thread.c +@@ -443,6 +443,7 @@ abi_long freebsd_umtx_sem2_wait(abi_ulong obj, size_t utsz, + + pthread_mutex_lock(&umtx_sem_lck); + if (!lock_user_struct(VERIFY_WRITE, t__usem2, obj, 0)) { ++ pthread_mutex_unlock(&umtx_sem_lck); + return -TARGET_EFAULT; + } + do { +@@ -471,10 +472,11 @@ abi_long freebsd_umtx_sem2_wait(abi_ulong obj, size_t utsz, + abi_long freebsd_umtx_sem2_wake(abi_ulong obj, uint32_t val) + { + struct target__usem2 *t__usem2; +- uint32_t count; ++ uint32_t count, flags; + + pthread_mutex_lock(&umtx_sem_lck); + if (!lock_user_struct(VERIFY_WRITE, t__usem2, obj, 0)) { ++ pthread_mutex_unlock(&umtx_sem_lck); + return -TARGET_EFAULT; + } + again: +@@ -487,14 +489,20 @@ abi_long freebsd_umtx_sem2_wake(abi_ulong obj, uint32_t val) + } + } + __get_user(count, &t__usem2->_count); ++ __get_user(flags, &t__usem2->_flags); + unlock_user_struct(t__usem2, obj, 1); + pthread_mutex_unlock(&umtx_sem_lck); + + DEBUG_UMTX(" %s: _umtx_op(%p, %d, %d, NULL, NULL)\n", + __func__, &t__usem2->_count, UMTX_OP_WAKE, INT_MAX); + +- return get_errno(_umtx_op(&t__usem2->_count, UMTX_OP_WAKE, ++ if (!flags) { ++ return get_errno(_umtx_op(&t__usem2->_count, UMTX_OP_WAKE_PRIVATE, ++ INT_MAX /* USEM_COUNT(count) */, NULL, NULL)); ++ } else { ++ return get_errno(_umtx_op(&t__usem2->_count, UMTX_OP_WAKE, + INT_MAX /* USEM_COUNT(count) */, NULL, NULL)); ++ } + } + unlock_user_struct(t__usem2, obj, 1); + pthread_mutex_unlock(&umtx_sem_lck); Property changes on: emulators/qemu-devel/files/extra-patch-89daa490c97173cfcb6bf071ef923a0b30be43ab ___________________________________________________________________ Added: fbsd:nokeywords ## -0,0 +1 ## +yes \ No newline at end of property Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property Index: emulators/qemu-devel/files/extra-patch-9650cd6e2499a6e5f8a6382032fa1636e4b93e6e =================================================================== --- emulators/qemu-devel/files/extra-patch-9650cd6e2499a6e5f8a6382032fa1636e4b93e6e (revision 0) +++ emulators/qemu-devel/files/extra-patch-9650cd6e2499a6e5f8a6382032fa1636e4b93e6e (working copy) @@ -0,0 +1,63 @@ +From 9650cd6e2499a6e5f8a6382032fa1636e4b93e6e Mon Sep 17 00:00:00 2001 +From: Stacey Son +Date: Fri, 21 Nov 2014 19:11:11 +0000 +Subject: [PATCH] Add support for the getpgid(2) and setpgid(2) system calls. + +--- + bsd-user/bsd-proc.h | 16 +++++++++++++++- + bsd-user/syscall.c | 8 ++++++++ + 2 files changed, 23 insertions(+), 1 deletion(-) + +diff --git a/bsd-user/bsd-proc.h b/bsd-user/bsd-proc.h +index d1c732a..5c1f91a 100644 +--- a/bsd-user/bsd-proc.h ++++ b/bsd-user/bsd-proc.h +@@ -1,7 +1,7 @@ + /* + * process related system call shims and definitions + * +- * Copyright (c) 2013 Stacey D. Son ++ * Copyright (c) 2013-14 Stacey D. Son + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by +@@ -268,6 +268,20 @@ static inline abi_long do_bsd_setegid(abi_long arg1) + return get_errno(setegid(arg1)); + } + ++/* getpgid(2) */ ++static inline abi_long do_bsd_getpgid(pid_t pid) ++{ ++ ++ return get_errno(getpgid(pid)); ++} ++ ++/* setpgid(2) */ ++static inline abi_long do_bsd_setpgid(int pid, int pgrp) ++{ ++ ++ return get_errno(setpgid(pid, pgrp)); ++} ++ + /* getpgrp(2) */ + static inline abi_long do_bsd_getpgrp(void) + { +diff --git a/bsd-user/syscall.c b/bsd-user/syscall.c +index deb9c79..6f467f8 100644 +--- a/bsd-user/syscall.c ++++ b/bsd-user/syscall.c +@@ -274,6 +274,14 @@ abi_long do_freebsd_syscall(void *cpu_env, int num, abi_long arg1, + ret = do_bsd_getpgrp(); + break; + ++ case TARGET_FREEBSD_NR_getpgid: /* getpgid(2) */ ++ ret = do_bsd_getpgid(arg1); ++ break; ++ ++ case TARGET_FREEBSD_NR_setpgid: /* setpgid(2) */ ++ ret = do_bsd_setpgid(arg1, arg2); ++ break; ++ + case TARGET_FREEBSD_NR_setreuid: /* setreuid(2) */ + ret = do_bsd_setreuid(arg1, arg2); + break; Property changes on: emulators/qemu-devel/files/extra-patch-9650cd6e2499a6e5f8a6382032fa1636e4b93e6e ___________________________________________________________________ Added: fbsd:nokeywords ## -0,0 +1 ## +yes \ No newline at end of property Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property Index: emulators/qemu-devel/files/extra-patch-9ec60058f0445120f26324970fce6f9f5e30d82f =================================================================== --- emulators/qemu-devel/files/extra-patch-9ec60058f0445120f26324970fce6f9f5e30d82f (revision 0) +++ emulators/qemu-devel/files/extra-patch-9ec60058f0445120f26324970fce6f9f5e30d82f (working copy) @@ -0,0 +1,276 @@ +From 9ec60058f0445120f26324970fce6f9f5e30d82f Mon Sep 17 00:00:00 2001 +From: Stacey Son +Date: Wed, 10 Dec 2014 13:38:37 +0000 +Subject: [PATCH] Eliminate deadlock in lock umutex code. + +This change eliminates a deadlock in freebsd_lock_umutex(), +freebsd_unlock_umutex(), and freebsd_umtx_mutex_wake2() by adding +a waiters count field to the target_umutex structure. By doing this +qemu can eliminate these _umtx_op() OPs in a non-endian dependent +way. +--- + bsd-user/freebsd/os-thread.c | 130 +++++++++++++++++++++++++++++-------------- + bsd-user/freebsd/os-thread.h | 2 +- + 2 files changed, 89 insertions(+), 43 deletions(-) + +diff --git a/bsd-user/freebsd/os-thread.c b/bsd-user/freebsd/os-thread.c +index 194b166..d143ab8 100644 +--- a/bsd-user/freebsd/os-thread.c ++++ b/bsd-user/freebsd/os-thread.c +@@ -38,7 +38,7 @@ + // #define DEBUG_UMTX(...) qemu_log(__VA_ARGS__) + #define DEBUG_UMTX(...) + +-#define DETECT_DEADLOCK 1 ++#define DETECT_DEADLOCK 0 + #define DEADLOCK_TO 30 + + #define NEW_STACK_SIZE 0x40000 +@@ -52,7 +52,8 @@ struct target_umutex { + uint32_t m_owner; /* Owner of the mutex */ + uint32_t m_flags; /* Flags of the mutex */ + uint32_t m_ceiling[2]; /* Priority protect ceiling */ +- uint32_t m_spare[4]; ++ uint32_t m_spare[3]; ++ uint32_t m_count; /* XXX qemu-only waiters count */ + }; + + struct target_ucond { +@@ -85,8 +86,10 @@ static pthread_mutex_t new_thread_lock = PTHREAD_MUTEX_INITIALIZER; + pthread_mutex_t *new_freebsd_thread_lock_ptr = &new_thread_lock; + + static pthread_mutex_t umtx_wait_lck = PTHREAD_MUTEX_INITIALIZER; ++#if 0 + static pthread_cond_t umtx_wait_cv = PTHREAD_COND_INITIALIZER; + static abi_ulong umtx_wait_addr; ++#endif + static pthread_mutex_t umtx_sem_lck = PTHREAD_MUTEX_INITIALIZER; + + static void rtp_to_schedparam(const struct rtprio *rtp, int *policy, +@@ -251,15 +254,15 @@ static abi_long _umtx_wait_uint_private(uint32_t *addr, uint32_t target_val, + } while (1); + } else + #endif /* DETECT_DEADLOCK */ +- return get_errno(_umtx_op(addr, UMTX_OP_WAIT_UINT_PRIVATE, target_val, +- (void *)utsz, ut)); ++ return get_errno(_umtx_op(addr, UMTX_OP_WAIT_UINT_PRIVATE, target_val, ++ (void *)utsz, ut)); + } + + abi_long freebsd_umtx_wait_uint_private(abi_ulong obj, uint32_t target_val, + size_t utsz, struct _umtx_time *ut) + { +- DEBUG_UMTX(" %s: _umtx_op(%p (%u), %d, 0x%x, %d, %p)\n", +- __func__, g2h(obj), *(uint32_t *)g2h(obj), UMTX_OP_WAIT_UINT_PRIVATE, ++ DEBUG_UMTX(" %s: _umtx_op(%p (%u), %d, 0x%x, %d, %p)\n", ++ __func__, g2h(obj), tswap32(*(uint32_t *)g2h(obj)), UMTX_OP_WAIT_UINT_PRIVATE, + target_val, (int)utsz, ut); + return _umtx_wait_uint_private(g2h(obj), target_val, utsz, ut); + } +@@ -328,8 +331,8 @@ abi_long freebsd_umtx_wait(abi_ulong targ_addr, abi_ulong target_id, + abi_long freebsd_umtx_wake_private(abi_ulong obj, uint32_t val) + { + +- DEBUG_UMTX(" %s: _umtx_op(%p, %d, %u, NULL, NULL)\n", +- __func__, g2h(obj), UMTX_OP_WAKE_PRIVATE, val); ++ DEBUG_UMTX(" %s: _umtx_op(%p (%d), %d, %u, NULL, NULL)\n", ++ __func__, g2h(obj), tswap32(*(uint32_t *)g2h(obj)), UMTX_OP_WAKE_PRIVATE, val); + return get_errno(_umtx_op(g2h(obj), UMTX_OP_WAKE_PRIVATE, val, NULL, NULL)); + } + +@@ -342,15 +345,14 @@ abi_long freebsd_umtx_nwake_private(abi_ulong target_array_addr, uint32_t num) + abi_ulong *uaddr; + abi_long ret = 0; + +- DEBUG_UMTX(" %s: _umtx_op(%p, %d, %d, NULL, NULL) Waking: ", ++ DEBUG_UMTX(" %s: _umtx_op(%p, %d, %d, NULL, NULL) Waking: ", + __func__, g2h(target_array_addr), UMTX_OP_NWAKE_PRIVATE, num); + if (!access_ok(VERIFY_READ, target_array_addr, num * sizeof(abi_ulong))) { + return -TARGET_EFAULT; + } + uaddr = (abi_ulong *)g2h(target_array_addr); + for (i = 0; i < (int32_t)num; i++) { +- DEBUG_UMTX("%p ", g2h(tswapal(uaddr[ii]))); +-_umtx_op(g2h(tswapal(uaddr[i])), UMTX_OP_WAKE, INT_MAX, NULL, NULL); ++ DEBUG_UMTX("%p (%u) ", g2h(tswapal(uaddr[i])), tswap32(*(uint32_t *)g2h(tswapal(uaddr[i]))) ); + ret = get_errno(_umtx_op(g2h(tswapal(uaddr[i])), UMTX_OP_WAKE_PRIVATE, + INT_MAX, NULL, NULL)); + if (is_error(ret)) { +@@ -390,19 +392,44 @@ _umtx_op(g2h(tswapal(uaddr[i])), UMTX_OP_WAKE, INT_MAX, NULL, NULL); + #endif /* UMTX_OP_NWAKE_PRIVATE */ + + #if defined(UMTX_OP_MUTEX_WAKE2) +-abi_long freebsd_umtx_mutex_wake2(abi_ulong target_addr, +- __unused uint32_t flags) ++abi_long freebsd_umtx_mutex_wake2(abi_ulong target_addr, uint32_t flags) + { +- abi_long ret = 0; ++ uint32_t count, owner, *addr; ++ struct target_umutex *target_umutex; + + pthread_mutex_lock(&umtx_wait_lck); +- DEBUG_UMTX(" %s: _umtx_op(%p, %d, 0x%x, NULL, NULL)\n", +- __func__, g2h(target_addr), UMTX_OP_MUTEX_WAKE2, flags); +- umtx_wait_addr = target_addr; +- ret = get_errno(pthread_cond_broadcast(&umtx_wait_cv)); ++ if (!lock_user_struct(VERIFY_WRITE, target_umutex, target_addr, 1)) { ++ pthread_mutex_unlock(&umtx_wait_lck); ++ return -TARGET_EFAULT; ++ } ++ __get_user(count, &target_umutex->m_count); ++ if (count > 1) { ++ __get_user(owner, &target_umutex->m_owner); ++ while ((owner & TARGET_UMUTEX_CONTESTED) == 0) { ++ if (tcmpset_32(&target_umutex->m_owner, owner, ++ (owner | TARGET_UMUTEX_CONTESTED))) { ++ break; ++ } ++ /* owner has changed */ ++ __get_user(owner, &target_umutex->m_owner); ++ } ++ } else if (count == 1) { ++ __get_user(owner, &target_umutex->m_owner); ++ while ((owner & ~TARGET_UMUTEX_CONTESTED) != 0 && ++ (owner & TARGET_UMUTEX_CONTESTED) == 0) { ++ if (tcmpset_32(&target_umutex->m_owner, owner, ++ (owner | TARGET_UMUTEX_CONTESTED))) { ++ break; ++ } ++ /* owner has changed */ ++ __get_user(owner, &target_umutex->m_owner); ++ } ++ } ++ addr = g2h(&target_umutex->m_count); ++ unlock_user(target_umutex, target_addr, 0); + pthread_mutex_unlock(&umtx_wait_lck); + +- return ret; ++ return get_errno(_umtx_op(addr, UMTX_OP_WAKE_PRIVATE, INT_MAX, NULL, NULL)); + } + #endif /* UMTX_OP_MUTEX_WAKE2 */ + +@@ -657,7 +684,7 @@ abi_long freebsd_umtx_mutex_wake(abi_ulong obj, abi_long val) + abi_long freebsd_lock_umutex(abi_ulong target_addr, uint32_t id, + struct timespec *ts, int mode) + { +- uint32_t owner, flags; ++ uint32_t owner, flags, count, *addr; + int ret = 0; + + for (;;) { +@@ -735,38 +762,45 @@ abi_long freebsd_lock_umutex(abi_ulong target_addr, uint32_t id, + continue; + } + +- DEBUG_UMTX(" %s: _umtx_op(%p, %d, 0x%x, NULL, NULL)\n", +- __func__, g2h(target_addr), UMTX_OP_WAIT_UINT, +- tswap32(target_umutex->m_owner)); +- unlock_user_struct(target_umutex, target_addr, 1); ++ __get_user(count, &target_umutex->m_count); ++ count++; ++ __put_user(count, &target_umutex->m_count); + +-again: +- if (ts == NULL) { +- ret = get_errno(pthread_cond_wait(&umtx_wait_cv, +- &umtx_wait_lck)); +- } else { +- ret = get_errno(pthread_cond_timedwait(&umtx_wait_cv, +- &umtx_wait_lck, ts)); +- } +- if (ret != 0) { +- pthread_mutex_unlock(&umtx_wait_lck); +- break; +- } +- if (target_addr != umtx_wait_addr) { +- goto again; +- } ++ addr = g2h(&target_umutex->m_count); ++ ++ unlock_user_struct(target_umutex, target_addr, 1); + pthread_mutex_unlock(&umtx_wait_lck); +- } + ++ DEBUG_UMTX(" %s: _umtx_op(%p, %d, 0x%x, NULL, NULL) count = %d\n", ++ __func__, g2h(target_addr), UMTX_OP_WAIT_UINT, ++ tswap32(target_umutex->m_owner), count); ++ ++ if (ts == NULL) { ++ ret = _umtx_wait_uint_private(addr, count, 0, NULL); ++ } else { ++ struct _umtx_time ut; ++ ++ ut._clockid = CLOCK_REALTIME; ++ ut._flags = UMTX_ABSTIME; ++ ut._timeout.tv_sec = ts->tv_sec; ++ ut._timeout.tv_nsec = ts->tv_nsec; ++ ++ ret = _umtx_wait_uint_private(addr, count, sizeof(ut), &ut); ++ } ++ ++ if (ret != 0) ++ break; ++ } + return ret; + } + + abi_long freebsd_unlock_umutex(abi_ulong target_addr, uint32_t id) + { + struct target_umutex *target_umutex; +- uint32_t owner; ++ uint32_t owner, count, *addr; + + ++ pthread_mutex_lock(&umtx_wait_lck); + if (!lock_user_struct(VERIFY_WRITE, target_umutex, target_addr, 0)) { + return -TARGET_EFAULT; + } +@@ -774,22 +808,34 @@ abi_long freebsd_unlock_umutex(abi_ulong target_addr, uint32_t id) + __get_user(owner, &target_umutex->m_owner); + if ((owner & ~TARGET_UMUTEX_CONTESTED) != id) { + unlock_user_struct(target_umutex, target_addr, 1); ++ pthread_mutex_unlock(&umtx_wait_lck); + return -TARGET_EPERM; + } + if ((owner & TARGET_UMUTEX_CONTESTED) == 0) { + if (tcmpset_32(&target_umutex->m_owner, owner, TARGET_UMTX_UNOWNED)) { ++ __put_user(0, &target_umutex->m_count); + unlock_user_struct(target_umutex, target_addr, 1); ++ pthread_mutex_unlock(&umtx_wait_lck); + return 0; + } + } + /* This is a contested lock. Unlock it. */ + __put_user(TARGET_UMUTEX_UNOWNED, &target_umutex->m_owner); ++ ++ __get_user(count, &target_umutex->m_count); ++ if (count) ++ count--; ++ __put_user(count, &target_umutex->m_count); ++ ++ addr = g2h(&target_umutex->m_count); ++ + unlock_user_struct(target_umutex, target_addr, 1); ++ pthread_mutex_unlock(&umtx_wait_lck); + + /* And wake up all those contesting it. */ + DEBUG_UMTX(" %s: _umtx_op(%p, %d, 0x%x, NULL, NULL)\n", + __func__, g2h(target_addr), UMTX_OP_WAKE, 0); +- return get_errno(_umtx_op(g2h(target_addr), UMTX_OP_WAKE, 0, 0, 0)); ++ return get_errno(_umtx_op(addr, UMTX_OP_WAKE_PRIVATE, INT_MAX, NULL, NULL)); + } + + /* +diff --git a/bsd-user/freebsd/os-thread.h b/bsd-user/freebsd/os-thread.h +index 9ed4f6d..59e441c 100644 +--- a/bsd-user/freebsd/os-thread.h ++++ b/bsd-user/freebsd/os-thread.h +@@ -1,7 +1,7 @@ + /* + * FreeBSD thread and user mutex related system call shims + * +- * Copyright (c) 2013 Stacey D. Son ++ * Copyright (c) 2013-14 Stacey D. Son + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by Property changes on: emulators/qemu-devel/files/extra-patch-9ec60058f0445120f26324970fce6f9f5e30d82f ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property Added: fbsd:nokeywords ## -0,0 +1 ## +yes \ No newline at end of property Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Index: emulators/qemu-devel/files/extra-patch-b43b3fe91c85201399f8b2248da267337342a869 =================================================================== --- emulators/qemu-devel/files/extra-patch-b43b3fe91c85201399f8b2248da267337342a869 (revision 0) +++ emulators/qemu-devel/files/extra-patch-b43b3fe91c85201399f8b2248da267337342a869 (working copy) @@ -0,0 +1,81 @@ +From b43b3fe91c85201399f8b2248da267337342a869 Mon Sep 17 00:00:00 2001 +From: Stacey Son +Date: Fri, 5 Dec 2014 22:39:23 +0000 +Subject: [PATCH] Add support for the + cpuset_getaffinity(2)/cpuset_setaffinity(2) syscalls. + +--- + bsd-user/freebsd/os-misc.h | 34 ++++++++++++++++++++++++---------- + bsd-user/syscall.c | 4 ++-- + 2 files changed, 26 insertions(+), 12 deletions(-) + +diff --git a/bsd-user/freebsd/os-misc.h b/bsd-user/freebsd/os-misc.h +index 7aa9b51..5b02792 100644 +--- a/bsd-user/freebsd/os-misc.h ++++ b/bsd-user/freebsd/os-misc.h +@@ -159,23 +159,37 @@ static inline abi_long do_freebsd_cpuset_getid(abi_long arg1, abi_ulong arg2, + } + + /* cpuset_getaffinity(2) */ +-static inline abi_long do_freebsd_cpuset_getaffinity(abi_long arg1, +- abi_ulong arg2, abi_ulong arg3, abi_ulong arg4, abi_ulong arg5, +- abi_ulong arg6) ++static inline abi_long do_freebsd_cpuset_getaffinity(cpulevel_t level, ++ cpuwhich_t which, id_t id, abi_ulong setsize, abi_ulong target_mask) + { ++ cpuset_t *mask; ++ abi_long ret; + +- qemu_log("qemu: Unsupported syscall cpuset_getaffinity()\n"); +- return -TARGET_ENOSYS; ++ mask = lock_user(VERIFY_WRITE, target_mask, setsize, 0); ++ if (mask == NULL) { ++ return -TARGET_EFAULT; ++ } ++ ret = get_errno(cpuset_getaffinity(level, which, id, setsize, mask)); ++ unlock_user(mask, setsize, ret); ++ ++ return ret; + } + + /* cpuset_setaffinity(2) */ +-static inline abi_long do_freebsd_cpuset_setaffinity(abi_long arg1, +- abi_ulong arg2, abi_ulong arg3, abi_ulong arg4, abi_ulong arg5, +- abi_ulong arg6) ++static inline abi_long do_freebsd_cpuset_setaffinity(cpulevel_t level, ++ cpuwhich_t which, id_t id, abi_ulong setsize, abi_ulong target_mask) + { ++ cpuset_t *mask; ++ abi_long ret; + +- qemu_log("qemu: Unsupported syscall cpuset_setaffinity()\n"); +- return -TARGET_ENOSYS; ++ mask = lock_user(VERIFY_READ, target_mask, setsize, 1); ++ if (mask == NULL) { ++ return -TARGET_EFAULT; ++ } ++ ret = get_errno(cpuset_setaffinity(level, which, id, setsize, mask)); ++ unlock_user(mask, setsize, 0); ++ ++ return ret; + } + + +diff --git a/bsd-user/syscall.c b/bsd-user/syscall.c +index 0a1e294..ac08fa2 100644 +--- a/bsd-user/syscall.c ++++ b/bsd-user/syscall.c +@@ -1466,11 +1466,11 @@ abi_long do_freebsd_syscall(void *cpu_env, int num, abi_long arg1, + break; + + case TARGET_FREEBSD_NR_cpuset_getaffinity: /* cpuset_getaffinity(2) */ +- ret = do_freebsd_cpuset_getaffinity(arg1, arg2, arg3, arg4, arg5, arg6); ++ ret = do_freebsd_cpuset_getaffinity(arg1, arg2, arg3, arg4, arg5); + break; + + case TARGET_FREEBSD_NR_cpuset_setaffinity: /* cpuset_setaffinity(2) */ +- ret = do_freebsd_cpuset_setaffinity(arg1, arg2, arg3, arg4, arg5, arg6); ++ ret = do_freebsd_cpuset_setaffinity(arg1, arg2, arg3, arg4, arg5); + break; + + Property changes on: emulators/qemu-devel/files/extra-patch-b43b3fe91c85201399f8b2248da267337342a869 ___________________________________________________________________ Added: fbsd:nokeywords ## -0,0 +1 ## +yes \ No newline at end of property Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property Index: emulators/qemu-devel/files/extra-patch-b8cf8682d4542d08864c4af069b235a151a10300 =================================================================== --- emulators/qemu-devel/files/extra-patch-b8cf8682d4542d08864c4af069b235a151a10300 (revision 0) +++ emulators/qemu-devel/files/extra-patch-b8cf8682d4542d08864c4af069b235a151a10300 (working copy) @@ -0,0 +1,120 @@ +From b8cf8682d4542d08864c4af069b235a151a10300 Mon Sep 17 00:00:00 2001 +From: Stacey Son +Date: Sat, 6 Dec 2014 00:38:32 +0000 +Subject: [PATCH] Bug fix: The cpuset mask should be byte swapped (if needed). + +The cpuset mask should be byte swapped for hosts/targets that are +different endians cpuset_getaffinity(2) and cpuset_setaffinity(2). +--- + bsd-user/freebsd/os-misc.h | 74 ++++++++++++++++++++++++++++++++++++++-------- + 1 file changed, 61 insertions(+), 13 deletions(-) + +diff --git a/bsd-user/freebsd/os-misc.h b/bsd-user/freebsd/os-misc.h +index 5b02792..56fffcd 100644 +--- a/bsd-user/freebsd/os-misc.h ++++ b/bsd-user/freebsd/os-misc.h +@@ -1,7 +1,7 @@ + /* + * miscellaneous FreeBSD system call shims + * +- * Copyright (c) 2013 Stacey D. Son ++ * Copyright (c) 2013-14 Stacey D. Son + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by +@@ -158,19 +158,69 @@ static inline abi_long do_freebsd_cpuset_getid(abi_long arg1, abi_ulong arg2, + return put_user_s32(setid, target_setid); + } + ++static abi_ulong copy_from_user_cpuset_mask(cpuset_t *mask, ++ abi_ulong target_mask_addr) ++{ ++ int i, j, k; ++ abi_ulong b, *target_mask; ++ ++ target_mask = lock_user(VERIFY_READ, target_mask_addr, ++ (CPU_SETSIZE / 8), 1); ++ if (target_mask == NULL) { ++ return -TARGET_EFAULT; ++ } ++ CPU_ZERO(mask); ++ k = 0; ++ for (i = 0; i < ((CPU_SETSIZE/8)/sizeof(abi_ulong)); i++) { ++ __get_user(b, &target_mask[i]); ++ for (j = 0; j < TARGET_ABI_BITS; j++) { ++ if ((b >> j) & 1) { ++ CPU_SET(k, mask); ++ } ++ k++; ++ } ++ } ++ unlock_user(target_mask, target_mask_addr, 0); ++ ++ return 0; ++} ++ ++static abi_ulong copy_to_user_cpuset_mask(abi_ulong target_mask_addr, ++ cpuset_t *mask) ++{ ++ int i, j, k; ++ abi_ulong b, *target_mask; ++ ++ target_mask = lock_user(VERIFY_WRITE, target_mask_addr, ++ (CPU_SETSIZE / 8), 0); ++ if (target_mask == NULL) { ++ return -TARGET_EFAULT; ++ } ++ k = 0; ++ for (i = 0; i < ((CPU_SETSIZE/8)/sizeof(abi_ulong)); i++) { ++ b = 0; ++ for (j = 0; j < TARGET_ABI_BITS; j++) { ++ b |= ((CPU_ISSET(k, mask) != 0) << j); ++ k++; ++ } ++ __put_user(b, &target_mask[i]); ++ } ++ unlock_user(target_mask, target_mask_addr, (CPU_SETSIZE / 8)); ++ ++ return 0; ++} ++ + /* cpuset_getaffinity(2) */ + static inline abi_long do_freebsd_cpuset_getaffinity(cpulevel_t level, + cpuwhich_t which, id_t id, abi_ulong setsize, abi_ulong target_mask) + { +- cpuset_t *mask; ++ cpuset_t mask; + abi_long ret; + +- mask = lock_user(VERIFY_WRITE, target_mask, setsize, 0); +- if (mask == NULL) { +- return -TARGET_EFAULT; ++ ret = get_errno(cpuset_getaffinity(level, which, id, setsize, &mask)); ++ if (ret == 0) { ++ ret = copy_to_user_cpuset_mask(target_mask, &mask); + } +- ret = get_errno(cpuset_getaffinity(level, which, id, setsize, mask)); +- unlock_user(mask, setsize, ret); + + return ret; + } +@@ -179,15 +229,13 @@ static inline abi_long do_freebsd_cpuset_getaffinity(cpulevel_t level, + static inline abi_long do_freebsd_cpuset_setaffinity(cpulevel_t level, + cpuwhich_t which, id_t id, abi_ulong setsize, abi_ulong target_mask) + { +- cpuset_t *mask; ++ cpuset_t mask; + abi_long ret; + +- mask = lock_user(VERIFY_READ, target_mask, setsize, 1); +- if (mask == NULL) { +- return -TARGET_EFAULT; ++ ret = copy_from_user_cpuset_mask(&mask, target_mask); ++ if (ret == 0) { ++ ret = get_errno(cpuset_setaffinity(level, which, id, setsize, &mask)); + } +- ret = get_errno(cpuset_setaffinity(level, which, id, setsize, mask)); +- unlock_user(mask, setsize, 0); + + return ret; + } Property changes on: emulators/qemu-devel/files/extra-patch-b8cf8682d4542d08864c4af069b235a151a10300 ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property Added: fbsd:nokeywords ## -0,0 +1 ## +yes \ No newline at end of property Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Index: emulators/qemu-devel/files/extra-patch-bf8de490b6a42d2ef504072cdc0899638091196a =================================================================== --- emulators/qemu-devel/files/extra-patch-bf8de490b6a42d2ef504072cdc0899638091196a (revision 0) +++ emulators/qemu-devel/files/extra-patch-bf8de490b6a42d2ef504072cdc0899638091196a (working copy) @@ -0,0 +1,131 @@ +From bf8de490b6a42d2ef504072cdc0899638091196a Mon Sep 17 00:00:00 2001 +From: Stacey Son +Date: Tue, 18 Nov 2014 15:43:44 +0000 +Subject: [PATCH] Emulate umtx_sem2_{wait, wake} in userland. + +Because of big/little endian issues umtx_sem2 must be emulated as much +as possible in userland. +--- + bsd-user/freebsd/os-thread.c | 81 +++++++++++++++++++++++++++++++++++++++----- + 1 file changed, 72 insertions(+), 9 deletions(-) + +diff --git a/bsd-user/freebsd/os-thread.c b/bsd-user/freebsd/os-thread.c +index 88fcc51..9ac1219 100644 +--- a/bsd-user/freebsd/os-thread.c ++++ b/bsd-user/freebsd/os-thread.c +@@ -83,6 +83,7 @@ pthread_mutex_t *new_freebsd_thread_lock_ptr = &new_thread_lock; + static pthread_mutex_t umtx_wait_lck = PTHREAD_MUTEX_INITIALIZER; + static pthread_cond_t umtx_wait_cv = PTHREAD_COND_INITIALIZER; + static abi_ulong umtx_wait_addr; ++static pthread_mutex_t umtx_sem_lck = PTHREAD_MUTEX_INITIALIZER; + + static void rtp_to_schedparam(const struct rtprio *rtp, int *policy, + struct sched_param *param) +@@ -235,36 +236,98 @@ abi_long freebsd_umtx_mutex_wake2(abi_ulong target_addr, + abi_long freebsd_umtx_sem2_wait(abi_ulong obj, size_t utsz, + struct _umtx_time *ut) + { ++ struct target__usem2 *t__usem2; ++ uint32_t count; + +- /* XXX Assumes struct _usem is opauque to the user */ +- if (!access_ok(VERIFY_WRITE, obj, sizeof(struct target__usem2))) { ++ pthread_mutex_lock(&umtx_sem_lck); ++ if (!lock_user_struct(VERIFY_WRITE, t__usem2, obj, 0)) { + return -TARGET_EFAULT; + } +- return get_errno(_umtx_op(g2h(obj), UMTX_OP_SEM2_WAIT, 0, (void *)utsz, +- ut)); ++ do { ++ __get_user(count, &t__usem2->_count); ++ } while (!tcmpset_32(&t__usem2->_count, count, count | USEM_HAS_WAITERS)); ++ unlock_user_struct(t__usem2, obj, 1); ++ pthread_mutex_unlock(&umtx_sem_lck); ++ ++ if (USEM_COUNT(count) != 0) ++ return (0); ++ return get_errno(_umtx_op(&t__usem2->_count, UMTX_OP_WAIT_UINT, ++ tswap32(count | USEM_HAS_WAITERS), (void *)utsz, ut)); + } + + abi_long freebsd_umtx_sem2_wake(abi_ulong obj, uint32_t val) + { ++ struct target__usem2 *t__usem2; ++ uint32_t count; + +- return get_errno(_umtx_op(g2h(obj), UMTX_OP_SEM2_WAKE, val, NULL, NULL)); ++ pthread_mutex_lock(&umtx_sem_lck); ++ if (!lock_user_struct(VERIFY_WRITE, t__usem2, obj, 0)) { ++ return -TARGET_EFAULT; ++ } ++again: ++ __get_user(count, &t__usem2->_count); ++ if (USEM_COUNT(count) > 0) { ++ if (USEM_COUNT(count) == 1) { ++ if (!tcmpset_32(&t__usem2->_count, count, 1)) { ++ /* count has changed, try again. */ ++ goto again; ++ } ++ } ++ __get_user(count, &t__usem2->_count); ++ unlock_user_struct(t__usem2, obj, 1); ++ pthread_mutex_unlock(&umtx_sem_lck); ++ return get_errno(_umtx_op(&t__usem2->_count, UMTX_OP_WAKE, tswap32(count), ++ NULL, NULL)); ++ } ++ unlock_user_struct(t__usem2, obj, 1); ++ pthread_mutex_unlock(&umtx_sem_lck); ++ return (0); + } + #endif /* ! __FreeBSD_version > 1100000 */ + + abi_long freebsd_umtx_sem_wait(abi_ulong obj, size_t utsz, + struct _umtx_time *ut) + { +- /* XXX Assumes struct _usem is opauque to the user */ +- if (!access_ok(VERIFY_WRITE, obj, sizeof(struct target__usem))) { ++ struct target__usem *t__usem; ++ uint32_t count; ++ ++ pthread_mutex_lock(&umtx_sem_lck); ++ if (!lock_user_struct(VERIFY_WRITE, t__usem, obj, 0)) { + return -TARGET_EFAULT; + } +- return get_errno(_umtx_op(g2h(obj), UMTX_OP_SEM_WAIT, 0, (void *)utsz, ut)); ++ __put_user(1, &t__usem->_has_waiters); ++ __get_user(count, &t__usem->_count); ++ unlock_user_struct(t__usem, obj, 1); ++ pthread_mutex_unlock(&umtx_sem_lck); ++ if (count != 0) { ++ return (0); ++ } ++ ++ return get_errno(_umtx_op(&t__usem->_count, UMTX_OP_WAIT_UINT, tswap32(count), ++ (void *)utsz, ut)); + } + + abi_long freebsd_umtx_sem_wake(abi_ulong obj, uint32_t val) + { ++ struct target__usem *t__usem; ++ uint32_t count; + +- return get_errno(_umtx_op(g2h(obj), UMTX_OP_SEM_WAKE, val, NULL, NULL)); ++ pthread_mutex_lock(&umtx_sem_lck); ++ if (!lock_user_struct(VERIFY_WRITE, t__usem, obj, 0)) { ++ return -TARGET_EFAULT; ++ } ++ __get_user(count, &t__usem->_count); ++ if (count > 0) { ++ if (count == 1) ++ __put_user(0, &t__usem->_has_waiters); ++ unlock_user_struct(t__usem, obj, 1); ++ pthread_mutex_unlock(&umtx_sem_lck); ++ return get_errno(_umtx_op(&t__usem->_count, UMTX_OP_WAKE, tswap32(count), ++ NULL, NULL)); ++ } ++ unlock_user_struct(t__usem, obj, 1); ++ pthread_mutex_unlock(&umtx_sem_lck); ++ return (0); + } + #endif /* ! __FreeBSD_version > 900000 */ + Property changes on: emulators/qemu-devel/files/extra-patch-bf8de490b6a42d2ef504072cdc0899638091196a ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property Added: fbsd:nokeywords ## -0,0 +1 ## +yes \ No newline at end of property Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Index: emulators/qemu-devel/files/extra-patch-c9ff14ece1eab3efeb683b1e9752f5f7fb6b3870 =================================================================== --- emulators/qemu-devel/files/extra-patch-c9ff14ece1eab3efeb683b1e9752f5f7fb6b3870 (revision 0) +++ emulators/qemu-devel/files/extra-patch-c9ff14ece1eab3efeb683b1e9752f5f7fb6b3870 (working copy) @@ -0,0 +1,35 @@ +From c9ff14ece1eab3efeb683b1e9752f5f7fb6b3870 Mon Sep 17 00:00:00 2001 +From: Stacey Son +Date: Tue, 18 Nov 2014 18:53:57 +0000 +Subject: [PATCH] Wake up all the blocked threads when doing *_wake. + +--- + bsd-user/freebsd/os-thread.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/bsd-user/freebsd/os-thread.c b/bsd-user/freebsd/os-thread.c +index 2ea3495..22d96a9 100644 +--- a/bsd-user/freebsd/os-thread.c ++++ b/bsd-user/freebsd/os-thread.c +@@ -276,8 +276,8 @@ abi_long freebsd_umtx_sem2_wake(abi_ulong obj, uint32_t val) + __get_user(count, &t__usem2->_count); + unlock_user_struct(t__usem2, obj, 1); + pthread_mutex_unlock(&umtx_sem_lck); +- return get_errno(_umtx_op(&t__usem2->_count, UMTX_OP_WAKE, tswap32(count), +- NULL, NULL)); ++ return get_errno(_umtx_op(&t__usem2->_count, UMTX_OP_WAKE, ++ INT_MAX /* USEM_COUNT(count) */, NULL, NULL)); + } + unlock_user_struct(t__usem2, obj, 1); + pthread_mutex_unlock(&umtx_sem_lck); +@@ -322,8 +322,8 @@ abi_long freebsd_umtx_sem_wake(abi_ulong obj, uint32_t val) + __put_user(0, &t__usem->_has_waiters); + unlock_user_struct(t__usem, obj, 1); + pthread_mutex_unlock(&umtx_sem_lck); +- return get_errno(_umtx_op(&t__usem->_count, UMTX_OP_WAKE, tswap32(count), +- NULL, NULL)); ++ return get_errno(_umtx_op(&t__usem->_count, UMTX_OP_WAKE, ++ INT_MAX /* count */, NULL, NULL)); + } + unlock_user_struct(t__usem, obj, 1); + pthread_mutex_unlock(&umtx_sem_lck); Property changes on: emulators/qemu-devel/files/extra-patch-c9ff14ece1eab3efeb683b1e9752f5f7fb6b3870 ___________________________________________________________________ Added: fbsd:nokeywords ## -0,0 +1 ## +yes \ No newline at end of property Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property Index: emulators/qemu-devel/files/extra-patch-cabfcd6c231c9425b9ac27c9ecca983786c5eff1 =================================================================== --- emulators/qemu-devel/files/extra-patch-cabfcd6c231c9425b9ac27c9ecca983786c5eff1 (revision 0) +++ emulators/qemu-devel/files/extra-patch-cabfcd6c231c9425b9ac27c9ecca983786c5eff1 (working copy) @@ -0,0 +1,43 @@ +From cabfcd6c231c9425b9ac27c9ecca983786c5eff1 Mon Sep 17 00:00:00 2001 +From: Stacey Son +Date: Tue, 18 Nov 2014 17:20:10 +0000 +Subject: [PATCH] Add support for missing fsync(2). + +--- + bsd-user/bsd-file.h | 7 +++++++ + bsd-user/syscall.c | 4 ++++ + 2 files changed, 11 insertions(+) + +diff --git a/bsd-user/bsd-file.h b/bsd-user/bsd-file.h +index f697eac..defa8bb 100644 +--- a/bsd-user/bsd-file.h ++++ b/bsd-user/bsd-file.h +@@ -228,6 +228,13 @@ static inline abi_long do_bsd_close(abi_long arg1) + return get_errno(close(arg1)); + } + ++/* fsync(2) */ ++static inline abi_long do_bsd_fsync(abi_long arg1) ++{ ++ ++ return get_errno(fsync(arg1)); ++} ++ + /* closefrom(2) */ + static inline abi_long do_bsd_closefrom(abi_long arg1) + { +diff --git a/bsd-user/syscall.c b/bsd-user/syscall.c +index 243eb13..deb9c79 100644 +--- a/bsd-user/syscall.c ++++ b/bsd-user/syscall.c +@@ -481,6 +481,10 @@ abi_long do_freebsd_syscall(void *cpu_env, int num, abi_long arg1, + ret = do_bsd_close(arg1); + break; + ++ case TARGET_FREEBSD_NR_fsync: /* fsync(2) */ ++ ret = do_bsd_fsync(arg1); ++ break; ++ + case TARGET_FREEBSD_NR_closefrom: /* closefrom(2) */ + ret = do_bsd_closefrom(arg1); + break; Property changes on: emulators/qemu-devel/files/extra-patch-cabfcd6c231c9425b9ac27c9ecca983786c5eff1 ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property Added: fbsd:nokeywords ## -0,0 +1 ## +yes \ No newline at end of property Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Index: emulators/qemu-devel/files/extra-patch-cfd5876b814e70e95df84620b8d130a36be32edc =================================================================== --- emulators/qemu-devel/files/extra-patch-cfd5876b814e70e95df84620b8d130a36be32edc (revision 0) +++ emulators/qemu-devel/files/extra-patch-cfd5876b814e70e95df84620b8d130a36be32edc (working copy) @@ -0,0 +1,65 @@ +From cfd5876b814e70e95df84620b8d130a36be32edc Mon Sep 17 00:00:00 2001 +From: Stacey Son +Date: Fri, 21 Nov 2014 21:56:08 +0000 +Subject: [PATCH] Must check the flags field in umtx_sem2_wait() for private. + +--- + bsd-user/freebsd/os-thread.c | 22 +++++++++++++++++++--- + 1 file changed, 19 insertions(+), 3 deletions(-) + +diff --git a/bsd-user/freebsd/os-thread.c b/bsd-user/freebsd/os-thread.c +index 22d96a9..efd8bd7 100644 +--- a/bsd-user/freebsd/os-thread.c ++++ b/bsd-user/freebsd/os-thread.c +@@ -238,6 +238,7 @@ abi_long freebsd_umtx_sem2_wait(abi_ulong obj, size_t utsz, + { + struct target__usem2 *t__usem2; + uint32_t count; ++ uint32_t flags; /* either THREAD_SHARE (0 _private) or AUTO_SHARE (1) */ + + pthread_mutex_lock(&umtx_sem_lck); + if (!lock_user_struct(VERIFY_WRITE, t__usem2, obj, 0)) { +@@ -249,10 +250,21 @@ abi_long freebsd_umtx_sem2_wait(abi_ulong obj, size_t utsz, + unlock_user_struct(t__usem2, obj, 1); + pthread_mutex_unlock(&umtx_sem_lck); + ++ __get_user(flags, &t__usem2->_flags); ++ ++ DEBUG_UMTX(" %s: _umtx_op(%p, %d, flags=%d , 0x%x, %d, %p)\n", ++ __func__, &t__usem2->_count, UMTX_OP_WAIT_UINT, ++ t__usem2->_flags, t__usem2->_count, (int)utsz, ut); ++ + if (USEM_COUNT(count) != 0) + return (0); +- return get_errno(_umtx_op(&t__usem2->_count, UMTX_OP_WAIT_UINT, +- tswap32(count | USEM_HAS_WAITERS), (void *)utsz, ut)); ++ if (!flags) { ++ return get_errno(_umtx_op(&t__usem2->_count, UMTX_OP_WAIT_UINT_PRIVATE, ++ tswap32(count | USEM_HAS_WAITERS), (void *)utsz, ut)); ++ } else { ++ return get_errno(_umtx_op(&t__usem2->_count, UMTX_OP_WAIT_UINT, ++ tswap32(count | USEM_HAS_WAITERS), (void *)utsz, ut)); ++ } + } + + abi_long freebsd_umtx_sem2_wake(abi_ulong obj, uint32_t val) +@@ -268,7 +280,7 @@ abi_long freebsd_umtx_sem2_wake(abi_ulong obj, uint32_t val) + __get_user(count, &t__usem2->_count); + if (USEM_COUNT(count) > 0) { + if (USEM_COUNT(count) == 1) { +- if (!tcmpset_32(&t__usem2->_count, count, 1)) { ++ if (!tcmpset_32(&t__usem2->_count, count, USEM_COUNT(count))) { + /* count has changed, try again. */ + goto again; + } +@@ -276,6 +288,10 @@ abi_long freebsd_umtx_sem2_wake(abi_ulong obj, uint32_t val) + __get_user(count, &t__usem2->_count); + unlock_user_struct(t__usem2, obj, 1); + pthread_mutex_unlock(&umtx_sem_lck); ++ ++ DEBUG_UMTX(" %s: _umtx_op(%p, %d, %d, NULL, NULL)\n", ++ __func__, &t__usem2->_count, UMTX_OP_WAKE, INT_MAX); ++ + return get_errno(_umtx_op(&t__usem2->_count, UMTX_OP_WAKE, + INT_MAX /* USEM_COUNT(count) */, NULL, NULL)); + } Property changes on: emulators/qemu-devel/files/extra-patch-cfd5876b814e70e95df84620b8d130a36be32edc ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property Added: fbsd:nokeywords ## -0,0 +1 ## +yes \ No newline at end of property Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Index: emulators/qemu-devel/files/extra-patch-e41ec268589bd572b170b4f360928265f8472b2c =================================================================== --- emulators/qemu-devel/files/extra-patch-e41ec268589bd572b170b4f360928265f8472b2c (revision 0) +++ emulators/qemu-devel/files/extra-patch-e41ec268589bd572b170b4f360928265f8472b2c (working copy) @@ -0,0 +1,30 @@ +From e41ec268589bd572b170b4f360928265f8472b2c Mon Sep 17 00:00:00 2001 +From: Stacey Son +Date: Thu, 4 Dec 2014 18:58:50 +0000 +Subject: [PATCH] Bug fix: Don't copy out the parent thread id. + +Copying out the parent thread id (tid) just overwrites the child +thread id. So don't do it. +--- + bsd-user/freebsd/os-thread.c | 7 ++----- + 1 file changed, 2 insertions(+), 5 deletions(-) + +diff --git a/bsd-user/freebsd/os-thread.c b/bsd-user/freebsd/os-thread.c +index efd8bd7..6f8fee3 100644 +--- a/bsd-user/freebsd/os-thread.c ++++ b/bsd-user/freebsd/os-thread.c +@@ -124,12 +124,9 @@ void *new_freebsd_thread_start(void *arg) + cpu->host_tid = tid; + // ts->ts_tid = tid; + +- /* copy out the TID info */ ++ /* copy out the child TID */ + if (info->param.child_tid) { +- put_user(tid, info->param.child_tid, abi_long); +- } +- if (info->param.parent_tid) { +- put_user(info->parent_tid, info->param.parent_tid, abi_long); ++ put_user_ual(tid, info->param.child_tid); + } + + /* Set arch dependent registers to start thread. */ Property changes on: emulators/qemu-devel/files/extra-patch-e41ec268589bd572b170b4f360928265f8472b2c ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property Added: fbsd:nokeywords ## -0,0 +1 ## +yes \ No newline at end of property Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Index: emulators/qemu-devel/files/extra-patch-ea04e4628070f31ca8c00b8a3cbdd4bd25c19465 =================================================================== --- emulators/qemu-devel/files/extra-patch-ea04e4628070f31ca8c00b8a3cbdd4bd25c19465 (revision 0) +++ emulators/qemu-devel/files/extra-patch-ea04e4628070f31ca8c00b8a3cbdd4bd25c19465 (working copy) @@ -0,0 +1,22 @@ +From ea04e4628070f31ca8c00b8a3cbdd4bd25c19465 Mon Sep 17 00:00:00 2001 +From: Stacey Son +Date: Mon, 8 Dec 2014 19:01:41 +0000 +Subject: [PATCH] Add missing '#include' needed for FreeBSD 8. + +credit: nox@ +--- + bsd-user/bsd-ioctl.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/bsd-user/bsd-ioctl.c b/bsd-user/bsd-ioctl.c +index 7edb752..4609707 100644 +--- a/bsd-user/bsd-ioctl.c ++++ b/bsd-user/bsd-ioctl.c +@@ -28,6 +28,7 @@ + #endif + #include + #include ++#include /* needed for FreeBSD 8.4 */ + + #include + Property changes on: emulators/qemu-devel/files/extra-patch-ea04e4628070f31ca8c00b8a3cbdd4bd25c19465 ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property Added: fbsd:nokeywords ## -0,0 +1 ## +yes \ No newline at end of property Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Index: emulators/qemu-devel/files/extra-patch-fc128b9c49bb87d22772a74829c802117c3ef94f =================================================================== --- emulators/qemu-devel/files/extra-patch-fc128b9c49bb87d22772a74829c802117c3ef94f (revision 0) +++ emulators/qemu-devel/files/extra-patch-fc128b9c49bb87d22772a74829c802117c3ef94f (working copy) @@ -0,0 +1,263 @@ +From fc128b9c49bb87d22772a74829c802117c3ef94f Mon Sep 17 00:00:00 2001 +From: Stacey Son +Date: Fri, 5 Dec 2014 18:36:13 +0000 +Subject: [PATCH] Add stub for IPv6 ioctl(). + +This change adds a stub for IPv6 ioctl() as described in +netinet6/in6_var.h. The stub currently doesn't offer any +support but does silence the "Qemu unsupported ioctl" +warning messages by returning -1 (ENXIO) for the calling ioctl(). +--- + bsd-user/bsd-ioctl.c | 12 +++ + bsd-user/freebsd/os-ioctl-cmds.h | 3 + + bsd-user/freebsd/os-ioctl-in6_var.h | 201 ++++++++++++++++++++++++++++++++++++ + 3 files changed, 216 insertions(+) + create mode 100644 bsd-user/freebsd/os-ioctl-in6_var.h + +diff --git a/bsd-user/bsd-ioctl.c b/bsd-user/bsd-ioctl.c +index ae4784a..7edb752 100644 +--- a/bsd-user/bsd-ioctl.c ++++ b/bsd-user/bsd-ioctl.c +@@ -31,12 +31,24 @@ + + #include + ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ + #include "qemu.h" + #include "qemu-common.h" + + #include "bsd-ioctl.h" + #include "os-ioctl-cryptodev.h" + #include "os-ioctl-filio.h" ++#include "os-ioctl-in6_var.h" + #include "os-ioctl-ttycom.h" + + static const bitmask_transtbl iflag_tbl[] = { +diff --git a/bsd-user/freebsd/os-ioctl-cmds.h b/bsd-user/freebsd/os-ioctl-cmds.h +index f10d560..2ecb76d 100644 +--- a/bsd-user/freebsd/os-ioctl-cmds.h ++++ b/bsd-user/freebsd/os-ioctl-cmds.h +@@ -50,3 +50,6 @@ IOCTL(FIOSEEKHOLE, IOC_RW, MK_PTR(TYPE_ULONG)) + + /* crypto/cryptodev.h */ + IOCTL_SPECIAL(CRIOGET, IOC_RW, do_ioctl_unsupported, TYPE_INT) ++ ++/* netinet6/in6_var.h */ ++IOCTL_SPECIAL(SIOCGIFAFLAG_IN6, IOC_RW, do_ioctl_unsupported, MK_PTR(TYPE_INT)) +diff --git a/bsd-user/freebsd/os-ioctl-in6_var.h b/bsd-user/freebsd/os-ioctl-in6_var.h +new file mode 100644 +index 0000000..c42835f +--- /dev/null ++++ b/bsd-user/freebsd/os-ioctl-in6_var.h +@@ -0,0 +1,201 @@ ++/* ++ * FreeBSD in6 definitions for ioctl(2) emulation ++ * ++ * Copyright (c) 2014 Stacey D. Son ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, see . ++ */ ++#ifndef _IOCTL_IN6_VAR_H_ ++#define _IOCTL_IN6_VAR_H_ ++ ++/* see netinet6/in6_var.h */ ++ ++/* and see netinet/in6.h ++ * XXX target_in6_addr and target_sockaddr_in6 should maybe go ++ * somewhere else. ++ */ ++struct target_in6_addr { ++ union { ++ uint8_t __u6_addr8[16]; ++ uint16_t __u6_addr16[8]; ++ uint32_t __u6_addr32[4]; ++ } __u6_addr; ++}; ++ ++struct target_sockaddr_in6 { ++ uint8_t sin6_len; ++ uint8_t sin6_family; ++ uint16_t sin6_port; ++ uint32_t sin6_flowinfo; ++ struct target_in6_addr sin6_addr; ++ uint32_t sin6_scope_id; ++}; ++ ++struct target_in6_addrlifetime { ++ target_freebsd_time_t ia6t_expire; ++ target_freebsd_time_t ia6t_preferred; ++ u_int32_t ia6t_vltime; ++ u_int32_t ia6t_pltime; ++}; ++ ++struct target_in6_ifstat { ++ uint64_t ifs6_in_receive; ++ uint64_t ifs6_in_hdrerr; ++ uint64_t ifs6_in_toobig; ++ uint64_t ifs6_in_noroute; ++ uint64_t ifs6_in_addrerr; ++ uint64_t ifs6_in_protounknown; ++ ++ uint64_t ifs6_in_truncated; ++ uint64_t ifs6_in_discard; ++ ++ uint64_t ifs6_in_deliver; ++ ++ uint64_t ifs6_out_forward; ++ ++ uint64_t ifs6_out_request; ++ ++ uint64_t ifs6_out_discard; ++ uint64_t ifs6_out_fragok; ++ uint64_t ifs6_out_fragfail; ++ uint64_t ifs6_out_fragcreat; ++ ++ uint64_t ifs6_reass_reqd; ++ ++ uint64_t ifs6_reass_ok; ++ ++ uint64_t ifs6_reass_fail; ++ ++ uint64_t ifs6_in_mcast; ++ uint64_t ifs6_out_mcast; ++}; ++ ++struct target_icmp6_ifstat { ++ uint64_t ifs6_in_msg; ++ uint64_t ifs6_in_error; ++ uint64_t ifs6_in_dstunreach; ++ uint64_t ifs6_in_adminprohib; ++ uint64_t ifs6_in_timeexceed; ++ uint64_t ifs6_in_paramprob; ++ uint64_t ifs6_in_pkttoobig; ++ uint64_t ifs6_in_echo; ++ uint64_t ifs6_in_echoreply; ++ uint64_t ifs6_in_routersolicit; ++ uint64_t ifs6_in_routeradvert; ++ uint64_t ifs6_in_neighborsolicit; ++ uint64_t ifs6_in_neighboradvert; ++ uint64_t ifs6_in_redirect; ++ uint64_t ifs6_in_mldquery; ++ uint64_t ifs6_in_mldreport; ++ uint64_t ifs6_in_mlddone; ++ ++ uint64_t ifs6_out_msg; ++ uint64_t ifs6_out_error; ++ uint64_t ifs6_out_dstunreach; ++ uint64_t ifs6_out_adminprohib; ++ uint64_t ifs6_out_timeexceed; ++ uint64_t ifs6_out_paramprob; ++ uint64_t ifs6_out_pkttoobig; ++ uint64_t ifs6_out_echo; ++ uint64_t ifs6_out_echoreply; ++ uint64_t ifs6_out_routersolicit; ++ uint64_t ifs6_out_routeradvert; ++ uint64_t ifs6_out_neighborsolicit; ++ uint64_t ifs6_out_neighboradvert; ++ uint64_t ifs6_out_redirect; ++ uint64_t ifs6_out_mldquery; ++ uint64_t ifs6_out_mldreport; ++ uint64_t ifs6_out_mlddone; ++}; ++ ++#ifndef TARGET_IFNAMSIZ ++#define TARGET_IFNAMSIZ 16 ++#endif ++ ++struct target_in6_ifreq { ++ char ifr_name[TARGET_IFNAMSIZ]; ++ union { ++ struct target_sockaddr_in6 ifru_addr; ++ struct target_sockaddr_in6 ifru_dstaddr; ++ int ifru_flags; ++ int ifru_flags6; ++ int ifru_metric; ++ abi_ulong ifru_data; ++ struct target_in6_addrlifetime ifru_lifetime; ++ struct target_in6_ifstat ifru_stat; ++ struct target_icmp6_ifstat ifru_icmp6stat; ++ u_int32_t ifru_scope_id[16]; ++ } ifr_ifru; ++}; ++ ++#define TARGET_SIOCGIFDSTADDR_IN6 TARGET_IOWR('i', 34, struct target_in6_ifreq) ++#define TARGET_SIOCGIFNETMASK_IN6 TARGET_IOWR('i', 37, struct target_in6_ifreq) ++ ++#define TARGET_SIOCDIFADDR_IN6 TARGET_IOW('i', 25, struct target_in6_ifreq) ++/* NOT YET ++#define TARGET_OSIOCAIFADDR_IN6 TARGET_IOW('i', 26, struct target_oin6_aliasreq) ++#define TARGET_SIOCAIFADDR_IN6 TARGET_IOW('i', 27, struct target_in6_aliasreq) ++ ++#define TARGET_SIOCSIFPHYADDR_IN6 TARGET_IOW('i', 70, struct target_in6_aliasreq) ++*/ ++#define TARGET_SIOCGIFPSRCADDR_IN6 TARGET_IOWR('i', 71, struct target_in6_ifreq) ++#define TARGET_SIOCGIFPDSTADDR_IN6 TARGET_IOWR('i', 72, struct target_in6_ifreq) ++ ++#define TARGET_SIOCGIFAFLAG_IN6 TARGET_IOWR('i', 73, struct target_in6_ifreq) ++ ++/* NOT YET ++#define TARGET_SIOCGDRLST_IN6 TARGET_IOWR('i', 74, struct target_in6_drlist) ++ ++#define TARGET_SIOCGIFINFO_IN6 TARGET_IOWR('i', 108, struct target_in6_ndireq) ++#define TARGET_SIOCSIFINFO_IN6 TARGET_IOWR('i', 109, struct target_in6_ndireq) ++*/ ++#define TARGET_SIOCSNDFLUSH_IN6 TARGET_IOWR('i', 77, struct target_in6_ifreq) ++/* NOT YET ++#define TARGET_SIOCGNBRINFO_IN6 TARGET_IOWR('i', 78, struct target_in6_nbrinfo) ++*/ ++#define TARGET_SIOCSPFXFLUSH_IN6 TARGET_IOWR('i', 79, struct target_in6_ifreq) ++#define TARGET_SIOCSRTRFLUSH_IN6 TARGET_IOWR('i', 80, struct target_in6_ifreq) ++ ++#define TARGET_SIOCGIFALIFETIME_IN6 TARGET_IOWR('i', 81, struct target_in6_ifreq) ++#define TARGET_SIOCSIFALIFETIME_IN6 TARGET_IOWR('i', 82, struct target_in6_ifreq) ++#define TARGET_SIOCGIFSTAT_IN6 TARGET_IOWR('i', 83, struct target_in6_ifreq) ++#define TARGET_SIOCGIFSTAT_ICMP6 TARGET_IOWR('i', 84, struct target_in6_ifreq) ++ ++/* NOT YET ++#define TARGET_SIOCSDEFIFACE_IN6 TARGET_IOWR('i', 85, struct target_in6_ndifreq) ++#define TARGET_SIOCGDEFIFACE_IN6 TARGET_IOWR('i', 86, struct target_in6_ndifreq) ++ ++#define TARGET_SIOCSIFINFO_FLAGS TARGET_IOWR('i', 87, struct target_in6_ndireq) ++*/ ++ ++#define TARGET_SIOCSSCOPE6 TARGET_IOW('i', 88, struct target_in6_ifreq) ++#define TARGET_SIOCGSCOPE6 TARGET_IOWR('i', 89, struct target_in6_ifreq) ++#define TARGET_SIOCGSCOPE6DEF TARGET_IOWR('i', 90, struct target_in6_ifreq) ++ ++/* NOT YET ++#define TARGET_SIOCSIFPREFIX_IN6 TARGET_IOW('i', 100, struct target_in6_prefixreq) ++#define TARGET_SIOCGIFPREFIX_IN6 TARGET_IOWR('i', 101, struct target_in6_prefixreq) ++#define TARGET_SIOCDIFPREFIX_IN6 TARGET_IOW('i', 102, struct target_in6_prefixreq) ++#define TARGET_SIOCAIFPREFIX_IN6 TARGET_IOW('i', 103, struct target_in6_rrenumreq) ++#define TARGET_SIOCCIFPREFIX_IN6 TARGET_IOW('i', 104, struct target_in6_rrenumreq) ++#define TARGET_SIOCSGIFPREFIX_IN6 TARGET_IOW('i', 105, struct target_in6_rrenumreq) ++ ++#define TARGET_SIOCGETSGCNT_IN6 TARGET_IOWR('u', 106, struct target_sioc_sg_req6) ++#define TARGET_SIOCGETMIFCNT_IN6 TARGET_IOWR('u', 107, struct target_sioc_mif_req6) ++ ++#define TARGET_SIOCAADDRCTL_POLICY TARGET_IOW('u', 108, struct target_in6_addrpolicy) ++#define TARGET_SIOCDADDRCTL_POLICY TARGET_IOW('u', 109, struct target_in6_addrpolicy) ++*/ ++ ++#endif /* !_IOCTL_IN6_VAR_H_ */ Property changes on: emulators/qemu-devel/files/extra-patch-fc128b9c49bb87d22772a74829c802117c3ef94f ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property Added: fbsd:nokeywords ## -0,0 +1 ## +yes \ No newline at end of property Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property