The following patch stops the segfault (which happens because cpu_unlink_tb() is fiddling with the links between tbs without taking the tb_lock, so another thread can come in via eg tb_add_jump() and cause corruption of the linked lists). However, there are a number of comments in the TB handling code about things being non-thread-safe or not SMP safe, so I need to have a more careful think about the whole thing.
diff --git a/exec.c b/exec.c
index db9ff55..5f4a50b 100644
--- a/exec.c
+++ b/exec.c
@@ -1606,9 +1606,8 @@ static void cpu_unlink_tb(CPUState *env)
emulation this often isn't actually as bad as it sounds. Often
signals are used primarily to interrupt blocking syscalls. */
TranslationBlock *tb;
- static spinlock_t interrupt_lock = SPIN_LOCK_UNLOCKED;
- spin_lock(&interrupt_lock);
+ spin_lock(&tb_lock);
tb = env->current_tb;
/* if the cpu is currently executing code, we must unlink it and
all the potentially executing TB */
@@ -1616,7 +1615,7 @@ static void cpu_unlink_tb(CPUState *env) env->current_tb = NULL; tb_reset_jump_recursive(tb);
}
- spin_unlock(&interrupt_lock);
+ spin_unlock(&tb_lock);
}
/* mask must never be zero, except for A20 change call */
The following patch stops the segfault (which happens because cpu_unlink_tb() is fiddling with the links between tbs without taking the tb_lock, so another thread can come in via eg tb_add_jump() and cause corruption of the linked lists). However, there are a number of comments in the TB handling code about things being non-thread-safe or not SMP safe, so I need to have a more careful think about the whole thing.
diff --git a/exec.c b/exec.c tb(CPUState *env) nBlock *tb;
index db9ff55..5f4a50b 100644
--- a/exec.c
+++ b/exec.c
@@ -1606,9 +1606,8 @@ static void cpu_unlink_
emulation this often isn't actually as bad as it sounds. Often
signals are used primarily to interrupt blocking syscalls. */
Translatio
- static spinlock_t interrupt_lock = SPIN_LOCK_UNLOCKED;
- spin_lock( &interrupt_ lock); &tb_lock) ; tb(CPUState *env)
env-> current_ tb = NULL;
tb_reset_ jump_recursive( tb); &interrupt_ lock); &tb_lock) ;
+ spin_lock(
tb = env->current_tb;
/* if the cpu is currently executing code, we must unlink it and
all the potentially executing TB */
@@ -1616,7 +1615,7 @@ static void cpu_unlink_
}
- spin_unlock(
+ spin_unlock(
}
/* mask must never be zero, except for A20 change call */