mirror of https://gitee.com/openkylin/qemu.git
cpu-exec: Do not invalidate original TB in cpu_exec_nocache()
Instead of invalidating an original TB in cpu_exec_nocache() prematurely, just save a link to it in the temporary generated TB. If cpu_io_recompile() is raised subsequently from the temporary TB, invalidate the original one as well. That allows reusing the original TB each time cpu_exec_nocache() is called to handle expired instruction counter in icount mode. Signed-off-by: Sergey Fedorov <serge.fdrv@gmail.com> Message-Id: <1435656909-29116-1-git-send-email-serge.fdrv@gmail.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
This commit is contained in:
parent
af103c9310
commit
02d57ea115
|
@ -231,19 +231,15 @@ static void cpu_exec_nocache(CPUState *cpu, int max_cycles,
|
|||
TranslationBlock *orig_tb)
|
||||
{
|
||||
TranslationBlock *tb;
|
||||
target_ulong pc = orig_tb->pc;
|
||||
target_ulong cs_base = orig_tb->cs_base;
|
||||
uint64_t flags = orig_tb->flags;
|
||||
|
||||
/* Should never happen.
|
||||
We only end up here when an existing TB is too long. */
|
||||
if (max_cycles > CF_COUNT_MASK)
|
||||
max_cycles = CF_COUNT_MASK;
|
||||
|
||||
/* tb_gen_code can flush our orig_tb, invalidate it now */
|
||||
tb_phys_invalidate(orig_tb, -1);
|
||||
tb = tb_gen_code(cpu, pc, cs_base, flags,
|
||||
tb = tb_gen_code(cpu, orig_tb->pc, orig_tb->cs_base, orig_tb->flags,
|
||||
max_cycles | CF_NOCACHE);
|
||||
tb->orig_tb = tcg_ctx.tb_ctx.tb_invalidated_flag ? NULL : orig_tb;
|
||||
cpu->current_tb = tb;
|
||||
/* execute the generated code */
|
||||
trace_exec_tb_nocache(tb, tb->pc);
|
||||
|
|
|
@ -155,6 +155,8 @@ struct TranslationBlock {
|
|||
void *tc_ptr; /* pointer to the translated code */
|
||||
/* next matching tb for physical address. */
|
||||
struct TranslationBlock *phys_hash_next;
|
||||
/* original tb when cflags has CF_NOCACHE */
|
||||
struct TranslationBlock *orig_tb;
|
||||
/* first and second physical page containing code. The lower bit
|
||||
of the pointer tells the index in page_next[] */
|
||||
struct TranslationBlock *page_next[2];
|
||||
|
|
|
@ -1533,6 +1533,14 @@ void cpu_io_recompile(CPUState *cpu, uintptr_t retaddr)
|
|||
cs_base = tb->cs_base;
|
||||
flags = tb->flags;
|
||||
tb_phys_invalidate(tb, -1);
|
||||
if (tb->cflags & CF_NOCACHE) {
|
||||
if (tb->orig_tb) {
|
||||
/* Invalidate original TB if this TB was generated in
|
||||
* cpu_exec_nocache() */
|
||||
tb_phys_invalidate(tb->orig_tb, -1);
|
||||
}
|
||||
tb_free(tb);
|
||||
}
|
||||
/* FIXME: In theory this could raise an exception. In practice
|
||||
we have already translated the block once so it's probably ok. */
|
||||
tb_gen_code(cpu, pc, cs_base, flags, cflags);
|
||||
|
|
Loading…
Reference in New Issue