diff --git a/exec-all.h b/exec-all.h
index c211242..5374804 100644
--- a/exec-all.h
+++ b/exec-all.h
@@ -256,9 +256,14 @@ static inline void tb_set_jmp_target(TranslationBlock *tb,
 
 #endif
 
+extern bool threaded;
 static inline void tb_add_jump(TranslationBlock *tb, int n,
                                TranslationBlock *tb_next)
 {
+    if (threaded) {
+        /* multi-threaded applications break with TB chaining */
+        return;
+    }
     /* NOTE: this test is only needed for thread safety */
     if (!tb->jmp_next[n]) {
         /* patch the native jump address */
diff --git a/exec.c b/exec.c
index 6b92198..a214097 100644
--- a/exec.c
+++ b/exec.c
@@ -82,6 +82,7 @@ TranslationBlock *tb_phys_hash[CODE_GEN_PHYS_HASH_SIZE];
 static int nb_tbs;
 /* any access to the tbs or the page table must use this lock */
 spinlock_t tb_lock = SPIN_LOCK_UNLOCKED;
+bool threaded;
 
 #if defined(__arm__) || defined(__sparc_v9__)
 /* The prologue must be reachable with a direct jump. ARM and Sparc64
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 312aec5..58ec7a8 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -4010,6 +4010,7 @@ static int do_fork(CPUState *env, unsigned int flags, abi_ulong newsp,
         ts->bprm = parent_ts->bprm;
         ts->info = parent_ts->info;
 #if defined(CONFIG_USE_NPTL)
+        threaded = true;
         nptl_flags = flags;
         flags &= ~CLONE_NPTL_FLAGS2;
 
