[PATCH] arm64: Ensure bits ASID[15:8] are masked out when the kernel uses 8-bit ASIDs
Mark Rutland
mark.rutland at arm.com
Tue Dec 3 08:22:20 PST 2024
On Tue, Dec 03, 2024 at 03:19:41PM +0000, Catalin Marinas wrote:
> 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.
>
> Signed-off-by: Catalin Marinas <catalin.marinas at arm.com>
> Cc: <stable at vger.kernel.org>
> Cc: Will Deacon <will at kernel.org>
> Cc: Mark Rutland <mark.rutland at arm.com>
> Cc: Marc Zyngier <maz at kernel.org>
> Cc: James Morse <james.morse at arm.com>
Acked-by: Mark Rutland <mark.rutland at arm.com>
Mark.
> ---
> arch/arm64/mm/context.c | 4 ++--
> 1 file changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/arch/arm64/mm/context.c b/arch/arm64/mm/context.c
> index 188197590fc9..b2ac06246327 100644
> --- 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))
>
More information about the linux-arm-kernel
mailing list