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