Commit 5c751e99c3ed3bbbf4610f64141fe4c00e843b71
1 parent
b5e19d4c
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
Showing
1 changed file
with
20 additions
and
8 deletions
exec.c
| @@ -1366,6 +1366,21 @@ CPUState *cpu_copy(CPUState *env) | @@ -1366,6 +1366,21 @@ CPUState *cpu_copy(CPUState *env) | ||
| 1366 | 1366 | ||
| 1367 | #if !defined(CONFIG_USER_ONLY) | 1367 | #if !defined(CONFIG_USER_ONLY) |
| 1368 | 1368 | ||
| 1369 | +static inline void tlb_flush_jmp_cache(CPUState *env, target_ulong addr) | ||
| 1370 | +{ | ||
| 1371 | + unsigned int i; | ||
| 1372 | + | ||
| 1373 | + /* Discard jump cache entries for any tb which might potentially | ||
| 1374 | + overlap the flushed page. */ | ||
| 1375 | + i = tb_jmp_cache_hash_page(addr - TARGET_PAGE_SIZE); | ||
| 1376 | + memset (&env->tb_jmp_cache[i], 0, | ||
| 1377 | + TB_JMP_PAGE_SIZE * sizeof(TranslationBlock *)); | ||
| 1378 | + | ||
| 1379 | + i = tb_jmp_cache_hash_page(addr); | ||
| 1380 | + memset (&env->tb_jmp_cache[i], 0, | ||
| 1381 | + TB_JMP_PAGE_SIZE * sizeof(TranslationBlock *)); | ||
| 1382 | +} | ||
| 1383 | + | ||
| 1369 | /* NOTE: if flush_global is true, also flush global entries (not | 1384 | /* NOTE: if flush_global is true, also flush global entries (not |
| 1370 | implemented yet) */ | 1385 | implemented yet) */ |
| 1371 | void tlb_flush(CPUState *env, int flush_global) | 1386 | void tlb_flush(CPUState *env, int flush_global) |
| @@ -1428,7 +1443,6 @@ static inline void tlb_flush_entry(CPUTLBEntry *tlb_entry, target_ulong addr) | @@ -1428,7 +1443,6 @@ static inline void tlb_flush_entry(CPUTLBEntry *tlb_entry, target_ulong addr) | ||
| 1428 | void tlb_flush_page(CPUState *env, target_ulong addr) | 1443 | void tlb_flush_page(CPUState *env, target_ulong addr) |
| 1429 | { | 1444 | { |
| 1430 | int i; | 1445 | int i; |
| 1431 | - TranslationBlock *tb; | ||
| 1432 | 1446 | ||
| 1433 | #if defined(DEBUG_TLB) | 1447 | #if defined(DEBUG_TLB) |
| 1434 | printf("tlb_flush_page: " TARGET_FMT_lx "\n", addr); | 1448 | printf("tlb_flush_page: " TARGET_FMT_lx "\n", addr); |
| @@ -1448,13 +1462,7 @@ void tlb_flush_page(CPUState *env, target_ulong addr) | @@ -1448,13 +1462,7 @@ void tlb_flush_page(CPUState *env, target_ulong addr) | ||
| 1448 | #endif | 1462 | #endif |
| 1449 | #endif | 1463 | #endif |
| 1450 | 1464 | ||
| 1451 | - /* Discard jump cache entries for any tb which might potentially | ||
| 1452 | - overlap the flushed page. */ | ||
| 1453 | - i = tb_jmp_cache_hash_page(addr - TARGET_PAGE_SIZE); | ||
| 1454 | - memset (&env->tb_jmp_cache[i], 0, TB_JMP_PAGE_SIZE * sizeof(tb)); | ||
| 1455 | - | ||
| 1456 | - i = tb_jmp_cache_hash_page(addr); | ||
| 1457 | - memset (&env->tb_jmp_cache[i], 0, TB_JMP_PAGE_SIZE * sizeof(tb)); | 1465 | + tlb_flush_jmp_cache(env, addr); |
| 1458 | 1466 | ||
| 1459 | #if !defined(CONFIG_SOFTMMU) | 1467 | #if !defined(CONFIG_SOFTMMU) |
| 1460 | if (addr < MMAP_AREA_END) | 1468 | if (addr < MMAP_AREA_END) |
| @@ -1706,6 +1714,10 @@ int tlb_set_page_exec(CPUState *env, target_ulong vaddr, | @@ -1706,6 +1714,10 @@ int tlb_set_page_exec(CPUState *env, target_ulong vaddr, | ||
| 1706 | } else { | 1714 | } else { |
| 1707 | te->addr_read = -1; | 1715 | te->addr_read = -1; |
| 1708 | } | 1716 | } |
| 1717 | + | ||
| 1718 | + if (te->addr_code != -1) { | ||
| 1719 | + tlb_flush_jmp_cache(env, te->addr_code); | ||
| 1720 | + } | ||
| 1709 | if (prot & PAGE_EXEC) { | 1721 | if (prot & PAGE_EXEC) { |
| 1710 | te->addr_code = address; | 1722 | te->addr_code = address; |
| 1711 | } else { | 1723 | } else { |