From nobody Wed Apr 1 09:46:38 2026 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 23F0E2F39CE for ; Mon, 30 Mar 2026 19:10:06 +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=1774897807; cv=none; b=Ro6XphldShUbZwUd11aMLfEd7+Tj55tfO9F1Upo+ZseGDJPaf41M6dOH7V4IFuTphRhBDzmqbQbyXbbN3sOI1nEOco6UiIZVSlyQ9+nLuHzFK3HtrcBPXOXvx4Kcc0KdU9xfw4D7u2pC8GVXSl7nQvYtFDTOrXB1l+UQYPH3TMQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1774897807; c=relaxed/simple; bh=7cwqOo5YYIi6EEuVb0HQj+PzP6hAeiwH/oTu7i28ImA=; h=From:To:Cc:Subject:Date:Message-ID:MIME-Version; b=brZxL7HDPVWE9JgO9jMh+y0reaSay5djb8o+5SR0kVV5K7ezq3z+Igjg46Ln809uoYa4tgzuW/hVEIvi2NLEZ53vq07X+tQ6QQuD160wsAcqdqx0fTkMgiCBVS9XMxv+heiHlyh86cx1Q50rJUyK868Z1cucOG7X4ePljZHaosQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=HJ94OImU; 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="HJ94OImU" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 18A07C2BCB1; Mon, 30 Mar 2026 19:10:03 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1774897806; bh=7cwqOo5YYIi6EEuVb0HQj+PzP6hAeiwH/oTu7i28ImA=; h=From:To:Cc:Subject:Date:From; b=HJ94OImU7GMyHM4uljmrb7iv42zXvBXPjHLHk7aFPJ8GtkTXzyt+Z+Ub9FMldtrNV B1aROpTAGd+N3SmxP5aotw7Kv0MXTEv1SI/r5uNU8RSh07dHCddlb3lO49VU9nnbzw 73rUx5yLLMvh3idMDOJIul59XbHFEmyRXox0OBdIkit2v8VNOuw5aphNKRj8AN+pIU v3X6LPYv9SY16oy6PGlIwua2xRZPAgToxDT4C7jUvA1WSagYLtLI/cfxB4bQ8/qW/H 8XbfE4AGskrIkuPVQxBVxvDbYU1ArIB6BaondWy55i0X2NX9NF36Ep7Io4qPSGGxd3 3FxJMgTZiAJiQ== From: Mike Rapoport To: x86@kernel.org Cc: Borislav Petkov , Bert Karwatzki , Dave Hansen , Ingo Molnar , Mike Rapoport , "H. Peter Anvin" , Peter Zijlstra , Thomas Gleixner , linux-kernel@vger.kernel.org, kernel test robot Subject: [PATCH v2] x86/alternative: delay freeing of smp_locks section Date: Mon, 30 Mar 2026 22:10:00 +0300 Message-ID: <20260330191000.1190533-1-rppt@kernel.org> X-Mailer: git-send-email 2.53.0 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: "Mike Rapoport (Microsoft)" On SMP systems alternative_instructions() frees memory occupied by smp_locks section immediately after patching the lock instructions. The memory is freed using free_init_pages() that calls free_reserved_area() that essentially does __free_page() for every page in the range. Up until recently it didn't update memblock state so in cases when CONFIG_ARCH_KEEP_MEMBLOCK is enabled (on x86 it is selected by INTEL_TDX_HOST), the state of memblock and the memory map would be inconsistent. Additionally, with CONFIG_DEFERRED_STRUCT_PAGE_INIT enabled feeing of smp_locks happens before the memory map is fully initialized and freeing reserved memory may case an access to not-yet-initialized struct page when __free_page() searches for a buddy page. Following the discussion in [1], implementation of memblock_free_late() and free_reserved_area() was unified to ensure that reserved memory that's freed after memblock transfers the pages to the buddy allocator is actually freed and that the memblock and the memory map are consistent. As a part of these changes, free_reserved_area() now WARN()s when it is called before the initialization of the memory map is complete. The memory map is fully initialized in page_alloc_init_late() that completes before initcalls are executed, so it is safe to free reserved memory in any initcall except early_initcall(). Move freeing of smp_locks section to an initcall to ensure it will happen after the memory map is fully initialized. Since it does not matter which exactly initcall to use and the code lives in arch/, pick arch_initcall. [1] https://lore.kernel.org/all/ec2aaef14783869b3be6e3c253b2dcbf67dbc12a.ca= mel@kernel.crashing.org Reported-By: Bert Karwatzki Reported-by: kernel test robot Closes: https://lore.kernel.org/oe-lkp/202603302154.b50adaf1-lkp@intel.com Tested-By: Bert Karwatzki Link: https://lore.kernel.org/r/20260327140109.7561-1-spasswolf@web.de Signed-off-by: Mike Rapoport (Microsoft) --- arch/x86/kernel/alternative.c | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/arch/x86/kernel/alternative.c b/arch/x86/kernel/alternative.c index e87da25d1236..62936a3bde19 100644 --- a/arch/x86/kernel/alternative.c +++ b/arch/x86/kernel/alternative.c @@ -2448,19 +2448,31 @@ void __init alternative_instructions(void) __smp_locks, __smp_locks_end, _text, _etext); } +#endif =20 + restart_nmi(); + alternatives_patched =3D 1; + + alt_reloc_selftest(); +} + +#ifdef CONFIG_SMP +/* + * With CONFIG_DEFERRED_STRUCT_PAGE_INIT enabled we can free_init_pages() = only + * after the deferred initialization of the memory map is complete. + */ +static int __init free_smp_locks(void) +{ if (!uniproc_patched || num_possible_cpus() =3D=3D 1) { free_init_pages("SMP alternatives", (unsigned long)__smp_locks, (unsigned long)__smp_locks_end); } -#endif =20 - restart_nmi(); - alternatives_patched =3D 1; - - alt_reloc_selftest(); + return 0; } +arch_initcall(free_smp_locks); +#endif =20 /** * text_poke_early - Update instructions on a live kernel at boot time base-commit: e77a5a5cfe43b4c25bd44a3818e487033287517f --=20 2.53.0