On Mon, 2025-01-20 at 22:04 +0200, Nadav Amit wrote: > > What about this scenario for instance? > > CPU0 CPU1 CPU2 > ---- ---- ---- > (1) use_global_asid(mm): > mm->context.asid_trans = T; > mm->context.global_asid = G; > > (2) switch_mm(..., next=mm): > *Observes global_asid = G > => loads CR3 with PCID=G > => fills TLB under G. > TLB caches PTE[G, V] = P > (for some reason) > > (3) > flush_tlb_mm_range(mm): > *Sees global_asid == > 0 > (stale/old value) > => flush_tlb_multi() > => IPI flush for > dyn. > If the TLB flush is about a page table change that happened before CPUs 0 and 1 switched to the global ASID, then CPUs 0 and 1 will not see the old page table contents after the switch. If the TLB flush is about a page table change that happened after the transition to a global ASID, flush_tlb_mm_range() should see that global ASID, and flush accordingly. What am I missing? > (4) IPI arrives on CPU1: > flush_tlb_func(...): > is_global_asid(G)? yes, > skip invalidate; broadcast > flush assumed to cover it. > > (5) IPI completes on > CPU2: > Dyn. ASIDs are > flushed, > but CPU1’s global > ASID > was never > invalidated! > > (6) CPU1 uses stale TLB entries under ASID G. > TLB continues to use PTE[G, V] = P, as it > was not invalidated. > > > > > -- All Rights Reversed.