From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1Jt3W0-0006X8-Hq for qemu-devel@nongnu.org; Mon, 05 May 2008 12:26:12 -0400 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1Jt3Vx-0006UC-Na for qemu-devel@nongnu.org; Mon, 05 May 2008 12:26:11 -0400 Received: from [199.232.76.173] (port=41154 helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1Jt3Vx-0006U9-GG for qemu-devel@nongnu.org; Mon, 05 May 2008 12:26:09 -0400 Received: from miranda.se.axis.com ([193.13.178.8]) by monty-python.gnu.org with esmtps (TLS-1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.60) (envelope-from ) id 1Jt3Vx-0003fp-0c for qemu-devel@nongnu.org; Mon, 05 May 2008 12:26:09 -0400 Received: from axis.com (edgar.se.axis.com [10.93.151.1]) by miranda.se.axis.com (8.13.4/8.13.4/Debian-3sarge3) with ESMTP id m45GQ67t008188 for ; Mon, 5 May 2008 18:26:06 +0200 Date: Mon, 5 May 2008 18:26:05 +0200 From: "Edgar E. Iglesias" Message-ID: <20080505162605.GC23506@edgar.se.axis.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Subject: [Qemu-devel] Incoherency between the tlb and the tb_jmp_cache Reply-To: qemu-devel@nongnu.org List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org I'm seeing occational segfaults on my guest CRIS linux due to what I beleieve to be incoherency between the tlb and the tb_jmp_cache. This patch seems to solve the issue. Does the patch make sense or am I missing something? Best regards -- Edgar E. Iglesias Axis Communications AB commit 6b79550cc79e23169274236daaa8a765de0ed27f Author: Edgar E. Iglesias Date: Mon May 5 18:02:36 2008 +0200 Break out tb jmp cache flushing into a separate inline function. Make sure to flush the jmp cache when we replace tlb entries. diff --git a/exec.c b/exec.c index eb3c8ab..59bca69 100644 --- a/exec.c +++ b/exec.c @@ -1366,6 +1366,21 @@ CPUState *cpu_copy(CPUState *env) #if !defined(CONFIG_USER_ONLY) +static inline void tlb_flush_jmp_cache(CPUState *env, target_ulong addr) +{ + unsigned int i; + + /* Discard jump cache entries for any tb which might potentially + overlap the flushed page. */ + i = tb_jmp_cache_hash_page(addr - TARGET_PAGE_SIZE); + memset (&env->tb_jmp_cache[i], 0, + TB_JMP_PAGE_SIZE * sizeof(TranslationBlock *)); + + i = tb_jmp_cache_hash_page(addr); + memset (&env->tb_jmp_cache[i], 0, + TB_JMP_PAGE_SIZE * sizeof(TranslationBlock *)); +} + /* NOTE: if flush_global is true, also flush global entries (not implemented yet) */ void tlb_flush(CPUState *env, int flush_global) @@ -1428,7 +1443,6 @@ static inline void tlb_flush_entry(CPUTLBEntry *tlb_entry, target_ulong addr) void tlb_flush_page(CPUState *env, target_ulong addr) { int i; - TranslationBlock *tb; #if defined(DEBUG_TLB) printf("tlb_flush_page: " TARGET_FMT_lx "\n", addr); @@ -1448,13 +1462,7 @@ void tlb_flush_page(CPUState *env, target_ulong addr) #endif #endif - /* Discard jump cache entries for any tb which might potentially - overlap the flushed page. */ - i = tb_jmp_cache_hash_page(addr - TARGET_PAGE_SIZE); - memset (&env->tb_jmp_cache[i], 0, TB_JMP_PAGE_SIZE * sizeof(tb)); - - i = tb_jmp_cache_hash_page(addr); - memset (&env->tb_jmp_cache[i], 0, TB_JMP_PAGE_SIZE * sizeof(tb)); + tlb_flush_jmp_cache(env, addr); #if !defined(CONFIG_SOFTMMU) if (addr < MMAP_AREA_END) @@ -1706,6 +1714,10 @@ int tlb_set_page_exec(CPUState *env, target_ulong vaddr, } else { te->addr_read = -1; } + + if (te->addr_code != -1) { + tlb_flush_jmp_cache(env, te->addr_code); + } if (prot & PAGE_EXEC) { te->addr_code = address; } else {