From nobody Tue Apr 7 13:10:39 2026 Received: from mxct.zte.com.cn (mxct.zte.com.cn [183.62.165.209]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 9E3551DED4C for ; Fri, 13 Mar 2026 02:56:34 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=183.62.165.209 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1773370597; cv=none; b=pkWsnrXAR+NgIP/qs1ICTWjVrp0VVbxoWxOQNHSgu1etqWanBkhWwIlGI4lK19CePohhVGf9x4k8IAG0VVBddaqUQ9yvOYEP41cpVKtQRLnTLe9yDdjEbvyeNNjP4sJZ3id0vv/nU55E2orpdihq52lJzGbsZh/hgkKvr8ZObjg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1773370597; c=relaxed/simple; bh=ONyZ5Ghk9bqi+LraRfAybG51/Jd1Ccs5nxMgsJkcGQA=; h=Message-ID:Date:Mime-Version:From:To:Cc:Subject:Content-Type; b=H/p8iu1peQMMy+s8vzDgNJV6ajztsSQObg7zddbIe1PMJ33vO2A9HJW3S6tE69YT9jtkghBX8pMjfYCBTxDpvMVqibfyHvfFSrdqnky7MpEwxYm22XfINAvC8uiceC4d7f7W9GavoMFvCzvJ30t7nwWoTe53chAbxieIOKg2JKI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=zte.com.cn; spf=pass smtp.mailfrom=zte.com.cn; arc=none smtp.client-ip=183.62.165.209 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=zte.com.cn Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=zte.com.cn Received: from mse-fl2.zte.com.cn (unknown [10.5.228.133]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange x25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mxct.zte.com.cn (FangMail) with ESMTPS id 4fX8JT0kRJz51Sjp; Fri, 13 Mar 2026 10:56:25 +0800 (CST) Received: from xaxapp04.zte.com.cn ([10.99.98.157]) by mse-fl2.zte.com.cn with SMTP id 62D2uFU2087779; Fri, 13 Mar 2026 10:56:15 +0800 (+08) (envelope-from hu.shengming@zte.com.cn) Received: from mapi (xaxapp01[null]) by mapi (Zmail) with MAPI id mid32; Fri, 13 Mar 2026 10:56:16 +0800 (CST) X-Zmail-TransId: 2af969b37cd0ec5-ee738 X-Mailer: Zmail v1.0 Message-ID: <20260313105616335IVh7tn1pSkAHNnfckGCQ-@zte.com.cn> Date: Fri, 13 Mar 2026 10:56:16 +0800 (CST) Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 From: To: , , Cc: , , , , , Subject: =?UTF-8?B?W1BBVENIXSByaXNjdjogbW06IFZlcmlmeSBwZXItaGFydCBBU0lEIGJpdHMgd2hlbiB1c2luZyBBU0lEIGFsbG9jYXRvcg==?= X-MAIL: mse-fl2.zte.com.cn 62D2uFU2087779 X-TLS: YES X-SPF-DOMAIN: zte.com.cn X-ENVELOPE-SENDER: hu.shengming@zte.com.cn X-SPF: None X-SOURCE-IP: 10.5.228.133 unknown Fri, 13 Mar 2026 10:56:25 +0800 X-Fangmail-Anti-Spam-Filtered: true X-Fangmail-MID-QID: 69B37CD9.000/4fX8JT0kRJz51Sjp Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Shengming Hu RISC-V probes the number of implemented ASID bits in SATP on the boot hart and enables the ASID allocator based on that result. However, the privileged spec allows harts to implement fewer ASID bits by hardwiring the upper bits to zero. If a secondary hart implements fewer ASID bits than the boot hart while the ASID allocator is enabled, different Linux ASIDs may alias on that hart. This can allow stale TLB entries to survive and potentially corrupt memory. Verify the number of implemented ASID bits on each CPU as it comes online, and refuse to online CPUs that support fewer ASID bits than the boot CPU. Signed-off-by: Shengming Hu --- arch/riscv/include/asm/mmu_context.h | 2 ++ arch/riscv/kernel/smpboot.c | 3 ++ arch/riscv/mm/context.c | 42 ++++++++++++++++++++++++---- 3 files changed, 41 insertions(+), 6 deletions(-) diff --git a/arch/riscv/include/asm/mmu_context.h b/arch/riscv/include/asm/= mmu_context.h index dbf27a78df6c..0cca20b7dbe1 100644 --- a/arch/riscv/include/asm/mmu_context.h +++ b/arch/riscv/include/asm/mmu_context.h @@ -16,6 +16,8 @@ void switch_mm(struct mm_struct *prev, struct mm_struct *next, struct task_struct *task); +int verify_cpu_asid_bits(void); + #define activate_mm activate_mm static inline void activate_mm(struct mm_struct *prev, struct mm_struct *next) diff --git a/arch/riscv/kernel/smpboot.c b/arch/riscv/kernel/smpboot.c index 8b628580fe11..9774a591c1a5 100644 --- a/arch/riscv/kernel/smpboot.c +++ b/arch/riscv/kernel/smpboot.c @@ -230,6 +230,9 @@ asmlinkage __visible void smp_callin(void) return; } + if (verify_cpu_asid_bits()) + return; + /* All kernel threads share the same mm context. */ mmgrab(mm); current->active_mm =3D mm; diff --git a/arch/riscv/mm/context.c b/arch/riscv/mm/context.c index 55c20ad1f744..2a830f021ce5 100644 --- a/arch/riscv/mm/context.c +++ b/arch/riscv/mm/context.c @@ -22,6 +22,7 @@ DEFINE_STATIC_KEY_FALSE(use_asid_allocator); static unsigned long num_asids; +static unsigned long asid_bits; static atomic_long_t current_version; @@ -224,16 +225,16 @@ static inline void set_mm(struct mm_struct *prev, } } -static int __init asids_init(void) +static unsigned long get_cpu_asid_bits(void) { - unsigned long asid_bits, old; + unsigned long asid_bit_count, old; /* Figure-out number of ASID bits in HW */ old =3D csr_read(CSR_SATP); - asid_bits =3D old | (SATP_ASID_MASK << SATP_ASID_SHIFT); - csr_write(CSR_SATP, asid_bits); - asid_bits =3D (csr_read(CSR_SATP) >> SATP_ASID_SHIFT) & SATP_ASID_MASK; - asid_bits =3D fls_long(asid_bits); + asid_bit_count =3D old | (SATP_ASID_MASK << SATP_ASID_SHIFT); + csr_write(CSR_SATP, asid_bit_count); + asid_bit_count =3D (csr_read(CSR_SATP) >> SATP_ASID_SHIFT) & SATP_ASID_M= ASK; + asid_bit_count =3D fls_long(asid_bit_count); csr_write(CSR_SATP, old); /* @@ -242,6 +243,30 @@ static int __init asids_init(void) * to remove unwanted TLB enteries. */ local_flush_tlb_all(); + return asid_bit_count; +} + +int verify_cpu_asid_bits(void) +{ + unsigned long cpu_asid_bits =3D get_cpu_asid_bits(); + + if (cpu_asid_bits < asid_bits) { + /* + * The ASID allocator is initialized using the boot CPU's ASID width. + * We cannot safely shrink the system-wide ASID space at runtime, so + * reject secondary CPU bringup if it supports fewer ASID bits than + * the boot CPU. + */ + pr_crit("CPU%d: ASID bits (%lu) smaller than boot CPU (%lu), refusing to= online\n", + smp_processor_id(), cpu_asid_bits, asid_bits); + return -EINVAL; + } + return 0; +} + +static int __init asids_init(void) +{ + asid_bits =3D get_cpu_asid_bits(); /* Pre-compute ASID details */ if (asid_bits) { @@ -279,6 +304,11 @@ static inline void set_mm(struct mm_struct *prev, { /* Nothing to do here when there is no MMU */ } + +int verify_cpu_asid_bits(void) +{ + return 0; +} #endif /* --=20 2.25.1