On 26/06/2015 17:54, Frederic Konrad wrote: >> > I think it doesn't requires to be synchronous as each VCPUs only clear > it's own > tlb here: > > void tlb_flush(CPUState *cpu, int flush_global) > { > CPUArchState *env = cpu->env_ptr; > > #if defined(DEBUG_TLB) > printf("tlb_flush:\n"); > #endif > /* must reset current TB so that interrupts cannot modify the > links while we are modifying them */ > cpu->current_tb = NULL; > > memset(env->tlb_table, -1, sizeof(env->tlb_table)); > memset(env->tlb_v_table, -1, sizeof(env->tlb_v_table)); > memset(cpu->tb_jmp_cache, 0, sizeof(cpu->tb_jmp_cache)); > > env->vtlb_index = 0; > env->tlb_flush_addr = -1; > env->tlb_flush_mask = 0; > tlb_flush_count++; > } > > So what happen is: > An arm instruction want to clear tlb of all VCPUs eg: IS version of > TLBIALL. > The VCPU which execute the TLBIALL_IS can't flush tlb of other VCPU. > It will just ask all VCPU thread to exit and to do tlb_flush hence the > async_work. > > Maybe the big issue might be memory barrier instruction here which I didn't > checked.
Yeah, ISTR that in some cases you have to wait for other CPUs to invalidate the TLB before proceeding. Maybe it's only when you have a dmb instruction, but it's probably simpler for QEMU to always do it synchronously. Paolo