From 02d57ea115b7669f588371c86484a2e8ebc369be Mon Sep 17 00:00:00 2001 From: Sergey Fedorov Date: Tue, 30 Jun 2015 12:35:09 +0300 Subject: 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 Message-Id: <1435656909-29116-1-git-send-email-serge.fdrv@gmail.com> Signed-off-by: Paolo Bonzini --- include/exec/exec-all.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include/exec') diff --git a/include/exec/exec-all.h b/include/exec/exec-all.h index a6fce04f65..84272253b3 100644 --- a/include/exec/exec-all.h +++ b/include/exec/exec-all.h @@ -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]; -- cgit v1.2.3-55-g7522 From b4a4b8d0e0767c85946fd8fc404643bf5766351a Mon Sep 17 00:00:00 2001 From: Peter Crosthwaite Date: Sun, 5 Jul 2015 14:08:53 -0700 Subject: cpu_defs: Simplify CPUTLB padding logic There was a complicated subtractive arithmetic for determining the padding on the CPUTLBEntry structure. Simplify this with a union. Signed-off-by: Peter Crosthwaite Message-Id: <1436130533-18565-1-git-send-email-crosthwaite.peter@gmail.com> Signed-off-by: Paolo Bonzini --- include/exec/cpu-defs.h | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) (limited to 'include/exec') diff --git a/include/exec/cpu-defs.h b/include/exec/cpu-defs.h index 98b9cff310..5093be26ac 100644 --- a/include/exec/cpu-defs.h +++ b/include/exec/cpu-defs.h @@ -105,17 +105,18 @@ typedef struct CPUTLBEntry { bit 3 : indicates that the entry is invalid bit 2..0 : zero */ - target_ulong addr_read; - target_ulong addr_write; - target_ulong addr_code; - /* Addend to virtual address to get host address. IO accesses - use the corresponding iotlb value. */ - uintptr_t addend; - /* padding to get a power of two size */ - uint8_t dummy[(1 << CPU_TLB_ENTRY_BITS) - - (sizeof(target_ulong) * 3 + - ((-sizeof(target_ulong) * 3) & (sizeof(uintptr_t) - 1)) + - sizeof(uintptr_t))]; + union { + struct { + target_ulong addr_read; + target_ulong addr_write; + target_ulong addr_code; + /* Addend to virtual address to get host address. IO accesses + use the corresponding iotlb value. */ + uintptr_t addend; + }; + /* padding to get a power of two size */ + uint8_t dummy[1 << CPU_TLB_ENTRY_BITS]; + }; } CPUTLBEntry; QEMU_BUILD_BUG_ON(sizeof(CPUTLBEntry) != (1 << CPU_TLB_ENTRY_BITS)); -- cgit v1.2.3-55-g7522 From 414b15c909c88e4cf5f10e80d033b3aa90bcc9e1 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Wed, 24 Jun 2015 14:16:26 +0200 Subject: 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 --- cpu-exec.c | 2 +- cpus.c | 2 +- include/exec/exec-all.h | 21 --------------------- include/qom/cpu.h | 4 +++- qom/cpu.c | 2 +- softmmu_template.h | 4 ++-- translate-all.c | 3 ++- 7 files changed, 10 insertions(+), 28 deletions(-) (limited to 'include/exec') diff --git a/cpu-exec.c b/cpu-exec.c index 407fa4715a..713540fc8f 100644 --- a/cpu-exec.c +++ b/cpu-exec.c @@ -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), diff --git a/cpus.c b/cpus.c index a822ce3d80..c1e74d9824 100644 --- a/cpus.c +++ b/cpus.c @@ -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 84272253b3..29775c012c 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 20aabc9cb3..39712ab7cb 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. diff --git a/qom/cpu.c b/qom/cpu.c index eb9cfeca18..62f4b5de44 100644 --- a/qom/cpu.c +++ b/qom/cpu.c @@ -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 d42d89d541..50dec1c510 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 755cdaba9c..9c46ffa0e3 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"); } -- cgit v1.2.3-55-g7522