Skip to content

Commit c0900d1

Browse files
committed
arm64: Ensure bits ASID[15:8] are masked out when the kernel uses 8-bit ASIDs
Linux currently sets the TCR_EL1.AS bit unconditionally during CPU bring-up. On an 8-bit ASID CPU, this is RES0 and ignored, otherwise 16-bit ASIDs are enabled. However, if running in a VM and the hypervisor reports 8-bit ASIDs (ID_AA64MMFR0_EL1.ASIDBits == 0) on a 16-bit ASIDs CPU, Linux uses bits 8 to 63 as a generation number for tracking old process ASIDs. The bottom 8 bits of this generation end up being written to TTBR1_EL1 and also used for the ASID-based TLBI operations as the upper 8 bits of the ASID. Following an ASID roll-over event we can have threads of the same application with the same 8-bit ASID but different generation numbers running on separate CPUs. Both TLB caching and the TLBI operations will end up using different actual 16-bit ASIDs for the same process. A similar scenario can happen in a big.LITTLE configuration if the boot CPU only uses 8-bit ASIDs while secondary CPUs have 16-bit ASIDs. Ensure that the ASID generation is only tracked by bits 16 and up, leaving bits 15:8 as 0 if the kernel uses 8-bit ASIDs. Note that clearing TCR_EL1.AS is not sufficient since the architecture requires that the top 8 bits of the ASID passed to TLBI instructions are 0 rather than ignored in such configuration. Cc: [email protected] Cc: Will Deacon <[email protected]> Cc: Mark Rutland <[email protected]> Cc: Marc Zyngier <[email protected]> Cc: James Morse <[email protected]> Acked-by: Mark Rutland <[email protected]> Acked-by: Marc Zyngier <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Catalin Marinas <[email protected]>
1 parent c2b46ae commit c0900d1

File tree

1 file changed

+2
-2
lines changed

1 file changed

+2
-2
lines changed

arch/arm64/mm/context.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,9 +32,9 @@ static unsigned long nr_pinned_asids;
3232
static unsigned long *pinned_asid_map;
3333

3434
#define ASID_MASK (~GENMASK(asid_bits - 1, 0))
35-
#define ASID_FIRST_VERSION (1UL << asid_bits)
35+
#define ASID_FIRST_VERSION (1UL << 16)
3636

37-
#define NUM_USER_ASIDS ASID_FIRST_VERSION
37+
#define NUM_USER_ASIDS (1UL << asid_bits)
3838
#define ctxid2asid(asid) ((asid) & ~ASID_MASK)
3939
#define asid2ctxid(asid, genid) ((asid) | (genid))
4040

0 commit comments

Comments
 (0)