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>
This commit is contained in:
parent
b4a4b8d0e0
commit
414b15c909
@ -196,7 +196,7 @@ static inline tcg_target_ulong cpu_tb_exec(CPUState *cpu, uint8_t *tb_ptr)
|
|||||||
}
|
}
|
||||||
#endif /* DEBUG_DISAS */
|
#endif /* DEBUG_DISAS */
|
||||||
|
|
||||||
cpu->can_do_io = 0;
|
cpu->can_do_io = !use_icount;
|
||||||
next_tb = tcg_qemu_tb_exec(env, tb_ptr);
|
next_tb = tcg_qemu_tb_exec(env, tb_ptr);
|
||||||
cpu->can_do_io = 1;
|
cpu->can_do_io = 1;
|
||||||
trace_exec_tb_exit((void *) (next_tb & ~TB_EXIT_MASK),
|
trace_exec_tb_exit((void *) (next_tb & ~TB_EXIT_MASK),
|
||||||
|
2
cpus.c
2
cpus.c
@ -145,7 +145,7 @@ int64_t cpu_get_icount_raw(void)
|
|||||||
|
|
||||||
icount = timers_state.qemu_icount;
|
icount = timers_state.qemu_icount;
|
||||||
if (cpu) {
|
if (cpu) {
|
||||||
if (!cpu_can_do_io(cpu)) {
|
if (!cpu->can_do_io) {
|
||||||
fprintf(stderr, "Bad icount read\n");
|
fprintf(stderr, "Bad icount read\n");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
@ -346,27 +346,6 @@ extern int singlestep;
|
|||||||
/* cpu-exec.c */
|
/* cpu-exec.c */
|
||||||
extern volatile sig_atomic_t exit_request;
|
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)
|
#if !defined(CONFIG_USER_ONLY)
|
||||||
void migration_bitmap_extend(ram_addr_t old, ram_addr_t new);
|
void migration_bitmap_extend(ram_addr_t old, ram_addr_t new);
|
||||||
#endif
|
#endif
|
||||||
|
@ -231,7 +231,9 @@ struct kvm_run;
|
|||||||
* @icount_decr: Number of cycles left, with interrupt flag in high bit.
|
* @icount_decr: Number of cycles left, with interrupt flag in high bit.
|
||||||
* This allows a single read-compare-cbranch-write sequence to test
|
* This allows a single read-compare-cbranch-write sequence to test
|
||||||
* for both decrementer underflow and exceptions.
|
* 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.
|
* @env_ptr: Pointer to subclass-specific CPUArchState field.
|
||||||
* @current_tb: Currently executing TB.
|
* @current_tb: Currently executing TB.
|
||||||
* @gdb_regs: Additional GDB registers.
|
* @gdb_regs: Additional GDB registers.
|
||||||
|
@ -247,7 +247,7 @@ static void cpu_common_reset(CPUState *cpu)
|
|||||||
cpu->mem_io_vaddr = 0;
|
cpu->mem_io_vaddr = 0;
|
||||||
cpu->icount_extra = 0;
|
cpu->icount_extra = 0;
|
||||||
cpu->icount_decr.u32 = 0;
|
cpu->icount_decr.u32 = 0;
|
||||||
cpu->can_do_io = 0;
|
cpu->can_do_io = 1;
|
||||||
cpu->exception_index = -1;
|
cpu->exception_index = -1;
|
||||||
memset(cpu->tb_jmp_cache, 0, TB_JMP_CACHE_SIZE * sizeof(void *));
|
memset(cpu->tb_jmp_cache, 0, TB_JMP_CACHE_SIZE * sizeof(void *));
|
||||||
}
|
}
|
||||||
|
@ -154,7 +154,7 @@ static inline DATA_TYPE glue(io_read, SUFFIX)(CPUArchState *env,
|
|||||||
|
|
||||||
physaddr = (physaddr & TARGET_PAGE_MASK) + addr;
|
physaddr = (physaddr & TARGET_PAGE_MASK) + addr;
|
||||||
cpu->mem_io_pc = retaddr;
|
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);
|
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);
|
MemoryRegion *mr = iotlb_to_region(cpu, physaddr);
|
||||||
|
|
||||||
physaddr = (physaddr & TARGET_PAGE_MASK) + addr;
|
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);
|
cpu_io_recompile(cpu, retaddr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -222,6 +222,7 @@ static int cpu_restore_state_from_tb(CPUState *cpu, TranslationBlock *tb,
|
|||||||
gen_intermediate_code_pc(env, tb);
|
gen_intermediate_code_pc(env, tb);
|
||||||
|
|
||||||
if (tb->cflags & CF_USE_ICOUNT) {
|
if (tb->cflags & CF_USE_ICOUNT) {
|
||||||
|
assert(use_icount);
|
||||||
/* Reset the cycle counter to the start of the block. */
|
/* Reset the cycle counter to the start of the block. */
|
||||||
cpu->icount_decr.u16.low += tb->icount;
|
cpu->icount_decr.u16.low += tb->icount;
|
||||||
/* Clear the IO flag. */
|
/* Clear the IO flag. */
|
||||||
@ -1470,7 +1471,7 @@ static void tcg_handle_interrupt(CPUState *cpu, int mask)
|
|||||||
|
|
||||||
if (use_icount) {
|
if (use_icount) {
|
||||||
cpu->icount_decr.u16.high = 0xffff;
|
cpu->icount_decr.u16.high = 0xffff;
|
||||||
if (!cpu_can_do_io(cpu)
|
if (!cpu->can_do_io
|
||||||
&& (mask & ~old_mask) != 0) {
|
&& (mask & ~old_mask) != 0) {
|
||||||
cpu_abort(cpu, "Raised interrupt while not in I/O function");
|
cpu_abort(cpu, "Raised interrupt while not in I/O function");
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user