--- /dev/null
+From 270445a91055004fc3c93507fb72aa18bc500622 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 29 May 2024 09:39:10 +0200
+Subject: memblock: make memblock_set_node() also warn about use of
+ MAX_NUMNODES
+
+From: Jan Beulich <jbeulich@suse.com>
+
+[ Upstream commit e0eec24e2e199873f43df99ec39773ad3af2bff7 ]
+
+On an (old) x86 system with SRAT just covering space above 4Gb:
+
+ ACPI: SRAT: Node 0 PXM 0 [mem 0x100000000-0xfffffffff] hotplug
+
+the commit referenced below leads to this NUMA configuration no longer
+being refused by a CONFIG_NUMA=y kernel (previously
+
+ NUMA: nodes only cover 6144MB of your 8185MB e820 RAM. Not used.
+ No NUMA configuration found
+ Faking a node at [mem 0x0000000000000000-0x000000027fffffff]
+
+was seen in the log directly after the message quoted above), because of
+memblock_validate_numa_coverage() checking for NUMA_NO_NODE (only). This
+in turn led to memblock_alloc_range_nid()'s warning about MAX_NUMNODES
+triggering, followed by a NULL deref in memmap_init() when trying to
+access node 64's (NODE_SHIFT=6) node data.
+
+To compensate said change, make memblock_set_node() warn on and adjust
+a passed in value of MAX_NUMNODES, just like various other functions
+already do.
+
+Fixes: ff6c3d81f2e8 ("NUMA: optimize detection of memory with no node id assigned by firmware")
+Signed-off-by: Jan Beulich <jbeulich@suse.com>
+Cc: stable@vger.kernel.org
+Link: https://lore.kernel.org/r/1c8a058c-5365-4f27-a9f1-3aeb7fb3e7b2@suse.com
+Signed-off-by: Mike Rapoport (IBM) <rppt@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ mm/memblock.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+--- a/mm/memblock.c
++++ b/mm/memblock.c
+@@ -1321,6 +1321,10 @@ int __init_memblock memblock_set_node(ph
+ int start_rgn, end_rgn;
+ int i, ret;
+
++ if (WARN_ONCE(nid == MAX_NUMNODES,
++ "Usage of MAX_NUMNODES is deprecated. Use NUMA_NO_NODE instead\n"))
++ nid = NUMA_NO_NODE;
++
+ ret = memblock_isolate_range(type, base, size, &start_rgn, &end_rgn);
+ if (ret)
+ return ret;
--- /dev/null
+From 8043832e2a123fd9372007a29192f2f3ba328cd6 Mon Sep 17 00:00:00 2001
+From: "Mike Rapoport (IBM)" <rppt@kernel.org>
+Date: Fri, 14 Jun 2024 11:05:43 +0300
+Subject: memblock: use numa_valid_node() helper to check for invalid node ID
+
+From: Mike Rapoport (IBM) <rppt@kernel.org>
+
+commit 8043832e2a123fd9372007a29192f2f3ba328cd6 upstream.
+
+Introduce numa_valid_node(nid) that verifies that nid is a valid node ID
+and use that instead of comparing nid parameter with either NUMA_NO_NODE
+or MAX_NUMNODES.
+
+This makes the checks for valid node IDs consistent and more robust and
+allows to get rid of multiple WARNings.
+
+Suggested-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Mike Rapoport (IBM) <rppt@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ include/linux/numa.h | 5 +++++
+ mm/memblock.c | 28 +++++++---------------------
+ 2 files changed, 12 insertions(+), 21 deletions(-)
+
+--- a/include/linux/numa.h
++++ b/include/linux/numa.h
+@@ -15,6 +15,11 @@
+ #define NUMA_NO_NODE (-1)
+ #define NUMA_NO_MEMBLK (-1)
+
++static inline bool numa_valid_node(int nid)
++{
++ return nid >= 0 && nid < MAX_NUMNODES;
++}
++
+ /* optionally keep NUMA memory info available post init */
+ #ifdef CONFIG_NUMA_KEEP_MEMINFO
+ #define __initdata_or_meminfo
+--- a/mm/memblock.c
++++ b/mm/memblock.c
+@@ -754,7 +754,7 @@ bool __init_memblock memblock_validate_n
+
+ /* calculate lose page */
+ for_each_mem_pfn_range(i, MAX_NUMNODES, &start_pfn, &end_pfn, &nid) {
+- if (nid == NUMA_NO_NODE)
++ if (!numa_valid_node(nid))
+ nr_pages += end_pfn - start_pfn;
+ }
+
+@@ -1043,7 +1043,7 @@ static bool should_skip_region(struct me
+ return false;
+
+ /* only memory regions are associated with nodes, check it */
+- if (nid != NUMA_NO_NODE && nid != m_nid)
++ if (numa_valid_node(nid) && nid != m_nid)
+ return true;
+
+ /* skip hotpluggable memory regions if needed */
+@@ -1100,10 +1100,6 @@ void __next_mem_range(u64 *idx, int nid,
+ int idx_a = *idx & 0xffffffff;
+ int idx_b = *idx >> 32;
+
+- if (WARN_ONCE(nid == MAX_NUMNODES,
+- "Usage of MAX_NUMNODES is deprecated. Use NUMA_NO_NODE instead\n"))
+- nid = NUMA_NO_NODE;
+-
+ for (; idx_a < type_a->cnt; idx_a++) {
+ struct memblock_region *m = &type_a->regions[idx_a];
+
+@@ -1197,9 +1193,6 @@ void __init_memblock __next_mem_range_re
+ int idx_a = *idx & 0xffffffff;
+ int idx_b = *idx >> 32;
+
+- if (WARN_ONCE(nid == MAX_NUMNODES, "Usage of MAX_NUMNODES is deprecated. Use NUMA_NO_NODE instead\n"))
+- nid = NUMA_NO_NODE;
+-
+ if (*idx == (u64)ULLONG_MAX) {
+ idx_a = type_a->cnt - 1;
+ if (type_b != NULL)
+@@ -1285,7 +1278,7 @@ void __init_memblock __next_mem_pfn_rang
+
+ if (PFN_UP(r->base) >= PFN_DOWN(r->base + r->size))
+ continue;
+- if (nid == MAX_NUMNODES || nid == r_nid)
++ if (!numa_valid_node(nid) || nid == r_nid)
+ break;
+ }
+ if (*idx >= type->cnt) {
+@@ -1321,10 +1314,6 @@ int __init_memblock memblock_set_node(ph
+ int start_rgn, end_rgn;
+ int i, ret;
+
+- if (WARN_ONCE(nid == MAX_NUMNODES,
+- "Usage of MAX_NUMNODES is deprecated. Use NUMA_NO_NODE instead\n"))
+- nid = NUMA_NO_NODE;
+-
+ ret = memblock_isolate_range(type, base, size, &start_rgn, &end_rgn);
+ if (ret)
+ return ret;
+@@ -1434,9 +1423,6 @@ phys_addr_t __init memblock_alloc_range_
+ enum memblock_flags flags = choose_memblock_flags();
+ phys_addr_t found;
+
+- if (WARN_ONCE(nid == MAX_NUMNODES, "Usage of MAX_NUMNODES is deprecated. Use NUMA_NO_NODE instead\n"))
+- nid = NUMA_NO_NODE;
+-
+ if (!align) {
+ /* Can't use WARNs this early in boot on powerpc */
+ dump_stack();
+@@ -1449,7 +1435,7 @@ again:
+ if (found && !memblock_reserve(found, size))
+ goto done;
+
+- if (nid != NUMA_NO_NODE && !exact_nid) {
++ if (numa_valid_node(nid) && !exact_nid) {
+ found = memblock_find_in_range_node(size, align, start,
+ end, NUMA_NO_NODE,
+ flags);
+@@ -1969,7 +1955,7 @@ static void __init_memblock memblock_dum
+ end = base + size - 1;
+ flags = rgn->flags;
+ #ifdef CONFIG_NUMA
+- if (memblock_get_region_node(rgn) != MAX_NUMNODES)
++ if (numa_valid_node(memblock_get_region_node(rgn)))
+ snprintf(nid_buf, sizeof(nid_buf), " on node %d",
+ memblock_get_region_node(rgn));
+ #endif
+@@ -2158,7 +2144,7 @@ static void __init memmap_init_reserved_
+ start = region->base;
+ end = start + region->size;
+
+- if (nid == NUMA_NO_NODE || nid >= MAX_NUMNODES)
++ if (!numa_valid_node(nid))
+ nid = early_pfn_to_nid(PFN_DOWN(start));
+
+ reserve_bootmem_region(start, end, nid);
+@@ -2247,7 +2233,7 @@ static int memblock_debug_show(struct se
+
+ seq_printf(m, "%4d: ", i);
+ seq_printf(m, "%pa..%pa ", ®->base, &end);
+- if (nid != MAX_NUMNODES)
++ if (numa_valid_node(nid))
+ seq_printf(m, "%4d ", nid);
+ else
+ seq_printf(m, "%4c ", 'x');