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…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user