From patchwork Tue Nov 24 16:59:58 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Leon Alrae X-Patchwork-Id: 548161 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 2298B1402A8 for ; Wed, 25 Nov 2015 04:03:03 +1100 (AEDT) Received: from localhost ([::1]:39844 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1a1Gzd-0001SW-2z for incoming@patchwork.ozlabs.org; Tue, 24 Nov 2015 12:03:01 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:59938) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1a1GxF-0006Ef-4j for qemu-devel@nongnu.org; Tue, 24 Nov 2015 12:00:38 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1a1GxE-0003xk-20 for qemu-devel@nongnu.org; Tue, 24 Nov 2015 12:00:33 -0500 Received: from mailapp01.imgtec.com ([195.59.15.196]:26634) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1a1GxD-0003xd-S9 for qemu-devel@nongnu.org; Tue, 24 Nov 2015 12:00:31 -0500 Received: from hhmail02.hh.imgtec.org (unknown [10.100.10.20]) by Websense Email Security Gateway with ESMTPS id 566423A1E2649 for ; Tue, 24 Nov 2015 17:00:26 +0000 (GMT) Received: from lalrae-linux.kl.imgtec.org (192.168.14.163) by hhmail02.hh.imgtec.org (10.100.10.20) with Microsoft SMTP Server (TLS) id 14.3.235.1; Tue, 24 Nov 2015 17:00:30 +0000 From: Leon Alrae To: Date: Tue, 24 Nov 2015 16:59:58 +0000 Message-ID: <1448384398-1783-3-git-send-email-leon.alrae@imgtec.com> X-Mailer: git-send-email 1.7.9.5 In-Reply-To: <1448384398-1783-1-git-send-email-leon.alrae@imgtec.com> References: <1448384398-1783-1-git-send-email-leon.alrae@imgtec.com> MIME-Version: 1.0 X-Originating-IP: [192.168.14.163] X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x X-Received-From: 195.59.15.196 Subject: [Qemu-devel] [PULL 2/2] target-mips: flush QEMU TLB when disabling 64-bit addressing 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 CP0.Status.KX/SX/UX bits are responsible for enabling access to 64-bit Kernel/Supervisor/User Segments. If bit is cleared an access to corresponding segment should generate Address Error Exception. However, the guest may still be able to access some pages belonging to the disabled 64-bit segment because we forget to flush QEMU TLB. This patch fixes it. Signed-off-by: Leon Alrae --- target-mips/cpu.h | 18 +++++++++++++++++- target-mips/op_helper.c | 13 ------------- 2 files changed, 17 insertions(+), 14 deletions(-) diff --git a/target-mips/cpu.h b/target-mips/cpu.h index fa919c1..89c01f7 100644 --- a/target-mips/cpu.h +++ b/target-mips/cpu.h @@ -961,6 +961,15 @@ static inline void compute_hflags(CPUMIPSState *env) } #ifndef CONFIG_USER_ONLY +static inline void cpu_mips_tlb_flush(CPUMIPSState *env, int flush_global) +{ + MIPSCPU *cpu = mips_env_get_cpu(env); + + /* Flush qemu's TLB and discard all shadowed entries. */ + tlb_flush(CPU(cpu), flush_global); + env->tlb->tlb_in_use = env->tlb->nb_tlb; +} + /* Called for updates to CP0_Status. */ static inline void sync_c0_status(CPUMIPSState *env, CPUMIPSState *cpu, int tc) { @@ -999,6 +1008,7 @@ static inline void sync_c0_status(CPUMIPSState *env, CPUMIPSState *cpu, int tc) static inline void cpu_mips_store_status(CPUMIPSState *env, target_ulong val) { uint32_t mask = env->CP0_Status_rw_bitmask; + target_ulong old = env->CP0_Status; if (env->insn_flags & ISA_MIPS32R6) { bool has_supervisor = extract32(mask, CP0St_KSU, 2) == 0x3; @@ -1014,7 +1024,13 @@ static inline void cpu_mips_store_status(CPUMIPSState *env, target_ulong val) mask &= ~(((1 << CP0St_SR) | (1 << CP0St_NMI)) & val); } - env->CP0_Status = (env->CP0_Status & ~mask) | (val & mask); + env->CP0_Status = (old & ~mask) | (val & mask); +#if defined(TARGET_MIPS64) + if ((env->CP0_Status ^ old) & (old & (7 << CP0St_UX))) { + /* Access to at least one of the 64-bit segments has been disabled */ + cpu_mips_tlb_flush(env, 1); + } +#endif if (env->CP0_Config3 & (1 << CP0C3_MT)) { sync_c0_status(env, env, env->current_tc); } else { diff --git a/target-mips/op_helper.c b/target-mips/op_helper.c index 056d53b..d2c98c9 100644 --- a/target-mips/op_helper.c +++ b/target-mips/op_helper.c @@ -23,10 +23,6 @@ #include "exec/cpu_ldst.h" #include "sysemu/kvm.h" -#ifndef CONFIG_USER_ONLY -static inline void cpu_mips_tlb_flush (CPUMIPSState *env, int flush_global); -#endif - /*****************************************************************************/ /* Exceptions processing helpers */ @@ -1846,15 +1842,6 @@ target_ulong helper_yield(CPUMIPSState *env, target_ulong arg) #ifndef CONFIG_USER_ONLY /* TLB management */ -static void cpu_mips_tlb_flush (CPUMIPSState *env, int flush_global) -{ - MIPSCPU *cpu = mips_env_get_cpu(env); - - /* Flush qemu's TLB and discard all shadowed entries. */ - tlb_flush(CPU(cpu), flush_global); - env->tlb->tlb_in_use = env->tlb->nb_tlb; -} - static void r4k_mips_tlb_flush_extra (CPUMIPSState *env, int first) { /* Discard entries from env->tlb[first] onwards. */