Question about the "TLBs and I-cache are private to each vCPU" guarantee with VTTBR_EL2.CnP

Oliver Upton oupton at kernel.org
Mon Jul 6 23:36:08 PDT 2026


On Tue, Jul 07, 2026 at 10:41:35AM +0800, Tangnianyao wrote:
> On 7/6/2026 23:33, Mark Rutland wrote:
> > If *both* of the vCPUs set TTBRn_EL1.CnP, then surely that is
> > indistinguishable from physical CPUs:
> >
> >     PE0(core0,smt0)         PE1(core0,smt1)
> >     cpu0 va->pa0        
> >                             cpu1 flush local tlb
> >                             cpu1 modify desc to va->pa1
> >     cpu0 hit *va->pa1*
> >
> > Mark. 
> >
> > .
> >
> Thanks for the clarification.
> Stage-1 CnP determines whether Stage-1 translation entries may be shared
> across vCPUs, and the hardware is responsible for enforcing the
> architectural semantics.
> 
> Given that, why does KVM still need to guarantee that TLBs are private to
> each vCPU?
> 
> Assuming VTTBR_EL2.CnP == 1:
> If TTBRx_EL1.CnP == 1, the guest is responsible for ensuring that the
> translations referenced by TTBRx_EL1 are shareable, as required by the
> architecture.
> If TTBRx_EL1.CnP == 0, the hardware must ensure that Stage-1 translations
> are not shared, again according to the architectural definition.
> 
> The reason I'm asking is the potential performance impact. In a scenario
> where multiple vCPUs of the same VM are scheduled onto a single PE, this
> TLB flush may prevent a vCPU from reusing its previously populated
> translation entries, potentially increasing TLB misses.

The problem is you can't infer the state of the TLB based on the current
value of CnP at stage-1. CnP only applies to the current TTBR;
nothing stops the guest from using a mix of CnP=0/1 for different TTBRs.

KVM still needs to invalidate in the case that the PE retained a CnP=0
TLB entry for a different stage-1 context than the one configured at
the time of vcpu_load().

Thanks,
Oliver



More information about the linux-arm-kernel mailing list