From 74c4912f097bab98a8b0f8ec2bee1db269505c14 Mon Sep 17 00:00:00 2001 From: Benjamin Herrenschmidt Date: Fri, 15 Feb 2019 18:00:25 +0100 Subject: [PATCH] target/ppc: Fix synchronization of mttcg with broadcast TLB flushes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Let's use the generic helper tlb_flush_all_cpus_synced() instead of iterating the CPUs ourselves. We do lose the optimization of clearing the "other" CPUs "need flush" flags but this shouldn't be a problem in practice. Signed-off-by: Benjamin Herrenschmidt Signed-off-by: Cédric Le Goater Message-Id: <20190215170029.15641-9-clg@kaod.org> Signed-off-by: David Gibson --- target/ppc/helper_regs.h | 27 ++++++++++----------------- 1 file changed, 10 insertions(+), 17 deletions(-) diff --git a/target/ppc/helper_regs.h b/target/ppc/helper_regs.h index 5efd18049e..a2205e1044 100644 --- a/target/ppc/helper_regs.h +++ b/target/ppc/helper_regs.h @@ -174,26 +174,19 @@ static inline int hreg_store_msr(CPUPPCState *env, target_ulong value, static inline void check_tlb_flush(CPUPPCState *env, bool global) { CPUState *cs = CPU(ppc_env_get_cpu(env)); - if (env->tlb_need_flush & TLB_NEED_LOCAL_FLUSH) { - tlb_flush(cs); + + /* Handle global flushes first */ + if (global && (env->tlb_need_flush & TLB_NEED_GLOBAL_FLUSH)) { + env->tlb_need_flush &= ~TLB_NEED_GLOBAL_FLUSH; env->tlb_need_flush &= ~TLB_NEED_LOCAL_FLUSH; + tlb_flush_all_cpus_synced(cs); + return; } - /* Propagate TLB invalidations to other CPUs when the guest uses broadcast - * TLB invalidation instructions. - */ - if (global && (env->tlb_need_flush & TLB_NEED_GLOBAL_FLUSH)) { - CPUState *other_cs; - CPU_FOREACH(other_cs) { - if (other_cs != cs) { - PowerPCCPU *cpu = POWERPC_CPU(other_cs); - CPUPPCState *other_env = &cpu->env; - - other_env->tlb_need_flush &= ~TLB_NEED_LOCAL_FLUSH; - tlb_flush(other_cs); - } - } - env->tlb_need_flush &= ~TLB_NEED_GLOBAL_FLUSH; + /* Then handle local ones */ + if (env->tlb_need_flush & TLB_NEED_LOCAL_FLUSH) { + env->tlb_need_flush &= ~TLB_NEED_LOCAL_FLUSH; + tlb_flush(cs); } } #else