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
This commit is contained in:
		
							parent
							
								
									8004340674
								
							
						
					
					
						commit
						36bdbe5479
					
				
							
								
								
									
										13
									
								
								cpu-exec.c
									
									
									
									
									
								
							
							
						
						
									
										13
									
								
								cpu-exec.c
									
									
									
									
									
								
							@ -21,6 +21,8 @@
 | 
				
			|||||||
#include "exec.h"
 | 
					#include "exec.h"
 | 
				
			||||||
#include "disas.h"
 | 
					#include "disas.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int tb_invalidated_flag;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
//#define DEBUG_EXEC
 | 
					//#define DEBUG_EXEC
 | 
				
			||||||
//#define DEBUG_SIGNAL
 | 
					//#define DEBUG_SIGNAL
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -273,8 +275,17 @@ int cpu_exec(CPUState *env1)
 | 
				
			|||||||
                    tb->tc_ptr = tc_ptr;
 | 
					                    tb->tc_ptr = tc_ptr;
 | 
				
			||||||
                    tb->cs_base = (unsigned long)cs_base;
 | 
					                    tb->cs_base = (unsigned long)cs_base;
 | 
				
			||||||
                    tb->flags = flags;
 | 
					                    tb->flags = flags;
 | 
				
			||||||
                    /* XXX: an MMU exception can occur here */
 | 
					                    tb_invalidated_flag = 0;
 | 
				
			||||||
                    cpu_gen_code(env, tb, CODE_GEN_MAX_SIZE, &code_gen_size);
 | 
					                    cpu_gen_code(env, tb, CODE_GEN_MAX_SIZE, &code_gen_size);
 | 
				
			||||||
 | 
					                    if (tb_invalidated_flag) {
 | 
				
			||||||
 | 
					                        /* as some TB could have been invalidated because
 | 
				
			||||||
 | 
					                           of memory exceptions while generating the code, we
 | 
				
			||||||
 | 
					                           must recompute the hash index here */
 | 
				
			||||||
 | 
					                        ptb = &tb_hash[tb_hash_func((unsigned long)pc)];
 | 
				
			||||||
 | 
					                        while (*ptb != NULL)
 | 
				
			||||||
 | 
					                            ptb = &(*ptb)->hash_next;
 | 
				
			||||||
 | 
					                        T0 = 0;
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
                    *ptb = tb;
 | 
					                    *ptb = tb;
 | 
				
			||||||
                    tb->hash_next = NULL;
 | 
					                    tb->hash_next = NULL;
 | 
				
			||||||
                    tb_link(tb);
 | 
					                    tb_link(tb);
 | 
				
			||||||
 | 
				
			|||||||
@ -416,6 +416,7 @@ static inline int spin_trylock(spinlock_t *lock)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
extern spinlock_t tb_lock;
 | 
					extern spinlock_t tb_lock;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					extern int tb_invalidated_flag;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#if defined(TARGET_I386) && !defined(CONFIG_USER_ONLY)
 | 
					#if defined(TARGET_I386) && !defined(CONFIG_USER_ONLY)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										2
									
								
								exec.c
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								exec.c
									
									
									
									
									
								
							@ -362,6 +362,8 @@ static inline void tb_invalidate(TranslationBlock *tb, int parity)
 | 
				
			|||||||
    unsigned int h, n1;
 | 
					    unsigned int h, n1;
 | 
				
			||||||
    TranslationBlock *tb1, *tb2;
 | 
					    TranslationBlock *tb1, *tb2;
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
 | 
					    tb_invalidated_flag = 1;
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
    /* remove the TB from the hash list */
 | 
					    /* remove the TB from the hash list */
 | 
				
			||||||
    h = tb_hash_func(tb->pc);
 | 
					    h = tb_hash_func(tb->pc);
 | 
				
			||||||
    tb_remove(&tb_hash[h], tb, 
 | 
					    tb_remove(&tb_hash[h], tb, 
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user