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 21 #include "exec.h"
22 22 #include "disas.h"
23 23  
  24 +int tb_invalidated_flag;
  25 +
24 26 //#define DEBUG_EXEC
25 27 //#define DEBUG_SIGNAL
26 28  
... ... @@ -273,8 +275,17 @@ int cpu_exec(CPUState *env1)
273 275 tb->tc_ptr = tc_ptr;
274 276 tb->cs_base = (unsigned long)cs_base;
275 277 tb->flags = flags;
276   - /* XXX: an MMU exception can occur here */
  278 + tb_invalidated_flag = 0;
277 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 289 *ptb = tb;
279 290 tb->hash_next = NULL;
280 291 tb_link(tb);
... ...
exec-all.h
... ... @@ -416,6 +416,7 @@ static inline int spin_trylock(spinlock_t *lock)
416 416  
417 417 extern spinlock_t tb_lock;
418 418  
  419 +extern int tb_invalidated_flag;
419 420  
420 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 362 unsigned int h, n1;
363 363 TranslationBlock *tb1, *tb2;
364 364  
  365 + tb_invalidated_flag = 1;
  366 +
365 367 /* remove the TB from the hash list */
366 368 h = tb_hash_func(tb->pc);
367 369 tb_remove(&tb_hash[h], tb,
... ...