diff options
author | Paolo Bonzini <pbonzini@redhat.com> | 2015-06-24 14:16:26 +0200 |
---|---|---|
committer | Paolo Bonzini <pbonzini@redhat.com> | 2015-08-14 23:40:32 +0200 |
commit | 414b15c909c88e4cf5f10e80d033b3aa90bcc9e1 (patch) | |
tree | 04d817361a25bc06a6243d5cfcf693017fe4bc5c | |
parent | b4a4b8d0e0767c85946fd8fc404643bf5766351a (diff) | |
download | qemu-414b15c909c88e4cf5f10e80d033b3aa90bcc9e1.zip qemu-414b15c909c88e4cf5f10e80d033b3aa90bcc9e1.tar.gz qemu-414b15c909c88e4cf5f10e80d033b3aa90bcc9e1.tar.bz2 |
exec: drop cpu_can_do_io, just read cpu->can_do_io
After commit 626cf8f (icount: set can_do_io outside TB execution,
2014-12-08), can_do_io is set to 1 if not executing code. It is
no longer necessary to make this assumption in cpu_can_do_io.
It is also possible to remove the use_icount test, simply by
never setting cpu->can_do_io to 0 unless use_icount is true.
With these changes cpu_can_do_io boils down to a read of
cpu->can_do_io.
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
-rw-r--r-- | cpu-exec.c | 2 | ||||
-rw-r--r-- | cpus.c | 2 | ||||
-rw-r--r-- | include/exec/exec-all.h | 21 | ||||
-rw-r--r-- | include/qom/cpu.h | 4 | ||||
-rw-r--r-- | qom/cpu.c | 2 | ||||
-rw-r--r-- | softmmu_template.h | 4 | ||||
-rw-r--r-- | translate-all.c | 3 |
7 files changed, 10 insertions, 28 deletions
@@ -196,7 +196,7 @@ static inline tcg_target_ulong cpu_tb_exec(CPUState *cpu, uint8_t *tb_ptr) } #endif /* DEBUG_DISAS */ - cpu->can_do_io = 0; + cpu->can_do_io = !use_icount; next_tb = tcg_qemu_tb_exec(env, tb_ptr); cpu->can_do_io = 1; trace_exec_tb_exit((void *) (next_tb & ~TB_EXIT_MASK), @@ -145,7 +145,7 @@ int64_t cpu_get_icount_raw(void) icount = timers_state.qemu_icount; if (cpu) { - if (!cpu_can_do_io(cpu)) { + if (!cpu->can_do_io) { fprintf(stderr, "Bad icount read\n"); exit(1); } diff --git a/include/exec/exec-all.h b/include/exec/exec-all.h index 8427225..29775c0 100644 --- a/include/exec/exec-all.h +++ b/include/exec/exec-all.h @@ -346,27 +346,6 @@ extern int singlestep; /* cpu-exec.c */ extern volatile sig_atomic_t exit_request; -/** - * cpu_can_do_io: - * @cpu: The CPU for which to check IO. - * - * Deterministic execution requires that IO only be performed on the last - * instruction of a TB so that interrupts take effect immediately. - * - * Returns: %true if memory-mapped IO is safe, %false otherwise. - */ -static inline bool cpu_can_do_io(CPUState *cpu) -{ - if (!use_icount) { - return true; - } - /* If not executing code then assume we are ok. */ - if (cpu->current_tb == NULL) { - return true; - } - return cpu->can_do_io != 0; -} - #if !defined(CONFIG_USER_ONLY) void migration_bitmap_extend(ram_addr_t old, ram_addr_t new); #endif diff --git a/include/qom/cpu.h b/include/qom/cpu.h index 20aabc9..39712ab 100644 --- a/include/qom/cpu.h +++ b/include/qom/cpu.h @@ -231,7 +231,9 @@ struct kvm_run; * @icount_decr: Number of cycles left, with interrupt flag in high bit. * This allows a single read-compare-cbranch-write sequence to test * for both decrementer underflow and exceptions. - * @can_do_io: Nonzero if memory-mapped IO is safe. + * @can_do_io: Nonzero if memory-mapped IO is safe. Deterministic execution + * requires that IO only be performed on the last instruction of a TB + * so that interrupts take effect immediately. * @env_ptr: Pointer to subclass-specific CPUArchState field. * @current_tb: Currently executing TB. * @gdb_regs: Additional GDB registers. @@ -247,7 +247,7 @@ static void cpu_common_reset(CPUState *cpu) cpu->mem_io_vaddr = 0; cpu->icount_extra = 0; cpu->icount_decr.u32 = 0; - cpu->can_do_io = 0; + cpu->can_do_io = 1; cpu->exception_index = -1; memset(cpu->tb_jmp_cache, 0, TB_JMP_CACHE_SIZE * sizeof(void *)); } diff --git a/softmmu_template.h b/softmmu_template.h index d42d89d..50dec1c 100644 --- a/softmmu_template.h +++ b/softmmu_template.h @@ -154,7 +154,7 @@ static inline DATA_TYPE glue(io_read, SUFFIX)(CPUArchState *env, physaddr = (physaddr & TARGET_PAGE_MASK) + addr; cpu->mem_io_pc = retaddr; - if (mr != &io_mem_rom && mr != &io_mem_notdirty && !cpu_can_do_io(cpu)) { + if (mr != &io_mem_rom && mr != &io_mem_notdirty && !cpu->can_do_io) { cpu_io_recompile(cpu, retaddr); } @@ -374,7 +374,7 @@ static inline void glue(io_write, SUFFIX)(CPUArchState *env, MemoryRegion *mr = iotlb_to_region(cpu, physaddr); physaddr = (physaddr & TARGET_PAGE_MASK) + addr; - if (mr != &io_mem_rom && mr != &io_mem_notdirty && !cpu_can_do_io(cpu)) { + if (mr != &io_mem_rom && mr != &io_mem_notdirty && !cpu->can_do_io) { cpu_io_recompile(cpu, retaddr); } diff --git a/translate-all.c b/translate-all.c index 755cdab..9c46ffa 100644 --- a/translate-all.c +++ b/translate-all.c @@ -222,6 +222,7 @@ static int cpu_restore_state_from_tb(CPUState *cpu, TranslationBlock *tb, gen_intermediate_code_pc(env, tb); if (tb->cflags & CF_USE_ICOUNT) { + assert(use_icount); /* Reset the cycle counter to the start of the block. */ cpu->icount_decr.u16.low += tb->icount; /* Clear the IO flag. */ @@ -1470,7 +1471,7 @@ static void tcg_handle_interrupt(CPUState *cpu, int mask) if (use_icount) { cpu->icount_decr.u16.high = 0xffff; - if (!cpu_can_do_io(cpu) + if (!cpu->can_do_io && (mask & ~old_mask) != 0) { cpu_abort(cpu, "Raised interrupt while not in I/O function"); } |