Commit 74c4912f authored by Benjamin Herrenschmidt's avatar Benjamin Herrenschmidt Committed by David Gibson
Browse files

target/ppc: Fix synchronization of mttcg with broadcast TLB flushes



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: default avatarBenjamin Herrenschmidt <benh@kernel.crashing.org>
Signed-off-by: default avatarCédric Le Goater <clg@kaod.org>
Message-Id: <20190215170029.15641-9-clg@kaod.org>
Signed-off-by: default avatarDavid Gibson <david@gibson.dropbear.id.au>
parent 34525595
Loading
Loading
Loading
Loading
+10 −17
Original line number Diff line number Diff line
@@ -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);
        env->tlb_need_flush &= ~TLB_NEED_LOCAL_FLUSH;
    }

    /* Propagate TLB invalidations to other CPUs when the guest uses broadcast
     * TLB invalidation instructions.
     */
    /* Handle global flushes first */
    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;
        env->tlb_need_flush &= ~TLB_NEED_LOCAL_FLUSH;
        tlb_flush_all_cpus_synced(cs);
        return;
    }

    /* 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