From: Catalin Marinas <catalin.marinas@xxxxxxx> commit c0900d15d31c2597dd9f634c8be2b71762199890 upstream. 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: stable@xxxxxxxxxxxxxxx Cc: Will Deacon <will@xxxxxxxxxx> Cc: Mark Rutland <mark.rutland@xxxxxxx> Cc: Marc Zyngier <maz@xxxxxxxxxx> Cc: James Morse <james.morse@xxxxxxx> Acked-by: Mark Rutland <mark.rutland@xxxxxxx> Acked-by: Marc Zyngier <maz@xxxxxxxxxx> Link: https://lore.kernel.org/r/20241203151941.353796-1-catalin.marinas@xxxxxxx Signed-off-by: Catalin Marinas <catalin.marinas@xxxxxxx> Signed-off-by: Greg Kroah-Hartman <gregkh@xxxxxxxxxxxxxxxxxxx> --- arch/arm64/mm/context.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) --- a/arch/arm64/mm/context.c +++ b/arch/arm64/mm/context.c @@ -32,9 +32,9 @@ static unsigned long nr_pinned_asids; static unsigned long *pinned_asid_map; #define ASID_MASK (~GENMASK(asid_bits - 1, 0)) -#define ASID_FIRST_VERSION (1UL << asid_bits) +#define ASID_FIRST_VERSION (1UL << 16) -#define NUM_USER_ASIDS ASID_FIRST_VERSION +#define NUM_USER_ASIDS (1UL << asid_bits) #define ctxid2asid(asid) ((asid) & ~ASID_MASK) #define asid2ctxid(asid, genid) ((asid) | (genid)) Patches currently in stable-queue which might be from catalin.marinas@xxxxxxx are queue-6.1/arm64-fix-.data.rel.ro-size-assertion-when-config_lt.patch queue-6.1/arm64-tls-fix-context-switching-of-tpidrro_el0-when-kpti-is-enabled.patch queue-6.1/perf-arm-cmn-ensure-port-and-device-id-bits-are-set-.patch queue-6.1/acpi-arm64-adjust-error-handling-procedure-in-gtdt_p.patch queue-6.1/dma-allow-dma_get_cache_alignment-to-be-overridden-by-the-arch-code.patch queue-6.1/kselftest-arm64-mte-fix-printf-type-warnings-about-_.patch queue-6.1/kselftest-arm64-mte-fix-printf-type-warnings-about-l.patch queue-6.1/arm64-ptrace-fix-partial-setregset-for-nt_arm_tagged_addr_ctrl.patch queue-6.1/perf-arm-smmuv3-fix-lockdep-assert-in-event_init.patch queue-6.1/mm-slab-decouple-arch_kmalloc_minalign-from-arch_dma_minalign.patch queue-6.1/arm64-ensure-bits-asid-are-masked-out-when-the-kernel-uses-8-bit-asids.patch