diff options
author | edgar_igl <edgar_igl@c046a42c-6fe2-441c-8c8c-71466251a162> | 2008-05-06 08:44:21 +0000 |
---|---|---|
committer | edgar_igl <edgar_igl@c046a42c-6fe2-441c-8c8c-71466251a162> | 2008-05-06 08:44:21 +0000 |
commit | 5c751e99c3ed3bbbf4610f64141fe4c00e843b71 (patch) | |
tree | 0304849e4dc38e54aca4ca75ae8fd6504c4d54a9 /exec.c | |
parent | b5e19d4ce7a1af127ee3c84bd724594904f0f173 (diff) |
Make sure we flush cached blocks from the tb-jmp-cache when we replace valid tlb entries.
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4352 c046a42c-6fe2-441c-8c8c-71466251a162
Diffstat (limited to 'exec.c')
-rw-r--r-- | exec.c | 28 |
1 files changed, 20 insertions, 8 deletions
@@ -1366,6 +1366,21 @@ CPUState *cpu_copy(CPUState *env) #if !defined(CONFIG_USER_ONLY) +static inline void tlb_flush_jmp_cache(CPUState *env, target_ulong addr) +{ + unsigned int i; + + /* Discard jump cache entries for any tb which might potentially + overlap the flushed page. */ + i = tb_jmp_cache_hash_page(addr - TARGET_PAGE_SIZE); + memset (&env->tb_jmp_cache[i], 0, + TB_JMP_PAGE_SIZE * sizeof(TranslationBlock *)); + + i = tb_jmp_cache_hash_page(addr); + memset (&env->tb_jmp_cache[i], 0, + TB_JMP_PAGE_SIZE * sizeof(TranslationBlock *)); +} + /* NOTE: if flush_global is true, also flush global entries (not implemented yet) */ void tlb_flush(CPUState *env, int flush_global) @@ -1428,7 +1443,6 @@ static inline void tlb_flush_entry(CPUTLBEntry *tlb_entry, target_ulong addr) void tlb_flush_page(CPUState *env, target_ulong addr) { int i; - TranslationBlock *tb; #if defined(DEBUG_TLB) printf("tlb_flush_page: " TARGET_FMT_lx "\n", addr); @@ -1448,13 +1462,7 @@ void tlb_flush_page(CPUState *env, target_ulong addr) #endif #endif - /* Discard jump cache entries for any tb which might potentially - overlap the flushed page. */ - i = tb_jmp_cache_hash_page(addr - TARGET_PAGE_SIZE); - memset (&env->tb_jmp_cache[i], 0, TB_JMP_PAGE_SIZE * sizeof(tb)); - - i = tb_jmp_cache_hash_page(addr); - memset (&env->tb_jmp_cache[i], 0, TB_JMP_PAGE_SIZE * sizeof(tb)); + tlb_flush_jmp_cache(env, addr); #if !defined(CONFIG_SOFTMMU) if (addr < MMAP_AREA_END) @@ -1706,6 +1714,10 @@ int tlb_set_page_exec(CPUState *env, target_ulong vaddr, } else { te->addr_read = -1; } + + if (te->addr_code != -1) { + tlb_flush_jmp_cache(env, te->addr_code); + } if (prot & PAGE_EXEC) { te->addr_code = address; } else { |