On 5/12/25 05:34, gregkh@linuxfoundation.org wrote:
This is a note to let you know that I've just added the patch titled
memblock: Accept allocated memory before use in memblock_double_array()
to the 6.6-stable tree which can be found at: http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git%3Ba=su...
The filename of the patch is: memblock-accept-allocated-memory-before-use-in-memblock_double_array.patch and it can be found in the queue-6.6 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree, please let stable@vger.kernel.org know about it.
The 6.6 version of the patch needs a fixup. As mentioned in the patch description, any release before v6.12 needs to have the accept_memory() call changed from:
accept_memory(addr, new_alloc_size);
to
accept_memory(addr, addr + new_alloc_size);
Do you need for me to send a v6.6 specific patch?
Thanks, Tom
From da8bf5daa5e55a6af2b285ecda460d6454712ff4 Mon Sep 17 00:00:00 2001 From: Tom Lendacky thomas.lendacky@amd.com Date: Thu, 8 May 2025 12:24:10 -0500 Subject: memblock: Accept allocated memory before use in memblock_double_array()
From: Tom Lendacky thomas.lendacky@amd.com
commit da8bf5daa5e55a6af2b285ecda460d6454712ff4 upstream.
When increasing the array size in memblock_double_array() and the slab is not yet available, a call to memblock_find_in_range() is used to reserve/allocate memory. However, the range returned may not have been accepted, which can result in a crash when booting an SNP guest:
RIP: 0010:memcpy_orig+0x68/0x130 Code: ... RSP: 0000:ffffffff9cc03ce8 EFLAGS: 00010006 RAX: ff11001ff83e5000 RBX: 0000000000000000 RCX: fffffffffffff000 RDX: 0000000000000bc0 RSI: ffffffff9dba8860 RDI: ff11001ff83e5c00 RBP: 0000000000002000 R08: 0000000000000000 R09: 0000000000002000 R10: 000000207fffe000 R11: 0000040000000000 R12: ffffffff9d06ef78 R13: ff11001ff83e5000 R14: ffffffff9dba7c60 R15: 0000000000000c00 memblock_double_array+0xff/0x310 memblock_add_range+0x1fb/0x2f0 memblock_reserve+0x4f/0xa0 memblock_alloc_range_nid+0xac/0x130 memblock_alloc_internal+0x53/0xc0 memblock_alloc_try_nid+0x3d/0xa0 swiotlb_init_remap+0x149/0x2f0 mem_init+0xb/0xb0 mm_core_init+0x8f/0x350 start_kernel+0x17e/0x5d0 x86_64_start_reservations+0x14/0x30 x86_64_start_kernel+0x92/0xa0 secondary_startup_64_no_verify+0x194/0x19b
Mitigate this by calling accept_memory() on the memory range returned before the slab is available.
Prior to v6.12, the accept_memory() interface used a 'start' and 'end' parameter instead of 'start' and 'size', therefore the accept_memory() call must be adjusted to specify 'start + size' for 'end' when applying to kernels prior to v6.12.
Cc: stable@vger.kernel.org # see patch description, needs adjustments for <= 6.11 Fixes: dcdfdd40fa82 ("mm: Add support for unaccepted memory") Signed-off-by: Tom Lendacky thomas.lendacky@amd.com Link: https://lore.kernel.org/r/da1ac73bf4ded761e21b4e4bb5178382a580cd73.174672505... Signed-off-by: Mike Rapoport (Microsoft) rppt@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
mm/memblock.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-)
--- a/mm/memblock.c +++ b/mm/memblock.c @@ -460,7 +460,14 @@ static int __init_memblock memblock_doub min(new_area_start, memblock.current_limit), new_alloc_size, PAGE_SIZE);
new_array = addr ? __va(addr) : NULL;
if (addr) {
/* The memory may not have been accepted, yet. */
accept_memory(addr, new_alloc_size);
new_array = __va(addr);
} else {
new_array = NULL;
} if (!addr) { pr_err("memblock: Failed to double %s array from %ld to %ld entries !\n",}
Patches currently in stable-queue which might be from thomas.lendacky@amd.com are
queue-6.6/memblock-accept-allocated-memory-before-use-in-memblock_double_array.patch
On Mon, May 12, 2025 at 08:15:22AM -0500, Tom Lendacky wrote:
On 5/12/25 05:34, gregkh@linuxfoundation.org wrote:
This is a note to let you know that I've just added the patch titled
memblock: Accept allocated memory before use in memblock_double_array()
to the 6.6-stable tree which can be found at: http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git%3Ba=su...
The filename of the patch is: memblock-accept-allocated-memory-before-use-in-memblock_double_array.patch and it can be found in the queue-6.6 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree, please let stable@vger.kernel.org know about it.
The 6.6 version of the patch needs a fixup. As mentioned in the patch description, any release before v6.12 needs to have the accept_memory() call changed from:
accept_memory(addr, new_alloc_size);
to
accept_memory(addr, addr + new_alloc_size);
Do you need for me to send a v6.6 specific patch?
Yes please, I'll go drop this one now.
thanks.
greg k-h
commit da8bf5daa5e55a6af2b285ecda460d6454712ff4 upstream.
When increasing the array size in memblock_double_array() and the slab is not yet available, a call to memblock_find_in_range() is used to reserve/allocate memory. However, the range returned may not have been accepted, which can result in a crash when booting an SNP guest:
RIP: 0010:memcpy_orig+0x68/0x130 Code: ... RSP: 0000:ffffffff9cc03ce8 EFLAGS: 00010006 RAX: ff11001ff83e5000 RBX: 0000000000000000 RCX: fffffffffffff000 RDX: 0000000000000bc0 RSI: ffffffff9dba8860 RDI: ff11001ff83e5c00 RBP: 0000000000002000 R08: 0000000000000000 R09: 0000000000002000 R10: 000000207fffe000 R11: 0000040000000000 R12: ffffffff9d06ef78 R13: ff11001ff83e5000 R14: ffffffff9dba7c60 R15: 0000000000000c00 memblock_double_array+0xff/0x310 memblock_add_range+0x1fb/0x2f0 memblock_reserve+0x4f/0xa0 memblock_alloc_range_nid+0xac/0x130 memblock_alloc_internal+0x53/0xc0 memblock_alloc_try_nid+0x3d/0xa0 swiotlb_init_remap+0x149/0x2f0 mem_init+0xb/0xb0 mm_core_init+0x8f/0x350 start_kernel+0x17e/0x5d0 x86_64_start_reservations+0x14/0x30 x86_64_start_kernel+0x92/0xa0 secondary_startup_64_no_verify+0x194/0x19b
Mitigate this by calling accept_memory() on the memory range returned before the slab is available.
Prior to v6.12, the accept_memory() interface used a 'start' and 'end' parameter instead of 'start' and 'size', therefore the accept_memory() call must be adjusted to specify 'start + size' for 'end' when applying to kernels prior to v6.12.
Cc: stable@vger.kernel.org # see patch description, needs adjustments for <= 6.11 Fixes: dcdfdd40fa82 ("mm: Add support for unaccepted memory") Signed-off-by: Tom Lendacky thomas.lendacky@amd.com Link: https://lore.kernel.org/r/da1ac73bf4ded761e21b4e4bb5178382a580cd73.174672505... Signed-off-by: Mike Rapoport (Microsoft) rppt@kernel.org
---
This version of the patch is to be applied to the v6.6 stable branch. --- mm/memblock.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-)
diff --git a/mm/memblock.c b/mm/memblock.c index 047dce35cf6e..0695284232f3 100644 --- a/mm/memblock.c +++ b/mm/memblock.c @@ -460,7 +460,14 @@ static int __init_memblock memblock_double_array(struct memblock_type *type, min(new_area_start, memblock.current_limit), new_alloc_size, PAGE_SIZE);
- new_array = addr ? __va(addr) : NULL; + if (addr) { + /* The memory may not have been accepted, yet. */ + accept_memory(addr, addr + new_alloc_size); + + new_array = __va(addr); + } else { + new_array = NULL; + } } if (!addr) { pr_err("memblock: Failed to double %s array from %ld to %ld entries !\n",
base-commit: 9c2dd8954dad0430e83ee55b985ba55070e50cf7
[ Sasha's backport helper bot ]
Hi,
Summary of potential issues: ❌ Build failures detected
The upstream commit SHA1 provided is correct: da8bf5daa5e55a6af2b285ecda460d6454712ff4
Note: The patch differs from the upstream commit: --- 1: da8bf5daa5e55 ! 1: 22fb53476f796 memblock: Accept allocated memory before use in memblock_double_array() @@ Metadata ## Commit message ## memblock: Accept allocated memory before use in memblock_double_array()
+ commit da8bf5daa5e55a6af2b285ecda460d6454712ff4 upstream. + When increasing the array size in memblock_double_array() and the slab is not yet available, a call to memblock_find_in_range() is used to reserve/allocate memory. However, the range returned may not have been @@ mm/memblock.c: static int __init_memblock memblock_double_array(struct memblock_ - new_array = addr ? __va(addr) : NULL; + if (addr) { + /* The memory may not have been accepted, yet. */ -+ accept_memory(addr, new_alloc_size); ++ accept_memory(addr, addr + new_alloc_size); + + new_array = __va(addr); + } else { ---
Results of testing on various branches:
| Branch | Patch Apply | Build Test | |---------------------------|-------------|------------| | stable/linux-6.14.y | Success | Success | | stable/linux-6.12.y | Success | Success | | stable/linux-6.6.y | Success | Success | | stable/linux-6.1.y | Success | Failed | | stable/linux-5.15.y | Success | Failed | | stable/linux-5.10.y | Success | Failed | | stable/linux-5.4.y | Success | Failed |
Build Errors: Build error for stable/linux-6.1.y: mm/memblock.c: In function 'memblock_double_array': mm/memblock.c:460:25: error: implicit declaration of function 'accept_memory'; did you mean 'add_memory'? [-Wimplicit-function-declaration] 460 | accept_memory(addr, addr + new_alloc_size); | ^~~~~~~~~~~~~ | add_memory make[2]: *** [scripts/Makefile.build:250: mm/memblock.o] Error 1 make[2]: Target 'mm/' not remade because of errors. make[1]: *** [scripts/Makefile.build:503: mm] Error 2 make[1]: Target './' not remade because of errors. make: *** [Makefile:2013: .] Error 2 make: Target '__all' not remade because of errors.
Build error for stable/linux-5.15.y: mm/memblock.c: In function 'memblock_double_array': mm/memblock.c:455:25: error: implicit declaration of function 'accept_memory'; did you mean 'add_memory'? [-Werror=implicit-function-declaration] 455 | accept_memory(addr, addr + new_alloc_size); | ^~~~~~~~~~~~~ | add_memory cc1: some warnings being treated as errors make[1]: *** [scripts/Makefile.build:289: mm/memblock.o] Error 1 make[1]: Target '__build' not remade because of errors. make: *** [Makefile:1914: mm] Error 2 make: Target '__all' not remade because of errors.
Build error for stable/linux-5.10.y: kernel/trace/trace_events_synth.c: In function 'synth_event_reg': kernel/trace/trace_events_synth.c:847:9: warning: ISO C90 forbids mixed declarations and code [-Wdeclaration-after-statement] 847 | int ret = trace_event_reg(call, type, data); | ^~~ mm/memblock.c: In function 'memblock_double_array': mm/memblock.c:455:25: error: implicit declaration of function 'accept_memory'; did you mean 'add_memory'? [-Werror=implicit-function-declaration] 455 | accept_memory(addr, addr + new_alloc_size); | ^~~~~~~~~~~~~ | add_memory cc1: some warnings being treated as errors make[1]: *** [scripts/Makefile.build:286: mm/memblock.o] Error 1 make[1]: Target '__build' not remade because of errors. make: *** [Makefile:1840: mm] Error 2 In file included from ./include/linux/kernel.h:15, from ./include/linux/list.h:9, from ./include/linux/kobject.h:19, from ./include/linux/of.h:17, from ./include/linux/clk-provider.h:9, from drivers/clk/qcom/clk-rpmh.c:6: drivers/clk/qcom/clk-rpmh.c: In function 'clk_rpmh_bcm_send_cmd': ./include/linux/minmax.h:20:35: warning: comparison of distinct pointer types lacks a cast [-Wcompare-distinct-pointer-types] 20 | (!!(sizeof((typeof(x) *)1 == (typeof(y) *)1))) | ^~ ./include/linux/minmax.h:26:18: note: in expansion of macro '__typecheck' 26 | (__typecheck(x, y) && __no_side_effects(x, y)) | ^~~~~~~~~~~ ./include/linux/minmax.h:36:31: note: in expansion of macro '__safe_cmp' 36 | __builtin_choose_expr(__safe_cmp(x, y), \ | ^~~~~~~~~~ ./include/linux/minmax.h:45:25: note: in expansion of macro '__careful_cmp' 45 | #define min(x, y) __careful_cmp(x, y, <) | ^~~~~~~~~~~~~ drivers/clk/qcom/clk-rpmh.c:273:21: note: in expansion of macro 'min' 273 | cmd_state = min(cmd_state, BCM_TCS_CMD_VOTE_MASK); | ^~~ drivers/firmware/efi/mokvar-table.c: In function 'efi_mokvar_table_init': drivers/firmware/efi/mokvar-table.c:107:23: warning: unused variable 'size' [-Wunused-variable] 107 | unsigned long size; | ^~~~ make: Target '__all' not remade because of errors.
Build error for stable/linux-5.4.y: arch/x86/entry/entry_64.o: warning: objtool: .entry.text+0x1e1: stack state mismatch: cfa1=7+56 cfa2=7+40 arch/x86/kvm/vmx/vmenter.o: warning: objtool: __vmx_vcpu_run()+0x12a: return with modified stack frame mm/memblock.c: In function 'memblock_double_array': mm/memblock.c:435:25: error: implicit declaration of function 'accept_memory'; did you mean 'add_memory'? [-Werror=implicit-function-declaration] 435 | accept_memory(addr, addr + new_alloc_size); | ^~~~~~~~~~~~~ | add_memory cc1: some warnings being treated as errors make[1]: *** [scripts/Makefile.build:262: mm/memblock.o] Error 1 In file included from ./include/linux/list.h:9, from ./include/linux/kobject.h:19, from ./include/linux/of.h:17, from ./include/linux/clk-provider.h:9, from drivers/clk/qcom/clk-rpmh.c:6: drivers/clk/qcom/clk-rpmh.c: In function 'clk_rpmh_bcm_send_cmd': ./include/linux/kernel.h:843:43: warning: comparison of distinct pointer types lacks a cast [-Wcompare-distinct-pointer-types] 843 | (!!(sizeof((typeof(x) *)1 == (typeof(y) *)1))) | ^~ ./include/linux/kernel.h:857:18: note: in expansion of macro '__typecheck' 857 | (__typecheck(x, y) && __no_side_effects(x, y)) | ^~~~~~~~~~~ ./include/linux/kernel.h:867:31: note: in expansion of macro '__safe_cmp' 867 | __builtin_choose_expr(__safe_cmp(x, y), \ | ^~~~~~~~~~ ./include/linux/kernel.h:876:25: note: in expansion of macro '__careful_cmp' 876 | #define min(x, y) __careful_cmp(x, y, <) | ^~~~~~~~~~~~~ drivers/clk/qcom/clk-rpmh.c:273:21: note: in expansion of macro 'min' 273 | cmd_state = min(cmd_state, BCM_TCS_CMD_VOTE_MASK); | ^~~ make[1]: Target '__build' not remade because of errors. make: *** [Makefile:1758: mm] Error 2 fs/xfs/libxfs/xfs_inode_fork.c: In function 'xfs_ifork_verify_attr': fs/xfs/libxfs/xfs_inode_fork.c:735:13: warning: the comparison will always evaluate as 'true' for the address of 'i_df' will never be NULL [-Waddress] 735 | if (!XFS_IFORK_PTR(ip, XFS_ATTR_FORK)) | ^ In file included from fs/xfs/libxfs/xfs_inode_fork.c:14: ./fs/xfs/xfs_inode.h:38:33: note: 'i_df' declared here 38 | struct xfs_ifork i_df; /* data fork */ | ^~~~ drivers/gpu/drm/i915/display/intel_dp.c: In function 'intel_dp_mode_valid': drivers/gpu/drm/i915/display/intel_dp.c:639:33: warning: 'drm_dp_dsc_sink_max_slice_count' reading 16 bytes from a region of size 0 [-Wstringop-overread] 639 | drm_dp_dsc_sink_max_slice_count(intel_dp->dsc_dpcd, | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 640 | true); | ~~~~~ drivers/gpu/drm/i915/display/intel_dp.c:639:33: note: referencing argument 1 of type 'const u8[16]' {aka 'const unsigned char[16]'} In file included from drivers/gpu/drm/i915/display/intel_dp.c:39: ./include/drm/drm_dp_helper.h:1174:4: note: in a call to function 'drm_dp_dsc_sink_max_slice_count' 1174 | u8 drm_dp_dsc_sink_max_slice_count(const u8 dsc_dpcd[DP_DSC_RECEIVER_CAP_SIZE], | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ drivers/net/dsa/microchip/ksz9477.c: In function 'ksz9477_reset_switch': drivers/net/dsa/microchip/ksz9477.c:198:12: warning: unused variable 'data8' [-Wunused-variable] 198 | u8 data8; | ^~~~~ In file included from ./include/linux/bitops.h:5, from ./include/linux/kernel.h:12, from ./include/linux/list.h:9, from ./include/linux/module.h:9, from drivers/net/ethernet/qlogic/qed/qed_debug.c:6: drivers/net/ethernet/qlogic/qed/qed_debug.c: In function 'qed_grc_dump_addr_range': ./include/linux/bits.h:8:33: warning: overflow in conversion from 'long unsigned int' to 'u8' {aka 'unsigned char'} changes value from '(long unsigned int)((int)vf_id << 8 | 128)' to '128' [-Woverflow] 8 | #define BIT(nr) (UL(1) << (nr)) | ^ drivers/net/ethernet/qlogic/qed/qed_debug.c:2572:31: note: in expansion of macro 'BIT' 2572 | fid = BIT(PXP_PRETEND_CONCRETE_FID_VFVALID_SHIFT) | | ^~~ drivers/gpu/drm/nouveau/dispnv50/wndw.c:628:1: warning: conflicting types for 'nv50_wndw_new_' due to enum/integer mismatch; have 'int(const struct nv50_wndw_func *, struct drm_device *, enum drm_plane_type, const char *, int, const u32 *, u32, enum nv50_disp_interlock_type, u32, struct nv50_wndw **)' {aka 'int(const struct nv50_wndw_func *, struct drm_device *, enum drm_plane_type, const char *, int, const unsigned int *, unsigned int, enum nv50_disp_interlock_type, unsigned int, struct nv50_wndw **)'} [-Wenum-int-mismatch] 628 | nv50_wndw_new_(const struct nv50_wndw_func *func, struct drm_device *dev, | ^~~~~~~~~~~~~~ In file included from drivers/gpu/drm/nouveau/dispnv50/wndw.c:22: drivers/gpu/drm/nouveau/dispnv50/wndw.h:39:5: note: previous declaration of 'nv50_wndw_new_' with type 'int(const struct nv50_wndw_func *, struct drm_device *, enum drm_plane_type, const char *, int, const u32 *, enum nv50_disp_interlock_type, u32, u32, struct nv50_wndw **)' {aka 'int(const struct nv50_wndw_func *, struct drm_device *, enum drm_plane_type, const char *, int, const unsigned int *, enum nv50_disp_interlock_type, unsigned int, unsigned int, struct nv50_wndw **)'} 39 | int nv50_wndw_new_(const struct nv50_wndw_func *, struct drm_device *, | ^~~~~~~~~~~~~~ make: Target '_all' not remade because of errors.
linux-stable-mirror@lists.linaro.org