From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (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 4E4AD30C36C; Thu, 19 Feb 2026 02:05:01 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1771466701; cv=none; b=gVmiWA/yzwyrsE/xMQn/XVi2iX02X84gUmNmmjIWZlNwGA2gOlzYuQnU2exXuhrbB7R6fP1ysH/jtqc6J3xUzY9/0nmk6wtiQl8r1D2UsfWzujfNGcwJQgz7wdwe4EBvq9R9OGv9IiOuT9Nn5CP17bO0rkFOHf5mj4QnQZBf1Do= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1771466701; c=relaxed/simple; bh=Ckx5Vm1eSpTtUf4BNRfhEFhCZzJhmRXKfZBCmXOxmwU=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=La+4SDHYYAygxhWwdhaI+zqv5xjc3UgVY3vfHpPnTrQ3Lp/FeOZG7nwHropNEyUYTYks6f8S9PwWxgyRtPz+2PxB3acjwUlckLAcBku4zUKYuimfKO4K60+kCatQERSVUGw0duL81WwhGKi0rs0oQ4XX/9bx9Q8mh/zZgn8kVes= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=S4QYXJP+; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="S4QYXJP+" Received: by smtp.kernel.org (Postfix) with ESMTPSA id D8D31C2BC86; Thu, 19 Feb 2026 02:04:59 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1771466700; bh=Ckx5Vm1eSpTtUf4BNRfhEFhCZzJhmRXKfZBCmXOxmwU=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=S4QYXJP+qwbtSWeXgYlw4QjizvVtqFxZV0g2PYlo5qJ/kKATq7omvalUyJ8NygLtb KQEzSK9h/NhnjndBCJFyYjdowKcIz8zKSew4PUoU0eM7dNz45yppdkfjCrIEE6pJMV S4BTnywakj+bjCMjAIjHyaONKfjuW7sLt1zsGIDpG0vfeRiAmes8OBstuekvqMBnP8 s83/ibkcc6IKNqOYNFvE6TcSXvbx6Ul+KTvAhYsjiVMSexn7D9EqEBIWkhFirA/nIj MdTEk0Yb3oaS8u5L7iGrgp0U9T2ATO86TumhorHK/Y90cmDMgArHSX2If9BcRujLpy svTZlASBRMC1w== From: Sasha Levin To: patches@lists.linux.dev, stable@vger.kernel.org Cc: John Garry , Huacai Chen , Thomas Bogendoerfer , Sasha Levin , chenhuacai@kernel.org, jiaxun.yang@flygoat.com, linux-mips@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH AUTOSEL 6.19-5.10] MIPS: Loongson: Make cpumask_of_node() robust against NUMA_NO_NODE Date: Wed, 18 Feb 2026 21:04:05 -0500 Message-ID: <20260219020422.1539798-29-sashal@kernel.org> X-Mailer: git-send-email 2.51.0 In-Reply-To: <20260219020422.1539798-1-sashal@kernel.org> References: <20260219020422.1539798-1-sashal@kernel.org> Precedence: bulk X-Mailing-List: stable@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-stable: review X-Patchwork-Hint: Ignore X-stable-base: Linux 6.19.2 Content-Transfer-Encoding: 8bit From: John Garry [ Upstream commit d55d3fe2d1470ac5b6e93efe7998b728013c9fc8 ] The arch definition of cpumask_of_node() cannot handle NUMA_NO_NODE - which is a valid index - so add a check for this. Signed-off-by: John Garry Reviewed-by: Huacai Chen Signed-off-by: Thomas Bogendoerfer Signed-off-by: Sasha Levin --- LLM Generated explanations, may be completely bogus: Good. `NUMA_NO_NODE` is defined as `-1`. ## 3. Bug Mechanism The bug is clear: - `NUMA_NO_NODE` = `-1` - The old macro: `&__node_cpumask[node]` with `node = -1` results in `&__node_cpumask[-1]` - This is an **out-of-bounds array access** at index -1, reading memory before the start of the array - This is undefined behavior in C and could lead to: - Returning garbage data (incorrect CPU mask) - Kernel crash/oops if the memory before the array is unmapped - Subtle corruption or incorrect scheduling decisions The fix returns `cpu_all_mask` when `NUMA_NO_NODE` is passed, which is the semantically correct behavior: "no specific node" means "all CPUs are valid." ## 4. Consistency with Other Architectures The investigation confirmed that multiple architectures already handle this case: - **PowerPC**: checks for `-1`, returns `cpu_all_mask` - **SPARC64**: checks for `-1`, returns `cpu_all_mask` - **MIPS IP27**: checks for `-1`, returns `cpu_all_mask` - **asm-generic/numa.h**: checks for `NUMA_NO_NODE`, returns `cpu_all_mask` - **arm64**: had a similar fix applied (commit `a194c5f2d2b3a`) This fix brings the MIPS Loongson implementation in line with the established pattern. ## 5. Scope and Risk Assessment - **One line changed** in a macro definition - **One file touched** (architecture-specific topology header) - **Extremely low risk** - only adds a conditional check; the existing behavior is preserved for all valid node values - **Well-established pattern** - identical to what other architectures already do - **Reviewed by Loongson maintainer** (Huacai Chen) ## 6. User Impact - Without this fix, any caller of `cpumask_of_node(NUMA_NO_NODE)` on MIPS Loongson triggers **out-of-bounds array access** - This is an actual memory safety bug, not a theoretical issue - `NUMA_NO_NODE` is a valid value returned by various kernel APIs (e.g., `dev_to_node()` for devices without NUMA affinity) - Impact: potential kernel crash, undefined behavior, or incorrect scheduling/memory allocation decisions ## 7. Stable Criteria Evaluation | Criteria | Assessment | |----------|-----------| | Obviously correct | YES - matches pattern used by 4+ other architectures | | Fixes real bug | YES - out-of-bounds array access with index -1 | | Important issue | YES - memory safety / potential crash | | Small and contained | YES - single line change | | No new features | Correct - pure bug fix | | Tested | YES - reviewed by subsystem maintainer, identical pattern in other archs | ## Verification - Verified `NUMA_NO_NODE` is defined as `(-1)` in `include/linux/nodemask_types.h:15` - Verified `__node_cpumask[]` is indexed by `node` directly in the old macro, so passing -1 causes out-of-bounds access - Verified via git log that similar fixes exist for LoongArch (`94b0c831eda77`) and arm64 (`a194c5f2d2b3a`) - Verified that PowerPC, SPARC64, and MIPS IP27 already have the same NUMA_NO_NODE guard pattern - Verified the generic implementation in `include/asm-generic/numa.h` also checks for NUMA_NO_NODE - Verified the fix returns `cpu_all_mask` which is consistent with all other architecture implementations - Verified the change is a single-line macro modification with no dependencies on other commits ## Conclusion This is a textbook stable backport candidate. It fixes a real out-of- bounds memory access bug (array index -1) with a minimal, obviously correct one-line change that follows an established pattern used by multiple other architectures. The fix was reviewed by the Loongson maintainer. The risk of regression is effectively zero since the fix only adds a guard for a specific invalid input while preserving existing behavior for all valid inputs. **YES** arch/mips/include/asm/mach-loongson64/topology.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/mips/include/asm/mach-loongson64/topology.h b/arch/mips/include/asm/mach-loongson64/topology.h index 3414a1fd17835..89bb4deab98a6 100644 --- a/arch/mips/include/asm/mach-loongson64/topology.h +++ b/arch/mips/include/asm/mach-loongson64/topology.h @@ -7,7 +7,7 @@ #define cpu_to_node(cpu) (cpu_logical_map(cpu) >> 2) extern cpumask_t __node_cpumask[]; -#define cpumask_of_node(node) (&__node_cpumask[node]) +#define cpumask_of_node(node) ((node) == NUMA_NO_NODE ? cpu_all_mask : &__node_cpumask[node]) struct pci_bus; extern int pcibus_to_node(struct pci_bus *); -- 2.51.0