From patchwork Tue Jul 1 11:26:29 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Pavel Dovgalyuk X-Patchwork-Id: 366055 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id C975B1400AF for ; Tue, 1 Jul 2014 21:27:47 +1000 (EST) Received: from localhost ([::1]:46271 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1X1wDy-0007GD-0P for incoming@patchwork.ozlabs.org; Tue, 01 Jul 2014 07:27:46 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:58723) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1X1wCr-0005RH-UY for qemu-devel@nongnu.org; Tue, 01 Jul 2014 07:26:45 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1X1wCj-0001ut-AE for qemu-devel@nongnu.org; Tue, 01 Jul 2014 07:26:37 -0400 Received: from mail.ispras.ru ([83.149.199.45]:33203) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1X1wCi-0001ug-V3 for qemu-devel@nongnu.org; Tue, 01 Jul 2014 07:26:29 -0400 Received: from PASHAISP (unknown [80.250.189.177]) by mail.ispras.ru (Postfix) with ESMTPSA id 35538540159 for ; Tue, 1 Jul 2014 15:26:28 +0400 (MSK) From: "Pavel Dovgaluk" To: "'QEMU Developers'" Date: Tue, 1 Jul 2014 15:26:29 +0400 Message-ID: <008001cf951f$4ddb3490$e9919db0$@Dovgaluk@ispras.ru> MIME-Version: 1.0 X-Mailer: Microsoft Office Outlook 12.0 Thread-Index: Ac+VH02WarRrh6mxTMitGIepLna7NA== Content-Language: ru X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x X-Received-From: 83.149.199.45 Subject: [Qemu-devel] [RFC PATCH 12/22] cpu_ld/cpu_st bugfix X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org MMU helper functions are called from generated code and other helper functions. In both cases they try to get function's return address for using it while restoring virtual CPU state. When MMU helper is called from some other helper function (like helper_maskmov_xmm) through cpu_st* function, the return address will point to that helper. That is why CPU state cannot be restored in the case of MMU fault. This patch introduces several inline helpers to load return address which points to the right place. Signed-off-by: Pavel Dovgalyuk diff --git a/include/exec/cpu_ldst_template.h b/include/exec/cpu_ldst_template.h index 006093a..10d9f8f 100644 --- a/include/exec/cpu_ldst_template.h +++ b/include/exec/cpu_ldst_template.h @@ -61,6 +61,16 @@ #define MMUSUFFIX _mmu #endif +/* inline helper ld function */ + +static inline DATA_TYPE +glue(glue(helper_inline_ld, SUFFIX), MEMSUFFIX)(CPUArchState *env, target_ulong addr, + int mmu_idx) +{ + return glue(glue(helper_call_ld, SUFFIX), MMUSUFFIX)(env, addr, mmu_idx, + GETRA()); +} + /* generic load/store macros */ static inline RES_TYPE @@ -76,7 +86,7 @@ glue(glue(cpu_ld, USUFFIX), MEMSUFFIX)(CPUArchState *env, target_ulong ptr) mmu_idx = CPU_MMU_INDEX; if (unlikely(env->tlb_table[mmu_idx][page_index].ADDR_READ != (addr & (TARGET_PAGE_MASK | (DATA_SIZE - 1))))) { - res = glue(glue(helper_ld, SUFFIX), MMUSUFFIX)(env, addr, mmu_idx); + res = glue(glue(helper_inline_ld, SUFFIX), MEMSUFFIX)(env, addr, mmu_idx); } else { uintptr_t hostaddr = addr + env->tlb_table[mmu_idx][page_index].addend; res = glue(glue(ld, USUFFIX), _raw)(hostaddr); @@ -97,8 +107,8 @@ glue(glue(cpu_lds, SUFFIX), MEMSUFFIX)(CPUArchState *env, target_ulong ptr) mmu_idx = CPU_MMU_INDEX; if (unlikely(env->tlb_table[mmu_idx][page_index].ADDR_READ != (addr & (TARGET_PAGE_MASK | (DATA_SIZE - 1))))) { - res = (DATA_STYPE)glue(glue(helper_ld, SUFFIX), - MMUSUFFIX)(env, addr, mmu_idx); + res = (DATA_STYPE)glue(glue(helper_inline_ld, SUFFIX), + MEMSUFFIX)(env, addr, mmu_idx); } else { uintptr_t hostaddr = addr + env->tlb_table[mmu_idx][page_index].addend; res = glue(glue(lds, SUFFIX), _raw)(hostaddr); @@ -109,6 +119,16 @@ glue(glue(cpu_lds, SUFFIX), MEMSUFFIX)(CPUArchState *env, target_ulong ptr) #ifndef SOFTMMU_CODE_ACCESS +/* inline helper st function */ + +static inline void +glue(glue(helper_inline_st, SUFFIX), MEMSUFFIX)(CPUArchState *env, target_ulong addr, + DATA_TYPE val, int mmu_idx) +{ + glue(glue(helper_call_st, SUFFIX), MMUSUFFIX)(env, addr, val, mmu_idx, + GETRA()); +} + /* generic store macro */ static inline void @@ -124,7 +144,7 @@ glue(glue(cpu_st, SUFFIX), MEMSUFFIX)(CPUArchState *env, target_ulong ptr, mmu_idx = CPU_MMU_INDEX; if (unlikely(env->tlb_table[mmu_idx][page_index].addr_write != (addr & (TARGET_PAGE_MASK | (DATA_SIZE - 1))))) { - glue(glue(helper_st, SUFFIX), MMUSUFFIX)(env, addr, v, mmu_idx); + glue(glue(helper_inline_st, SUFFIX), MEMSUFFIX)(env, addr, v, mmu_idx); } else { uintptr_t hostaddr = addr + env->tlb_table[mmu_idx][page_index].addend; glue(glue(st, SUFFIX), _raw)(hostaddr, v); diff --git a/include/exec/exec-all.h b/include/exec/exec-all.h index 5e5d86e..a1c69f0 --- a/include/exec/exec-all.h +++ b/include/exec/exec-all.h @@ -21,6 +21,7 @@ #define _EXEC_ALL_H_ #include "qemu-common.h" +#include "replay/replay.h" /* allow to see translation results - the slowdown should be negligible, so we leave it */ #define DEBUG_DISAS @@ -212,6 +213,7 @@ static inline unsigned int tb_phys_hash_func(tb_page_addr_t pc) void tb_free(TranslationBlock *tb); void tb_flush(CPUArchState *env); +void tb_flush_all(void); void tb_phys_invalidate(TranslationBlock *tb, tb_page_addr_t page_addr); #if defined(USE_DIRECT_JUMP) @@ -344,6 +346,33 @@ bool io_mem_write(struct MemoryRegion *mr, hwaddr addr, void tlb_fill(CPUState *cpu, target_ulong addr, int is_write, int mmu_idx, uintptr_t retaddr); +uint8_t helper_call_ldb_cmmu(CPUArchState *env, target_ulong addr, + int mmu_idx, uintptr_t retaddr); +uint16_t helper_call_ldw_cmmu(CPUArchState *env, target_ulong addr, + int mmu_idx, uintptr_t retaddr); +uint32_t helper_call_ldl_cmmu(CPUArchState *env, target_ulong addr, + int mmu_idx, uintptr_t retaddr); +uint64_t helper_call_ldq_cmmu(CPUArchState *env, target_ulong addr, + int mmu_idx, uintptr_t retaddr); + +uint8_t helper_call_ldb_mmu(CPUArchState *env, target_ulong addr, + int mmu_idx, uintptr_t retaddr); +uint16_t helper_call_ldw_mmu(CPUArchState *env, target_ulong addr, + int mmu_idx, uintptr_t retaddr); +uint32_t helper_call_ldl_mmu(CPUArchState *env, target_ulong addr, + int mmu_idx, uintptr_t retaddr); +uint64_t helper_call_ldq_mmu(CPUArchState *env, target_ulong addr, + int mmu_idx, uintptr_t retaddr); + +void helper_call_stb_mmu(CPUArchState *env, target_ulong addr, + uint8_t val, int mmu_idx, uintptr_t retaddr); +void helper_call_stw_mmu(CPUArchState *env, target_ulong addr, + uint16_t val, int mmu_idx, uintptr_t retaddr); +void helper_call_stl_mmu(CPUArchState *env, target_ulong addr, + uint32_t val, int mmu_idx, uintptr_t retaddr); +void helper_call_stq_mmu(CPUArchState *env, target_ulong addr, + uint64_t val, int mmu_idx, uintptr_t retaddr); + #endif #if defined(CONFIG_USER_ONLY) @@ -358,7 +387,8 @@ tb_page_addr_t get_page_addr_code(CPUArchState *env1, target_ulong addr); typedef void (CPUDebugExcpHandler)(CPUArchState *env); -void cpu_set_debug_excp_handler(CPUDebugExcpHandler *handler); +CPUDebugExcpHandler *cpu_set_debug_excp_handler(CPUDebugExcpHandler *handler); +void cpu_handle_debug_exception(CPUArchState *env); /* vl.c */ extern int singlestep; @@ -380,6 +410,12 @@ static inline bool cpu_can_do_io(CPUState *cpu) if (!use_icount) { return true; } + /* In replay mode interrupts are processed immediately in any case, + even in the middle of the TB. + */ + if (replay_mode != REPLAY_NONE) + return 1; + /* If not executing code then assume we are ok. */ if (cpu->current_tb == NULL) { return true; diff --git a/softmmu_template.h b/softmmu_template.h index 5a07f99..1053cf3 --- a/softmmu_template.h +++ b/softmmu_template.h @@ -311,6 +311,15 @@ glue(glue(helper_ld, SUFFIX), MMUSUFFIX)(CPUArchState *env, target_ulong addr, return helper_te_ld_name (env, addr, mmu_idx, GETRA()); } +DATA_TYPE +glue(glue(helper_call_ld, SUFFIX), MMUSUFFIX)(CPUArchState *env, + target_ulong addr, + int mmu_idx, + uintptr_t retaddr) +{ + return helper_te_ld_name(env, addr, mmu_idx, retaddr); +} + #ifndef SOFTMMU_CODE_ACCESS /* Provide signed versions of the load routines as well. We can of course @@ -505,6 +514,15 @@ glue(glue(helper_st, SUFFIX), MMUSUFFIX)(CPUArchState *env, target_ulong addr, helper_te_st_name(env, addr, val, mmu_idx, GETRA()); } +void +glue(glue(helper_call_st, SUFFIX), MMUSUFFIX)(CPUArchState *env, + target_ulong addr, + DATA_TYPE val, int mmu_idx, + uintptr_t retaddr) +{ + helper_te_st_name(env, addr, val, mmu_idx, retaddr); +} + #endif /* !defined(SOFTMMU_CODE_ACCESS) */ #undef READ_ACCESS_TYPE