Commit 36bdbe5479cebb5765779a430d14daddddcab871

Authored by bellard
1 parent 80043406

fixed TB linking in case of code invalidation (fixes random segfaults)


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@469 c046a42c-6fe2-441c-8c8c-71466251a162
cpu-exec.c
@@ -21,6 +21,8 @@ @@ -21,6 +21,8 @@
21 #include "exec.h" 21 #include "exec.h"
22 #include "disas.h" 22 #include "disas.h"
23 23
  24 +int tb_invalidated_flag;
  25 +
24 //#define DEBUG_EXEC 26 //#define DEBUG_EXEC
25 //#define DEBUG_SIGNAL 27 //#define DEBUG_SIGNAL
26 28
@@ -273,8 +275,17 @@ int cpu_exec(CPUState *env1) @@ -273,8 +275,17 @@ int cpu_exec(CPUState *env1)
273 tb->tc_ptr = tc_ptr; 275 tb->tc_ptr = tc_ptr;
274 tb->cs_base = (unsigned long)cs_base; 276 tb->cs_base = (unsigned long)cs_base;
275 tb->flags = flags; 277 tb->flags = flags;
276 - /* XXX: an MMU exception can occur here */ 278 + tb_invalidated_flag = 0;
277 cpu_gen_code(env, tb, CODE_GEN_MAX_SIZE, &code_gen_size); 279 cpu_gen_code(env, tb, CODE_GEN_MAX_SIZE, &code_gen_size);
  280 + if (tb_invalidated_flag) {
  281 + /* as some TB could have been invalidated because
  282 + of memory exceptions while generating the code, we
  283 + must recompute the hash index here */
  284 + ptb = &tb_hash[tb_hash_func((unsigned long)pc)];
  285 + while (*ptb != NULL)
  286 + ptb = &(*ptb)->hash_next;
  287 + T0 = 0;
  288 + }
278 *ptb = tb; 289 *ptb = tb;
279 tb->hash_next = NULL; 290 tb->hash_next = NULL;
280 tb_link(tb); 291 tb_link(tb);
exec-all.h
@@ -416,6 +416,7 @@ static inline int spin_trylock(spinlock_t *lock) @@ -416,6 +416,7 @@ static inline int spin_trylock(spinlock_t *lock)
416 416
417 extern spinlock_t tb_lock; 417 extern spinlock_t tb_lock;
418 418
  419 +extern int tb_invalidated_flag;
419 420
420 #if defined(TARGET_I386) && !defined(CONFIG_USER_ONLY) 421 #if defined(TARGET_I386) && !defined(CONFIG_USER_ONLY)
421 422
@@ -362,6 +362,8 @@ static inline void tb_invalidate(TranslationBlock *tb, int parity) @@ -362,6 +362,8 @@ static inline void tb_invalidate(TranslationBlock *tb, int parity)
362 unsigned int h, n1; 362 unsigned int h, n1;
363 TranslationBlock *tb1, *tb2; 363 TranslationBlock *tb1, *tb2;
364 364
  365 + tb_invalidated_flag = 1;
  366 +
365 /* remove the TB from the hash list */ 367 /* remove the TB from the hash list */
366 h = tb_hash_func(tb->pc); 368 h = tb_hash_func(tb->pc);
367 tb_remove(&tb_hash[h], tb, 369 tb_remove(&tb_hash[h], tb,