Question about the "TLBs and I-cache are private to each vCPU" guarantee with VTTBR_EL2.CnP
Tangnianyao
tangnianyao at huawei.com
Mon Jul 6 19:41:35 PDT 2026
On 7/6/2026 23:33, Mark Rutland wrote:
> On Mon, Jul 06, 2026 at 10:15:04PM +0800, Tangnianyao wrote:
>> Two SMT threads(PE0,PE1) on the same physical core share TLB.
> Critially those are *NOT* allowed to share entries allocated with
> CnP==0, and are only allowed to share entries where CnP was enabled at
> stage 1 (and stage 2 if applicable).
>
> Please see the ARM ARM:
>
> https://developer.arm.com/documentation/ddi0487/mc/
>
> Specifically, section D8.12.3.4 "Common not private translations":
>
> https://developer.arm.com/documentation/ddi0487/mc/-Part-D-The-AArch64-System-Level-Architecture/-Chapter-D8-The-AArch64-Virtual-Memory-System-Architecture/-D8-16-Translation-Lookaside-Buffers/-D8-16-3-Use-of-ASIDs-and-VMIDs-to-reduce-TLB-maintenance-requirements
>
>> VM0 has 2 vcpus, vcpu0 and vcpu1 that share all architectural context
>> except the address translation context.
>>
>> Vcpu0 may observe TLB entries that are supposed to be private to vcpu1
>> in the following case:
>>
>> PE0(core0,smt0) PE1(core0,smt1)
>> vcpu0 load
>> vcpu0 va->pa0
>> vcpu0 put
>> vcpu1 load
>> vcpu1 flush local tlb
>> vcpu1 modify desc to va->pa1
>> vcpu0 load
>> vcpu0 hit *va->pa1*
> How is CnP managed in this example?
>
> If *either* of the vCPUs don't set TTBRn_EL1.CnP, that is not permitted
> to happen.
>
> 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.
Thanks,
Nianyao Tang
More information about the linux-arm-kernel
mailing list