mirror of
https://github.com/yuzu-emu/unicorn.git
synced 2025-01-11 02:15:37 +00:00
tcg: Prepare safe tb_jmp_cache lookup out of tb_lock
Ensure atomicity of CPU's 'tb_jmp_cache' access for future translation block lookup out of 'tb_lock'. Note that this patch does *not* make CPU's TLB invalidation safe if it is done from some other thread while the CPU is in its execution loop. Backports commit 89a16b1e4294e3664667a151c2f70c84dfac6fd9 from qemu
This commit is contained in:
parent
371101a184
commit
9eb02a540d
|
@ -175,7 +175,7 @@ static TranslationBlock *tb_find_slow(CPUState *cpu,
|
|||
|
||||
found:
|
||||
/* we add the TB in the virtual pc hash table */
|
||||
cpu->tb_jmp_cache[tb_jmp_cache_hash_func(pc)] = tb;
|
||||
atomic_set(&cpu->tb_jmp_cache[tb_jmp_cache_hash_func(pc)], tb);
|
||||
return tb;
|
||||
}
|
||||
|
||||
|
@ -194,7 +194,8 @@ static inline TranslationBlock *tb_find_fast(CPUState *cpu,
|
|||
cpu_get_tb_cpu_state(env, &pc, &cs_base, &flags);
|
||||
// Unicorn: commented out
|
||||
//tb_lock();
|
||||
tb = cpu->tb_jmp_cache[tb_jmp_cache_hash_func(pc)];
|
||||
// Unicorn: atomic_read used instead of atomic_rcu_read
|
||||
tb = atomic_read(&cpu->tb_jmp_cache[tb_jmp_cache_hash_func(pc)]);
|
||||
if (unlikely(!tb || tb->pc != pc || tb->cs_base != cs_base ||
|
||||
tb->flags != flags)) {
|
||||
tb = tb_find_slow(cpu, pc, cs_base, flags);
|
||||
|
|
|
@ -904,6 +904,7 @@ void tb_flush(CPUState *cpu)
|
|||
{
|
||||
struct uc_struct* uc = cpu->uc;
|
||||
TCGContext *tcg_ctx = uc->tcg_ctx;
|
||||
int i;
|
||||
|
||||
#if defined(DEBUG_FLUSH)
|
||||
printf("qemu: flush code_size=%ld nb_tbs=%d avg_tb_size=%ld\n",
|
||||
|
@ -918,7 +919,9 @@ void tb_flush(CPUState *cpu)
|
|||
}
|
||||
tcg_ctx->tb_ctx.nb_tbs = 0;
|
||||
|
||||
memset(cpu->tb_jmp_cache, 0, sizeof(cpu->tb_jmp_cache));
|
||||
for (i = 0; i < TB_JMP_CACHE_SIZE; ++i) {
|
||||
atomic_set(&cpu->tb_jmp_cache[i], NULL);
|
||||
}
|
||||
cpu->tb_flushed = true;
|
||||
|
||||
memset(tcg_ctx->tb_ctx.tb_phys_hash, 0, sizeof(tcg_ctx->tb_ctx.tb_phys_hash));
|
||||
|
@ -1092,8 +1095,8 @@ void tb_phys_invalidate(struct uc_struct *uc,
|
|||
|
||||
/* remove the TB from the hash list */
|
||||
h = tb_jmp_cache_hash_func(tb->pc);
|
||||
if (cpu->tb_jmp_cache[h] == tb) {
|
||||
cpu->tb_jmp_cache[h] = NULL;
|
||||
if (atomic_read(&cpu->tb_jmp_cache[h]) == tb) {
|
||||
atomic_set(&cpu->tb_jmp_cache[h], NULL);
|
||||
}
|
||||
|
||||
/* suppress this TB from the two jump lists */
|
||||
|
|
Loading…
Reference in a new issue