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

From: Mark Rutland

Date: Mon Jul 06 2026 - 12:24:20 EST


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.