From nobody Thu Jun 18 07:54:40 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 E79B22BF3F4; Fri, 1 May 2026 04:08:50 +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=1777608531; cv=none; b=TN9Z2WGUERxwMDQXyuoI2+I9xl/rRGwsRNeXbjsGeI9xD+H03M+vskUs2xr6IKDDfzejkk5JdRTWbULJzQVpkDqdvgnU/XNCH+pfXm/1DJvOK1layTkjezsqqUotp4ptRPXrsDKssEQwZSfV1+1zVeuKjLQ5l/6440OIMlX9cME= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777608531; c=relaxed/simple; bh=JlUvFHpCA3SGzTQKdf6SJ+DOcUBCUPFgx5KEWx/vo+Y=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=CasJv49G1cmO0VG6IrBLNg0geCzQzEn7HyMoFsR76jPw+G0jz+dPrKuAd2P3ponD/PLdlEhDxJDs9sYvoR7sKWVldRrwWF1PyZQZFTWMNUkioHxUb45QVc/V/KjZTm02Zml9z1H9ZE8PHqt1MiWwGMbuXI31DnftzxKj2QneWxo= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=PZJNIoAO; 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="PZJNIoAO" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 7B61EC2BCB9; Fri, 1 May 2026 04:08:50 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1777608530; bh=JlUvFHpCA3SGzTQKdf6SJ+DOcUBCUPFgx5KEWx/vo+Y=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=PZJNIoAOT4WPQ7ghmRUgmoQmJ+naVWxq9ntdWI+E1ekkZaRQscPoF8haN6uifXEbr zF7W+cVHv0ZPAJ4DkABtFV+ooNx08qO0PvsYdq50QhkkQAsIUOqDKvtxIFUdJhQx35 8qAye3DHHsv3Z2CihkWuxTjFO75MReK0GIsG15DFLgTT7DTNOT5pGmzEnTU/EuDmIs cujd0Nb7Ahw07FNLMCKHaxsFPf9sStxlT0/oYZl0lqMwupUYy0WKYsECJycAHfHq38 5bgmEdnS+zq+AxXhIKMIecYoekWzH57QY7CQSuvomDNChA7+AhLYEY2at4FMeuy4rZ QyEUOVbgB+14w== From: Josh Poimboeuf To: x86@kernel.org Cc: linux-kernel@vger.kernel.org, live-patching@vger.kernel.org, Peter Zijlstra , Joe Lawrence , Song Liu , Miroslav Benes , Petr Mladek Subject: [PATCH v2 01/53] objtool/klp: Fix is_uncorrelated_static_local() for Clang Date: Thu, 30 Apr 2026 21:07:49 -0700 Message-ID: X-Mailer: git-send-email 2.53.0 In-Reply-To: References: 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: Joe Lawrence For naming function-local static locals, GCC uses ., e.g. __already_done.15, while Clang uses . with optional ., e.g. create_worker.__already_done.111 The existing is_uncorrelated_static_local() check only matches the GCC convention where the variable name is a prefix. Handle both cases by checking for a prefix match (GCC) and by checking after the first dot separator (Clang). Fixes: dd590d4d57eb ("objtool/klp: Introduce klp diff subcommand for diffin= g object files") Signed-off-by: Joe Lawrence Acked-by: Song Liu Reviewed-by: Miroslav Benes Signed-off-by: Josh Poimboeuf --- tools/objtool/klp-diff.c | 33 +++++++++++++++++++++++---------- 1 file changed, 23 insertions(+), 10 deletions(-) diff --git a/tools/objtool/klp-diff.c b/tools/objtool/klp-diff.c index 0b0d1503851f..b1b068e9b4c7 100644 --- a/tools/objtool/klp-diff.c +++ b/tools/objtool/klp-diff.c @@ -242,16 +242,17 @@ static struct symbol *next_file_symbol(struct elf *el= f, struct symbol *sym) static bool is_uncorrelated_static_local(struct symbol *sym) { static const char * const vars[] =3D { - "__already_done.", - "__func__.", - "__key.", - "__warned.", - "_entry.", - "_entry_ptr.", - "_rs.", - "descriptor.", - "CSWTCH.", + "__already_done", + "__func__", + "__key", + "__warned", + "_entry", + "_entry_ptr", + "_rs", + "descriptor", + "CSWTCH", }; + const char *dot; =20 if (!is_object_sym(sym) || !is_local_sym(sym)) return false; @@ -259,8 +260,20 @@ static bool is_uncorrelated_static_local(struct symbol= *sym) if (!strcmp(sym->sec->name, ".data.once")) return true; =20 + dot =3D strchr(sym->name, '.'); + if (!dot) + return false; + for (int i =3D 0; i < ARRAY_SIZE(vars); i++) { - if (strstarts(sym->name, vars[i])) + size_t len =3D strlen(vars[i]); + + /* GCC: . */ + if (strstarts(sym->name, vars[i]) && (sym->name[len] =3D=3D '.')) + return true; + + /* Clang: .[.] */ + if (strstarts(dot + 1, vars[i]) && + (dot[1 + len] =3D=3D '.' || dot[1 + len] =3D=3D '\0')) return true; } =20 --=20 2.53.0 From nobody Thu Jun 18 07:54:40 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 5C45E2DFA5B; Fri, 1 May 2026 04:08:51 +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=1777608531; cv=none; b=p3VyBKBxvLLeIwklS98CcWrWEerdqySPDbB2xhljG0jE06iAQGFjDtsDoo308iF3J+EvXRXgoyWM6ZovcAl6gIXPMi0Zl9dDg1ITs9joUPvkHCgwqNv7oVNhSEMUjyXiKygF1kMQVNyUswn2Zrl5kz7ybzqEYDD2lHT5jmfohJ0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777608531; c=relaxed/simple; bh=+60H085Djk62NlTyS/d3jVQprhrQBih8YD1olXS3z6w=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=U+IhmuPbnsOsBHFAiGHjFXQ2hlkE4vSjlM+KVLK6hw7Ts6vECpmEUrg42/YxVXUOGW7CaVRA8p7hbhuepPOwUoaK2artkbgHAMEtrXG05Y8Yz6g3r5g3vHhBrXwo+1GahwRHj9GYnUCAYQ2mMZolK3Qlz9M1YCEO/ftVvBTU43A= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=oiQ96GQi; 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="oiQ96GQi" Received: by smtp.kernel.org (Postfix) with ESMTPSA id EA4FAC2BCC6; Fri, 1 May 2026 04:08:50 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1777608531; bh=+60H085Djk62NlTyS/d3jVQprhrQBih8YD1olXS3z6w=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=oiQ96GQirQzajAaxPudNAR2OzQ1mWgCohph2KSmLudrfVWSLlIkLsaUhqGr3KC9nv 1B4XwpCcAl1BsI6PrVxJpedB4LnWp4GVZRe0ysbLW3ypxS4kPyt0UuBYR7wdErNL7q Cgql/2O3k245aVzIp6bRLJaDuPKLC6XFQj9qSUTynNNHmyqaHvJJlTbTo26NFFPiTq fcLz96/VuxQbYNtr49u9HQGtua5ztnRZyTGHtjH2OnEOp/GXaHC+BbpUrIYZicYWvv f4P4OLu2aZZ3C2L1jlsuT8HPBz2BaeAmnXC1J898hoemiTKEaEELBgNqewstsh5mFt /vQSZCetPYZlg== From: Josh Poimboeuf To: x86@kernel.org Cc: linux-kernel@vger.kernel.org, live-patching@vger.kernel.org, Peter Zijlstra , Joe Lawrence , Song Liu , Miroslav Benes , Petr Mladek Subject: [PATCH v2 02/53] objtool/klp: Fix .data..once static local non-correlation Date: Thu, 30 Apr 2026 21:07:50 -0700 Message-ID: <2b864105c4f0d5c58006ec43f6ddde1bef2fe250.1777575752.git.jpoimboe@kernel.org> X-Mailer: git-send-email 2.53.0 In-Reply-To: References: 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" While there was once a section named .data.once, it has since been renamed to .data..once with commit dbefa1f31a91 ("Rename .data.once to .data..once to fix resetting WARN*_ONCE"). Fix it. Fixes: dd590d4d57eb ("objtool/klp: Introduce klp diff subcommand for diffin= g object files") Acked-by: Song Liu Reviewed-by: Miroslav Benes Signed-off-by: Josh Poimboeuf --- tools/objtool/klp-diff.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tools/objtool/klp-diff.c b/tools/objtool/klp-diff.c index b1b068e9b4c7..cb26c1c92a74 100644 --- a/tools/objtool/klp-diff.c +++ b/tools/objtool/klp-diff.c @@ -257,7 +257,8 @@ static bool is_uncorrelated_static_local(struct symbol = *sym) if (!is_object_sym(sym) || !is_local_sym(sym)) return false; =20 - if (!strcmp(sym->sec->name, ".data.once")) + /* WARN_ONCE, etc */ + if (!strcmp(sym->sec->name, ".data..once")) return true; =20 dot =3D strchr(sym->name, '.'); --=20 2.53.0 From nobody Thu Jun 18 07:54:40 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 F0CE12F4A16; Fri, 1 May 2026 04:08:51 +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=1777608532; cv=none; b=jLlH4fqKxZpoJQWJ9ojoDlgJvogVhMpV4oJkLMlXIfXPYQvvHV7QEXVQNty3o7qRNEigOQduhF8aZGITV11plhKK5rnWKKxCS9i8PHJVxuC4WG3Tdo9lGqhstbF0W4JZ7LvAGY1a8/w8sn0JDaNO/k9Texfps6M1/JfUfu7251o= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777608532; c=relaxed/simple; bh=+NM3TboCjx9zMokNZj1lQYyUCDXizYcds2lJrXgjfgQ=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=mwPeaH0YCiW02dCWEtHo6H2/IYuM6byH/+8cGTu2jMFteBy2bX+hKhlnBiqyi6NnoiReogHFkVhu6PaD1NuNKtk/htR5TMy/LG+qqny3RtctKC9T1/veWuGs6P+6Jv7wZTAm8xrTiKMUtdV9YBkyT6Rwrb8ljAkH8o+TPjt0IFg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=FgnM87Yl; 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="FgnM87Yl" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 65E8EC2BCB7; Fri, 1 May 2026 04:08:51 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1777608531; bh=+NM3TboCjx9zMokNZj1lQYyUCDXizYcds2lJrXgjfgQ=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=FgnM87YlXl6u+uSiby63QlCT85KpQZPEkzYWC/p0Fi7GP8mSB2kkoGY5SHfXbAV6T lZCwjYmNG8zHqVP8p+RfiN7sAMiITbRFFGp8b6j35LTW33T+S82ZgRMO6c/PhY0oK2 jLxZbLNgebcNe44h1bp2LcdN0048DB7JM3lN4r4TUIfFkpwjz+t83/Fg3rfhbUofmy 8n49ss2pWAxUW0Zekt0U8F4xSG5I78hYD9vvIUu0YM/GcunyHlz0v44WEbifppCOaH sQQZhcHYQa09IjtPXtZlTdL3w1WMuqRfMfqO5KSt7jjVu+zlTSHklLmNkc1shvMclO Jn/6HTPRKYRuQ== From: Josh Poimboeuf To: x86@kernel.org Cc: linux-kernel@vger.kernel.org, live-patching@vger.kernel.org, Peter Zijlstra , Joe Lawrence , Song Liu , Miroslav Benes , Petr Mladek Subject: [PATCH v2 03/53] objtool/klp: Don't correlate __ADDRESSABLE() symbols Date: Thu, 30 Apr 2026 21:07:51 -0700 Message-ID: <8e69c287bd6c33cec1535228e2239b33f4602bc6.1777575752.git.jpoimboe@kernel.org> X-Mailer: git-send-email 2.53.0 In-Reply-To: References: 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" Symbols created by __ADDRESSABLE() are only used to convince the toolchain not to optimize out the referenced symbol. Reviewed-by: Miroslav Benes Signed-off-by: Josh Poimboeuf Acked-by: Song Liu --- tools/objtool/klp-diff.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/tools/objtool/klp-diff.c b/tools/objtool/klp-diff.c index cb26c1c92a74..36753eeba58c 100644 --- a/tools/objtool/klp-diff.c +++ b/tools/objtool/klp-diff.c @@ -352,6 +352,15 @@ static bool is_special_section_aux(struct section *sec) return false; } =20 +/* + * Symbols created by ___ADDRESSABLE() are only used to convince the toolc= hain + * not to optimize out the referenced symbol. + */ +static bool is_addressable_sym(struct symbol *sym) +{ + return !strcmp(sym->sec->name, ".discard.addressable"); +} + /* * These symbols should never be correlated, so their local patched versio= ns * are used instead of linking to the originals. @@ -365,6 +374,7 @@ static bool dont_correlate(struct symbol *sym) is_uncorrelated_static_local(sym) || is_clang_tmp_label(sym) || is_string_sec(sym->sec) || + is_addressable_sym(sym) || is_special_section(sym->sec) || is_special_section_aux(sym->sec) || strstarts(sym->name, "__initcall__"); --=20 2.53.0 From nobody Thu Jun 18 07:54:40 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 64C562F9D98; Fri, 1 May 2026 04:08:52 +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=1777608532; cv=none; b=MGp3LW6Ev057VkZUDqrrDpM4V01+w2G4k0GeawGU1S00SnZMaz11T3k6m5RkCsGrP/YVWZdZ35dYtV9mBhI7hpsBncMTcPgcKUuFB77pp4E3sOqSHznYG2ANmYGnI1FFECpjJB3+TBEtMcwGSFTiBfbCwm4HDJyKFboGiBObCsA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777608532; c=relaxed/simple; bh=qH4RZkCPnkCHZ+L+3uEq2QGmezXAYx2GOoMqX7Scsoc=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=ZTx4QsXKgHJ0fKdNGD3kkWGnzlCwt9+YzqNZCwdfInrKa/Rq65zqyUuRgzpssp/AbpRyhZzXtLhMebQdCZHUJaMVU5pPGoDVDyijkOARP70mFY1WZesC1e/oilZeBZMx9gXHuyEf6gpVesD5Df53jDv8yS78ySSb0DO2mmhBJU0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=X16wkMbh; 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="X16wkMbh" Received: by smtp.kernel.org (Postfix) with ESMTPSA id D5C9AC2BCC9; Fri, 1 May 2026 04:08:51 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1777608532; bh=qH4RZkCPnkCHZ+L+3uEq2QGmezXAYx2GOoMqX7Scsoc=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=X16wkMbhUQYyQBV0wTQPttuyyXnD8v2BypPkt+h9aMPZJy0dqb6c6FbZr1X7Fe/4M 6Gh5Q3TnzZHdBY1x6W0hOB9TuVefmGqWxoHReOEqJBkBQGBB5UYpQ/pBJptpSjLC7U lm95KPvozbFekVtR1cRCK+5tsCtsJ9RlE9jhPw7IND2t36o6TVAy6i9f90RQS6sJDW kg5WLfpbAk9/0nUBrjOc1nbBgPOsAHV+qYA18u2ji//+Yb46B9X6+7A8zCiIc0J+/g 99MGIEmM8BkkKtxWdf5TjYhZiSWokF28+tint/ZG4YV8H5P6e+5XotHDRlvsOnQzBY pisIpNXIrgP3A== From: Josh Poimboeuf To: x86@kernel.org Cc: linux-kernel@vger.kernel.org, live-patching@vger.kernel.org, Peter Zijlstra , Joe Lawrence , Song Liu , Miroslav Benes , Petr Mladek Subject: [PATCH v2 04/53] objtool/klp: Don't correlate absolute symbols Date: Thu, 30 Apr 2026 21:07:52 -0700 Message-ID: X-Mailer: git-send-email 2.53.0 In-Reply-To: References: 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" Some arch/x86/crypto/*.S files define local .set/.equ constants that get duplicated in vmlinux.o. This causes klp-diff to fail with "Multiple correlation candidates" errors since it can't uniquely match these between orig and patched builds. Skip ABS symbols in dont_correlate(). They're purely compile-time assembly constants that are never referenced by relocations, so they don't need correlation. Acked-by: Song Liu Reviewed-by: Miroslav Benes Signed-off-by: Josh Poimboeuf --- tools/objtool/klp-diff.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/tools/objtool/klp-diff.c b/tools/objtool/klp-diff.c index 36753eeba58c..27ebe1b1f463 100644 --- a/tools/objtool/klp-diff.c +++ b/tools/objtool/klp-diff.c @@ -361,6 +361,15 @@ static bool is_addressable_sym(struct symbol *sym) return !strcmp(sym->sec->name, ".discard.addressable"); } =20 +/* + * ABS symbols are typically assembly .set/.equ constants which are never + * referenced by relocations. (Exclude FILE symbols which are also SHN_AB= S.) + */ +static bool is_abs_sym(struct symbol *sym) +{ + return sym->sym.st_shndx =3D=3D SHN_ABS && !is_file_sym(sym); +} + /* * These symbols should never be correlated, so their local patched versio= ns * are used instead of linking to the originals. @@ -370,6 +379,7 @@ static bool dont_correlate(struct symbol *sym) return is_file_sym(sym) || is_null_sym(sym) || is_sec_sym(sym) || + is_abs_sym(sym) || is_prefix_func(sym) || is_uncorrelated_static_local(sym) || is_clang_tmp_label(sym) || --=20 2.53.0 From nobody Thu Jun 18 07:54:40 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 C0F602FFF89; Fri, 1 May 2026 04:08:52 +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=1777608532; cv=none; b=jhD5C3UHVH71HjFFHAOOX1xfcIQzZfexdO9kXq9KVqYw6UYX2AZyLbDpZVj8vVD1zzp/+Ed4CIE7sPQW+JkdKXP7djq6BNkfuC6s76J9OMAC7E0a6EboeR76vP1KZwpGmvvgMUbaYKNis51N9pBnN5Jq+8jTCS/JMOHLRZdUUCI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777608532; c=relaxed/simple; bh=f4v9384o0P5MUr3FWq57o3ckMed62usQCso6ioufjoo=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=ekWvpIlUC1q5n2/7CBHwvgmGAuPbYCgOvhnc+BphOCa1sDziPlvITbNqAZyJJnq3qgCCDd5XkOqVlGPEiExYPEojlA973XHgZzHALFHKDZP7+SUrugrp1qXVD0DSZcBUYfzJoa+Oe1IKYasKG+aTZQRXhax4CVpzd9bSbdYb9mo= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=GSRvlsVs; 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="GSRvlsVs" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 4E7DBC2BCB9; Fri, 1 May 2026 04:08:52 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1777608532; bh=f4v9384o0P5MUr3FWq57o3ckMed62usQCso6ioufjoo=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=GSRvlsVsSmQ+Hmnd2ozOqDYkIfkMBp81VHSqu92iLVo9MFOJc5+nk0Fi2JNNfPPJR /WSwa2r+mRlbvW+1bGcTH8uwrZ4fc1uNRy94HPASicYoPU4YsGucde5sd7WHeCgFeL A+lHQ3OfDVekhv4vhvVSxt6BZApHxHfldSviRTSV70dxByLF0H7UHADtSVvyosylfM WR3w4v4VLe2bVKsiPZYhPwQ5KdZMUJaGlBX8HrFPcKeBXbTw/hWTvUluoSPqt7trsn U9GJH9gMKqkHcbGTMQe5ZzPIK5SrysOS7SSvqOC9tzilX6pMZblc3QinRNnhhMcrxS YY5QZDXLV2oug== From: Josh Poimboeuf To: x86@kernel.org Cc: linux-kernel@vger.kernel.org, live-patching@vger.kernel.org, Peter Zijlstra , Joe Lawrence , Song Liu , Miroslav Benes , Petr Mladek Subject: [PATCH v2 05/53] objtool/klp: Don't correlate __initstub__ symbols Date: Thu, 30 Apr 2026 21:07:53 -0700 Message-ID: <1fa5106be35420eae021835f4ff25ac535070dfb.1777575752.git.jpoimboe@kernel.org> X-Mailer: git-send-email 2.53.0 In-Reply-To: References: 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" With LTO, the initcall infrastructure generates __initstub__kmod_* wrapper functions in .init.text. These are the LTO equivalent of __initcall__kmod_* data pointers, which are already excluded from correlation. These are __init functions whose memory is freed after boot, so there's no reason to include or reference them in a livepatch module. Acked-by: Song Liu Reviewed-by: Miroslav Benes Signed-off-by: Josh Poimboeuf --- tools/objtool/klp-diff.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/tools/objtool/klp-diff.c b/tools/objtool/klp-diff.c index 27ebe1b1f463..4f668117c45e 100644 --- a/tools/objtool/klp-diff.c +++ b/tools/objtool/klp-diff.c @@ -370,6 +370,12 @@ static bool is_abs_sym(struct symbol *sym) return sym->sym.st_shndx =3D=3D SHN_ABS && !is_file_sym(sym); } =20 +static bool is_initcall_sym(struct symbol *sym) +{ + return strstarts(sym->name, "__initcall__") || + strstarts(sym->name, "__initstub__"); +} + /* * These symbols should never be correlated, so their local patched versio= ns * are used instead of linking to the originals. @@ -384,10 +390,10 @@ static bool dont_correlate(struct symbol *sym) is_uncorrelated_static_local(sym) || is_clang_tmp_label(sym) || is_string_sec(sym->sec) || + is_initcall_sym(sym) || is_addressable_sym(sym) || is_special_section(sym->sec) || - is_special_section_aux(sym->sec) || - strstarts(sym->name, "__initcall__"); + is_special_section_aux(sym->sec); } =20 struct process_demangled_name_data { --=20 2.53.0 From nobody Thu Jun 18 07:54:40 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 5D3743093C1; Fri, 1 May 2026 04:08:53 +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=1777608533; cv=none; b=qZbwseBSe1BayL+9TrGzGQ2mpiz9734tHuiA391KpfWyFRFPjcaHwDbnm8PKvD4CqBaX0udZM/GGkswEsa6rSU5a2/wp5lVrNcZdFoxAsLoUpZc7UaW4ZKDecBR/GZlZaRhEKTo/BjydI48WVLQfrL/FKm+/c1oKLHmFrixXSh8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777608533; c=relaxed/simple; bh=kx/DM46jLcl46ytKU6Wkkwpr6I9x6N6yRUUppki+X3k=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=cq+MQD9FcoU/6t3yAkATnEgaf8oPSc7mz4XWctbhcXefsMLHGKMZCzJVolsS0E0/JGKWc3t7mzrQuEa4JHCDRzwiCCcsmxiUsLNB2Pc3TFgERzktYdI5UrZQk3Br4PU0jdC1RGsCaY556r4rM6DvcDegcJxdVeoHnDvWw+tEJn0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=Ug0zvKh6; 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="Ug0zvKh6" Received: by smtp.kernel.org (Postfix) with ESMTPSA id BCD12C2BCB8; Fri, 1 May 2026 04:08:52 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1777608533; bh=kx/DM46jLcl46ytKU6Wkkwpr6I9x6N6yRUUppki+X3k=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=Ug0zvKh6CIa34t0ye6V1PNLzXcSWy1w/8P2OC1UDNeOvVNDHwKKPAPodIw3O7zfqz hxH9uCuqSuAsZaZXQV5SJbMi7MVrfRKb7EF0lrNgAMw2pyf5TPc8Y1jahyVCoxQN4l 9/WV3OUHwoKcVpHYk0Z1J9OWWRBpDB1OqX+44gwsfRmDiYgBe3yWTgnkaMe2wkC1Vb rlbTIr53mynppupYqMH57SQYOK4hx/1d8Om9HWPxZmQ6JmhSfpT1X2GO8jHk7UNCx8 UQHcPGwDELgKXP9tVnYOpuEb05gdFFIxhTEcgxHdRxefY0m/I02vBhNSDuf/m3W4Ac RH8weLN4kGjmQ== From: Josh Poimboeuf To: x86@kernel.org Cc: linux-kernel@vger.kernel.org, live-patching@vger.kernel.org, Peter Zijlstra , Joe Lawrence , Song Liu , Miroslav Benes , Petr Mladek Subject: [PATCH v2 06/53] objtool/klp: Don't report uncorrelated functions as new Date: Thu, 30 Apr 2026 21:07:54 -0700 Message-ID: <8709eeaf528ed434a5fb1c2056927bae6ceb473a.1777575752.git.jpoimboe@kernel.org> X-Mailer: git-send-email 2.53.0 In-Reply-To: References: 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" Clang LTO uses __UNIQUE_ID() to generate some uniquely named wrapper functions, like initstubs. If they're uncorrelated, prevent them from being reported as new functions and included unnecessarily. Note that dont_correlate() already includes prefix functions, so prefix functions are still being ignored here. Acked-by: Song Liu Reviewed-by: Miroslav Benes Signed-off-by: Josh Poimboeuf --- tools/objtool/klp-diff.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/objtool/klp-diff.c b/tools/objtool/klp-diff.c index 4f668117c45e..ccb16a45107e 100644 --- a/tools/objtool/klp-diff.c +++ b/tools/objtool/klp-diff.c @@ -802,7 +802,7 @@ static int mark_changed_functions(struct elfs *e) =20 /* Find changed functions */ for_each_sym(e->orig, sym_orig) { - if (!is_func_sym(sym_orig) || is_prefix_func(sym_orig)) + if (!is_func_sym(sym_orig) || dont_correlate(sym_orig)) continue; =20 patched_sym =3D sym_orig->twin; @@ -818,7 +818,7 @@ static int mark_changed_functions(struct elfs *e) =20 /* Find added functions and print them */ for_each_sym(e->patched, patched_sym) { - if (!is_func_sym(patched_sym) || is_prefix_func(patched_sym)) + if (!is_func_sym(patched_sym) || dont_correlate(patched_sym)) continue; =20 if (!patched_sym->twin) { --=20 2.53.0 From nobody Thu Jun 18 07:54:40 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 AB08230B51A; Fri, 1 May 2026 04:08:53 +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=1777608533; cv=none; b=aBwBB3meOqXxllgvQPuGn4tbaZGsekqWiHYMCI+7ncDrdOzb/I4KY1CzmFZWlm97CpleGsuKfMnuLfr3D3MOO1YD+FM4NLvqFP6JJV/5ul346xqlSnwQ420iu92W4LlwcfiWsuwLQHsVy98KzV526szGflTuaGRkATiP/2lSuGM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777608533; c=relaxed/simple; bh=4uHNmNTMs6Cvsbo7XOnU9ntyLG2KD6N0hm/d06JUQYc=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=ReRHLcj6opmeEq1RvHNARjzRQ1JBgkdSmODaEchRBA/2I8n3SKU7o4NdFlN3qjlNHhOJ4o51Du4BRH5774wVv59tFiai6OLCW07nf3p0RIAAu/NSrdqspvwddq/GYwgcA47YbqK/7JXHoPnzts+lMbvlXXNY7BSbZNrSRDiRjpQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=J375LHWm; 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="J375LHWm" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 35ECEC2BCC6; Fri, 1 May 2026 04:08:53 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1777608533; bh=4uHNmNTMs6Cvsbo7XOnU9ntyLG2KD6N0hm/d06JUQYc=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=J375LHWmOz2F7UsxX8f8qx1fK5JLd0V5FFy7UJvRJxxlyVUYNEAEYqrn6o3JLUWon IXHYigIqpz80uTw7QxWkL2YW41eZ+NdeL/929fVcOFiTYJQfuPqUuoVpELu2EBp5mE H/T5Qq4RtVxm6Hb9bDqaeLPYjBaYM3jIh3y2lyUu4S8kBKNZGBTmJ7g+dillE5cW7i 5GXQOLFtKIqLn5ILUzT4BW5Dv01/0q+5GQS2mGxEw5TEm9Jig+rK3QY0kED/LioxSh QLpz05YjLjReabM+Lgea2/iwFIFHrJbNJTZH65xZMVZc0BagqeM7Qyw+tqnrwO0b+7 cU44BUVEPVzNA== From: Josh Poimboeuf To: x86@kernel.org Cc: linux-kernel@vger.kernel.org, live-patching@vger.kernel.org, Peter Zijlstra , Joe Lawrence , Song Liu , Miroslav Benes , Petr Mladek Subject: [PATCH v2 07/53] objtool/klp: Improve local label check Date: Thu, 30 Apr 2026 21:07:55 -0700 Message-ID: <54175a1446aae952ad4d886eec3f64fcbdbeb375.1777575752.git.jpoimboe@kernel.org> X-Mailer: git-send-email 2.53.0 In-Reply-To: References: 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" Clang emits various .L-prefixed local symbols beyond .Ltmp*, such as .L__const.* for local constant data. These are assembler-local labels not present in kallsyms, so they can never be resolved at module load time. Broaden the check from .Ltmp* to all .L* symbols so they get cloned into the patch module instead. Signed-off-by: Josh Poimboeuf Acked-by: Song Liu --- tools/objtool/klp-diff.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/tools/objtool/klp-diff.c b/tools/objtool/klp-diff.c index ccb16a45107e..c5d4c9ed8580 100644 --- a/tools/objtool/klp-diff.c +++ b/tools/objtool/klp-diff.c @@ -282,14 +282,14 @@ static bool is_uncorrelated_static_local(struct symbo= l *sym) } =20 /* - * Clang emits several useless .Ltmp_* code labels. + * .L symbols are assembler-local labels not present in kallsyms. They mu= st + * never become KLP relocations; instead their data is cloned into the pat= ch + * module. This covers .Ltmp* (Clang temp labels), .L__const.* (Clang loc= al + * constants), and any other assembler-local pattern. */ -static bool is_clang_tmp_label(struct symbol *sym) +static bool is_local_label(struct symbol *sym) { - return is_notype_sym(sym) && - is_text_sec(sym->sec) && - strstarts(sym->name, ".Ltmp") && - isdigit(sym->name[5]); + return strstarts(sym->name, ".L"); } =20 static bool is_special_section(struct section *sec) @@ -388,7 +388,7 @@ static bool dont_correlate(struct symbol *sym) is_abs_sym(sym) || is_prefix_func(sym) || is_uncorrelated_static_local(sym) || - is_clang_tmp_label(sym) || + is_local_label(sym) || is_string_sec(sym->sec) || is_initcall_sym(sym) || is_addressable_sym(sym) || --=20 2.53.0 From nobody Thu Jun 18 07:54:40 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 1760030E834; Fri, 1 May 2026 04:08:54 +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=1777608534; cv=none; b=NisJerC2Z6PLEeuf8x+v2qyjBbnmDr8sWViib0g2yMjI3HMNe8jsJCTsx5jQIQ0aDEtDbvKHN41fqAdh/EXJ/TqrsGH2owH7rUKDrp/hipcePyD/oLlluje7qPwG8vfgqecrZP7v9yEWdgdyvYA8SvxVOrDyZMTML3dk9xJM0dk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777608534; c=relaxed/simple; bh=2+H7JiSFT/KZm+ogeaf0AbpRHFZ1id0DN/+htSs4/xA=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=jewkoGhDTugMo6fT0YrekVARyM8YgN61fqGJsU96QPbSBhE5AiO7Ge5I8MX15gB0/mJkRQe4vIH7JFqnFQ29GsErj67o1JH1E3eDotmgpMiWSmpwneT07Px1XFqsK40J/DJ1GVOVZXvKqM4re3as23vZVbNalZJ9itIFhs7fqtU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=MW51tNMt; 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="MW51tNMt" Received: by smtp.kernel.org (Postfix) with ESMTPSA id A7702C2BCB9; Fri, 1 May 2026 04:08:53 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1777608534; bh=2+H7JiSFT/KZm+ogeaf0AbpRHFZ1id0DN/+htSs4/xA=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=MW51tNMtda3Jcu9eGQWDhzA7ErZ3mlu/D655hdJhwEYChzSvaMPaL+QRPd6JAnCS/ Pc16+Xnr7jo0R0Sz6xbuWPIsdrE49/ydeYZuAU4U+TPsBEzOf9Wf0fQOqSxcLpUIlr XIbM6y3gPmdLFfLWrvBpsv54fNTdjsmfRtOLQBnajNzsVU7zpv3Sb5+Bws9bFOVRz/ 3Q28i92LqM4BqQ4G6sbODhH1F9R0vTyz4YHSZvnZNvbZBkFg3Kp1T4M+/ZbRc3fPhD k14trMV5gmc9OeWvTp7MV9ClbROajHR4DWMhjts3zBcnFL9ub84wMZl1cCvzUyJmeY 3UklL6gGkmkRA== From: Josh Poimboeuf To: x86@kernel.org Cc: linux-kernel@vger.kernel.org, live-patching@vger.kernel.org, Peter Zijlstra , Joe Lawrence , Song Liu , Miroslav Benes , Petr Mladek Subject: [PATCH v2 08/53] objtool/klp: Fix create_fake_symbols() skipping entsize-based sections Date: Thu, 30 Apr 2026 21:07:56 -0700 Message-ID: X-Mailer: git-send-email 2.53.0 In-Reply-To: References: 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: Joe Lawrence create_fake_symbols() has two phases: creating symbols from ANNOTATE_DATA_SPECIAL entries, and a fallback that uses sh_entsize for special sections like .static_call_sites. When .discard.annotate_data is absent, the function returns early, skipping the entsize fallback and silently allowing unsupported module-local static call keys through. Fix it by jumping to the entsize phase instead of returning early. Fixes: dd590d4d57eb ("objtool/klp: Introduce klp diff subcommand for diffin= g object files") Assisted-by: Claude:claude-4-opus Signed-off-by: Joe Lawrence Acked-by: Song Liu Reviewed-by: Miroslav Benes Signed-off-by: Josh Poimboeuf --- tools/objtool/klp-diff.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/objtool/klp-diff.c b/tools/objtool/klp-diff.c index c5d4c9ed8580..0653bf6a33bd 100644 --- a/tools/objtool/klp-diff.c +++ b/tools/objtool/klp-diff.c @@ -1374,7 +1374,7 @@ static int create_fake_symbols(struct elf *elf) =20 sec =3D find_section_by_name(elf, ".discard.annotate_data"); if (!sec || !sec->rsec) - return 0; + goto entsize; =20 for_each_reloc(sec->rsec, reloc) { unsigned long offset, size; @@ -1406,7 +1406,7 @@ static int create_fake_symbols(struct elf *elf) /* * 2) Make symbols for sh_entsize, and simple arrays of pointers: */ - +entsize: for_each_sec(elf, sec) { unsigned int entry_size; unsigned long offset; --=20 2.53.0 From nobody Thu Jun 18 07:54:40 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 8773230FC21; Fri, 1 May 2026 04:08:54 +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=1777608534; cv=none; b=qoOb/unQQoST3HRqngKKbPDq95DCyDbyzwkJr0XwCSW74lKP8TzRUZZObxZqC4vaW8Bm3tNZ85CEOjHulF19dGz/CH6YI9inXjzND53tnMU53bPCvygdSY4qkcRh/vGvbEK5fpX74PY2VApUOh/AnyFIO/iBDS9RbDuJNB322Nk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777608534; c=relaxed/simple; bh=b5BNPd+bg7GvS5BnsS8maFnsD2ISFL3v5zG+hbXUHwk=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=PTdH83vunT/FEfMqslZv0ujId2tDuDO02SaKoOSqGVarN0sQNDVC+GOa4x6nzNMB89ZZWlZv77I4xNdv9+hLWupSbex4qNwUHCYzykgf8vTPqRmOlbsXYwTptXLWwh+dUBFrldS8LiVsFwCe9VQrKgoUfKMhc2QG1VxbDSgkmzA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=UTBP2cOo; 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="UTBP2cOo" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 22505C2BCC7; Fri, 1 May 2026 04:08:54 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1777608534; bh=b5BNPd+bg7GvS5BnsS8maFnsD2ISFL3v5zG+hbXUHwk=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=UTBP2cOoLzjVoyofU8VG7UTLzKhH2cfjA9kzbwvdWCS2187vTOqBFKTOMfdzoOh/D F7vYvz27Lu3c0YE0j8DLyP/1BFmsJndujJ2f2aC4eJtXPL0Ee8iMWlKVTRsefQ204t TtvhtS6FoLhgaxgqWgrQCIb4nNRsyRoxwDGy5bRDIhrv8S/l9/+DiJw7Bsix7o5vYj bMFnQT/Um3qkyeFteL2anebEUSaxc5LbzY6xY+IL9cPMzDRozrm6kMCJ28xil7iFiK 2ZqR8Ctck6q9uuBWyuSyvec93FFdtWjM1bQcfzy+s4cp9g81EOVw4OqA2MByx4fope QyjqxV6kb7BAw== From: Josh Poimboeuf To: x86@kernel.org Cc: linux-kernel@vger.kernel.org, live-patching@vger.kernel.org, Peter Zijlstra , Joe Lawrence , Song Liu , Miroslav Benes , Petr Mladek Subject: [PATCH v2 09/53] objtool: Replace iterator callback with for_each_sym_by_mangled_name() Date: Thu, 30 Apr 2026 21:07:57 -0700 Message-ID: X-Mailer: git-send-email 2.53.0 In-Reply-To: References: 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" Convert the callback-based iterate_sym_by_demangled_name() with a new for_each_sym_by_demangled_name() macro. This eliminates the callback struct/function and makes the code more compact and readable. Signed-off-by: Josh Poimboeuf Acked-by: Song Liu Reviewed-by: Miroslav Benes --- tools/objtool/elf.c | 68 ++++++++--------------------- tools/objtool/include/objtool/elf.h | 32 ++++++++++++-- tools/objtool/klp-diff.c | 42 ++++++------------ 3 files changed, 60 insertions(+), 82 deletions(-) diff --git a/tools/objtool/elf.c b/tools/objtool/elf.c index f3df2bde119f..dc39132f71c1 100644 --- a/tools/objtool/elf.c +++ b/tools/objtool/elf.c @@ -27,27 +27,16 @@ =20 static ssize_t demangled_name_len(const char *name); =20 -static inline u32 str_hash(const char *str) -{ - return jhash(str, strlen(str), 0); -} - -static inline u32 str_hash_demangled(const char *str) +u32 str_hash_demangled(const char *str) { return jhash(str, demangled_name_len(str), 0); } =20 -#define __elf_table(name) (elf->name##_hash) -#define __elf_bits(name) (elf->name##_bits) - -#define __elf_table_entry(name, key) \ - __elf_table(name)[hash_min(key, __elf_bits(name))] - #define elf_hash_add(name, node, key) \ ({ \ struct elf_hash_node *__node =3D node; \ - __node->next =3D __elf_table_entry(name, key); \ - __elf_table_entry(name, key) =3D __node; \ + __node->next =3D __elf_table_entry(elf, name, key); \ + __elf_table_entry(elf, name, key) =3D __node; \ }) =20 static inline void __elf_hash_del(struct elf_hash_node *node, @@ -69,30 +58,20 @@ static inline void __elf_hash_del(struct elf_hash_node = *node, } =20 #define elf_hash_del(name, node, key) \ - __elf_hash_del(node, &__elf_table_entry(name, key)) - -#define elf_list_entry(ptr, type, member) \ -({ \ - typeof(ptr) __ptr =3D (ptr); \ - __ptr ? container_of(__ptr, type, member) : NULL; \ -}) - -#define elf_hash_for_each_possible(name, obj, member, key) \ - for (obj =3D elf_list_entry(__elf_table_entry(name, key), typeof(*obj), m= ember); \ - obj; \ - obj =3D elf_list_entry(obj->member.next, typeof(*(obj)), member)) + __elf_hash_del(node, &__elf_table_entry(elf, name, key)) =20 #define elf_alloc_hash(name, size) \ ({ \ - __elf_bits(name) =3D max(10, ilog2(size)); \ - __elf_table(name) =3D mmap(NULL, sizeof(struct elf_hash_node *) << __elf_= bits(name), \ + __elf_bits(elf, name) =3D max(10, ilog2(size)); \ + __elf_table(elf, name) =3D mmap(NULL, \ + sizeof(struct elf_hash_node *) << __elf_bits(elf, name), \ PROT_READ|PROT_WRITE, \ MAP_PRIVATE|MAP_ANON, -1, 0); \ - if (__elf_table(name) =3D=3D (void *)-1L) { \ + if (__elf_table(elf, name) =3D=3D (void *)-1L) { \ ERROR_GLIBC("mmap fail " #name); \ - __elf_table(name) =3D NULL; \ + __elf_table(elf, name) =3D NULL; \ } \ - __elf_table(name); \ + __elf_table(elf, name); \ }) =20 static inline unsigned long __sym_start(struct symbol *s) @@ -141,7 +120,7 @@ struct section *find_section_by_name(const struct elf *= elf, const char *name) { struct section *sec; =20 - elf_hash_for_each_possible(section_name, sec, name_hash, str_hash(name)) { + elf_hash_for_each_possible(elf, section_name, sec, name_hash, str_hash(na= me)) { if (!strcmp(sec->name, name)) return sec; } @@ -154,7 +133,7 @@ static struct section *find_section_by_index(struct elf= *elf, { struct section *sec; =20 - elf_hash_for_each_possible(section, sec, hash, idx) { + elf_hash_for_each_possible(elf, section, sec, hash, idx) { if (sec->idx =3D=3D idx) return sec; } @@ -166,7 +145,7 @@ static struct symbol *find_symbol_by_index(struct elf *= elf, unsigned int idx) { struct symbol *sym; =20 - elf_hash_for_each_possible(symbol, sym, hash, idx) { + elf_hash_for_each_possible(elf, symbol, sym, hash, idx) { if (sym->idx =3D=3D idx) return sym; } @@ -285,7 +264,7 @@ struct symbol *find_symbol_by_name(const struct elf *el= f, const char *name) { struct symbol *sym; =20 - elf_hash_for_each_possible(symbol_name, sym, name_hash, str_hash(name)) { + elf_hash_for_each_possible(elf, symbol_name, sym, name_hash, str_hash(nam= e)) { if (!strcmp(sym->name, name)) return sym; } @@ -300,7 +279,7 @@ static struct symbol *find_local_symbol_by_file_and_nam= e(const struct elf *elf, { struct symbol *sym; =20 - elf_hash_for_each_possible(symbol_name, sym, name_hash, str_hash_demangle= d(name)) { + elf_hash_for_each_possible(elf, symbol_name, sym, name_hash, str_hash_dem= angled(name)) { if (sym->bind =3D=3D STB_LOCAL && sym->file =3D=3D file && !strcmp(sym->name, name)) { return sym; @@ -314,7 +293,7 @@ struct symbol *find_global_symbol_by_name(const struct = elf *elf, const char *nam { struct symbol *sym; =20 - elf_hash_for_each_possible(symbol_name, sym, name_hash, str_hash_demangle= d(name)) { + elf_hash_for_each_possible(elf, symbol_name, sym, name_hash, str_hash_dem= angled(name)) { if (!strcmp(sym->name, name) && !is_local_sym(sym)) return sym; } @@ -322,19 +301,6 @@ struct symbol *find_global_symbol_by_name(const struct= elf *elf, const char *nam return NULL; } =20 -void iterate_global_symbol_by_demangled_name(const struct elf *elf, - const char *demangled_name, - void (*process)(struct symbol *sym, void *data), - void *data) -{ - struct symbol *sym; - - elf_hash_for_each_possible(symbol_name, sym, name_hash, str_hash(demangle= d_name)) { - if (!strcmp(sym->demangled_name, demangled_name) && !is_local_sym(sym)) - process(sym, data); - } -} - struct reloc *find_reloc_by_dest_range(const struct elf *elf, struct secti= on *sec, unsigned long offset, unsigned int len) { @@ -347,7 +313,7 @@ struct reloc *find_reloc_by_dest_range(const struct elf= *elf, struct section *se return NULL; =20 for_offset_range(o, offset, offset + len) { - elf_hash_for_each_possible(reloc, reloc, hash, + elf_hash_for_each_possible(elf, reloc, reloc, hash, sec_offset_hash(rsec, o)) { if (reloc->sec !=3D rsec) continue; diff --git a/tools/objtool/include/objtool/elf.h b/tools/objtool/include/ob= jtool/elf.h index 25573e5af76e..b142984eb9b5 100644 --- a/tools/objtool/include/objtool/elf.h +++ b/tools/objtool/include/objtool/elf.h @@ -21,6 +21,13 @@ #define SEC_NAME_LEN 1024 #define SYM_NAME_LEN 512 =20 +static inline u32 str_hash(const char *str) +{ + return jhash(str, strlen(str), 0); +} + +u32 str_hash_demangled(const char *str); + #define bswap_if_needed(elf, val) __bswap_if_needed(&elf->ehdr, val) =20 #ifdef LIBELF_USE_DEPRECATED @@ -130,6 +137,23 @@ struct elf { struct symbol *symbol_data; }; =20 +#define __elf_table(elf, name) ((elf)->name##_hash) +#define __elf_bits(elf, name) ((elf)->name##_bits) + +#define __elf_table_entry(elf, name, key) \ + __elf_table(elf, name)[hash_min(key, __elf_bits(elf, name))] + +#define elf_list_entry(ptr, type, member) \ +({ \ + typeof(ptr) __ptr =3D (ptr); \ + __ptr ? container_of(__ptr, type, member) : NULL; \ +}) + +#define elf_hash_for_each_possible(elf, name, obj, member, key) \ + for (obj =3D elf_list_entry(__elf_table_entry(elf, name, key), typeof(*ob= j), member); \ + obj; \ + obj =3D elf_list_entry(obj->member.next, typeof(*(obj)), member)) + struct elf *elf_open_read(const char *name, int flags); struct elf *elf_create_file(GElf_Ehdr *ehdr, const char *name); =20 @@ -186,9 +210,6 @@ struct symbol *find_func_by_offset(struct section *sec,= unsigned long offset); struct symbol *find_symbol_by_offset(struct section *sec, unsigned long of= fset); struct symbol *find_symbol_by_name(const struct elf *elf, const char *name= ); struct symbol *find_global_symbol_by_name(const struct elf *elf, const cha= r *name); -void iterate_global_symbol_by_demangled_name(const struct elf *elf, const = char *demangled_name, - void (*process)(struct symbol *sym, void *data), - void *data); struct symbol *find_symbol_containing(const struct section *sec, unsigned = long offset); int find_symbol_hole_containing(const struct section *sec, unsigned long o= ffset); struct reloc *find_reloc_by_dest(const struct elf *elf, struct section *se= c, unsigned long offset); @@ -468,6 +489,11 @@ static inline void set_sym_next_reloc(struct reloc *re= loc, struct reloc *next) #define for_each_sym_continue(elf, sym) \ list_for_each_entry_continue(sym, &elf->symbols, global_list) =20 +#define for_each_sym_by_demangled_name(elf, name, sym) \ + elf_hash_for_each_possible(elf, symbol_name, sym, name_hash, \ + str_hash(name)) \ + if (strcmp(sym->demangled_name, name)) {} else + #define rsec_next_reloc(rsec, reloc) \ reloc_idx(reloc) < sec_num_entries(rsec) - 1 ? reloc + 1 : NULL =20 diff --git a/tools/objtool/klp-diff.c b/tools/objtool/klp-diff.c index 0653bf6a33bd..30ce234e01a1 100644 --- a/tools/objtool/klp-diff.c +++ b/tools/objtool/klp-diff.c @@ -46,11 +46,6 @@ static const struct option klp_diff_options[] =3D { =20 static DEFINE_HASHTABLE(exports, 15); =20 -static inline u32 str_hash(const char *str) -{ - return jhash(str, strlen(str), 0); -} - static char *escape_str(const char *orig) { size_t len =3D 0; @@ -396,22 +391,6 @@ static bool dont_correlate(struct symbol *sym) is_special_section_aux(sym->sec); } =20 -struct process_demangled_name_data { - struct symbol *ret; - int count; -}; - -static void process_demangled_name(struct symbol *sym, void *d) -{ - struct process_demangled_name_data *data =3D d; - - if (sym->twin) - return; - - data->count++; - data->ret =3D sym; -} - /* * When there is no full name match, try match demangled_name. This would * match original foo.llvm.123 to patched foo.llvm.456. @@ -423,16 +402,23 @@ static void process_demangled_name(struct symbol *sym= , void *d) static int find_global_symbol_by_demangled_name(struct elf *elf, struct sy= mbol *sym, struct symbol **out_sym) { - struct process_demangled_name_data data =3D {}; + struct symbol *sym2, *result =3D NULL; + int count =3D 0; =20 - iterate_global_symbol_by_demangled_name(elf, sym->demangled_name, - process_demangled_name, - &data); - if (data.count > 1) { - ERROR("Multiple (%d) correlation candidates for %s", data.count, sym->na= me); + for_each_sym_by_demangled_name(elf, sym->demangled_name, sym2) { + if (is_local_sym(sym2) || sym2->twin) + continue; + + count++; + result =3D sym2; + } + + if (count > 1) { + ERROR("Multiple (%d) correlation candidates for %s", count, sym->name); return -1; } - *out_sym =3D data.ret; + + *out_sym =3D result; return 0; } =20 --=20 2.53.0 From nobody Thu Jun 18 07:54:40 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 3E1B33128D4; Fri, 1 May 2026 04:08:55 +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=1777608535; cv=none; b=oR88yAKTDKVpqY3sTZuhpapDgg/cvHT/V8RZKCQLI/8h83n+WuvF3CtxNUnbys8Hz8ymstJQCRb1RAY3G7hgm0o+DdAnCOZmbJES5dCcu4/szxZM86T9ermxsrPna/5YrYZWNePQNHp8UyFErfpq9LxernWv+t0G1htYTSk3O78= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777608535; c=relaxed/simple; bh=xrqI9AmsCre03ULrPQ3iszwiwGHge+FkRf5Hhx9yY8M=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=u1pFYYxMIcwONk+ec0bQcRM4KU8rJrsYwz6UNdq6tgWI1Iel/Yp4vNl+UMMT1EQgMG4EncDk0sFWcEj52lnc+NdaV+39R2R3XXMNjZ/Mca0tTAYpovvFKjqPzN4QNDIMYW1IoB/crHKaeb3ZKaNVmGFRokdbcU2bdorHv2ym8Js= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=IHPZRN32; 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="IHPZRN32" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 97DD2C2BCB8; Fri, 1 May 2026 04:08:54 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1777608535; bh=xrqI9AmsCre03ULrPQ3iszwiwGHge+FkRf5Hhx9yY8M=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=IHPZRN32rmVKqO0yMgLbFKDLzwlyIlVyOAm9BFNP77ga0JarFi2mlnp5+Rmk8S1qV QnEAYhyMlpF5TJT7WXvMiM2lwXt26fyu2lK+Kj6sM5J6oXHOM4sTaQSVJVtMU2/TOF SiBar8ugMyx6HPfpyX43Y8sduVGJA8KyCbbDbHYhyM0ED/RW0ZW+yNTNX7WLLc+B0m iJdY3lhY5EXx2KJTEhNmIbD0SL5hXvNo4oK/KtX46GGK3S6WfxH+AyDO0fkJqD/E7s sEvc4BhKk9NpZgg1ZH6/t0IfJiJPBeKP0oVBeefu6tB/DO2q2bm9GTvGKlORw5VMSX +IsrnseMep+Ow== From: Josh Poimboeuf To: x86@kernel.org Cc: linux-kernel@vger.kernel.org, live-patching@vger.kernel.org, Peter Zijlstra , Joe Lawrence , Song Liu , Miroslav Benes , Petr Mladek Subject: [PATCH v2 10/53] objtool/klp: Fix --debug-checksum for duplicate symbol names Date: Thu, 30 Apr 2026 21:07:58 -0700 Message-ID: <83781c62e85a35d641b7d793b133195e3a4abba7.1777575752.git.jpoimboe@kernel.org> X-Mailer: git-send-email 2.53.0 In-Reply-To: References: 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" find_symbol_by_name() only returns the first match, so --debug-checksum=3D silently ignores any subsequent duplicately named functions after the first. Fix that, along with a new for_each_sym_by_name() helper. Acked-by: Song Liu Signed-off-by: Josh Poimboeuf Reviewed-by: Miroslav Benes --- tools/objtool/check.c | 15 ++++++++++----- tools/objtool/include/objtool/elf.h | 5 +++++ 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/tools/objtool/check.c b/tools/objtool/check.c index 9b11cf3193b9..e3604b1201f9 100644 --- a/tools/objtool/check.c +++ b/tools/objtool/check.c @@ -3677,18 +3677,23 @@ static int checksum_debug_init(struct objtool_file = *file) =20 s =3D dup; while (*s) { - struct symbol *func; + bool found =3D false; + struct symbol *sym; char *comma; =20 comma =3D strchr(s, ','); if (comma) *comma =3D '\0'; =20 - func =3D find_symbol_by_name(file->elf, s); - if (!func || !is_func_sym(func)) + for_each_sym_by_name(file->elf, s, sym) { + if (!is_func_sym(sym)) + continue; + sym->debug_checksum =3D 1; + found =3D true; + } + + if (!found) WARN("--debug-checksum: can't find '%s'", s); - else - func->debug_checksum =3D 1; =20 if (!comma) break; diff --git a/tools/objtool/include/objtool/elf.h b/tools/objtool/include/ob= jtool/elf.h index b142984eb9b5..00b04029023e 100644 --- a/tools/objtool/include/objtool/elf.h +++ b/tools/objtool/include/objtool/elf.h @@ -489,6 +489,11 @@ static inline void set_sym_next_reloc(struct reloc *re= loc, struct reloc *next) #define for_each_sym_continue(elf, sym) \ list_for_each_entry_continue(sym, &elf->symbols, global_list) =20 +#define for_each_sym_by_name(elf, _name, sym) \ + elf_hash_for_each_possible(elf, symbol_name, sym, name_hash, \ + str_hash_demangled(_name)) \ + if (strcmp(sym->name, _name)) {} else + #define for_each_sym_by_demangled_name(elf, name, sym) \ elf_hash_for_each_possible(elf, symbol_name, sym, name_hash, \ str_hash(name)) \ --=20 2.53.0 From nobody Thu Jun 18 07:54:40 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 9D4F53148B5; Fri, 1 May 2026 04:08:55 +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=1777608535; cv=none; b=e449aDWjfkcCz50ey2C2R1NDwmDh5fGsZeFfDfL3ld07mTfc83iEi6m4s2nI0b+/mJzi/JLMPYwEUd+arX9CfNoRZYkIFS4UFMTyzUjnkela5PlYYHHS3faenKgqfUmbM/loX+UfT7+6GqRpK5CW4nAkwSiYrv98qi4lqbk1kxc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777608535; c=relaxed/simple; bh=1MDEzI3Nle2lKZXTUSbVIrCvlFXpF+YXjQJda5aqVt8=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=tbuL4+GY3kcqJbb716CJjU+OXy9X/4RDp+bXp2FTx/JF8SpNVrx/FbrEQGZkSrVTApm8QF/HX8C4U2gGkuEZxwbD7fSuv5v7OpFz5IsFUxcDO2MX4n4E7QhXAOYT4v+ZkObsFgBO+22si0HZ2PTppyoN+m/iBZT/ACVgPGZnnDA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=lLf5jVpd; 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="lLf5jVpd" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 27CD4C2BCFD; Fri, 1 May 2026 04:08:55 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1777608535; bh=1MDEzI3Nle2lKZXTUSbVIrCvlFXpF+YXjQJda5aqVt8=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=lLf5jVpdcQC7cXR6Fq96WXy/So4qfDmqfzuw8oILFU5NUAL0FSZ+Bl5eCECnGZUrx oMBadNg/72EcohP4qqAsH2FyvevlY/oxc5pN3wpQJ+5ErUJKHCOlLaP3JaF0AJc3gw lRdzgoFBGS76uhtILlOSCkgxr0Wj70h3zY297gIo7LiQ914B4omPJ1K+5/gqpnkfJm l0dh3KLUjIqYfa4xzysxjIAaJ1CNfHtT2jPxP9GUHD+9ICnn2g1tUAJHVcS+hhPsAL LlrJWKRHkZ1HDIO62JBQHnyEpX9RW0cHw7T3eVHAZQfxdixhDDcR/02FpbWZRRns1t UJUyK6TGjfIoQ== From: Josh Poimboeuf To: x86@kernel.org Cc: linux-kernel@vger.kernel.org, live-patching@vger.kernel.org, Peter Zijlstra , Joe Lawrence , Song Liu , Miroslav Benes , Petr Mladek Subject: [PATCH v2 11/53] objtool/klp: Fix handling of zero-length .altinstr_replacement sections Date: Thu, 30 Apr 2026 21:07:59 -0700 Message-ID: X-Mailer: git-send-email 2.53.0 In-Reply-To: References: 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" When a section is empty (e.g. only zero-length alternative replacements), there are no symbols to convert a section symbol reference to. Skip the reloc instead of erroring out. Fixes: dd590d4d57eb ("objtool/klp: Introduce klp diff subcommand for diffin= g object files") Acked-by: Song Liu Reviewed-by: Miroslav Benes Signed-off-by: Josh Poimboeuf --- tools/objtool/klp-diff.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/tools/objtool/klp-diff.c b/tools/objtool/klp-diff.c index 30ce234e01a1..a226e99948b3 100644 --- a/tools/objtool/klp-diff.c +++ b/tools/objtool/klp-diff.c @@ -1005,6 +1005,13 @@ static int convert_reloc_secsym_to_sym(struct elf *e= lf, struct reloc *reloc) /* No dedicated section; find the symbol manually */ sym =3D find_symbol_containing(sec, arch_adjusted_addend(reloc)); if (!sym) { + /* + * This is presumably an .altinstr_replacement section which is + * empty due to it only having zero-length replacement(s). + */ + if (!sec_size(sec)) + return 1; + /* * This can happen for special section references to weak code * whose symbol has been stripped by the linker. @@ -1265,6 +1272,7 @@ static int clone_sym_relocs(struct elfs *e, struct sy= mbol *patched_sym) =20 for_each_reloc(patched_rsec, patched_reloc) { unsigned long offset; + int ret; =20 if (reloc_offset(patched_reloc) < start || reloc_offset(patched_reloc) >=3D end) @@ -1278,12 +1286,15 @@ static int clone_sym_relocs(struct elfs *e, struct = symbol *patched_sym) !strcmp(patched_reloc->sym->sec->name, ".altinstr_aux")) continue; =20 - if (convert_reloc_sym(e->patched, patched_reloc)) { + ret =3D convert_reloc_sym(e->patched, patched_reloc); + if (ret < 0) { ERROR_FUNC(patched_rsec->base, reloc_offset(patched_reloc), "failed to convert reloc sym '%s' to its proper format", patched_reloc->sym->name); return -1; } + if (ret > 0) + continue; =20 offset =3D out_sym->offset + (reloc_offset(patched_reloc) - patched_sym-= >offset); =20 --=20 2.53.0 From nobody Thu Jun 18 07:54:40 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 0E6813164DF; Fri, 1 May 2026 04:08:56 +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=1777608536; cv=none; b=kPBz0ky5tTPO9BarRkVvYY0UyrwWOYwUHbkVcT7O3uVGDJ6LvLvtTLPRbvv2GO9NRTgTQMUEVHNAMFoPK9Ivqy0iDL/lV4MTKaXgLQ/t0USCyrDL+qYY8bgPX2Z4RT4KKUgkbFGNgbr3m11mXDJguEhCLCmr36O/mG9GQZkxa9w= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777608536; c=relaxed/simple; bh=upnZpGO2ehfLykc94uj/fnnF7vh4EjIm6g3kzY61rCc=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=T9opzg6UzJAHyPDHDAlQfZ0dmEORABGYb5bhAByJLX31ZmCBlPESUmZXYU7XMDSzny+LP6LPdSVNEBohzJGnnz1l6v33AVjNQokawoXoUY3C6vBrPut8BtMFafL45lpT92Ms7lwVngpKIXoSL22EEDHHC+8WYkYbTiOCls2n/CY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=kJeJz4gI; 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="kJeJz4gI" Received: by smtp.kernel.org (Postfix) with ESMTPSA id A03BEC2BCB8; Fri, 1 May 2026 04:08:55 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1777608535; bh=upnZpGO2ehfLykc94uj/fnnF7vh4EjIm6g3kzY61rCc=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=kJeJz4gIUTZyq13n3rF4u70PI/4vp0rzXl97KEjGVjwnoNxHcR/ld3agD6Yiw+nm9 RGW6rqKGcCQHYQbjaPlQdDFETkqBEEx4FOaLJuYnn1OdB7aqQ7KxEGStlnQdyXKinY hWysWV1uxF7WBpKG3vXo8CBTBmNfhwyWV9UhUv0j8CxVoZl9bTaKi0fZJRQeQ/f8cV dd2FJZAFQ7qjy0LEPsx9f6sAkCeJVv5BY7qXbsVGP4m7aHmm92B8yL5R4wdXyvMC1l 6orrnyUj0s/O4umAs24vQVFCvbb2FY1SNKMabavNg+xVRTGSUVcsZnH+RGxEuEofhO ox3b/arq2fPqA== From: Josh Poimboeuf To: x86@kernel.org Cc: linux-kernel@vger.kernel.org, live-patching@vger.kernel.org, Peter Zijlstra , Joe Lawrence , Song Liu , Miroslav Benes , Petr Mladek Subject: [PATCH v2 12/53] objtool/klp: Fix cloning of zero-length section symbols Date: Thu, 30 Apr 2026 21:08:00 -0700 Message-ID: X-Mailer: git-send-email 2.53.0 In-Reply-To: References: 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" Fix NULL dereference when cloning a symbol from an empty section. sec->data is only populated for sections with non-zero size. Fixes: dd590d4d57eb ("objtool/klp: Introduce klp diff subcommand for diffin= g object files") Acked-by: Song Liu Reviewed-by: Miroslav Benes Signed-off-by: Josh Poimboeuf --- tools/objtool/klp-diff.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/objtool/klp-diff.c b/tools/objtool/klp-diff.c index a226e99948b3..17a6146b9406 100644 --- a/tools/objtool/klp-diff.c +++ b/tools/objtool/klp-diff.c @@ -681,7 +681,7 @@ static struct symbol *__clone_symbol(struct elf *elf, s= truct symbol *patched_sym size_t size; =20 /* bss doesn't have data */ - if (patched_sym->sec->data->d_buf) + if (patched_sym->sec->data && patched_sym->sec->data->d_buf) data =3D patched_sym->sec->data->d_buf + patched_sym->offset; =20 if (is_sec_sym(patched_sym)) --=20 2.53.0 From nobody Thu Jun 18 07:54:40 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 BCE8B31E839; Fri, 1 May 2026 04:08:56 +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=1777608536; cv=none; b=jEjeufUwjzQ+vq8O4oBNEWc53NuhGZ3ugqteL27nGOWcgTXeHg+OvErefLtjBWjra3hdhFH+d8GHnXn374Tmsi21VCWiCqy66RaYjp29zNcs+y3L9Oj52wlxC1pNcgJK2V7/0vES1k0Oocni31tnyaRTiBnUI5SA7qfkNmsFIBU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777608536; c=relaxed/simple; bh=XZoB30TRiIWGU6vD7AMbd49ugbJOhYtr+PZg8o6TBlc=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=D9NCUk9dG7J9Cr18nao4kfIx7ldWfOFwsT5EVHRgmMvpOOghRWlnK2cnSkaTbqBSRjsDMiOUNpsEdEhrmB4rOqyxOkXXzLTRwNtEC4TRSvwAuE94rgOjH2FQjOYm5FYlYb7A9xpHimZAp+LPJnXDQYJOvS/LhHdLE3lBbwLp2v0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=NqNCz/lm; 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="NqNCz/lm" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 1A01BC2BCB9; Fri, 1 May 2026 04:08:56 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1777608536; bh=XZoB30TRiIWGU6vD7AMbd49ugbJOhYtr+PZg8o6TBlc=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=NqNCz/lmIEbp4naZtF1qIaDKYWKIU1qiYAUuK1HFz1mFbkQH5gL1i0voopbBOirhp fWYF2wg8oBfVPDfkOXZL4EiiygdcA2YovaeNqnccTk56bWG26zP0IYOkTLUTpEAGt+ iSV2WtmwXtDE7F+suBNLym17L01r7i32I2YG3vnQ8NrmXekotCb+djQwoPF7xTsDPB TAh5VFnPNYbFvjs33MWFdEMHIzOzyiJTSy5Ub9U7sIm7GaYFnrN6cfz+i8lrw3E4WO NH2eOnj6Zd0+MiWlFlPVmEw9JYq3Z5YBXXCuJNhZGAg2gYlRoKqGIYigR1SLcqMEHK f2pTfvovMz7rw== From: Josh Poimboeuf To: x86@kernel.org Cc: linux-kernel@vger.kernel.org, live-patching@vger.kernel.org, Peter Zijlstra , Joe Lawrence , Song Liu , Miroslav Benes , Petr Mladek Subject: [PATCH v2 13/53] objtool/klp: Fix XXH3 state memory leak Date: Thu, 30 Apr 2026 21:08:01 -0700 Message-ID: <5467cb2bca420351d4cc0bde19c2a340d2640df8.1777575752.git.jpoimboe@kernel.org> X-Mailer: git-send-email 2.53.0 In-Reply-To: References: 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" The XXH3 state allocated in checksum_init() is never freed. Free it in checksum_finish(). Acked-by: Song Liu Reviewed-by: Miroslav Benes Signed-off-by: Josh Poimboeuf --- tools/objtool/include/objtool/checksum.h | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/objtool/include/objtool/checksum.h b/tools/objtool/inclu= de/objtool/checksum.h index 7fe21608722a..0bd16fe9168b 100644 --- a/tools/objtool/include/objtool/checksum.h +++ b/tools/objtool/include/objtool/checksum.h @@ -26,6 +26,7 @@ static inline void checksum_finish(struct symbol *func) { if (func && func->csum.state) { func->csum.checksum =3D XXH3_64bits_digest(func->csum.state); + XXH3_freeState(func->csum.state); func->csum.state =3D NULL; } } --=20 2.53.0 From nobody Thu Jun 18 07:54:40 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 03CA731E835; Fri, 1 May 2026 04:08:57 +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=1777608537; cv=none; b=KoHD+fWYaPLwq+YRULRCcNmSpbgXczF7wsQdzlY66Hzz0f6WWyJV55XxECGKiA/B0w4fZMXxU2vwQ/BufwymrI5pOlZkedjiDbwSGk9PQ7Iwuh7urGt0RSP5if6pacvbQXi/OuLItpx2gOQOPbydxKRoNdgE4HwPotjKm6GTDHo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777608537; c=relaxed/simple; bh=vx0LRuwFgx/egOMGaVY1AhX8N1g/jxnrAnySQWz2yeA=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=dyZKTNG89hX8EwsxTUVY8cpvUlbUs+frywN5uMHVbsr6+/054oKqT77xdVH2Sjz577Tb7qv1n4GSavg/OiAQur3/5eaW7WmjBBkCaFNRyIvK0jWEedXSpIvsPa4yGFKvBfUSrrjcg4CwaUOZCcFVDdx6w5CoEEH9j9ejAjOeC48= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=J6Cca5bf; 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="J6Cca5bf" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 92C70C2BCB8; Fri, 1 May 2026 04:08:56 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1777608536; bh=vx0LRuwFgx/egOMGaVY1AhX8N1g/jxnrAnySQWz2yeA=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=J6Cca5bfbvnv+8cFSdNQ+RWrBi8Q3cR5pYsrx/79Z4K7SSfmHwmdl9HKjd8RRzkPV KFIzS2cOm+8fO7/Dx1ey8RfqvQasHED8PJez1kgh9E61umMDwo4a24k7RB7Zu/rMRy AK3kx4030+gYfxvOBYSd2BvBEPEoYy7x0fv6XtWYVhZN+Qx5D3Qh/1s9nIvtWfvDiq +IUgXcswCGwWvfgmhHv3AhBdS420z45vF+biIEP6cr9hPqUFtYsD2uGH4vA2dJi/uu HH8jTTLwCuyi7kRgbeYBQ3gA/5IMgcRt0mytnnTyBYvJ3OwgSoyaYmZdpbzlDICxv7 QwgHtEm84Z1Vw== From: Josh Poimboeuf To: x86@kernel.org Cc: linux-kernel@vger.kernel.org, live-patching@vger.kernel.org, Peter Zijlstra , Joe Lawrence , Song Liu , Miroslav Benes , Petr Mladek Subject: [PATCH v2 14/53] objtool/klp: Fix extraction of text annotations for alternatives Date: Thu, 30 Apr 2026 21:08:02 -0700 Message-ID: X-Mailer: git-send-email 2.53.0 In-Reply-To: References: 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" Objtool is failing to extract text annotations which reference .altinstr_replacement instructions: 1) Alternative replacement fake symbols are NOTYPE rather than FUNC, and they don't have sym->included set, thus they aren't recognized by should_keep_special_sym(). 2) .discard.annotate_insn gets processed before .altinstr_replacement, so the referenced (fake) symbols don't have clones yet. Fix the first issue by checking for a valid clone instead of sym->included and by accepting NOTYPE symbols when processing .discard.annotate_insn. Fix the second issue by deferring text annotation processing until after the other special sections have been cloned. Fixes: dd590d4d57eb ("objtool/klp: Introduce klp diff subcommand for diffin= g object files") Acked-by: Song Liu Reviewed-by: Miroslav Benes Signed-off-by: Josh Poimboeuf --- tools/objtool/klp-diff.c | 33 ++++++++++++++++++++++++++++----- 1 file changed, 28 insertions(+), 5 deletions(-) diff --git a/tools/objtool/klp-diff.c b/tools/objtool/klp-diff.c index 17a6146b9406..42970b38728f 100644 --- a/tools/objtool/klp-diff.c +++ b/tools/objtool/klp-diff.c @@ -1437,6 +1437,7 @@ static int create_fake_symbols(struct elf *elf) /* Keep a special section entry if it references an included function */ static bool should_keep_special_sym(struct elf *elf, struct symbol *sym) { + bool annotate_insn =3D !strcmp(sym->sec->name, ".discard.annotate_insn"); struct reloc *reloc; =20 if (is_sec_sym(sym) || !sym->sec->rsec) @@ -1446,7 +1447,16 @@ static bool should_keep_special_sym(struct elf *elf,= struct symbol *sym) if (convert_reloc_sym(elf, reloc)) continue; =20 - if (is_func_sym(reloc->sym) && reloc->sym->included) + if (!reloc->sym->clone || is_undef_sym(reloc->sym->clone)) + continue; + + /* + * Keep special section references to cloned functions. + * In some cases annotate_insn can also reference cloned alt + * replacement fake symbols; keep those references as well. + */ + if (is_func_sym(reloc->sym) || + (annotate_insn && is_notype_sym(reloc->sym))) return true; } =20 @@ -1590,15 +1600,28 @@ static int clone_special_section(struct elfs *e, st= ruct section *patched_sec) /* Extract only the needed bits from special sections */ static int clone_special_sections(struct elfs *e) { - struct section *patched_sec; + struct section *sec, *annotate_insn =3D NULL; =20 - for_each_sec(e->patched, patched_sec) { - if (is_special_section(patched_sec)) { - if (clone_special_section(e, patched_sec)) + for_each_sec(e->patched, sec) { + if (is_special_section(sec)) { + if (!strcmp(sec->name, ".discard.annotate_insn")) { + annotate_insn =3D sec; + continue; + } + if (clone_special_section(e, sec)) return -1; } } =20 + /* + * Do .discard.annotate_insn last, it can reference other special + * sections (alt replacements) so they need to be cloned first. + */ + if (annotate_insn) { + if (clone_special_section(e, annotate_insn)) + return -1; + } + return 0; } =20 --=20 2.53.0 From nobody Thu Jun 18 07:54:40 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 9AC04322C88; Fri, 1 May 2026 04:08:57 +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=1777608537; cv=none; b=lp7uutNxbO5xTkx9wOOjVSjKMJchYhYh7gEC1sXZnlRGY5CdYtiFA1wE+SO0d/OOcOpbjkQ81YLx0r8RWH9GYib3EJELb0jkE3a64S6DuFfNs3UiQ21oyrPWUO9NzFNglMNDgtqVITdvsxCKPmqUhWLtrebUNH0zyuaFxxk2mGU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777608537; c=relaxed/simple; bh=EDtmbPEuWLU6hPRugmbzubNjPHNatHodc8G92yCghyU=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=SAUEtZFx40RSHnGzNmWQpxGZ06pSTyCbkArrjJAZNMZH3/Cq8JpfU3nMm1gWEAh9ACJ9uRdX/rLLSBFMFsdFT3VxSr1neR/FmKOzwAmniL+IMgIlhW30hBQAgahhSD5mdaV+3iAEbcoJlY0JS9WWQbqEIDVWLu9ulAqA0bb9gQg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=DwrgLeB/; 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="DwrgLeB/" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 0FB13C2BCB7; Fri, 1 May 2026 04:08:57 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1777608537; bh=EDtmbPEuWLU6hPRugmbzubNjPHNatHodc8G92yCghyU=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=DwrgLeB/GQssweY1OnM/53JyxBSjI6RVMzj4r972uDlK2psn5AQoUDuzsPWkV6VaK y0zu+unBqOuX+sw7V+zQIH+5Vh+Inj3+9FzJot1N8T3TZ0PvavCZ3IzzK/xO+X4bY+ YanT3iU/mmebqgIfMObrUXE9gBZ4MQzA9bOlyLwQx5vqHtvB5mT6MyY7xgTuyVwQdF wSo08tjqdODsjSgAIsKRvFVCh4hHIckTCvaYSDFyHau/PsYBp+cxrn7Jp9aiVRG/na vvPDBKTewbfYOUWd7biFYJQdKdyaJQ3gkcD+BwqaxBUY3o878tocLqJsI76lNikE9/ TgYIx0uFNuTZQ== From: Josh Poimboeuf To: x86@kernel.org Cc: linux-kernel@vger.kernel.org, live-patching@vger.kernel.org, Peter Zijlstra , Joe Lawrence , Song Liu , Miroslav Benes , Petr Mladek Subject: [PATCH v2 15/53] objtool/klp: Fix kCFI trap handling Date: Thu, 30 Apr 2026 21:08:03 -0700 Message-ID: X-Mailer: git-send-email 2.53.0 In-Reply-To: References: 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" .kcfi_traps contains references to kCFI trap instruction locations. When a KCFI type check fails at an indirect call, the trap handler looks up the faulting address in this section. Add it to the special sections list so the entries get extracted for the changed functions they reference. Acked-by: Song Liu Reviewed-by: Miroslav Benes Signed-off-by: Josh Poimboeuf --- tools/objtool/klp-diff.c | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/objtool/klp-diff.c b/tools/objtool/klp-diff.c index 42970b38728f..dd0e51dfc621 100644 --- a/tools/objtool/klp-diff.c +++ b/tools/objtool/klp-diff.c @@ -291,6 +291,7 @@ static bool is_special_section(struct section *sec) { static const char * const specials[] =3D { ".altinstructions", + ".kcfi_traps", ".smp_locks", "__bug_table", "__ex_table", --=20 2.53.0 From nobody Thu Jun 18 07:54:40 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 E73762FE582; Fri, 1 May 2026 04:08:57 +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=1777608538; cv=none; b=Y3MUA+F8d+F6uY3ox9EN+AVpDiZ502Vc3I6DEbrdYXaO4eNz9tdK7Wl3cJvgQXM5wfN51AhKNrfqO+vStrqU/Udc8EAtv0wF4MceGtlZwsbeCjQjxRcj7h3KGE/k+PGRo6v9cES0C5Z+eNDNmMA0w9PFXTg6f/pniHrnE13cz8c= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777608538; c=relaxed/simple; bh=Thr4wxf4FdYm4riP7kTt4KLaS2jq2dvObY7uSSp6BGc=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=oV9F51WfluO3a3uLvP6XdA7yZ1A5r36ZsFL2dhnpHeEmguJUaLfykHWzWakY8QYj++orgB/JWWB4wZ+wPkUwsgKCswdB95j9HMh9ojTxWEEPAR6v8MAlGhkySzLDo+y+nn0OA6d94AFq447rJZF6V1F9jHyp6wYSqcYdUkgNYdw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=DJyjMQur; 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="DJyjMQur" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 7E367C2BCB9; Fri, 1 May 2026 04:08:57 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1777608537; bh=Thr4wxf4FdYm4riP7kTt4KLaS2jq2dvObY7uSSp6BGc=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=DJyjMQurpP7bce3TU0VyQPZ2tPmM4SjR54i0OeNfSC7P839ow9w/sT0FTiZPWXr2U msY4oS0SvX+r1c7aTBR9LWdLNztOlLMoFVpWFjmk6io+Hu5OkFqY6LrkuY5PFDtjHk Wn3LWXSXtmNhzrZWtbdYLIQpZXjBL00RLE9gaL2zXvDCfDzOTxb1Azn6UL2iPyknk6 CXc1osdacDmOdLw+91gWAmD7E16orh1hj1xuFwcB0zPJBhUjhEUwVcRstNKceI9A+/ GjjmZMHNpVmS4BkemyRZ4MA2Y6qgJijW7cLSNEiMsq1vdPGCYMjiZx224W2DyWmh4a ktj9w+is+bl9w== From: Josh Poimboeuf To: x86@kernel.org Cc: linux-kernel@vger.kernel.org, live-patching@vger.kernel.org, Peter Zijlstra , Joe Lawrence , Song Liu , Miroslav Benes , Petr Mladek Subject: [PATCH v2 16/53] objtool/klp: Fix relocation conversion failures for R_X86_64_NONE Date: Thu, 30 Apr 2026 21:08:04 -0700 Message-ID: <00a7102c356daf80ebc8af174aa0c45d3cd56c96.1777575752.git.jpoimboe@kernel.org> X-Mailer: git-send-email 2.53.0 In-Reply-To: References: 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" Objtool has some hacks which NOP out certain calls/jumps and replace their relocations with R_X86_64_NONE. The klp-diff relocation extraction code will error out when trying to copy these relocations due to their negative addend, which would only makes sense for a PC-relative branch instruction. Just ignore them. Fixes: dd590d4d57eb ("objtool/klp: Introduce klp diff subcommand for diffin= g object files") Acked-by: Song Liu Reviewed-by: Miroslav Benes Signed-off-by: Josh Poimboeuf --- tools/objtool/klp-diff.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tools/objtool/klp-diff.c b/tools/objtool/klp-diff.c index dd0e51dfc621..19bc811db396 100644 --- a/tools/objtool/klp-diff.c +++ b/tools/objtool/klp-diff.c @@ -1033,6 +1033,9 @@ static int convert_reloc_secsym_to_sym(struct elf *el= f, struct reloc *reloc) */ static int convert_reloc_sym(struct elf *elf, struct reloc *reloc) { + if (reloc_type(reloc) =3D=3D R_NONE) + return 1; + if (is_reloc_allowed(reloc)) return 0; =20 --=20 2.53.0 From nobody Thu Jun 18 07:54:40 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 6B2292FE579; Fri, 1 May 2026 04:08:58 +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=1777608538; cv=none; b=L7/+m6pJ3vJQpVRuXBQQ/MIzG23NEU9bxAcKdU7elC5xYewbY4nN37jYf5dgBkqdq9qySM3t0CUOu+XYmajsaA6u0oDHFN1KTLehXX/bJa/9PI2PmchFtT/L1820YhjJ3uNqpCXiCLoeaM3z6fsYKxNOU3c04uBEC2K3Dvum3v4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777608538; c=relaxed/simple; bh=3Cgl/k80HbhHMq6p97AxTmNaySd47AXzO0dWEwccxCI=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=Af9cJ5Tvzt6IZ8GFe2aAxZfj3oSy7DUwSggvQZeb7g5nxfY6Hbn94NOVVANyZC+WWGhqps5Kq9q8qq/wKNHJgSPr4zRhgoYR2WpWfUEZr+FV//YS1t9o/Nbm9RyDRYlfn5FH6VAbtsrmbiO54MFqNLQAH9/uxybXFzra517zfoM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=X/ujpJEp; 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="X/ujpJEp" Received: by smtp.kernel.org (Postfix) with ESMTPSA id F2541C2BCB7; Fri, 1 May 2026 04:08:57 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1777608538; bh=3Cgl/k80HbhHMq6p97AxTmNaySd47AXzO0dWEwccxCI=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=X/ujpJEphJ5hNsqCwfa4FxBrdGCJVrqMsGiJnj4t4FxzP560WlKdRFc+/JD7Bl2bu 7bvh0OvSxHxyLcav7+Gtz/3j8GgTATC+bBZjh2s0aaUoLKZzOpGHX5UczIAMsyGV5n hzVcYBya97om9ZLPy1HOCMJ92dYDRA5iSAPHLSRWX1WrzskK37dc2qhnbMSnNHTUV2 NFJNimcWfzTUlNZcs4XbukQGPP5JsCID7VWqBE8+LNIJMNfjDegoKu7i09d/I0qq+8 FCgqCCFNotuVLir6gxojEnXWkw9+NN5GOQfxoOIn3sKyMoht0DBcsVrAhGHV3mHc1D o4AeDeMxCvVMA== From: Josh Poimboeuf To: x86@kernel.org Cc: linux-kernel@vger.kernel.org, live-patching@vger.kernel.org, Peter Zijlstra , Joe Lawrence , Song Liu , Miroslav Benes , Petr Mladek Subject: [PATCH v2 17/53] objtool: Move mark_rodata() to elf.c Date: Thu, 30 Apr 2026 21:08:05 -0700 Message-ID: <1462986f6b02ad95ac87115b5ddcc5260c036faf.1777575752.git.jpoimboe@kernel.org> X-Mailer: git-send-email 2.53.0 In-Reply-To: References: 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" Move the sec->rodata marking from check.c to elf.c so it's set during ELF reading rather than during the check pipeline. This makes the rodata flag available to all objtool users, including klp-diff which reads ELF files directly without running check(). Add an is_rodata_sec() helper to elf.h for consistency with is_text_sec() and is_string_sec(). Acked-by: Peter Zijlstra (Intel) Acked-by: Song Liu Reviewed-by: Miroslav Benes Signed-off-by: Josh Poimboeuf --- tools/objtool/check.c | 11 +++-------- tools/objtool/elf.c | 13 +++++++++++++ tools/objtool/include/objtool/elf.h | 5 +++++ 3 files changed, 21 insertions(+), 8 deletions(-) diff --git a/tools/objtool/check.c b/tools/objtool/check.c index e3604b1201f9..e7579c4e46dc 100644 --- a/tools/objtool/check.c +++ b/tools/objtool/check.c @@ -2566,7 +2566,6 @@ static int classify_symbols(struct objtool_file *file) static void mark_rodata(struct objtool_file *file) { struct section *sec; - bool found =3D false; =20 /* * Search for the following rodata sections, each of which can @@ -2579,15 +2578,11 @@ static void mark_rodata(struct objtool_file *file) * .rodata.str1.* sections are ignored; they don't contain jump tables. */ for_each_sec(file->elf, sec) { - if ((!strncmp(sec->name, ".rodata", 7) && - !strstr(sec->name, ".str1.")) || - !strncmp(sec->name, ".data.rel.ro", 12)) { - sec->rodata =3D true; - found =3D true; + if (is_rodata_sec(sec)) { + file->rodata =3D true; + return; } } - - file->rodata =3D found; } =20 static void mark_holes(struct objtool_file *file) diff --git a/tools/objtool/elf.c b/tools/objtool/elf.c index dc39132f71c1..87c6e00749c6 100644 --- a/tools/objtool/elf.c +++ b/tools/objtool/elf.c @@ -1138,6 +1138,17 @@ static int read_relocs(struct elf *elf) return 0; } =20 +static void mark_rodata(struct elf *elf) +{ + struct section *sec; + + for_each_sec(elf, sec) { + if ((strstarts(sec->name, ".rodata") && !strstr(sec->name, ".str1.")) || + strstarts(sec->name, ".data.rel.ro")) + sec->rodata =3D true; + } +} + struct elf *elf_open_read(const char *name, int flags) { struct elf *elf; @@ -1188,6 +1199,8 @@ struct elf *elf_open_read(const char *name, int flags) if (read_sections(elf)) goto err; =20 + mark_rodata(elf); + if (read_symbols(elf)) goto err; =20 diff --git a/tools/objtool/include/objtool/elf.h b/tools/objtool/include/ob= jtool/elf.h index 00b04029023e..ab5f7017ec34 100644 --- a/tools/objtool/include/objtool/elf.h +++ b/tools/objtool/include/objtool/elf.h @@ -317,6 +317,11 @@ static inline bool is_text_sec(struct section *sec) return sec->sh.sh_flags & SHF_EXECINSTR; } =20 +static inline bool is_rodata_sec(struct section *sec) +{ + return sec->rodata; +} + static inline bool sec_changed(struct section *sec) { return sec->_changed; --=20 2.53.0 From nobody Thu Jun 18 07:54:40 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 7C3AD3321A2; Fri, 1 May 2026 04:08:58 +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=1777608539; cv=none; b=pM9v52AmQ/3BfsYpshZBrtKo5V+0Y5uXkZR18i9b9tzyoCK5Kml2sWEW3mcYVs2Z661ZumIY1tokxPQAZAjURd+MymjzbieiNEhWHfdsyjVe2ufOrV63WoKklsIgeGaxv7bP/ZCI9e6wNflCswdxD5XoYv+K6sn67mPPIEe3tbU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777608539; c=relaxed/simple; bh=XjTMzGfi8bZF7bQaM0dm87pbnohW8womDStrdD8mTyA=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=aNBgTN9JLFX9cPo1Wu+jChITu2WJuLkfaWtQ8+a+6kUSUCN8zaTya11ZudXf4KY+SZVuSl+/wgQgcX6YfS05zmuL5jriDNwVjBvFmdb4MUxE8yes9cjGrpK/KjwBkd1O8YCixQq3esjVA8L3ZC+H170Csw/wwOtJsMgDvSEHoQk= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=eeYeQbLY; 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="eeYeQbLY" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 6C3C4C2BCC6; Fri, 1 May 2026 04:08:58 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1777608538; bh=XjTMzGfi8bZF7bQaM0dm87pbnohW8womDStrdD8mTyA=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=eeYeQbLYVHzIAYgoVCJFcHqKXLQjZ6IERnz0WUlH5bXoZhf45SEI0y2gpegqMRtfb 4PUy5c33fyEAPpM6X2pSz+1NoEyEsBontSQ7yWehuik01iZmHfQspmZW2zwKpah0wN T7ErI20WADNcoo4RvoSI6bbs1o8xsRUzA7TN8uZw4rGKha+l/qrsDqASzpzU8iO9GP YXSEvx5LGWwFVXEpolCGE4WJG0cgmurInRrlJRy+qseO+NigbwzuxnCwjZoFtrvgWE lFxOtKhFBmrTOKPnD8HYTvdH46reddefPyLkCgsBRl9xgaZ/VhEupkVl7SkW4mM/c9 macECQx4QKxfQ== From: Josh Poimboeuf To: x86@kernel.org Cc: linux-kernel@vger.kernel.org, live-patching@vger.kernel.org, Peter Zijlstra , Joe Lawrence , Song Liu , Miroslav Benes , Petr Mladek Subject: [PATCH v2 18/53] objtool/klp: Simplify reloc symbol conversion Date: Thu, 30 Apr 2026 21:08:06 -0700 Message-ID: <9572b2e15500e5ed8dcbaac78c966557d3000d85.1777575752.git.jpoimboe@kernel.org> X-Mailer: git-send-email 2.53.0 In-Reply-To: References: 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" Inline section_reference_needed() and is_reloc_allowed() into convert_reloc_sym() and remove the redundant is_reloc_allowed() check in clone_reloc(). Move the is_sec_sym() checks into the convert callees so they become no-ops when the reloc is already in the right format. This allows convert_reloc_sym() to unconditionally dispatch to the right converter based on section type. Signed-off-by: Josh Poimboeuf Acked-by: Song Liu Reviewed-by: Miroslav Benes --- tools/objtool/klp-diff.c | 76 +++++++++++++++------------------------- 1 file changed, 28 insertions(+), 48 deletions(-) diff --git a/tools/objtool/klp-diff.c b/tools/objtool/klp-diff.c index 19bc811db396..78633c9b68eb 100644 --- a/tools/objtool/klp-diff.c +++ b/tools/objtool/klp-diff.c @@ -838,39 +838,6 @@ static int clone_included_functions(struct elfs *e) return 0; } =20 -/* - * Determine whether a relocation should reference the section rather than= the - * underlying symbol. - */ -static bool section_reference_needed(struct section *sec) -{ - /* - * String symbols are zero-length and uncorrelated. It's easier to - * deal with them as section symbols. - */ - if (is_string_sec(sec)) - return true; - - /* - * .rodata has mostly anonymous data so there's no way to determine the - * length of a needed reference. just copy the whole section if needed. - */ - if (strstarts(sec->name, ".rodata")) - return true; - - /* UBSAN anonymous data */ - if (strstarts(sec->name, ".data..Lubsan") || /* GCC */ - strstarts(sec->name, ".data..L__unnamed_")) /* Clang */ - return true; - - return false; -} - -static bool is_reloc_allowed(struct reloc *reloc) -{ - return section_reference_needed(reloc->sym->sec) =3D=3D is_sec_sym(reloc-= >sym); -} - static struct export *find_export(struct symbol *sym) { struct export *export; @@ -979,11 +946,15 @@ static bool klp_reloc_needed(struct reloc *patched_re= loc) return true; } =20 +/* Return -1 error, 0 success, 1 skip */ static int convert_reloc_sym_to_secsym(struct elf *elf, struct reloc *relo= c) { struct symbol *sym =3D reloc->sym; struct section *sec =3D sym->sec; =20 + if (is_sec_sym(sym)) + return 0; + if (!sec->sym && !elf_create_section_symbol(elf, sec)) return -1; =20 @@ -993,11 +964,15 @@ static int convert_reloc_sym_to_secsym(struct elf *el= f, struct reloc *reloc) return 0; } =20 +/* Return -1 error, 0 success, 1 skip */ static int convert_reloc_secsym_to_sym(struct elf *elf, struct reloc *relo= c) { struct symbol *sym =3D reloc->sym; struct section *sec =3D sym->sec; =20 + if (!is_sec_sym(sym)) + return 0; + /* If the symbol has a dedicated section, it's easy to find */ sym =3D find_symbol_by_offset(sec, 0); if (sym && sym->len =3D=3D sec_size(sec)) @@ -1027,22 +1002,34 @@ static int convert_reloc_secsym_to_sym(struct elf *= elf, struct reloc *reloc) return 0; } =20 +/* + * Sections with anonymous or uncorrelated data (strings, UBSAN data) + * need section symbol references. + */ +static bool is_uncorrelated_section(struct section *sec) +{ + return is_string_sec(sec) || + strstarts(sec->name, ".rodata") || + strstarts(sec->name, ".data..Lubsan") || /* GCC */ + strstarts(sec->name, ".data..L__unnamed_"); /* Clang */ +} + /* * Convert a relocation symbol reference to the needed format: either a se= ction - * symbol or the underlying symbol itself. + * symbol or the underlying symbol itself. Return -1 error, 0 success, 1 = skip. */ static int convert_reloc_sym(struct elf *elf, struct reloc *reloc) { + struct section *sec =3D reloc->sym->sec; + if (reloc_type(reloc) =3D=3D R_NONE) return 1; =20 - if (is_reloc_allowed(reloc)) - return 0; - - if (section_reference_needed(reloc->sym->sec)) + if (is_uncorrelated_section(sec)) return convert_reloc_sym_to_secsym(elf, reloc); - else - return convert_reloc_secsym_to_sym(elf, reloc); + + /* Everything else: references should use named symbols. */ + return convert_reloc_secsym_to_sym(elf, reloc); } =20 /* @@ -1187,13 +1174,6 @@ static int clone_reloc(struct elfs *e, struct reloc = *patched_reloc, struct symbol *out_sym; bool klp; =20 - if (!is_reloc_allowed(patched_reloc)) { - ERROR_FUNC(patched_reloc->sec->base, reloc_offset(patched_reloc), - "missing symbol for reference to %s+%ld", - patched_sym->name, addend); - return -1; - } - klp =3D klp_reloc_needed(patched_reloc); =20 dbg_clone_reloc(sec, offset, patched_sym, addend, export, klp); @@ -1223,7 +1203,7 @@ static int clone_reloc(struct elfs *e, struct reloc *= patched_reloc, =20 /* * For strings, all references use section symbols, thanks to - * section_reference_needed(). clone_symbol() has cloned an empty + * convert_reloc_sym(). clone_symbol() has cloned an empty * version of the string section. Now copy the string itself. */ if (is_string_sec(patched_sym->sec)) { --=20 2.53.0 From nobody Thu Jun 18 07:54:40 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 491532BEC5E; Fri, 1 May 2026 04:08:59 +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=1777608539; cv=none; b=qTrBxvasx3qtvF772kcT8lSMPZ61En+ID947shpphyV/H0eDz9H1Y+UaqyIO7XKalkDKpnYFj5UwWuqzNvd84XiR68vyvNrZe40RkwC5oxWKPLEW10TtQA+ru1q+J3cRWhoibkJl6wH2M/vh9aMsysJ+jKRnvRWKT7DgF746qEE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777608539; c=relaxed/simple; bh=V5TjeaqIbFUsUWMkQqGV72vDZ7Ol+bs9z/fXO0pU1+8=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=FvmJT8M5fjnegqpEui1oCqVA5+4ltrQpu6r6nrakApsgHGGYF0OeTWIbXCf4pYsCtId5pZnHZwoHsgn9yLZow50C3LKYKsT4JPnfisVtbA4JqEdHMQENCKzWU8RIjVoxMwJe5cI60ftGjaiW+1QhhDfZem8+BFibzyyQe0A3e9M= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=U3ZQrewg; 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="U3ZQrewg" Received: by smtp.kernel.org (Postfix) with ESMTPSA id DA0BFC2BCB8; Fri, 1 May 2026 04:08:58 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1777608539; bh=V5TjeaqIbFUsUWMkQqGV72vDZ7Ol+bs9z/fXO0pU1+8=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=U3ZQrewg1+24PfF9O2o7ZS4Da3AwZypkKVRPn+XQRCYfkLX9BNHbv6ZBOIRQFMfWu HHjQNOPj2ytQmul5n2+Yyn1/XcJ5bvsqL6mNG2c2wNtsct2LlHpnfo5y+Jh3k2TC/K o9cl9T/+jjYfGu3GSV8/OMGAlzCftV+w4XYOd4zpPMNn8w0NH7pIwzOi7J3rd5PyC5 /KIJUEz72V/wUJEMArPtoXUMwjglKOO3xuw9p8JuMkeTPSF99+SFsI4kwTGNrmva3H ZAdBq7xy7XNIswkUmEpsWlijcpcf9kYGOKG8qzfotkI4ZPd/2JFMjbPNYJIy0zqFoG D3J+Zb/eVnADA== From: Josh Poimboeuf To: x86@kernel.org Cc: linux-kernel@vger.kernel.org, live-patching@vger.kernel.org, Peter Zijlstra , Joe Lawrence , Song Liu , Miroslav Benes , Petr Mladek Subject: [PATCH v2 19/53] objtool/klp: Fix pointer comparisons for rodata objects Date: Thu, 30 Apr 2026 21:08:07 -0700 Message-ID: <07de8098fd8981321baab0ff552f65aa2cfc31ec.1777575752.git.jpoimboe@kernel.org> X-Mailer: git-send-email 2.53.0 In-Reply-To: References: 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" klp-diff treats all rodata as uncorrelated, so any reference to it uses a duplicated copy rather than using a KLP reloc. For the contents of the data itself, a duplicated copy is fine. However, pointer comparisons (e.g., f->f_op =3D=3D &foo_ops) are broken. Fix it by correlating non-anonymous rodata objects. Also, use a new find_symbol_containing_inclusive() helper for matching the end of a symbol so bounds calculations don't get broken, for the case where an array or other symbol's ending address is used as part of a bounds calculation. While these are really two distinct changes, they need to be done in the same patch so as to avoid introducing bisection regressions. Signed-off-by: Josh Poimboeuf Acked-by: Song Liu Reviewed-by: Miroslav Benes --- tools/objtool/elf.c | 14 ++++++++++++++ tools/objtool/include/objtool/elf.h | 1 + tools/objtool/klp-diff.c | 15 +++++++++++++-- 3 files changed, 28 insertions(+), 2 deletions(-) diff --git a/tools/objtool/elf.c b/tools/objtool/elf.c index 87c6e00749c6..5a20dab683dd 100644 --- a/tools/objtool/elf.c +++ b/tools/objtool/elf.c @@ -207,6 +207,20 @@ struct symbol *find_symbol_containing(const struct sec= tion *sec, unsigned long o return sym ? sym->alias : NULL; } =20 +/* + * Also match the symbol end address which can be used for a bounds compar= ison. + */ +struct symbol *find_symbol_containing_inclusive(const struct section *sec, + unsigned long offset) +{ + struct symbol *sym =3D find_symbol_containing(sec, offset); + + if (!sym && offset) + sym =3D find_symbol_containing(sec, offset - 1); + + return sym; +} + /* * Returns size of hole starting at @offset. */ diff --git a/tools/objtool/include/objtool/elf.h b/tools/objtool/include/ob= jtool/elf.h index ab5f7017ec34..8a543cea43b9 100644 --- a/tools/objtool/include/objtool/elf.h +++ b/tools/objtool/include/objtool/elf.h @@ -211,6 +211,7 @@ struct symbol *find_symbol_by_offset(struct section *se= c, unsigned long offset); struct symbol *find_symbol_by_name(const struct elf *elf, const char *name= ); struct symbol *find_global_symbol_by_name(const struct elf *elf, const cha= r *name); struct symbol *find_symbol_containing(const struct section *sec, unsigned = long offset); +struct symbol *find_symbol_containing_inclusive(const struct section *sec,= unsigned long offset); int find_symbol_hole_containing(const struct section *sec, unsigned long o= ffset); struct reloc *find_reloc_by_dest(const struct elf *elf, struct section *se= c, unsigned long offset); struct reloc *find_reloc_by_dest_range(const struct elf *elf, struct secti= on *sec, diff --git a/tools/objtool/klp-diff.c b/tools/objtool/klp-diff.c index 78633c9b68eb..bf37c652188b 100644 --- a/tools/objtool/klp-diff.c +++ b/tools/objtool/klp-diff.c @@ -386,6 +386,7 @@ static bool dont_correlate(struct symbol *sym) is_uncorrelated_static_local(sym) || is_local_label(sym) || is_string_sec(sym->sec) || + (is_rodata_sec(sym->sec) && !is_object_sym(sym)) || is_initcall_sym(sym) || is_addressable_sym(sym) || is_special_section(sym->sec) || @@ -979,7 +980,7 @@ static int convert_reloc_secsym_to_sym(struct elf *elf,= struct reloc *reloc) goto found_sym; =20 /* No dedicated section; find the symbol manually */ - sym =3D find_symbol_containing(sec, arch_adjusted_addend(reloc)); + sym =3D find_symbol_containing_inclusive(sec, arch_adjusted_addend(reloc)= ); if (!sym) { /* * This is presumably an .altinstr_replacement section which is @@ -988,6 +989,17 @@ static int convert_reloc_secsym_to_sym(struct elf *elf= , struct reloc *reloc) if (!sec_size(sec)) return 1; =20 + /* + * .rodata is a mixed bag of named objects and anonymous data. + * + * Convert section symbol references to named object symbols + * when possible, to preserve pointer identity for const + * structs like file_operations. Otherwise a section symbol is + * fine. + */ + if (is_rodata_sec(sec)) + return 0; + /* * This can happen for special section references to weak code * whose symbol has been stripped by the linker. @@ -1009,7 +1021,6 @@ static int convert_reloc_secsym_to_sym(struct elf *el= f, struct reloc *reloc) static bool is_uncorrelated_section(struct section *sec) { return is_string_sec(sec) || - strstarts(sec->name, ".rodata") || strstarts(sec->name, ".data..Lubsan") || /* GCC */ strstarts(sec->name, ".data..L__unnamed_"); /* Clang */ } --=20 2.53.0 From nobody Thu Jun 18 07:54:40 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 C38243346A0; Fri, 1 May 2026 04:08:59 +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=1777608540; cv=none; b=raLE0uZQN4fjv/NVthiAHT+p5VWENw13yymC/UAo7hIWwGF5o3IvQXbOby3M+nkL+ue2H1A1pod2qpvG6aJ3oltEzetmFcdDyuNhLfl0Pob66NigUmozZy+GvtHoe12G+4Oa/Q0kQmn7L7AMxlxFyk0WHjurEVP5GVCjOscvdcg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777608540; c=relaxed/simple; bh=FIQZUcy2Hey8nvAFi1fgSV7gr9AZynhgSHpifcQ9pQk=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=iYIx2R9BP/C+AFMCeAFBJjdVdnSH0FILP9esrzvSWW5R/YVSigmGCGkoh7d4n9pg2haij32aNk9eWM+g6Ky1SZhvmTrJvHzRU+J/tWN0O2ExuG3TDoEIaylFiZzi2zDt3sNXzaoxmJ6uv76IpSH9IErDwfNE1+tayjUIylKUwS8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=NiY6eSOJ; 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="NiY6eSOJ" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 53C9BC2BCB9; Fri, 1 May 2026 04:08:59 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1777608539; bh=FIQZUcy2Hey8nvAFi1fgSV7gr9AZynhgSHpifcQ9pQk=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=NiY6eSOJuggPmeuLXETEDYfEfw12nxeCLpAXlCwmMLqQLXCCqSYdH3zw8CjIR3TUa 3N/JdpP7i8mBHa4cqIOQzM2iY08ZuLsoooId57subT3daJLJQZjWePU90a6r/PWz7w cdRLzJ2MqLViWM4I8q3AZO18+0SaYFFDrypAyji2fjsjU5xSRY7qq+/GRB+OsXO7T7 mhKkhNp9+1/MetP4qX8z4rVpBhjH9uLYxiIURn9HsgqGL1qw7hwfJCUw+0+y+LNcpx 0a0UqrH5PxBOrp1jMqznXSCA0Leet5lir7mD1Lp9Pvnmo7G2jqZWwjGpk99X6wXoGO NcWz8C5ICR7Ow== From: Josh Poimboeuf To: x86@kernel.org Cc: linux-kernel@vger.kernel.org, live-patching@vger.kernel.org, Peter Zijlstra , Joe Lawrence , Song Liu , Miroslav Benes , Petr Mladek Subject: [PATCH v2 20/53] objtool/klp: Don't correlate .rodata.cst* constant pool objects Date: Thu, 30 Apr 2026 21:08:08 -0700 Message-ID: <80d6f8df4db610a6c9f68031dc0153f04814f2fa.1777575752.git.jpoimboe@kernel.org> X-Mailer: git-send-email 2.53.0 In-Reply-To: References: 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" Clang aggregates UBSAN type descriptors into shared anonymous .data..L__unnamed_* sections. This data is used by UBSAN trap handlers. When a changed function has an UBSAN bounds check, klp-diff clones the entire UBSAN data section associated with the TU. Relocations within the cloned section that reference named rodata objects in .rodata.cst* (like 'exponent', 'pirq_ali_set.irqmap') become KLP relocations because those objects now get correlated. That results in a .klp.rela.vmlinux..data section which can easily have thousands of KLP relocs, most of which are completely superfluous, used by functions which aren't cloned to the patch module. The .rodata.cst* sections are SHF_MERGE constant pool sections containing small fixed-size data (lookup tables, bitmasks) that is only read by value. Pointer identity is never relevant for these objects, so correlating them is unnecessary. Exclude .rodata.cst* objects from correlation so they get cloned as local data instead of generating KLP relocations. It might be possible to someday treat UBSAN data sections as special sections, and only extract the few needed entries. But this works for now. Signed-off-by: Josh Poimboeuf Acked-by: Song Liu Reviewed-by: Miroslav Benes --- tools/objtool/klp-diff.c | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/tools/objtool/klp-diff.c b/tools/objtool/klp-diff.c index bf37c652188b..ca87bcb9afa3 100644 --- a/tools/objtool/klp-diff.c +++ b/tools/objtool/klp-diff.c @@ -372,6 +372,21 @@ static bool is_initcall_sym(struct symbol *sym) strstarts(sym->name, "__initstub__"); } =20 +/* + * Some .rodata is anonymous and can't be correlated due to there being no + * symbol names. + * + * The .rodata.cst* sections aren't technically anonymous, they're SHF_MER= GE + * constant pool sections containing small fixed-size data (lookup tables, + * bitmasks) which are only read by value, so pointer equivalence isn't ne= eded. + * They are typically referenced by UBSAN data sections. + */ +static bool is_anonymous_rodata(struct symbol *sym) +{ + return is_rodata_sec(sym->sec) && + (!is_object_sym(sym) || strstarts(sym->sec->name, ".rodata.cst")); +} + /* * These symbols should never be correlated, so their local patched versio= ns * are used instead of linking to the originals. @@ -386,7 +401,7 @@ static bool dont_correlate(struct symbol *sym) is_uncorrelated_static_local(sym) || is_local_label(sym) || is_string_sec(sym->sec) || - (is_rodata_sec(sym->sec) && !is_object_sym(sym)) || + is_anonymous_rodata(sym) || is_initcall_sym(sym) || is_addressable_sym(sym) || is_special_section(sym->sec) || --=20 2.53.0 From nobody Thu Jun 18 07:54:40 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 813433033E8; Fri, 1 May 2026 04:09:00 +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=1777608540; cv=none; b=dh905Z9RxH6DRGykWpUgMJEGpP1bF+E9b0M6U0z6AFkqUUZ6eT+tn6TP6GM48pvCJPh4bd88jSUsr7HZX1gcqLbnbi1b3nXT7Ec2VDhATD3WeL8/0j4NsfoSy+2e+hsl3cltj4BrzKUxANa/lOZoFDlWLhJxdiZq4jcMWC6TEuU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777608540; c=relaxed/simple; bh=djxbbA8QTsmn6CedczZq3P920XHpKxKsJKFDjpZyrgs=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=p2RY2AgY8lWApRcwUmP2gN9lEgsieGDqc1vT9PuQ564aHdpEOLOUdED6BUWXMU/+g5RLesWzh7uJji/Ixo24qLA0Ow930jJegPwLl9JWcUNiVw6lTr530xafRXyR8W9p8z+t+rqlZR3XJad3TnyJZLy/fIbtivWZiSGCeTR6vDM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=oeedLMQF; 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="oeedLMQF" Received: by smtp.kernel.org (Postfix) with ESMTPSA id C2897C2BCB7; Fri, 1 May 2026 04:08:59 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1777608540; bh=djxbbA8QTsmn6CedczZq3P920XHpKxKsJKFDjpZyrgs=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=oeedLMQFmWJ5XIKZTbUrWn54rHpj3Qjh9QQigos1uIXo/Ts1RTp0lHvQ7u7lksK0/ y8DmCPVIMcmdiJh25unk8wLhrDkEkp99zyLBQwcm/C34GBPqo/rnwZEHyXV6FmMc7J wEvJFay8SudfddBF4qqx2U16Jd+SbEpazOc6HMiUkqN0BuqDV8BdmKKGA+4egz++S0 l3l2tEGgEnwrCfr1QvGnGMds5xV7ZnrxEjORFbL3ESXjMhMh7INwZJEE3DQFuk41G4 k7t+q89wmZp9mj8Cn88Sz6N/jFc0FTbuHKmgKnepZfPhp6ocp0vE8IPXT8OLptsNcC naEZCXOBtnZyQ== From: Josh Poimboeuf To: x86@kernel.org Cc: linux-kernel@vger.kernel.org, live-patching@vger.kernel.org, Peter Zijlstra , Joe Lawrence , Song Liu , Miroslav Benes , Petr Mladek Subject: [PATCH v2 21/53] objtool/klp: Fix reloc corruption in convert_reloc_sym_to_secsym() Date: Thu, 30 Apr 2026 21:08:09 -0700 Message-ID: <9b419d82a20dbc54be4a59cfec04ab13987a2e6c.1777575752.git.jpoimboe@kernel.org> X-Mailer: git-send-email 2.53.0 In-Reply-To: References: 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" Use the section symbol's index instead of the old symbol's index when updating the ELF relocation entry in convert_reloc_sym_to_secsym(). Found by Sashiko review. Signed-off-by: Josh Poimboeuf Acked-by: Song Liu Reviewed-by: Miroslav Benes --- tools/objtool/klp-diff.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/objtool/klp-diff.c b/tools/objtool/klp-diff.c index ca87bcb9afa3..463b6daa5234 100644 --- a/tools/objtool/klp-diff.c +++ b/tools/objtool/klp-diff.c @@ -975,7 +975,7 @@ static int convert_reloc_sym_to_secsym(struct elf *elf,= struct reloc *reloc) return -1; =20 reloc->sym =3D sec->sym; - set_reloc_sym(elf, reloc, sym->idx); + set_reloc_sym(elf, reloc, sec->sym->idx); set_reloc_addend(elf, reloc, sym->offset + reloc_addend(reloc)); return 0; } --=20 2.53.0 From nobody Thu Jun 18 07:54:40 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 BF80D309F08; Fri, 1 May 2026 04:09:00 +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=1777608540; cv=none; b=t/0wE+fzSjVZ5AnTEODe+pbgqTOw3K+iBp+jA3h47wy0b57AEic9aBpgtvTDPfpDaqefyh3tQpowoSpWQwgL0EcCMqddYdEY9Jy8IJd1alillpl/rkaWAAdP3S3GweoD/P8oVtpOKUYwf1jMBXgvWU1YgKZoITd5c80i2NFrqm0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777608540; c=relaxed/simple; bh=zb7hC7l0LCStG+piTMPj7Oc08qllWAq6NyRRgV46RPs=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=o/b8MtVHZWGMapML2iTEtjHjW4HNSjjiRBJSjNmTmb4fsm5sGdJSfmABLFvkI4yITy8CemrRIzK/Rax7p8OFzxwrlgLjCWHD68gS5Gn9pgFhxiA8CvdXgsoSsU4nPx0nTRsZaAAb5AGdgkoqUlHqEZHlnhiH4y3v5Z6o2H70hIQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=BEA5937L; 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="BEA5937L" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 5B49BC2BCB8; Fri, 1 May 2026 04:09:00 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1777608540; bh=zb7hC7l0LCStG+piTMPj7Oc08qllWAq6NyRRgV46RPs=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=BEA5937LiiLtYHr9OrUApFk8IICwU8XWSkRvrQIWaM4+cNG1gBfyUvp6hBl0jtqmV z5qPbO9qTatnd74To8To8zUA521dR8OnrC3tga21KoGcNp8QBTqBVT+25f+dpu0qjN TE+PEtR/13fZUM0Sir/5J9tHkldxl3LErrciJ541VAKr9SB0bmxHmjzo6WrNulV0iW MbA/JtCixtWrc0U9kQDMv6Bo60NWJb33w9Bb/onwuup6REu6kLu1C3f/V8mJUUKShQ GGmHLgLZljNCC7/MZzI71Xy2YR/4iXk2OmozQNT7y7mZU11OV/qfb4n9X4SIr2V7In UTGDYpNEfSARw== From: Josh Poimboeuf To: x86@kernel.org Cc: linux-kernel@vger.kernel.org, live-patching@vger.kernel.org, Peter Zijlstra , Joe Lawrence , Song Liu , Miroslav Benes , Petr Mladek Subject: [PATCH v2 22/53] objtool: Fix reloc hash collision in find_reloc_by_dest_range() Date: Thu, 30 Apr 2026 21:08:10 -0700 Message-ID: <8f1c3b0616623fa498534b83eb5e8217e0ea44b2.1777575752.git.jpoimboe@kernel.org> X-Mailer: git-send-email 2.53.0 In-Reply-To: References: 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" In find_reloc_by_dest_range(), hash collisions can cause a high-offset relocation to appear when probing a low-offset hash bucket. Only return early when the best match found so far genuinely belongs to the current bucket (its offset is within the bucket's stride range). Otherwise, continue scanning later buckets which may contain lower-offset matches. This ensures the first reloc in the range gets returned. Acked-by: Peter Zijlstra (Intel) Fixes: 74b873e49d92 ("objtool: Optimize find_rela_by_dest_range()") Acked-by: Song Liu Reviewed-by: Miroslav Benes Signed-off-by: Josh Poimboeuf --- tools/objtool/elf.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/tools/objtool/elf.c b/tools/objtool/elf.c index 5a20dab683dd..f41280e454ca 100644 --- a/tools/objtool/elf.c +++ b/tools/objtool/elf.c @@ -315,8 +315,9 @@ struct symbol *find_global_symbol_by_name(const struct = elf *elf, const char *nam return NULL; } =20 +/* If there are multiple matches, return the first one in the range */ struct reloc *find_reloc_by_dest_range(const struct elf *elf, struct secti= on *sec, - unsigned long offset, unsigned int len) + unsigned long offset, unsigned int len) { struct reloc *reloc, *r =3D NULL; struct section *rsec; @@ -338,11 +339,11 @@ struct reloc *find_reloc_by_dest_range(const struct e= lf *elf, struct section *se r =3D reloc; } } - if (r) + if (r && (reloc_offset(r) & OFFSET_STRIDE_MASK) =3D=3D o) return r; } =20 - return NULL; + return r; } =20 struct reloc *find_reloc_by_dest(const struct elf *elf, struct section *se= c, unsigned long offset) --=20 2.53.0 From nobody Thu Jun 18 07:54:40 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 39B5833E37C; Fri, 1 May 2026 04:09: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=1777608541; cv=none; b=jkGLn6N+vPDe4yY90OW67S3i//zT0zEjZ0uA41vx+PUcDMNRJYhw/Rwrc1TfMNUEEtx4maL40ROOSD9rwqtSxUOc1GDWk3HOucaC+7+l6a6rjz7CVjhEnNfceBT+QBHu1Odt3sQUYBQjYe4cvh7/wQz/IA4YvvbbckGth/7u5hw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777608541; c=relaxed/simple; bh=0cgE2+HLfMAXuXxdci20y5BlxGcfiybyyBZ+oUe/nZ4=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=lnx/tXnAp5l338MhQvbMlHWi6tJD6xcX2lxl9A4kf8t53sicVKbaR9gQ+mxWmWdk1HXSaw2NKk3IdFafDSW9Miw0WEG8LVXNa54tDYseRBEnFfNcmumxXvB6/jkVZfU8fkdjNzoLYT9QX7fPR2uhlsIPgFRpsXhfKalGl4+yIdw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=lN+wb+17; 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="lN+wb+17" Received: by smtp.kernel.org (Postfix) with ESMTPSA id CA12DC2BCB7; Fri, 1 May 2026 04:09:00 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1777608541; bh=0cgE2+HLfMAXuXxdci20y5BlxGcfiybyyBZ+oUe/nZ4=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=lN+wb+17MN3nRa4zLaUb/Rj4rT39PqGXVVTCF15WkwYVTM/AD59HljCJQL+LrpA6E +f9fPw4jvgFzKkUoL3Lf9RJSbev//L5rFxJ2jTFst6j01wewfxBS2zDe11BnFlFUHY w6pa3Fl6oWBJdRaW1ICIdpJxgbdDHVevxq8TbLay9CcCfsvm3Q8LmAmMburnOTbEOa Ydw2/T+mudR/dP/mb1COZW1gpvhPauSARYbZZtFLYqwcivGSohK3UvB/KFw3fE8WA1 ITIk+U/an1iTrBKMb91MBBYhBZ22Nkw0Aqw3jrY6kZd5A6SS94LZw7Dv4yhmY5B+JT j37BpXTlGTKPQ== From: Josh Poimboeuf To: x86@kernel.org Cc: linux-kernel@vger.kernel.org, live-patching@vger.kernel.org, Peter Zijlstra , Joe Lawrence , Song Liu , Miroslav Benes , Petr Mladek Subject: [PATCH v2 23/53] klp-build: Fix hang on out-of-date .config Date: Thu, 30 Apr 2026 21:08:11 -0700 Message-ID: <5e2a75b8ce5120bbbec6c8e992f1d3c772b8e5d5.1777575752.git.jpoimboe@kernel.org> X-Mailer: git-send-email 2.53.0 In-Reply-To: References: 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" If .config is out of date with the kernel source, 'make syncconfig' hangs while waiting for user input on new config options. Detect the mismatch and return an error. Fixes: 6f93f7b06810 ("livepatch/klp-build: Fix inconsistent kernel version") Signed-off-by: Josh Poimboeuf Acked-by: Song Liu Reviewed-by: Miroslav Benes --- scripts/livepatch/klp-build | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/scripts/livepatch/klp-build b/scripts/livepatch/klp-build index 0ad7e6631314..e19d93b78fcb 100755 --- a/scripts/livepatch/klp-build +++ b/scripts/livepatch/klp-build @@ -306,7 +306,12 @@ set_kernelversion() { =20 stash_file "$file" =20 - kernelrelease=3D"$(cd "$SRC" && make syncconfig &>/dev/null && make -s ke= rnelrelease)" + if [[ -n "$(make -s listnewconfig 2>/dev/null)" ]]; then + die ".config mismatch, check your .config or run 'make olddefconfig'" + fi + make syncconfig &>/dev/null || die "make syncconfig failed" + + kernelrelease=3D"$(make -s kernelrelease)" [[ -z "$kernelrelease" ]] && die "failed to get kernel version" =20 sed -i "2i echo $kernelrelease; exit 0" scripts/setlocalversion --=20 2.53.0 From nobody Thu Jun 18 07:54:40 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 B28D1340283; Fri, 1 May 2026 04:09: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=1777608541; cv=none; b=V2JDKBsTQqczex8mJbV2mTBIMsHBP1FjYb3+cEkwIjHLXpP9ggKLU21WIBwOvUmWKe3UcEPDvigwYXzz5061+Vf9XWaLp/f8wee03K41LGGKuj2Q0A3EHFpT4LhGoiOv5mDauadOhTR3w2SgMVDaSuZTgwUO4OLIaIgs9juDehM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777608541; c=relaxed/simple; bh=LeLdvkaGeI52MJHHJIpetvWxTUeyqHasZJ3P0shfBW0=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=LJxfjlC+OLZLtWu26RyjJIowLrFF1c/gl3WXJok6ohcuRRH8KoJdNbDWafWVsClLIsdQ/yp1fMzTrBh4fuOBrxOj2v3JAbiMUTV+nMScIXP7YwsRLkhxq7MjWF99V3F/zQeNL8rb2Xh6xRLvRmSMzHtcLIAty+dskPj0zseUkpg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=gr0NV+ou; 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="gr0NV+ou" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 44782C2BCB8; Fri, 1 May 2026 04:09:01 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1777608541; bh=LeLdvkaGeI52MJHHJIpetvWxTUeyqHasZJ3P0shfBW0=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=gr0NV+oueqyr35nIEvXkHWv507vcgMgN/O0z8qg7U46qhn+uWqlkFy/U+hTAtGiYL Gx/qnhMmTyoJsCFJZnGrl+t2cb6KcMRXjF+hBBWC3M+RFQ2SJK1N5EBuBNnoipaC/o up/JJMPzpLO2VRrhns/GXOTpTMieW/Uw6rhioyXvhU/+mZQhv4b6xzIR9zVVPAFBBw eYaBUcblOC+/8TNp58W4YYXzK3sYAJFiiFJmESd+qIDY8ZTgk3IS/99K6I4+11OLEA s401gVXx5SS4R5vcEdDSxz+Soqpxu1mdtwHy6ezwZfbOQp3YdHM6RGwq4ivvyDe/Eu 9SKkm1CxvORLw== From: Josh Poimboeuf To: x86@kernel.org Cc: linux-kernel@vger.kernel.org, live-patching@vger.kernel.org, Peter Zijlstra , Joe Lawrence , Song Liu , Miroslav Benes , Petr Mladek Subject: [PATCH v2 24/53] klp-build: Fix checksum comparison for changed offsets Date: Thu, 30 Apr 2026 21:08:12 -0700 Message-ID: <6392d4f0c8837ccc0498a1c79a2d9534dacfce82.1777575752.git.jpoimboe@kernel.org> X-Mailer: git-send-email 2.53.0 In-Reply-To: References: 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" The klp-build -f/--show-first-changed feature uses diff to compare checksum log lines between original and patched objects. However, diff compares entire lines, including the offset field. When a function is at a different section offset, the offset field differs even though the instruction checksum is identical, causing the wrong instruction to be printed. Only compare the checksum field when looking for the first changed instruction. Also print both the original and patched offsets when they differ. Fixes: 78be9facfb5e ("livepatch/klp-build: Add --show-first-changed option = to show function divergence") Signed-off-by: Josh Poimboeuf Acked-by: Song Liu Reviewed-by: Miroslav Benes --- scripts/livepatch/klp-build | 30 +++++++++++++++++++++++------- 1 file changed, 23 insertions(+), 7 deletions(-) diff --git a/scripts/livepatch/klp-build b/scripts/livepatch/klp-build index e19d93b78fcb..8f0ea56f2640 100755 --- a/scripts/livepatch/klp-build +++ b/scripts/livepatch/klp-build @@ -727,13 +727,29 @@ diff_checksums() { ) =20 for func in ${funcs[$file]}; do - diff <( grep0 -E "^DEBUG: .*checksum: $func " "$orig_log" | sed "s|$= ORIG_DIR/||") \ - <( grep0 -E "^DEBUG: .*checksum: $func " "$patched_log" | sed "s|$= PATCHED_DIR/||") \ - | gawk '/^< DEBUG: / { - gsub(/:/, "") - printf "%s: %s: %s\n", $3, $5, $6 - exit - }' || true + local -a orig patched + paste <(grep0 -E "^DEBUG: .*checksum: $func " "$orig_log") \ + <(grep0 -E "^DEBUG: .*checksum: $func " "$patched_log") | + while IFS=3D read -r line; do + read -ra orig <<< "${line%%$'\t'*}" + read -ra patched <<< "${line#*$'\t'}" + + if [[ ${#patched[@]} -eq 0 ]]; then + printf "%s: %s: %s (removed)\n" "${orig[1]%:}" "${orig[3]}" "${orig[-= 2]}" + break + elif [[ ${#orig[@]} -eq 0 ]]; then + printf "%s: %s: %s (added)\n" "${patched[1]%:}" "${patched[3]}" "${pa= tched[-2]}" + break + fi + + [[ "${orig[-1]}" =3D=3D "${patched[-1]}" ]] && continue + + printf "%s: %s: %s" "${orig[1]%:}" "${orig[3]}" "${orig[-2]}" + [[ "${orig[-2]}" !=3D "${patched[-2]}" ]] && \ + printf " (patched: %s)" "${patched[-2]}" + printf "\n" + break + done || true done done } --=20 2.53.0 From nobody Thu Jun 18 07:54:40 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 A4BCE345741; Fri, 1 May 2026 04:09:02 +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=1777608542; cv=none; b=FVnuEVIoF1MYlCqTVnnQUdr56i9eFEgUO59qr8GhxgxEhSG5XcLKnd5ZxlUcyVZbOBLd58v5RfCV5wS4e0po8Y+dT4nnU5XXdijCv6r/pyzIHm9wxmjaO6IhxhlxVmIneSuy3LY0LQ/LPUZeej+FUFdjpD7RI3WdlqgTJpldGjw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777608542; c=relaxed/simple; bh=D8tuLnt0jX5cK8j/CyuHFHRPT9Nz4vaerNpKXeVU5Go=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=pA32JptPIGyD4oz6ikvRw9ZOOw1HlF6HH1Z0xlepF9q16Owm0mA8H8tO+et13WN7nHBK++0CaLzdmGmg4L6wQpr6nIqyOEXuTvpuYPfnNEOO3v6qrc1grZd2wy3njdIoblW0+Y2aSGWtN9OY9YmjHGHNqwQJmK3v1RF00XsDxo0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=gCksWzq5; 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="gCksWzq5" Received: by smtp.kernel.org (Postfix) with ESMTPSA id B492EC2BCB7; Fri, 1 May 2026 04:09:01 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1777608542; bh=D8tuLnt0jX5cK8j/CyuHFHRPT9Nz4vaerNpKXeVU5Go=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=gCksWzq5hEn3kWdUUsiugJrXa5dCZJu+k/RH5emEoVH5fef/AwP/P0sEQrX2QZXiN q4RDu5wsS9GBLmckWvD1lOwwAJmR7EwoCEYbRfthm2zoilgtnxrqkiNwIcdvWAjHCU lAdWLrwhd5oKNPjgxwxz9D69eq1P8ulpOe7mBaax/FsEcZoQeap+yVYNsFcsN5AHCo Iobyv2pr93q42L4MGOztQeP9Ju8pRfmaXmqzMJMt1OfDtljinLUrHEmZ5GpGf4clQg 8j6lkEAcsUxGPoJCWDdYFJfe6TZCGF4zm6YPG7npIOQ7iW5PFpz7T1fYe5rWZcv27q eDsFKsgveiRZA== From: Josh Poimboeuf To: x86@kernel.org Cc: linux-kernel@vger.kernel.org, live-patching@vger.kernel.org, Peter Zijlstra , Joe Lawrence , Song Liu , Miroslav Benes , Petr Mladek Subject: [PATCH v2 25/53] klp-build: Don't use errexit Date: Thu, 30 Apr 2026 21:08:13 -0700 Message-ID: <8f13b66e0fedccde18f9f740f09c3b0705c29deb.1777575752.git.jpoimboe@kernel.org> X-Mailer: git-send-email 2.53.0 In-Reply-To: References: 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" The errtrace option (combined with the ERR trap) already serves the same function (and more) as errexit, so errexit is redundant. And it has more pitfalls. Remove it. Acked-by: Song Liu Reviewed-by: Miroslav Benes Signed-off-by: Josh Poimboeuf --- scripts/livepatch/klp-build | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/scripts/livepatch/klp-build b/scripts/livepatch/klp-build index 8f0ea56f2640..68d61b72f39a 100755 --- a/scripts/livepatch/klp-build +++ b/scripts/livepatch/klp-build @@ -3,7 +3,7 @@ # # Build a livepatch module =20 -# shellcheck disable=3DSC1090,SC2155 +# shellcheck disable=3DSC1090,SC2155,SC2164 =20 if (( BASH_VERSINFO[0] < 4 || \ (BASH_VERSINFO[0] =3D=3D 4 && BASH_VERSINFO[1] < 4) )); then @@ -11,13 +11,12 @@ if (( BASH_VERSINFO[0] < 4 || \ exit 1 fi =20 -set -o errexit set -o errtrace set -o pipefail set -o nounset =20 # Allow doing 'cmd | mapfile -t array' instead of 'mapfile -t array < <(cm= d)'. -# This helps keep execution in pipes so pipefail+errexit can catch errors. +# This helps keep execution in pipes so pipefail+ERR trap can catch errors. shopt -s lastpipe =20 unset DEBUG_CLONE DIFF_CHECKSUM SKIP_CLEANUP XTRACE --=20 2.53.0 From nobody Thu Jun 18 07:54:40 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 A4B4E2BEC5E; Fri, 1 May 2026 04:09:02 +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=1777608542; cv=none; b=dXiI6wrEdRTr/PQE2azJwpWnHDt8dYQnTujNit7YluDFDmiMzU0cU3V4v4qVNee1xBo3lJOdgXpAUMnYlulrWi6XMTUXhd2zDKVGrvwQ2vND6cVC6m7hOuu27iGH91ehO3Hz7QG4a01UwtF2baDnvNTC1g9If1BSp1C6GOGQMss= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777608542; c=relaxed/simple; bh=duf4Qn4jJibidhGOYvdLIG55cwmiQxtfrqGHJsT9MI4=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=jUc3QVm7cCl9pGh+5c/G6HNkIjoMBGPMENYpxUA5A4QRDgpIh0vYdjGTzpdtxWBilZ0C/ZwS4XmKPcRaXbefN6P6xaOasCQBoVoGMDAkYIx7w711Et1kmG0Eh3G8LXY9Y+81sVN0eJYRbH4WNlgWrxHvYAZ3mdz9/P3fCYRr8zU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=heUOuFNp; 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="heUOuFNp" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 2EFB0C2BCB9; Fri, 1 May 2026 04:09:02 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1777608542; bh=duf4Qn4jJibidhGOYvdLIG55cwmiQxtfrqGHJsT9MI4=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=heUOuFNpMZ4giusmbiwvQMEYgGCCrvYJVn4rCc1jJUCICMgx0V6J1/sryF6XAG6y/ /qr91Nzkk4eAVN01XUvqHFyCMe3e9yqvxnrq4O7MnCTCSMFiMelw3xs92l3VkpP1A9 3Ltf31K8+5TXrVgd/7syuA9zWQMpaGCBkdaTzccjx0RqL8I6+ws7CObMJTCBqvQcSU xcZqB5jjp5rh/xB//KnCHeDOHYJTve10d0f8LXn20TiV5wF2WgZ+NbNvVNOs6hci30 O7uckESwNZPrP1mvhGWCNL2zG/ngGQcv+ucaHFChzJbRPqnKutzsNSSSuSRbPZ0+67 Wv+rW0D+plRNQ== From: Josh Poimboeuf To: x86@kernel.org Cc: linux-kernel@vger.kernel.org, live-patching@vger.kernel.org, Peter Zijlstra , Joe Lawrence , Song Liu , Miroslav Benes , Petr Mladek Subject: [PATCH v2 26/53] klp-build: Validate patch file existence Date: Thu, 30 Apr 2026 21:08:14 -0700 Message-ID: X-Mailer: git-send-email 2.53.0 In-Reply-To: References: 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" Make sure all patch files actually exist. Otherwise there can be confusing errors later. Acked-by: Song Liu Reviewed-by: Miroslav Benes Signed-off-by: Josh Poimboeuf --- scripts/livepatch/klp-build | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/scripts/livepatch/klp-build b/scripts/livepatch/klp-build index 68d61b72f39a..13709d20e295 100755 --- a/scripts/livepatch/klp-build +++ b/scripts/livepatch/klp-build @@ -157,6 +157,7 @@ process_args() { local short local long local args + local patch =20 short=3D"hfj:o:vdS:T" long=3D"help,show-first-changed,jobs:,output:,no-replace,verbose,debug,sh= ort-circuit:,keep-tmp" @@ -235,6 +236,10 @@ process_args() { =20 KEEP_TMP=3D"$keep_tmp" PATCHES=3D("$@") + + for patch in "${PATCHES[@]}"; do + [[ -f "$patch" ]] || die "$patch doesn't exist" + done } =20 # temporarily disable xtrace for especially verbose code --=20 2.53.0 From nobody Thu Jun 18 07:54:40 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 09B4B30E82E; Fri, 1 May 2026 04:09:03 +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=1777608543; cv=none; b=EXCw4DVA7cT0udqxHxj7t8SHVBBZrPfXHKYrb82yF2D4F4BMC9uhldBDx6dh2ZvIbVdsM53hClzPH+FkleA9RXqBkcv4EtqF6fetttUhNgSjG0sCLX+RRDKkm7vcRug1HEqlAn/gQy5ybib+/58L+9rZJ9FAlJm93nxxY33TfWY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777608543; c=relaxed/simple; bh=oFTd3CoD070wB8gHxriUGzEnBTACmjhaEPjW0KBDv1E=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=E4+2GrYiF2+4nBADpdm0N6RRh5Cck7uucM5/BkdkEdG8k2z3GPpzr2qdmo6dDRXAqJ5XfovXn5gZeoUQcFsMPKmwfPaku84m7ybN3rY2TSLAxQbmJT8mI6CcW085VbqAwBF+xu1wJh3R5zubbMvLh35k5J567kr3dj8gED2lcNY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=rcarRnlD; 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="rcarRnlD" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 9C8C6C2BCC6; Fri, 1 May 2026 04:09:02 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1777608542; bh=oFTd3CoD070wB8gHxriUGzEnBTACmjhaEPjW0KBDv1E=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=rcarRnlD26HqEgvI7xic180+F53CTTA1E5esi71LVi8gjdMXKaXgLqQhxkURa9Xo2 iAxRfECGaQUquV57U6kLmLbJzQGrgMFCAeraRQ2xoezblduOkBRC5wjvYxL92BG1dG zNHcM31MjdWy5BlVL8nL7BwZ1iBF13oDvbGj84C63mnwSQzlLmyfs6ihmhOTHj9SX+ RUjnu9WFLYqv1NLwBMGi3zutILopxMlsn+m3MnB21y1q7PyNe4STVjpSjL+xx43wmt WpxB/wxy9+J9u/Mg/1tGS4r1oy+jt3dWHAvbpVvO94xIH9SqHVv8b6E1jTtJMmu1dR RUfZE4hGTQMeQ== From: Josh Poimboeuf To: x86@kernel.org Cc: linux-kernel@vger.kernel.org, live-patching@vger.kernel.org, Peter Zijlstra , Joe Lawrence , Song Liu , Miroslav Benes , Petr Mladek Subject: [PATCH v2 27/53] klp-build: Suppress excessive fuzz output by default Date: Thu, 30 Apr 2026 21:08:15 -0700 Message-ID: X-Mailer: git-send-email 2.53.0 In-Reply-To: References: 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" When a patch applies with fuzz, the detailed output from the patch tool can be very noisy, especially for big patches. Suppress the fuzz details by default, while keeping the "applied with fuzz" warning. The noise can be restored with '--verbose'. Acked-by: Song Liu Reviewed-by: Miroslav Benes Signed-off-by: Josh Poimboeuf --- scripts/livepatch/klp-build | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/scripts/livepatch/klp-build b/scripts/livepatch/klp-build index 13709d20e295..dc2c5c33d1db 100755 --- a/scripts/livepatch/klp-build +++ b/scripts/livepatch/klp-build @@ -19,12 +19,11 @@ set -o nounset # This helps keep execution in pipes so pipefail+ERR trap can catch errors. shopt -s lastpipe =20 -unset DEBUG_CLONE DIFF_CHECKSUM SKIP_CLEANUP XTRACE +unset DEBUG_CLONE DIFF_CHECKSUM SKIP_CLEANUP VERBOSE XTRACE =20 REPLACE=3D1 SHORT_CIRCUIT=3D0 JOBS=3D"$(getconf _NPROCESSORS_ONLN)" -VERBOSE=3D"-s" shopt -o xtrace | grep -q 'on' && XTRACE=3D1 =20 # Avoid removing the previous $TMP_DIR until args have been fully processe= d. @@ -194,7 +193,7 @@ process_args() { shift ;; -v | --verbose) - VERBOSE=3D"V=3D1" + VERBOSE=3D1 shift ;; -d | --debug) @@ -381,7 +380,7 @@ apply_patch() { echo "$output" >&2 die "$patch did not apply" elif [[ "$output" =3D~ $drift_regex ]]; then - echo "$output" >&2 + [[ -v VERBOSE ]] && echo "$output" >&2 warn "${patch} applied with fuzz" fi =20 @@ -544,7 +543,11 @@ build_kernel() { # cmd+=3D("KBUILD_MODPOST_WARN=3D1") =20 - cmd+=3D("$VERBOSE") + if [[ -v VERBOSE ]]; then + cmd+=3D("V=3D1") + else + cmd+=3D("-s") + fi cmd+=3D("-j$JOBS") cmd+=3D("KCFLAGS=3D-ffunction-sections -fdata-sections") cmd+=3D("OBJTOOL_ARGS=3D${objtool_args[*]}") @@ -805,7 +808,11 @@ build_patch_module() { [[ $REPLACE -eq 0 ]] && cflags+=3D("-DKLP_NO_REPLACE") =20 cmd=3D("make") - cmd+=3D("$VERBOSE") + if [[ -v VERBOSE ]]; then + cmd+=3D("V=3D1") + else + cmd+=3D("-s") + fi cmd+=3D("-j$JOBS") cmd+=3D("--directory=3D.") cmd+=3D("M=3D$KMOD_DIR") --=20 2.53.0 From nobody Thu Jun 18 07:54:40 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 B18FB3101C8; Fri, 1 May 2026 04:09:03 +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=1777608545; cv=none; b=CAhuccataCevUaea+G7QBlfT2G6gZN9mEqTBAfwg6+Rd+k2WfNQQUVLspwAQQKwmC0gh+1rth0tx7L3SKsO+gIhELx81VVOUBez4WPvJpN+wgcV9LabqFGl8KPuBZxYyORc4gXiMiTeYBhYeQ6XxCGYQBx3TWmxCydJp8TpAppM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777608545; c=relaxed/simple; bh=f0Ve5bg2CjhT77knL5sFvHMeomh5ZlbAk6fCFX9rZXc=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=dU9nGIZXy2FdbiddUoWi6wRW6pGbKmbK60dixbqUmwCNm8Zlul1fE6ilPDOW5gba4M41327Uvv2Y98aXJLybOigfZ6IG3//8wqJcMNm5cet6C+9Z3e6qzSTcHAsr+iTvaeykYNL5DfjAINJZarM71upqmc0pync5KKYofrAao6Q= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=ZtIXwMXo; 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="ZtIXwMXo" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 17715C2BCB7; Fri, 1 May 2026 04:09:03 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1777608543; bh=f0Ve5bg2CjhT77knL5sFvHMeomh5ZlbAk6fCFX9rZXc=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=ZtIXwMXo5VjFnqr/ifRe6z+qLTkDV1Q0T2rxRjYpzomAwk3HJpBVT242wth9KpPcw JGoCWfxiPPbz5YJAF5Fc3d6VOZGPggRBwgrp14BKfuoEMGgPHBeskBm0QXgTEsQy4E zCObEQNgsAhCKUY9vf/BJRF7ikfbtHYfVjiEqy46pHTqpEPdbbKKeOv2VL/JSuUu2q JY/zk57eh5ppgy2UMdYHtSIUYjGoBqf0pL/O1h2iJxMydTPiOGxfuknlwT+jq4XEjc Q5M4UsPA4TKSqPCeB/+0CARF3k0VJqWwAzUiD2NtbjVOSECS3Rv6wk4sgdE71ZJTRE 5+3XNA1x2sMIg== From: Josh Poimboeuf To: x86@kernel.org Cc: linux-kernel@vger.kernel.org, live-patching@vger.kernel.org, Peter Zijlstra , Joe Lawrence , Song Liu , Miroslav Benes , Petr Mladek Subject: [PATCH v2 28/53] klp-build: Fix patch cleanup on interrupt Date: Thu, 30 Apr 2026 21:08:16 -0700 Message-ID: X-Mailer: git-send-email 2.53.0 In-Reply-To: References: 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" If a build error occurs and the user hits Ctrl-C while a large patch is being reverted during cleanup, the cleanup EXIT trap gets re-triggered and tries to re-revert the already partially-reverted patch. That causes 'patch -R' to repeatedly prompt "Unreversed patch detected! Ignore -R? [n]" for each already-reverted hunk, with no way to break out. Fix it by adding '--force' to the patch revert command in revert_patch(), which causes it to silently ignore already-reverted hunks. And ignore errors, as the cleanup is always best-effort. For similar reasons, add to APPLIED_PATCHES before (rather than after) applying the patch in apply_patch() so an interrupted apply will also get cleaned up. Fixes: d36a7343f4ba ("livepatch/klp-build: switch to GNU patch and recountd= iff") Acked-by: Song Liu Signed-off-by: Josh Poimboeuf Reviewed-by: Miroslav Benes --- scripts/livepatch/klp-build | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/livepatch/klp-build b/scripts/livepatch/klp-build index dc2c5c33d1db..9970e1f274ef 100755 --- a/scripts/livepatch/klp-build +++ b/scripts/livepatch/klp-build @@ -384,15 +384,15 @@ apply_patch() { warn "${patch} applied with fuzz" fi =20 - patch -d "$SRC" -p1 --no-backup-if-mismatch -r /dev/null "${extra_args[@]= }" --silent < "$patch" APPLIED_PATCHES+=3D("$patch") + patch -d "$SRC" -p1 --no-backup-if-mismatch -r /dev/null "${extra_args[@]= }" --silent < "$patch" } =20 revert_patch() { local patch=3D"$1" local tmp=3D() =20 - patch -d "$SRC" -p1 -R --silent --no-backup-if-mismatch -r /dev/null < "$= patch" + patch -d "$SRC" -p1 -R --force --no-backup-if-mismatch -r /dev/null &> /d= ev/null < "$patch" || true =20 for p in "${APPLIED_PATCHES[@]}"; do [[ "$p" =3D=3D "$patch" ]] && continue --=20 2.53.0 From nobody Thu Jun 18 07:54:40 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 F319E30E858; Fri, 1 May 2026 04:09:03 +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=1777608544; cv=none; b=JAEWu+vnO3ohT88N5udPhCxsnYIftp/kbHPE64aafbbw5yEu+ZPC/c0QEIGvcJnX+UDftfQpehzyjY6K0S+s5Zu9mrdqzXE7rxvd25f57O3fqTBwJ07IBOTYOAH/HlhnRNB3M5Ttvw1x9Z1KbsTQpgYk7apmmVb9WmO6+pBpVJU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777608544; c=relaxed/simple; bh=sOjPZIGXc7QuIPp7UhkHLTQ38hR0PnpHghxAZO7qmxk=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=fMOWKN7zf2zG0qVCnjAL57lkJ2WDpoLJDyuWMzGWEkWTr0kSBXxkDroLIdBbgkgsKomnKg8uupmiY6JrHNaZHB8e13aQTHAvHCZgZYVqNu2OSfEHE1ZlJvZYJY8ik3J8ozNX0Md8Siqk+8ksjr69CBd7tZi6zm1of4xaihHSAko= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=Zmui32L2; 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="Zmui32L2" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 85BA6C2BCB9; Fri, 1 May 2026 04:09:03 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1777608543; bh=sOjPZIGXc7QuIPp7UhkHLTQ38hR0PnpHghxAZO7qmxk=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=Zmui32L2phOMpoSXr5Mid+Pe2qJouJT3I4TfDUL2uOu6uX4F0M+cgZ8xaIFuRH5aW R98J+R1fFmfB319+IGscGegAqa0hAth+mqzD+GnDEyEsS2+3R++G5u7O0ykCX/veMX Nqu9D6h7c/PJOUlAD6gSvTAU6IeHWWWeLO/3jVw+6PFhgIOI/lPAajJAcI32RtcvGX jXNTIceAXXNjCc3SANYLmjOc4AMr+Qoo2RfZecALIUAchtzvYtmzwkY9UCYBXkR0ST dJ47amN0f8tYBXwYWpZZn0QuDl6SYU9ytMKmIoNNaEL+Nn0ubvX2Go2SQPzCk8D5ls Lrv0H+Yaz4sXA== From: Josh Poimboeuf To: x86@kernel.org Cc: linux-kernel@vger.kernel.org, live-patching@vger.kernel.org, Peter Zijlstra , Joe Lawrence , Song Liu , Miroslav Benes , Petr Mladek Subject: [PATCH v2 29/53] klp-build: Reject patches to vDSO Date: Thu, 30 Apr 2026 21:08:17 -0700 Message-ID: X-Mailer: git-send-email 2.53.0 In-Reply-To: References: 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" vDSO code runs in userspace and can't be livepatched. Such patches also cause spurious "new function" errors due to generated files like vdso*-image.c having unstable line numbers across builds. Acked-by: Song Liu Signed-off-by: Josh Poimboeuf Reviewed-by: Miroslav Benes --- scripts/livepatch/klp-build | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/livepatch/klp-build b/scripts/livepatch/klp-build index 9970e1f274ef..a70d48d98453 100755 --- a/scripts/livepatch/klp-build +++ b/scripts/livepatch/klp-build @@ -357,7 +357,7 @@ check_unsupported_patches() { =20 for file in "${files[@]}"; do case "$file" in - lib/*|*.S) + lib/*|*/vdso/*|*.S) die "${patch}: unsupported patch to $file" ;; esac --=20 2.53.0 From nobody Thu Jun 18 07:54:40 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 9686C35CB73; Fri, 1 May 2026 04:09:04 +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=1777608546; cv=none; b=BiN/YRXZTCDx0fFdMlC3t3ZfHqygcaXQrtlHJkEJra8uYyAfUe8sXEfPW/Yc6bQxB5MHd7f07EE4TEcZZ1LjMaKha+whOU/ufXRh6els3dxvi1lCsng+7ZXSUYxDkfeap6TTMf2qI68YhG0jXMG14B8bHBkfTb1VGFbNlnJ9knY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777608546; c=relaxed/simple; bh=C4H3QYns08OGG+5ZLV30DNEsVqONshg8FePcx0FJUVc=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=o104QYmsiROg8cVtExiYyTYPC3dsFrgHs3WHmLZlOHLLd0z4E0qLGQCBe8HDXz2BHu6no10RpxkbBIj9f7Dkm3Z0Wv8bjQve3cEABTKL5LQEn9hIYVvDGq8+0r8Jmhzv7dLLRWUV29z3Amnr2mlE+Ky5c+cx3Vs2eNXjBJ4GcpY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=dysIFujc; 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="dysIFujc" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 0A6E1C2BCC9; Fri, 1 May 2026 04:09:04 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1777608544; bh=C4H3QYns08OGG+5ZLV30DNEsVqONshg8FePcx0FJUVc=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=dysIFujctdwUPF/HClOO7A7XmGyr14pacL2NKWkeo33su8fDjZHxDmFTIOSsOPmXO 8jPZ48JNGj5X0eJDi3iPwMNKImDm/2C/oAOGOtCh5ANz0772gOOE2/fM/E9T0ozSKr cG7qoP+UyPNeVcg2KFryQCd6Ef5443+OkxPnk62QxmWdG8cSO3o3zUtlFXHJz+pqED qsDi2tIrupoy/XYBNet/Y3KvdBlFVclxPfmj4gFDZsp7o0tik9zHr6d/PlGaFOiIoU fxsW8KJW2Zaio3lmigPiY7zI4P4WfWaRn+BQDL46adeStv7IIefblbrEZn7LCe7ZYT bvv013aeLGl1A== From: Josh Poimboeuf To: x86@kernel.org Cc: linux-kernel@vger.kernel.org, live-patching@vger.kernel.org, Peter Zijlstra , Joe Lawrence , Song Liu , Miroslav Benes , Petr Mladek Subject: [PATCH v2 30/53] klp-build: Reject patches to realmode Date: Thu, 30 Apr 2026 21:08:18 -0700 Message-ID: X-Mailer: git-send-email 2.53.0 In-Reply-To: References: 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" Realmode code is compiled as a separate 16-bit binary and embedded into the kernel image via rmpiggy.S. It can't be livepatched. Acked-by: Song Liu Signed-off-by: Josh Poimboeuf Reviewed-by: Miroslav Benes --- scripts/livepatch/klp-build | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/livepatch/klp-build b/scripts/livepatch/klp-build index a70d48d98453..2bb35de5db75 100755 --- a/scripts/livepatch/klp-build +++ b/scripts/livepatch/klp-build @@ -357,7 +357,7 @@ check_unsupported_patches() { =20 for file in "${files[@]}"; do case "$file" in - lib/*|*/vdso/*|*.S) + lib/*|*/vdso/*|*/realmode/rm/*|*.S) die "${patch}: unsupported patch to $file" ;; esac --=20 2.53.0 From nobody Thu Jun 18 07:54:40 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 EE38530F958; Fri, 1 May 2026 04:09:04 +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=1777608545; cv=none; b=hLJvpH7Y05j0Pagyxuk26vTZHWG0zu7Z+mfP8tSJ0MF0ta9e/q+mgFRCKQhmwSljhxMbXQX/Rjnz+ZdKWfQ/MKyUs5k+/clpVhz/AOUGAXDy+FYMNdIdi06CDTTKkMzZGjqMSH40HfR6xHRKAAmoxXbAU79Y351fYUoiaYau4EA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777608545; c=relaxed/simple; bh=+cSOMoJ52+YC//3yBJ8PpJ9LJCgKreOela/CrfW2oxk=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=umo2ke2EkJxzT0JNQkRe1h0G64TtdqQENiQsuAQxuK8cgG/yeZd6KBLGwaRJAdQK9G0XfBE/BWmYCTcZn30gWa9/O4vlzKFgpPx/ns60elJuCHfASwGmlrGkgVKZRj3IBd7I3hGNpbzmLf1SKJ7g+ohnVmFr0N+i9NLGek3GTCM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=AIiyF5wL; 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="AIiyF5wL" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 81B69C2BCC6; Fri, 1 May 2026 04:09:04 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1777608544; bh=+cSOMoJ52+YC//3yBJ8PpJ9LJCgKreOela/CrfW2oxk=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=AIiyF5wLl+kWFlNnqB2iCf0JvENSB5fHk3EDZIf9sJpd00z+OvFgd+8qHzrhH5u5j KBwIHY6zvmr0vgbpTmmzMaagM8XTtMsb8iwAthB/LA4zsWZ2ulNTUcZ5kjbFJIogxX 42EC1GsA+KLwvMKHtcA19tc9+rxRjp8nv1+QyLE2821U5sGVgYLtGZeIFKZPGh6xk6 KHNgWyGxjugVpnz0UNoR1XoyivlA2KkOuLBAnbS1GJxeaQCh7W6qv/TDgd8lPr9mke XN3/R+mhgjMBrSLmwcoDeICAql4mkmRLGE/8MSoMX68/T/3ehpWg7qmh7Kdq+GlF8I z17Vq4eh2BFmg== From: Josh Poimboeuf To: x86@kernel.org Cc: linux-kernel@vger.kernel.org, live-patching@vger.kernel.org, Peter Zijlstra , Joe Lawrence , Song Liu , Miroslav Benes , Petr Mladek Subject: [PATCH v2 31/53] klp-build: Print "objtool klp diff" command in verbose mode Date: Thu, 30 Apr 2026 21:08:19 -0700 Message-ID: <949a2ff797f2c7e366dedc760aea726e7cae1b11.1777575752.git.jpoimboe@kernel.org> X-Mailer: git-send-email 2.53.0 In-Reply-To: References: 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" Print the full objtool command line when '--verbose' is given to help with debugging. Acked-by: Song Liu Signed-off-by: Josh Poimboeuf Reviewed-by: Miroslav Benes --- scripts/livepatch/klp-build | 1 + 1 file changed, 1 insertion(+) diff --git a/scripts/livepatch/klp-build b/scripts/livepatch/klp-build index 2bb35de5db75..355345aa94d2 100755 --- a/scripts/livepatch/klp-build +++ b/scripts/livepatch/klp-build @@ -681,6 +681,7 @@ diff_objects() { =20 ( cd "$ORIG_DIR" + [[ -v VERBOSE ]] && echo "${cmd[@]}" "${cmd[@]}" \ 1> >(tee -a "$log") \ 2> >(tee -a "$log" | "${filter[@]}" >&2) || \ --=20 2.53.0 From nobody Thu Jun 18 07:54:40 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 B1E373537CC; Fri, 1 May 2026 04:09:05 +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=1777608545; cv=none; b=Dzb7xgeUSddxtNrA/xQng4X73KFyXWmfn9494uIg0GXHxQ1QvEsbqPDrVnxQR/HI7Ve3yhUJcX3omOQWuh0QyEo/l17n5/pmZVGQIlcSSsTS3Osh60IoXh0vsqWruJyk2WgwVXu67GWwHqyF4R76y/gqmRr/Z4rKNKt27PG/a94= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777608545; c=relaxed/simple; bh=5WQETiS7rEgNgSdSGbmwnnu09ScP+70xY/bHo0tLzNw=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=R/qfFdciol8BmxdgJvBsEvc8Wazzulg4iBhDAm4rG1mRA3ouS1a6S8GYPE2MHjCkXfm0yAHklNBneomuSSMXNjgjoebvDFZ3hqMuh5lHcd3/g8dvIcuoGrG0xj8bCXOBpLlqkuQ4/ZhExw7djCPLIMjAznwLsjTNTw0CXj1n1Ro= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=ULdb7KDn; 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="ULdb7KDn" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 052E1C2BCC7; Fri, 1 May 2026 04:09:04 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1777608545; bh=5WQETiS7rEgNgSdSGbmwnnu09ScP+70xY/bHo0tLzNw=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=ULdb7KDnq0Kiv/T9146uuzTiDB05dqBKKpD9QaSKPJHNgsMGF2uX5qCdVRCkexjlm GzeCJLD8UR973Qt9+7xc+0rtypCUGuCzCtkQ2BBQKwO60j9uTv6ycfg4aS8xHgkTAE A3l+2KghGJr78sdGKj9jlA0oyynomCHS0xWOnin00Zd/wgJ/EnvB7lMuHpr0IOsGkB 9oJoMfmbATM2fpmq3T6GiJY8s+i6oyrngyfPVXXGmwq0u/rx4dFjj9eYCIlDo5qfuR vMTMOXLzIzm2zQp5kBLCXYLu73q6nrjiuzywsziZ5r7exjFEucyM1KH6GylnITMquw anubQKXJbkpZQ== From: Josh Poimboeuf To: x86@kernel.org Cc: linux-kernel@vger.kernel.org, live-patching@vger.kernel.org, Peter Zijlstra , Joe Lawrence , Song Liu , Miroslav Benes , Petr Mladek Subject: [PATCH v2 32/53] klp-build: Remove redundant SRC and OBJ variables Date: Thu, 30 Apr 2026 21:08:20 -0700 Message-ID: <63b0d7848597ad6011e1f56c8fdd53593d09a992.1777575752.git.jpoimboe@kernel.org> X-Mailer: git-send-email 2.53.0 In-Reply-To: References: 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" SRC and OBJ are both set to $(pwd) and are always identical. The script already enforces that klp-build runs from the kernel root directory, and builds are done in-place, making these variables unnecessary. Suggested-by: Song Liu Signed-off-by: Josh Poimboeuf Acked-by: Song Liu Reviewed-by: Miroslav Benes --- scripts/livepatch/klp-build | 67 ++++++++++++++++--------------------- 1 file changed, 28 insertions(+), 39 deletions(-) diff --git a/scripts/livepatch/klp-build b/scripts/livepatch/klp-build index 355345aa94d2..34a46bafdaec 100755 --- a/scripts/livepatch/klp-build +++ b/scripts/livepatch/klp-build @@ -33,11 +33,9 @@ SCRIPT=3D"$(basename "$0")" SCRIPT_DIR=3D"$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" FIX_PATCH_LINES=3D"$SCRIPT_DIR/fix-patch-lines" =20 -SRC=3D"$(pwd)" -OBJ=3D"$(pwd)" - -CONFIG=3D"$OBJ/.config" -TMP_DIR=3D"$OBJ/klp-tmp" +OBJTOOL=3D"$PWD/tools/objtool/objtool" +CONFIG=3D"$PWD/.config" +TMP_DIR=3D"$PWD/klp-tmp" =20 ORIG_DIR=3D"$TMP_DIR/orig" PATCHED_DIR=3D"$TMP_DIR/patched" @@ -88,7 +86,7 @@ declare -a STASHED_FILES =20 stash_file() { local file=3D"$1" - local rel_file=3D"${file#"$SRC"/}" + local rel_file=3D"${file#"$PWD"/}" =20 [[ ! -e "$file" ]] && die "no file to stash: $file" =20 @@ -102,7 +100,7 @@ restore_files() { local file =20 for file in "${STASHED_FILES[@]}"; do - mv -f "$STASH_DIR/$file" "$SRC/$file" || warn "can't restore file: $file" + mv -f "$STASH_DIR/$file" "$PWD/$file" || warn "can't restore file: $file" done =20 STASHED_FILES=3D() @@ -304,7 +302,7 @@ set_module_name() { # Hardcode the value printed by the localversion script to prevent patch # application from appending it with '+' due to a dirty working tree. set_kernelversion() { - local file=3D"$SRC/scripts/setlocalversion" + local file=3D"$PWD/scripts/setlocalversion" local kernelrelease =20 stash_file "$file" @@ -375,7 +373,7 @@ apply_patch() { =20 [[ ! -f "$patch" ]] && die "$patch doesn't exist" status=3D0 - output=3D$(patch -d "$SRC" -p1 --dry-run --no-backup-if-mismatch -r /dev/= null "${extra_args[@]}" < "$patch" 2>&1) || status=3D$? + output=3D$(patch -p1 --dry-run --no-backup-if-mismatch -r /dev/null "${ex= tra_args[@]}" < "$patch" 2>&1) || status=3D$? if [[ "$status" -ne 0 ]]; then echo "$output" >&2 die "$patch did not apply" @@ -385,14 +383,14 @@ apply_patch() { fi =20 APPLIED_PATCHES+=3D("$patch") - patch -d "$SRC" -p1 --no-backup-if-mismatch -r /dev/null "${extra_args[@]= }" --silent < "$patch" + patch -p1 --no-backup-if-mismatch -r /dev/null "${extra_args[@]}" --silen= t < "$patch" } =20 revert_patch() { local patch=3D"$1" local tmp=3D() =20 - patch -d "$SRC" -p1 -R --force --no-backup-if-mismatch -r /dev/null &> /d= ev/null < "$patch" || true + patch -p1 -R --force --no-backup-if-mismatch -r /dev/null &> /dev/null < = "$patch" || true =20 for p in "${APPLIED_PATCHES[@]}"; do [[ "$p" =3D=3D "$patch" ]] && continue @@ -430,8 +428,7 @@ validate_patches() { do_init() { # We're not yet smart enough to handle anything other than in-tree # builds in pwd. - [[ ! "$SRC" -ef "$SCRIPT_DIR/../.." ]] && die "please run from the kernel= root directory" - [[ ! "$OBJ" -ef "$SCRIPT_DIR/../.." ]] && die "please run from the kernel= root directory" + [[ ! "$PWD" -ef "$SCRIPT_DIR/../.." ]] && die "please run from the kernel= root directory" =20 (( SHORT_CIRCUIT <=3D 1 )) && rm -rf "$TMP_DIR" mkdir -p "$TMP_DIR" @@ -462,11 +459,11 @@ refresh_patch() { get_patch_output_files "$patch" | mapfile -t output_files =20 # Copy orig source files to 'a' - ( cd "$SRC" && echo "${input_files[@]}" | xargs cp --parents --target-dir= ectory=3D"$tmpdir/a" ) + echo "${input_files[@]}" | xargs cp --parents --target-directory=3D"$tmpd= ir/a" =20 # Copy patched source files to 'b' apply_patch "$patch" "--silent" - ( cd "$SRC" && echo "${output_files[@]}" | xargs cp --parents --target-di= rectory=3D"$tmpdir/b" ) + echo "${output_files[@]}" | xargs cp --parents --target-directory=3D"$tmp= dir/b" revert_patch "$patch" =20 # Diff 'a' and 'b' to make a clean patch @@ -510,10 +507,7 @@ clean_kernel() { cmd+=3D("-j$JOBS") cmd+=3D("clean") =20 - ( - cd "$SRC" - "${cmd[@]}" - ) + "${cmd[@]}" } =20 build_kernel() { @@ -554,12 +548,10 @@ build_kernel() { cmd+=3D("vmlinux") cmd+=3D("modules") =20 - ( - cd "$SRC" - "${cmd[@]}" \ - 1> >(tee -a "$log") \ - 2> >(tee -a "$log" | grep0 -v "modpost.*undefined!" >&2) - ) || die "$build kernel build failed" + "${cmd[@]}" \ + 1> >(tee -a "$log") \ + 2> >(tee -a "$log" | grep0 -v "modpost.*undefined!" >&2) \ + || die "$build kernel build failed" } =20 find_objects() { @@ -567,9 +559,9 @@ find_objects() { =20 # Find root-level vmlinux.o and non-root-level .ko files, # excluding klp-tmp/ and .git/ - find "$OBJ" \( -path "$TMP_DIR" -o -path "$OBJ/.git" -o -regex "$OBJ/[^/]= [^/]*\.ko" \) -prune -o \ + find "$PWD" \( -path "$TMP_DIR" -o -path "$PWD/.git" -o -regex "$PWD/[^/]= [^/]*\.ko" \) -prune -o \ -type f "${opts[@]}" \ - \( -name "*.ko" -o -path "$OBJ/vmlinux.o" \) \ + \( -name "*.ko" -o -path "$PWD/vmlinux.o" \) \ -printf '%P\n' } =20 @@ -585,7 +577,7 @@ copy_orig_objects() { xtrace_save "copying orig objects" for _file in "${files[@]}"; do local rel_file=3D"${_file/.ko/.o}" - local file=3D"$OBJ/$rel_file" + local file=3D"$PWD/$rel_file" local orig_file=3D"$ORIG_DIR/$rel_file" local orig_dir=3D"$(dirname "$orig_file")" =20 @@ -618,7 +610,7 @@ copy_patched_objects() { xtrace_save "copying changed objects" for _file in "${files[@]}"; do local rel_file=3D"${_file/.ko/.o}" - local file=3D"$OBJ/$rel_file" + local file=3D"$PWD/$rel_file" local orig_file=3D"$ORIG_DIR/$rel_file" local patched_file=3D"$PATCHED_DIR/$rel_file" local patched_dir=3D"$(dirname "$patched_file")" @@ -663,7 +655,7 @@ diff_objects() { =20 mkdir -p "$(dirname "$out_file")" =20 - cmd=3D("$SRC/tools/objtool/objtool") + cmd=3D("$OBJTOOL") cmd+=3D("klp") cmd+=3D("diff") (( ${#opts[@]} > 0 )) && cmd+=3D("${opts[@]}") @@ -716,7 +708,7 @@ diff_checksums() { fi done =20 - cmd=3D("$SRC/tools/objtool/objtool") + cmd=3D("$OBJTOOL") cmd+=3D("--checksum") cmd+=3D("--link") cmd+=3D("--dry-run") @@ -774,7 +766,7 @@ build_patch_module() { rm -rf "$KMOD_DIR" mkdir -p "$KMOD_DIR" =20 - cp -f "$SRC/scripts/livepatch/init.c" "$KMOD_DIR" + cp -f "$SCRIPT_DIR/init.c" "$KMOD_DIR" =20 echo "obj-m :=3D $NAME.o" > "$makefile" echo -n "$NAME-y :=3D init.o" >> "$makefile" @@ -820,12 +812,9 @@ build_patch_module() { cmd+=3D("KCFLAGS=3D${cflags[*]}") =20 # Build a "normal" kernel module with init.c and the diffed objects - ( - cd "$SRC" - "${cmd[@]}" \ - 1> >(tee -a "$log") \ - 2> >(tee -a "$log" >&2) - ) + "${cmd[@]}" \ + 1> >(tee -a "$log") \ + 2> >(tee -a "$log" >&2) =20 kmod_file=3D"$KMOD_DIR/$NAME.ko" =20 @@ -836,7 +825,7 @@ build_patch_module() { objcopy --remove-section=3D.BTF "$kmod_file" =20 # Fix (and work around) linker wreckage for klp syms / relocs - "$SRC/tools/objtool/objtool" klp post-link "$kmod_file" || die "objtool k= lp post-link failed" + "$OBJTOOL" klp post-link "$kmod_file" || die "objtool klp post-link faile= d" =20 cp -f "$kmod_file" "$OUTFILE" } --=20 2.53.0 From nobody Thu Jun 18 07:54:40 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 DFAD9359A94; Fri, 1 May 2026 04:09:05 +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=1777608545; cv=none; b=p+LaINcQZ1GZ+LZG8qLLRK8cnZkx9ggypE3O0xV9UHIYJy+oiQwZL6GNL5oLxsOKOC5i3O1dyJJIUoAg0241M2/1MmdXDf+YttNeschl5LnV+VkuYxL7gNTkXoChbwfkFC4FQ3K3IeD8iXmzeWKTrdOam2heqQL0h3wljVhLwxg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777608545; c=relaxed/simple; bh=6jE4uMMHkB1mOztBVCv0yYQ2rdykfzMXfWMb8wecjjQ=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=gJfwtQgmZ5asqvQ2Iwjp7O/EtVqMcG75h4FnTPCUZbbqSQlnu5ADkmjzerqUHZbWYnoDOgteSJoGssD27bQAdbWLRnwt8BQ4eZDSqHp91SQP3AfsALm7VW6hbJIJFzuNNNZZcs6Ud3/7SG1cld0HcCkxayqJDFrgv+kr3LKY47s= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=oeSqdBRv; 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="oeSqdBRv" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 75593C2BCB9; Fri, 1 May 2026 04:09:05 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1777608545; bh=6jE4uMMHkB1mOztBVCv0yYQ2rdykfzMXfWMb8wecjjQ=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=oeSqdBRvDbQ4razru/Lqyx/m/A0iPPvj1Q0InlNU2tF0lzWAIxcoNP7Hc3NbE+/pz X6+Fp56g2XhB7cwwaCHxXnyh0Bpx4D1ZPrqJsLCTfo9S1zsQfpFONLOYdE0SZ1XWOe edRQx/NGA/R0gfOvH2QUM3XuOXogBHwzkeOOmGEtcvkvO0CwAonffCoNQlaN1rPVm7 czisz9y3y2hx0XyuHCwrxzblIQVWqI8wi4pU+Q+3cCr7ip8/YhC8h+ZtGIIFm4VSmD KBWwNsfJJmmqZ5XJffrZ3Fi6Nu9i94o8CSklHVwT33geKGohD1MDsfnohrlSHk989Y O09gnPGr+ExbQ== From: Josh Poimboeuf To: x86@kernel.org Cc: linux-kernel@vger.kernel.org, live-patching@vger.kernel.org, Peter Zijlstra , Joe Lawrence , Song Liu , Miroslav Benes , Petr Mladek Subject: [PATCH v2 33/53] objtool/klp: Don't set sym->file for section symbols Date: Thu, 30 Apr 2026 21:08:21 -0700 Message-ID: X-Mailer: git-send-email 2.53.0 In-Reply-To: References: 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" Section symbols aren't grouped after their corresponding FILE symbols. Their sym->file should really be NULL rather than whatever random FILE happened to be last. Acked-by: Peter Zijlstra (Intel) Acked-by: Song Liu Signed-off-by: Josh Poimboeuf Reviewed-by: Miroslav Benes --- tools/objtool/elf.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/objtool/elf.c b/tools/objtool/elf.c index f41280e454ca..d9cee8d5d9e8 100644 --- a/tools/objtool/elf.c +++ b/tools/objtool/elf.c @@ -649,7 +649,7 @@ static int read_symbols(struct elf *elf) =20 if (is_file_sym(sym)) file =3D sym; - else if (sym->bind =3D=3D STB_LOCAL) + else if (sym->bind =3D=3D STB_LOCAL && !is_sec_sym(sym)) sym->file =3D file; } =20 --=20 2.53.0 From nobody Thu Jun 18 07:54:40 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 5C57E35A3A4; Fri, 1 May 2026 04:09: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=1777608546; cv=none; b=g9pSgg3ZiWZudf72bzMhqWcTaFyuYap9Ytx6OgLrglwdx9ShwacQfrjHcUIZrLlEEssjJHqb0ud16+MoWAbkVZ8BUK5eyhmHFAaqKNVPCDn2tol8V/Gsd1SLfvwYdVddySXROZZYE+mnlgrkCqcm++WCSUtqIdapzUo1inebfvk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777608546; c=relaxed/simple; bh=C6mO2sC+0qw428snku2YR7T+dAtQsZg8AqyYSoy1FIw=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=n6IyU5qtfHANlZ7nqdqVb1uKDO8kXVibzGvpWLq+D7mV0gEtNm9gO/wpQ+keJ4WtCcHA/Snyp1hh0H5RO/io9kXw38lgeMz+7nKtdd+2ECVIq8W5e6zSgpnbogob0sW+UiqjNGFaBFdWDgAFa/AYF6gWH+gzeQKCf0DHQQg64Yc= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=RWkI7Jek; 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="RWkI7Jek" Received: by smtp.kernel.org (Postfix) with ESMTPSA id EED1EC2BCB7; Fri, 1 May 2026 04:09:05 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1777608546; bh=C6mO2sC+0qw428snku2YR7T+dAtQsZg8AqyYSoy1FIw=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=RWkI7JekK6w7HBId1kcBSSczIfSuBPiEIvZUGBdXzkUh3FoeAixrCb70EDsQulMxo H/mJfxwh53xszMVPjDEze+wp4f+DD7PlHFHJ+biT/LIOTDWG+2FnNlUNV9T5Idk8N9 FWXqZN3Y2ZZ1AODfhZx+aNIPH4bWAm46tojLSjiDidsJt/liznKHM3MJhEqbdpPeZC mcTu3ATxbAnuIkAXO/3V+IRsEMe+oKhrbLBZRKcitoB7nCJQCwJbkK7+afhhkqHCUq bn0WoWeICnnHl79OSq6XuuJwNe3GjhJXhLDDx7wIpYR/4lMwENAYJolm0xr6XT5f34 TUk6QI3D/T9Bg== From: Josh Poimboeuf To: x86@kernel.org Cc: linux-kernel@vger.kernel.org, live-patching@vger.kernel.org, Peter Zijlstra , Joe Lawrence , Song Liu , Miroslav Benes , Petr Mladek Subject: [PATCH v2 34/53] objtool: Include libsubcmd headers directly from source tree Date: Thu, 30 Apr 2026 21:08:22 -0700 Message-ID: <9582e7b77cb498a490bab6b93c1b330525f1a5c8.1777575752.git.jpoimboe@kernel.org> X-Mailer: git-send-email 2.53.0 In-Reply-To: References: 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" Instead of installing libsubcmd headers to a build output directory and including from there, include directly from tools/lib/ where they already exist. This fixes clangd indexing which otherwise can't find libsubcmd headers. Acked-by: Song Liu Signed-off-by: Josh Poimboeuf Reviewed-by: Miroslav Benes --- tools/objtool/Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/objtool/Makefile b/tools/objtool/Makefile index b71d1886022e..a4484fd22a96 100644 --- a/tools/objtool/Makefile +++ b/tools/objtool/Makefile @@ -58,7 +58,7 @@ INCLUDES :=3D -I$(srctree)/tools/include \ -I$(srctree)/tools/arch/$(SRCARCH)/include \ -I$(srctree)/tools/objtool/include \ -I$(srctree)/tools/objtool/arch/$(SRCARCH)/include \ - -I$(LIBSUBCMD_OUTPUT)/include + -I$(srctree)/tools/lib =20 OBJTOOL_CFLAGS :=3D -std=3Dgnu11 -fomit-frame-pointer -O2 -g $(WARNINGS) \ $(INCLUDES) $(LIBELF_FLAGS) $(LIBXXHASH_CFLAGS) $(HOSTCFLAGS) @@ -135,7 +135,7 @@ $(LIBSUBCMD): fixdep $(LIBSUBCMD_OUTPUT) FORCE $(Q)$(MAKE) -C $(LIBSUBCMD_DIR) O=3D$(LIBSUBCMD_OUTPUT) \ DESTDIR=3D$(LIBSUBCMD_OUTPUT) prefix=3D subdir=3D \ $(HOST_OVERRIDES) EXTRA_CFLAGS=3D"$(OBJTOOL_CFLAGS)" \ - $@ install_headers + $@ =20 $(LIBSUBCMD)-clean: $(call QUIET_CLEAN, libsubcmd) --=20 2.53.0 From nobody Thu Jun 18 07:54:40 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 190933148B4; Fri, 1 May 2026 04:09: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=1777608549; cv=none; b=h+AgROeqQNRE4kQgT6f7wFhyiV8dglfriiolZjAlkUJ1Z51Ja8STZ+dMOJztAjzF1DXSpAgM/7ehpBRHInUsJRoXf9uwLDqplHaD1vzLf6cCL84CO3DqwO8b5+zFvZd6HBsi48HHQ9x2/ZS1/OohfQpj+SDvCdrnRlXHNOV6OU0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777608549; c=relaxed/simple; bh=PAmYtqsZr0HcMy1tdE3sw+RY8cBvKIrfx2uuoBzbka4=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=CQK4aBu29aXXvKDMq7gjEg89fuQbb9NTpw4A1E5rueO5Qi2Aydeg4DyI1EVvkKoS5whd4MqLMTkw4iuSWur9NOHKCMRGUej4Ag/ZYRIqlZPgaJy4bhvhVT8mF+bt2V/2GG/B1g5is4Np5X4unYEbFYN/tLM4AzOsxPIR085heyY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=oWkc6ZUr; 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="oWkc6ZUr" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 694B2C2BCC6; Fri, 1 May 2026 04:09:06 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1777608546; bh=PAmYtqsZr0HcMy1tdE3sw+RY8cBvKIrfx2uuoBzbka4=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=oWkc6ZUrTKd7wFbIs7KVl+GAEHAVmxpRLKaDEafmHX6/O5JZh2Prb/KaTwiHhZ1HM 6h3kyNqqKbhsU+HZ/byfLXjOBwJIqBCAwQjX18PIuNG0V9D7U5madz9EO2GUd1pWeF dSVE//9Bzbb8dAxv8GINp9YKpBxRhVjpBkORfcDSxWZKVz6oieL9sJal3sCYdwzm3d CCI1qiskSstCNDreTiCn/6ibbzsyz1u+jLi5/cynCvjk12vyZ0Qi398qnp9rkliVhx CZ3Zy79c4dPqdkKLB4FknZvZ3Z2Qu/DXurJZGeW3tUuN0HEQQ7zBPk494C2cSmpS1l QdfQoTIgR7hkQ== From: Josh Poimboeuf To: x86@kernel.org Cc: linux-kernel@vger.kernel.org, live-patching@vger.kernel.org, Peter Zijlstra , Joe Lawrence , Song Liu , Miroslav Benes , Petr Mladek Subject: [PATCH v2 35/53] objtool/klp: Create empty checksum sections for function-less object files Date: Thu, 30 Apr 2026 21:08:23 -0700 Message-ID: <94267cbd67da8e158153743b80f4d2bfb3f62b4a.1777575752.git.jpoimboe@kernel.org> X-Mailer: git-send-email 2.53.0 In-Reply-To: References: 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" If an object file has no functions, objtool has nothing to checksum, so it doesn't create the .discard.sym_checksum symbol. Then when 'objtool klp diff' reads symbol checksums, it errors out due to the missing .discard.sym_checksum section. Instead, just create an empty checksum section to signal to read_sym_checksums() that the file has been processed. Acked-by: Song Liu Signed-off-by: Josh Poimboeuf Reviewed-by: Miroslav Benes --- tools/objtool/check.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/tools/objtool/check.c b/tools/objtool/check.c index e7579c4e46dc..f020f21f94a7 100644 --- a/tools/objtool/check.c +++ b/tools/objtool/check.c @@ -1044,9 +1044,6 @@ static int create_sym_checksum_section(struct objtool= _file *file) if (sym->csum.checksum) idx++; =20 - if (!idx) - return 0; - sec =3D elf_create_section_pair(file->elf, ".discard.sym_checksum", entsi= ze, idx, idx); if (!sec) --=20 2.53.0 From nobody Thu Jun 18 07:54:40 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 4A6DA3612E2; Fri, 1 May 2026 04:09:07 +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=1777608547; cv=none; b=HXgSJsqpvRPOh1lt74/nL850YxyAlusmR+doBdLG3zamwmMvYO/GUEcN0FID+5AjApPxxs2zvx65kZFB1e3bxibaP/DQ6v9gXrMb+a9dZzSnqliQwJorHMxu7Sc1GPljeJBDJzk5mCsNG26ZH4BSNP3mIULxe3cBunIakQ7zOk0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777608547; c=relaxed/simple; bh=A20AvTEi6L7BTg1dmFVmmAv0wnARcCkDo3eAoHGEx18=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=BAjtPUjx/Aw3vhtBngDIOPLRCd1tqVamb7WsO7HzmH7j7A3Sf+5vABkV0mksGkQy5aiMNE3uqDkt5G9BMg0ro4RqGaDaf+hTyFjqPEwUubxGsEvFz9KVCQ1OVnBfZzxbjrmGli4iQugsFTR3Xg0faO2zvZa0fUqAr6VpWy79f3c= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=QB5oC6EX; 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="QB5oC6EX" Received: by smtp.kernel.org (Postfix) with ESMTPSA id DA183C2BCB7; Fri, 1 May 2026 04:09:06 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1777608547; bh=A20AvTEi6L7BTg1dmFVmmAv0wnARcCkDo3eAoHGEx18=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=QB5oC6EXQuZuIm1Lm526qA7zPBS/EdBCRZasdGQirjZkD187LtH4hegD3QrY4Uuzx WzCcAx2hkcR4WD4BalX17dCnMQSllG2/1xu/SSo1aOF2ovxPP9uWykEKz6hiebv1ut RIu9XTRi0tybY9uggfR0AN+ZyzMuHEvSmiVAJmJCAfKX1j35/8v/qhyn7cn83ORRbr vRHSWqRY3uk/RbCYFaegcmGTQHKwcl4X+DSdrOe0RH9zU70Ytp8+9unQXduyTnTKsA l7F4a3w9TE/n6Bi18MNCGzjO2qH8iIcNZKvkVN+uyyBGr7ch7KQW7RMkVkZ1rNm4vw Pu1kE8716wpKw== From: Josh Poimboeuf To: x86@kernel.org Cc: linux-kernel@vger.kernel.org, live-patching@vger.kernel.org, Peter Zijlstra , Joe Lawrence , Song Liu , Miroslav Benes , Petr Mladek Subject: [PATCH v2 36/53] objtool/klp: Handle Clang .data..Lanon anonymous data sections Date: Thu, 30 Apr 2026 21:08:24 -0700 Message-ID: X-Mailer: git-send-email 2.53.0 In-Reply-To: References: 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" Clang generates anonymous data sections named .data..Lanon.. These need section-symbol references in the same way as .data..Lubsan (GCC) and .data..L__unnamed_ (Clang UBSAN) sections. Without this, convert_reloc_sym() fails when processing relocations that reference these sections. Acked-by: Song Liu Signed-off-by: Josh Poimboeuf Reviewed-by: Miroslav Benes --- tools/objtool/klp-diff.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/tools/objtool/klp-diff.c b/tools/objtool/klp-diff.c index 463b6daa5234..7e58ef36f805 100644 --- a/tools/objtool/klp-diff.c +++ b/tools/objtool/klp-diff.c @@ -1030,14 +1030,15 @@ static int convert_reloc_secsym_to_sym(struct elf *= elf, struct reloc *reloc) } =20 /* - * Sections with anonymous or uncorrelated data (strings, UBSAN data) - * need section symbol references. + * Sections with anonymous or uncorrelated data (strings, UBSAN data, Clang + * anonymous constants) need section symbol references. */ static bool is_uncorrelated_section(struct section *sec) { return is_string_sec(sec) || strstarts(sec->name, ".data..Lubsan") || /* GCC */ - strstarts(sec->name, ".data..L__unnamed_"); /* Clang */ + strstarts(sec->name, ".data..L__unnamed_") || /* Clang */ + strstarts(sec->name, ".data..Lanon."); /* Clang */ } =20 /* --=20 2.53.0 From nobody Thu Jun 18 07:54:40 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 B590D31283E; Fri, 1 May 2026 04:09:07 +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=1777608547; cv=none; b=MFcD0Lc45miTKylysw/FTF9Fj0/0fqFjDsYLApjQDt4NSxd6RbHErXn90W5TE8jlGNCTWH1nDeqdIa8KUmVPrmjVe5gdIhuJshY9l7M8oAABCEUlLKPznLsGgOuaF4saAhdm4mPcvyVkGSpxsIVLwJc/ml2Hos+o42k6mwv92oo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777608547; c=relaxed/simple; bh=U1/zXTGHmGDeZk5zmEiLTowFn8oD8+hWbudhQLdzfVA=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=oOQQT3MCqyWXPFV3IUkb4Qyre1KltTAi/r8gR0vGS6U2XbhXAg5gHehhPA0Ku4FVJY90cFaP+VsiJpJpHSoj3J5bh7yav6Jtp9aJdUuJ97uKW5z55zGM7V/QtWdPYFUFXz886j/BC/yeW6Douem+nIwry6wbMUGTilrOmiNo98o= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=mPGiSoAV; 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="mPGiSoAV" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 5526EC2BCB9; Fri, 1 May 2026 04:09:07 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1777608547; bh=U1/zXTGHmGDeZk5zmEiLTowFn8oD8+hWbudhQLdzfVA=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=mPGiSoAVujosCaTs7qHYIAu7SdocyUdJIJp0ZbHB52+AinDT8Gknd14LlPrsoZoa7 hKq5Ffeync370AxGSPmVbC3As+T/96vu68N69edcCrA6u3DzDHKDGfgL/RfgKBWaK7 rvD3XXXh0nvIARIGTX2SPrwRH71yD6YlW1Iu09AdQFXM+Yw3joqI/z4yVOtRQIzfeP 55lp9OE8r6Oedzsm1rzWRXEsmfi4gTcnRoDRfTMBPIcZxTZ68SIBOxjGeId+ug8v2k 3TX6jmmJJ09ilmMx5IC2IxChGuF5Bm5Ba6wFHvdxCMm7FmsbGbngX4yVO++23p77Of XgMEpDggOpd/A== From: Josh Poimboeuf To: x86@kernel.org Cc: linux-kernel@vger.kernel.org, live-patching@vger.kernel.org, Peter Zijlstra , Joe Lawrence , Song Liu , Miroslav Benes , Petr Mladek Subject: [PATCH v2 37/53] objtool: Add is_alias_sym() helper Date: Thu, 30 Apr 2026 21:08:25 -0700 Message-ID: <87cfee570bfffb35961d9b6e5abfbfeae6d903dc.1777575752.git.jpoimboe@kernel.org> X-Mailer: git-send-email 2.53.0 In-Reply-To: References: 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" Improve readability with a new is_alias_sym() helper. No functional changes intended. Acked-by: Peter Zijlstra (Intel) Acked-by: Song Liu Signed-off-by: Josh Poimboeuf Reviewed-by: Miroslav Benes --- tools/objtool/check.c | 6 +++--- tools/objtool/include/objtool/elf.h | 5 +++++ 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/tools/objtool/check.c b/tools/objtool/check.c index f020f21f94a7..6c94eb32c090 100644 --- a/tools/objtool/check.c +++ b/tools/objtool/check.c @@ -491,7 +491,7 @@ static int decode_instructions(struct objtool_file *fil= e) return -1; } =20 - if (func->embedded_insn || func->alias !=3D func) + if (func->embedded_insn || is_alias_sym(func)) continue; =20 if (!find_insn(file, sec, func->offset)) { @@ -2229,7 +2229,7 @@ static int add_jump_table_alts(struct objtool_file *f= ile) return 0; =20 for_each_sym(file->elf, func) { - if (!is_func_sym(func) || func->alias !=3D func) + if (!is_func_sym(func) || is_alias_sym(func)) continue; =20 mark_func_jump_tables(file, func); @@ -4523,7 +4523,7 @@ static int validate_symbol(struct objtool_file *file,= struct section *sec, return 1; } =20 - if (sym->pfunc !=3D sym || sym->alias !=3D sym) + if (sym->pfunc !=3D sym || is_alias_sym(sym)) return 0; =20 insn =3D find_insn(file, sec, sym->offset); diff --git a/tools/objtool/include/objtool/elf.h b/tools/objtool/include/ob= jtool/elf.h index 8a543cea43b9..ccc72a692d9a 100644 --- a/tools/objtool/include/objtool/elf.h +++ b/tools/objtool/include/objtool/elf.h @@ -298,6 +298,11 @@ static inline bool is_local_sym(struct symbol *sym) return sym->bind =3D=3D STB_LOCAL; } =20 +static inline bool is_alias_sym(struct symbol *sym) +{ + return sym->alias !=3D sym; +} + static inline bool is_prefix_func(struct symbol *sym) { return sym->prefix; --=20 2.53.0 From nobody Thu Jun 18 07:54:40 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 2F399313267; Fri, 1 May 2026 04:09:08 +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=1777608548; cv=none; b=mAJpPAgyjiWW150iLUe+3/nPcipAcqtEWtF/JVqtUSA4pooyd2DZO9Mt/VAVaGqyxZh5B2OgnGaPMoVmmknI7Wh6OCC1s/+GSzrAkquMALjNyIJdKEsugpILhP7cTS2Fy8h3mHcR7rCllljTDwwBPq9ZO5wsqz0UKuIk05VrXEY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777608548; c=relaxed/simple; bh=1YoJrPuxqlDAdZSZ/V51TZ5Nbry8SmQdApKpcxnsBJA=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=Xwydkra7O268TsmNKf/awvmG9Ki9NvTv02eU8gdFWQb0nUVJ/rvwsdlaZD65fT/IrXL36dFp3jz0rdt56Cji/PfYmXRgqJIdO5m5x4rcRrLETySyGWWTiH8Kd8yjIRrVtmJDp91vS7RiYapjrwJ5u8A23/V+bJsgdx6G2hMTtRQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=p5rjoy+p; 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="p5rjoy+p" Received: by smtp.kernel.org (Postfix) with ESMTPSA id C337DC2BCB7; Fri, 1 May 2026 04:09:07 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1777608548; bh=1YoJrPuxqlDAdZSZ/V51TZ5Nbry8SmQdApKpcxnsBJA=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=p5rjoy+p1FAxRycGSp6pA9H2+tvEoCSisShhI78cbZ4jQ7za2pra9mweZ5ajvoODS jeHiKsH7mNwZK7VXQkoyv0UV9sn98oIdWlSSWFJnMG8dH41WtTkMghJfT/dynqR1AJ UjfO7jDd+Sfe3RX/4Trprj0Dnd7eRVGDC1EQ8PY5AKeALvnzAGufrorMWM8Rqd+242 aLpUQC22bzIfjOZdeDPNA0VS/tUwpo65ad9aWSLO42NCIYpH9vW1YMWT59CSCbjpev a3gljYuQ7dbkyuez5Tk16JPMQ1Uv286dy1Dsm2f7QAe4N8Hk7C1AB9+kWF6b2/Hzb3 U8jhlj5IbMmOw== From: Josh Poimboeuf To: x86@kernel.org Cc: linux-kernel@vger.kernel.org, live-patching@vger.kernel.org, Peter Zijlstra , Joe Lawrence , Song Liu , Miroslav Benes , Petr Mladek Subject: [PATCH v2 38/53] objtool: Add is_cold_func() helper Date: Thu, 30 Apr 2026 21:08:26 -0700 Message-ID: X-Mailer: git-send-email 2.53.0 In-Reply-To: References: 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" Add an is_cold_func() helper. No functional changes intended. Signed-off-by: Josh Poimboeuf Acked-by: Song Liu Reviewed-by: Miroslav Benes --- tools/objtool/check.c | 6 +++--- tools/objtool/include/objtool/elf.h | 5 +++++ tools/objtool/klp-diff.c | 3 ++- 3 files changed, 10 insertions(+), 4 deletions(-) diff --git a/tools/objtool/check.c b/tools/objtool/check.c index 6c94eb32c090..93a054adf209 100644 --- a/tools/objtool/check.c +++ b/tools/objtool/check.c @@ -2614,7 +2614,7 @@ static void mark_holes(struct objtool_file *file) if (insn->jump_dest) { struct symbol *dest_func =3D insn_func(insn->jump_dest); =20 - if (dest_func && dest_func->cold) + if (dest_func && is_cold_func(dest_func)) dest_func->ignore =3D true; } } @@ -4422,8 +4422,8 @@ static int create_prefix_symbol(struct objtool_file *= file, struct symbol *func) char name[SYM_NAME_LEN]; struct cfi_state *cfi; =20 - if (!is_func_sym(func) || is_prefix_func(func) || - func->cold || func->static_call_tramp) + if (!is_func_sym(func) || is_prefix_func(func) || is_cold_func(func) || + func->static_call_tramp) return 0; =20 if ((strlen(func->name) + sizeof("__pfx_") > SYM_NAME_LEN)) { diff --git a/tools/objtool/include/objtool/elf.h b/tools/objtool/include/ob= jtool/elf.h index ccc72a692d9a..e452784df702 100644 --- a/tools/objtool/include/objtool/elf.h +++ b/tools/objtool/include/objtool/elf.h @@ -308,6 +308,11 @@ static inline bool is_prefix_func(struct symbol *sym) return sym->prefix; } =20 +static inline bool is_cold_func(struct symbol *sym) +{ + return sym->cold; +} + static inline bool is_reloc_sec(struct section *sec) { return sec->sh.sh_type =3D=3D SHT_RELA || sec->sh.sh_type =3D=3D SHT_REL; diff --git a/tools/objtool/klp-diff.c b/tools/objtool/klp-diff.c index 7e58ef36f805..8728dda1e08c 100644 --- a/tools/objtool/klp-diff.c +++ b/tools/objtool/klp-diff.c @@ -1709,7 +1709,8 @@ static int create_klp_sections(struct elfs *e) unsigned long sympos; void *func_data; =20 - if (!is_func_sym(sym) || sym->cold || !sym->clone || !sym->clone->change= d) + if (!is_func_sym(sym) || is_cold_func(sym) || + !sym->clone || !sym->clone->changed) continue; =20 /* allocate klp_func_ext */ --=20 2.53.0 From nobody Thu Jun 18 07:54:40 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 A2DCD369236; Fri, 1 May 2026 04:09:08 +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=1777608548; cv=none; b=opWK8FxkLuMISMGPo/vcUC1+WPN3010ZpA+LLbnNk1cSrbXUt//UDdRaJtfrgVTJqCv4S8Til49UROGJVfatp0U3H9YGZLU+diexoPW3ZtoTODje0ie8WvXDyD5myS7YOs31dmlNSkjlix6UAW2NpXnUXFQHA2kidotirFRqc+0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777608548; c=relaxed/simple; bh=x+o7MttE8HaIrZqO53iTQAE6hE+z2eW5kHbKMjGZdRo=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=PU3hSVpWR8xeVmAIccdkoYDEO57AYGPcLL8wmpILn1K/i4LLApGVwJgdj/3chRh/+vi4jkN8faR3fzixR/5/LWYxjDsc9KfpH9Q4VdMoqubx7aJcWzi39ewiDDIyS6HcXNJRj/UcplPlfvWJSzKRmLqt6+DWWhhpZK9RqG+vD/E= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=KOKQivFY; 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="KOKQivFY" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 3E211C2BCF4; Fri, 1 May 2026 04:09:08 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1777608548; bh=x+o7MttE8HaIrZqO53iTQAE6hE+z2eW5kHbKMjGZdRo=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=KOKQivFYgaP8IShYRAbdczxLswCtBIr6d1BZhwSdP8jrRmiNEnxVzvORttcigUgR6 +zAzanQSTm8vLJDOEtXzp2lgMAtPGPLoGSdTftwRHGHx+L8Rd+h1ANRZkq7Ru797AT 25uZmFqPsU2D2O5qGbopG4ZMQAg4lk+4v9qs0nJpthKkchQP3skdyZ+8n7wo3tUseC TWRgtGt7mPQ7V1nS8bXUBeEZnFq0Q+/J1Vt045rZgG+xEFChBdoee/+lAam/Oj54ed xD9L/6/pUdk8UmJYimiQAN//CW29mDHu2L7ll7Vz8cqTdVUvUtZVgDYTA3eynFMKcu Vao3skvZUy7lQ== From: Josh Poimboeuf To: x86@kernel.org Cc: linux-kernel@vger.kernel.org, live-patching@vger.kernel.org, Peter Zijlstra , Joe Lawrence , Song Liu , Miroslav Benes , Petr Mladek Subject: [PATCH v2 39/53] objtool/klp: Extricate checksum calculation from validate_branch() Date: Thu, 30 Apr 2026 21:08:27 -0700 Message-ID: X-Mailer: git-send-email 2.53.0 In-Reply-To: References: 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" In preparation for porting the checksum code to other arches, make its functionality independent from the CFG reverse engineering code. Move it into a standalone calculate_checksums() function which iterates all functions and instructions directly, rather than being called inline from do_validate_branch(). Since checksum_update_insn() is no longer called during CFG traversal, it needs to manually iterate the alternatives. Acked-by: Song Liu Signed-off-by: Josh Poimboeuf Reviewed-by: Miroslav Benes --- tools/objtool/check.c | 106 +++++++++++++++++------ tools/objtool/include/objtool/checksum.h | 6 +- 2 files changed, 80 insertions(+), 32 deletions(-) diff --git a/tools/objtool/check.c b/tools/objtool/check.c index 93a054adf209..f019e1f06780 100644 --- a/tools/objtool/check.c +++ b/tools/objtool/check.c @@ -1350,10 +1350,7 @@ static struct reloc *insn_reloc(struct objtool_file = *file, struct instruction *i { struct reloc *reloc; =20 - if (insn->no_reloc) - return NULL; - - if (!file) + if (!file || insn->no_reloc || insn->fake) return NULL; =20 reloc =3D find_reloc_by_dest_range(file->elf, insn->sec, @@ -2622,9 +2619,17 @@ static void mark_holes(struct objtool_file *file) =20 static bool validate_branch_enabled(void) { - return opts.stackval || - opts.orc || - opts.uaccess || + return opts.stackval || + opts.orc || + opts.uaccess; +} + +static bool alts_needed(void) +{ + return validate_branch_enabled() || + opts.noinstr || + opts.hack_jump_label || + opts.disas || opts.checksum; } =20 @@ -2658,7 +2663,7 @@ static int decode_sections(struct objtool_file *file) * Must be before add_jump_destinations(), which depends on 'func' * being set for alternatives, to enable proper sibling call detection. */ - if (validate_branch_enabled() || opts.noinstr || opts.hack_jump_label || = opts.disas) { + if (alts_needed()) { if (add_special_section_alts(file)) return -1; } @@ -3654,6 +3659,7 @@ static bool skip_alt_group(struct instruction *insn) return alt_insn->type =3D=3D INSN_CLAC || alt_insn->type =3D=3D INSN_STAC; } =20 +#ifdef BUILD_KLP static int checksum_debug_init(struct objtool_file *file) { char *dup, *s; @@ -3701,8 +3707,10 @@ static void checksum_update_insn(struct objtool_file= *file, struct symbol *func, struct instruction *insn) { struct reloc *reloc =3D insn_reloc(file, insn); + struct alternative *alt; unsigned long offset; struct symbol *sym; + static bool in_alt; =20 if (insn->fake) return; @@ -3715,7 +3723,7 @@ static void checksum_update_insn(struct objtool_file = *file, struct symbol *func, if (call_dest) checksum_update(func, insn, call_dest->demangled_name, strlen(call_dest->demangled_name)); - return; + goto alts; } =20 sym =3D reloc->sym; @@ -3726,21 +3734,78 @@ static void checksum_update_insn(struct objtool_fil= e *file, struct symbol *func, =20 str =3D sym->sec->data->d_buf + sym->offset + offset; checksum_update(func, insn, str, strlen(str)); - return; + goto alts; } =20 if (is_sec_sym(sym)) { sym =3D find_symbol_containing(reloc->sym->sec, offset); if (!sym) - return; + goto alts; =20 offset -=3D sym->offset; } =20 checksum_update(func, insn, sym->demangled_name, strlen(sym->demangled_na= me)); checksum_update(func, insn, &offset, sizeof(offset)); + +alts: + for (alt =3D insn->alts; alt; alt =3D alt->next) { + struct alt_group *alt_group =3D alt->insn->alt_group; + + /* Prevent __ex_table recursion, e.g. LOAD_SEGMENT() */ + if (in_alt) + break; + in_alt =3D true; + + checksum_update(func, insn, &alt->type, sizeof(alt->type)); + + if (alt_group && alt_group->orig_group) { + struct instruction *alt_insn; + + checksum_update(func, insn, &alt_group->feature, sizeof(alt_group->feat= ure)); + + for (alt_insn =3D alt->insn; alt_insn; alt_insn =3D next_insn_same_sec(= file, alt_insn)) { + checksum_update_insn(file, func, alt_insn); + if (!alt_group->last_insn || alt_insn =3D=3D alt_group->last_insn) + break; + } + } else { + checksum_update_insn(file, func, alt->insn); + } + + in_alt =3D false; + } } =20 +static int calculate_checksums(struct objtool_file *file) +{ + struct instruction *insn; + struct symbol *func; + + if (checksum_debug_init(file)) + return -1; + + for_each_sym(file->elf, func) { + /* + * Skip cold subfunctions and aliases: they share the + * parent's checksum via func_for_each_insn() which + * follows func->cfunc into the cold subfunction. + */ + if (!is_func_sym(func) || is_cold_func(func) || + is_alias_sym(func) || !func->len) + continue; + + checksum_init(func); + + func_for_each_insn(file, func, insn) + checksum_update_insn(file, func, insn); + + checksum_finish(func); + } + return 0; +} +#endif /* BUILD_KLP */ + static int validate_branch(struct objtool_file *file, struct symbol *func, struct instruction *insn, struct insn_state state); static int do_validate_branch(struct objtool_file *file, struct symbol *fu= nc, @@ -4022,9 +4087,6 @@ static int do_validate_branch(struct objtool_file *fi= le, struct symbol *func, insn->trace =3D 0; next_insn =3D next_insn_to_validate(file, insn); =20 - if (opts.checksum && func && insn->sec) - checksum_update_insn(file, func, insn); - if (func && insn_func(insn) && func !=3D insn_func(insn)->pfunc) { /* Ignore KCFI type preambles, which always fall through */ if (is_prefix_func(func)) @@ -4090,9 +4152,6 @@ static int validate_unwind_hint(struct objtool_file *= file, struct symbol *func =3D insn_func(insn); int ret; =20 - if (opts.checksum) - checksum_init(func); - ret =3D validate_branch(file, func, insn, *state); if (ret) BT_INSN(insn, "<=3D=3D=3D (hint)"); @@ -4535,9 +4594,6 @@ static int validate_symbol(struct objtool_file *file,= struct section *sec, =20 func =3D insn_func(insn); =20 - if (opts.checksum) - checksum_init(func); - if (opts.trace && !fnmatch(opts.trace, sym->name, 0)) { trace_enable(); TRACE("%s: validation begin\n", sym->name); @@ -4550,9 +4606,6 @@ static int validate_symbol(struct objtool_file *file,= struct section *sec, TRACE("%s: validation %s\n\n", sym->name, ret ? "failed" : "end"); trace_disable(); =20 - if (opts.checksum) - checksum_finish(func); - return ret; } =20 @@ -5007,10 +5060,6 @@ int check(struct objtool_file *file) cfi_hash_add(&init_cfi); cfi_hash_add(&func_cfi); =20 - ret =3D checksum_debug_init(file); - if (ret) - goto out; - ret =3D decode_sections(file); if (ret) goto out; @@ -5101,6 +5150,9 @@ int check(struct objtool_file *file) warnings +=3D check_abs_references(file); =20 if (opts.checksum) { + ret =3D calculate_checksums(file); + if (ret) + goto out; ret =3D create_sym_checksum_section(file); if (ret) goto out; diff --git a/tools/objtool/include/objtool/checksum.h b/tools/objtool/inclu= de/objtool/checksum.h index 0bd16fe9168b..3f25df90305d 100644 --- a/tools/objtool/include/objtool/checksum.h +++ b/tools/objtool/include/objtool/checksum.h @@ -33,11 +33,7 @@ static inline void checksum_finish(struct symbol *func) =20 #else /* !BUILD_KLP */ =20 -static inline void checksum_init(struct symbol *func) {} -static inline void checksum_update(struct symbol *func, - struct instruction *insn, - const void *data, size_t size) {} -static inline void checksum_finish(struct symbol *func) {} +static inline int calculate_checksums(struct objtool_file *file) { return = -ENOSYS; } =20 #endif /* !BUILD_KLP */ =20 --=20 2.53.0 From nobody Thu Jun 18 07:54:40 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 1AEA336B046; Fri, 1 May 2026 04:09:09 +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=1777608549; cv=none; b=usCqQT/ZPKUwnYDANBvP4JTVKDiwNEyL/L67pB7coif2eFbR8GIby3ihDH/57mRa0ZfX1fAtwgZUCnd6ggyjvnQ5g0Ol3ZI7wT0Bxd5fVosnDrxMNeF/X4tDCRBDPjuQqis90wL59Fju5tfOibAsn0/0kR79L8esIZO/QWjmGUc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777608549; c=relaxed/simple; bh=m/ozg1EAde/Oq0i+pAtSNUYhLnhNOg5iFqi9kLnbM7k=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=FDIjEpqCEDDXzv1ZxVOBDdkyQ0UFgLNTcAupmQXBMv1x2gCgVTSIFOnegnh0/3bPiLt70YVX7X6IqnRW3uzZOtUrqgqM2mH6i921Kz2lfwsMm27NLr8j3NxL23U+EExCsAYvgOXkwvaQqp9VfBqTwzWM/uxB+RKSJsChsWhCv4U= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=S2MoqPvL; 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="S2MoqPvL" Received: by smtp.kernel.org (Postfix) with ESMTPSA id AEC68C2BCB7; Fri, 1 May 2026 04:09:08 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1777608549; bh=m/ozg1EAde/Oq0i+pAtSNUYhLnhNOg5iFqi9kLnbM7k=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=S2MoqPvLjobCDFbBephCUsWbaz29eUSsOx653JSjD6cgk1BM7YIJDJQ3kbfp0xnrt hxtBhCVHDiC/f0KUpgze6hG4twAxT8gsLPCh1Xdk+7SNDRJhZMrmlW/SQhvwwblCIv fVDZOOL1fjxVv3DvNQAlLS/f167BoxyZYGV2/XdXJ02N/NU3VVVr98/np/hjhozjEu PBHOx+zpwmeYzlZl2e+5WBE4RchJ0BAtFu7P7qNT4D3XH7EYPggpx2fzHXoKp5fh4U cTuQwWPxomwUPwMT/Ag5XvAm9I64O37O83g1YdTX3Y6UkclCoIfzZCnFNpwNov4Thd UVBe4iSwQ5jjg== From: Josh Poimboeuf To: x86@kernel.org Cc: linux-kernel@vger.kernel.org, live-patching@vger.kernel.org, Peter Zijlstra , Joe Lawrence , Song Liu , Miroslav Benes , Petr Mladek Subject: [PATCH v2 40/53] objtool: Consolidate file decoding into decode_file() Date: Thu, 30 Apr 2026 21:08:28 -0700 Message-ID: <36478f25bee19c8acbff3992e27436b544c4e26b.1777575752.git.jpoimboe@kernel.org> X-Mailer: git-send-email 2.53.0 In-Reply-To: References: 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" decode_sections() relies on CFI and cfi_hash initialization done separately in check(), making it unusable outside of check(). Consolidate the initialization into decode_sections() and rename it to decode_file(), and make it global along with free_insns() and insn_reloc() for use by other objtool components -- namely, the checksum code which will be moving to another file. Acked-by: Peter Zijlstra (Intel) Acked-by: Song Liu Signed-off-by: Josh Poimboeuf Reviewed-by: Miroslav Benes --- tools/objtool/check.c | 36 +++++++++++++-------------- tools/objtool/include/objtool/check.h | 5 ++++ 2 files changed, 22 insertions(+), 19 deletions(-) diff --git a/tools/objtool/check.c b/tools/objtool/check.c index f019e1f06780..49171ddc6f54 100644 --- a/tools/objtool/check.c +++ b/tools/objtool/check.c @@ -1346,7 +1346,7 @@ __weak bool arch_is_embedded_insn(struct symbol *sym) return false; } =20 -static struct reloc *insn_reloc(struct objtool_file *file, struct instruct= ion *insn) +struct reloc *insn_reloc(struct objtool_file *file, struct instruction *in= sn) { struct reloc *reloc; =20 @@ -2633,8 +2633,21 @@ static bool alts_needed(void) opts.checksum; } =20 -static int decode_sections(struct objtool_file *file) +int decode_file(struct objtool_file *file) { + arch_initial_func_cfi_state(&initial_func_cfi); + init_cfi_state(&init_cfi); + init_cfi_state(&func_cfi); + set_func_state(&func_cfi); + init_cfi_state(&force_undefined_cfi); + force_undefined_cfi.force_undefined =3D true; + + if (!cfi_hash_alloc(1UL << (file->elf->symbol_bits - 3))) + return -1; + + cfi_hash_add(&init_cfi); + cfi_hash_add(&func_cfi); + file->klp =3D is_livepatch_module(file); =20 mark_rodata(file); @@ -4998,7 +5011,7 @@ struct insn_chunk { * which can trigger more allocations for .debug_* sections whose data has= n't * been read yet. */ -static void free_insns(struct objtool_file *file) +void free_insns(struct objtool_file *file) { struct instruction *insn; struct insn_chunk *chunks =3D NULL, *chunk; @@ -5045,22 +5058,7 @@ int check(struct objtool_file *file) objtool_disas_ctx =3D disas_ctx; } =20 - arch_initial_func_cfi_state(&initial_func_cfi); - init_cfi_state(&init_cfi); - init_cfi_state(&func_cfi); - set_func_state(&func_cfi); - init_cfi_state(&force_undefined_cfi); - force_undefined_cfi.force_undefined =3D true; - - if (!cfi_hash_alloc(1UL << (file->elf->symbol_bits - 3))) { - ret =3D -1; - goto out; - } - - cfi_hash_add(&init_cfi); - cfi_hash_add(&func_cfi); - - ret =3D decode_sections(file); + ret =3D decode_file(file); if (ret) goto out; =20 diff --git a/tools/objtool/include/objtool/check.h b/tools/objtool/include/= objtool/check.h index 5f2f77bd9b41..6489e52ea2f2 100644 --- a/tools/objtool/include/objtool/check.h +++ b/tools/objtool/include/objtool/check.h @@ -155,6 +155,11 @@ struct instruction *next_insn_same_sec(struct objtool_= file *file, struct instruc insn && insn->offset < sym->offset + sym->len; \ insn =3D next_insn_same_sec(file, insn)) =20 +struct reloc *insn_reloc(struct objtool_file *file, struct instruction *in= sn); + +int decode_file(struct objtool_file *file); +void free_insns(struct objtool_file *file); + const char *objtool_disas_insn(struct instruction *insn); =20 extern size_t sym_name_max_len; --=20 2.53.0 From nobody Thu Jun 18 07:54:40 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 BD354377EC2; Fri, 1 May 2026 04:09:09 +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=1777608553; cv=none; b=uK4HSl3t6N+BaD3gIe8t15egRQNHo4yqdNIE06QC+1qwkbVn9PY409I1KfO28y80fpJLiispO+wb8T3DCjL37CQiWIHdeqRf85tRd9V5oVqC/hpgeqPPPSB8XgMApdXekeabQZr8hm3WADJEHUTJ3gNjkfbbUoNc9fkcqCHrcfM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777608553; c=relaxed/simple; bh=e7oEQ6SJLpFdZk2kmS/+iqVKxltT9tyXuHd9cNVZaCg=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=aEC/YuehyBYpOM0qf7YLLHsuz/PM0npVXiSBvAN7t2ZxuQd3Qx8Q4wzMN0H5eW91L1EqUIfFXtjXLSEhfB9lXgKReaw2w4eIuZAYkcVkDIEXUM4b3F7+NQNxlhXNO67UGY+abLRnMktHZ/cnbBZPB/ZgfOgbvw0CsFcl1Rs2xC4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=Q/sEPkNz; 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="Q/sEPkNz" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 277B3C2BCF4; Fri, 1 May 2026 04:09:09 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1777608549; bh=e7oEQ6SJLpFdZk2kmS/+iqVKxltT9tyXuHd9cNVZaCg=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=Q/sEPkNzhwi7KF8JwHF8mSll152KP61hoiG/aILcOVurjygHT93SBYgR3P2LzIE6P f1JbNFyr3z0EHrqja9CI0RepNtvhe6PwzordXURl13O8r3eV94cxJ9M+JE/ikaQsJu avC0x0H8LTGDfpVqsQnbwP8U68rk9zsQ0bUVOOoJALuAeodXjXhvTyWvqzISDGTGdA SzKisI7C5X1FfwCRdbGgn4yC9lRj+VSJPrUtj4pj3l+kVLT12g7CPUsr2OGXLADIqd bdZrDI59BL5hzW14tGbfIp9cHjdicyEUqa2HPtM+gi5ZQ4P3uP4GMOybOKF49K2u5H aCPebITj/OLnw== From: Josh Poimboeuf To: x86@kernel.org Cc: linux-kernel@vger.kernel.org, live-patching@vger.kernel.org, Peter Zijlstra , Joe Lawrence , Song Liu , Miroslav Benes , Petr Mladek Subject: [PATCH v2 41/53] objtool/klp: Add "objtool klp checksum" subcommand Date: Thu, 30 Apr 2026 21:08:29 -0700 Message-ID: X-Mailer: git-send-email 2.53.0 In-Reply-To: References: 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" Move the checksum functionality out of the main objtool command into a new "objtool klp checksum" subcommand. This has the benefit of making the code (and the patch generation process itself) more modular. For bisectability, both "objtool --checksum" and "objtool klp checksum" work for now. The former will be removed after klp-build has been converted to use the new subcommand. Acked-by: Song Liu Signed-off-by: Josh Poimboeuf Reviewed-by: Miroslav Benes --- tools/objtool/Build | 2 +- tools/objtool/builtin-klp.c | 1 + tools/objtool/check.c | 205 +----------------- tools/objtool/include/objtool/check.h | 6 + tools/objtool/include/objtool/checksum.h | 4 + tools/objtool/include/objtool/klp.h | 1 + tools/objtool/klp-checksum.c | 253 +++++++++++++++++++++++ tools/objtool/klp-diff.c | 2 +- 8 files changed, 269 insertions(+), 205 deletions(-) create mode 100644 tools/objtool/klp-checksum.c diff --git a/tools/objtool/Build b/tools/objtool/Build index 600da051af12..93a37b0dfd31 100644 --- a/tools/objtool/Build +++ b/tools/objtool/Build @@ -12,7 +12,7 @@ objtool-$(BUILD_DISAS) +=3D disas.o objtool-$(BUILD_DISAS) +=3D trace.o =20 objtool-$(BUILD_ORC) +=3D orc_gen.o orc_dump.o -objtool-$(BUILD_KLP) +=3D builtin-klp.o klp-diff.o klp-post-link.o +objtool-$(BUILD_KLP) +=3D builtin-klp.o klp-checksum.o klp-diff.o klp-post= -link.o =20 objtool-y +=3D libstring.o objtool-y +=3D libctype.o diff --git a/tools/objtool/builtin-klp.c b/tools/objtool/builtin-klp.c index 56d5a5b92f72..58c3b9bda3eb 100644 --- a/tools/objtool/builtin-klp.c +++ b/tools/objtool/builtin-klp.c @@ -13,6 +13,7 @@ struct subcmd { }; =20 static struct subcmd subcmds[] =3D { + { "checksum", "Generate per-function checksums", cmd_klp_checksum, }, { "diff", "Generate binary diff of two object files", cmd_klp_diff, }, { "post-link", "Finalize klp symbols/relocs after module linking", cmd_k= lp_post_link, }, }; diff --git a/tools/objtool/check.c b/tools/objtool/check.c index 49171ddc6f54..3e5d335d0e29 100644 --- a/tools/objtool/check.c +++ b/tools/objtool/check.c @@ -64,8 +64,8 @@ struct instruction *next_insn_same_sec(struct objtool_fil= e *file, return insn; } =20 -static struct instruction *next_insn_same_func(struct objtool_file *file, - struct instruction *insn) +struct instruction *next_insn_same_func(struct objtool_file *file, + struct instruction *insn) { struct instruction *next =3D next_insn_same_sec(file, insn); struct symbol *func =3D insn_func(insn); @@ -113,10 +113,6 @@ static struct instruction *prev_insn_same_sym(struct o= bjtool_file *file, for_each_sec(file->elf, __sec) \ sec_for_each_insn(file, __sec, insn) =20 -#define func_for_each_insn(file, func, insn) \ - for (insn =3D find_insn(file, func->sec, func->offset); \ - insn; \ - insn =3D next_insn_same_func(file, insn)) =20 #define sym_for_each_insn(file, sym, insn) \ for (insn =3D find_insn(file, sym->sec, sym->offset); \ @@ -1023,56 +1019,6 @@ static int create_direct_call_sections(struct objtoo= l_file *file) return 0; } =20 -#ifdef BUILD_KLP -static int create_sym_checksum_section(struct objtool_file *file) -{ - struct section *sec; - struct symbol *sym; - unsigned int idx =3D 0; - struct sym_checksum *checksum; - size_t entsize =3D sizeof(struct sym_checksum); - - sec =3D find_section_by_name(file->elf, ".discard.sym_checksum"); - if (sec) { - if (!opts.dryrun) - WARN("file already has .discard.sym_checksum section, skipping"); - - return 0; - } - - for_each_sym(file->elf, sym) - if (sym->csum.checksum) - idx++; - - sec =3D elf_create_section_pair(file->elf, ".discard.sym_checksum", entsi= ze, - idx, idx); - if (!sec) - return -1; - - idx =3D 0; - for_each_sym(file->elf, sym) { - if (!sym->csum.checksum) - continue; - - if (!elf_init_reloc(file->elf, sec->rsec, idx, idx * entsize, - sym, 0, R_TEXT64)) - return -1; - - checksum =3D (struct sym_checksum *)sec->data->d_buf + idx; - checksum->addr =3D 0; /* reloc */ - checksum->checksum =3D sym->csum.checksum; - - mark_sec_changed(file->elf, sec, true); - - idx++; - } - - return 0; -} -#else -static int create_sym_checksum_section(struct objtool_file *file) { return= -EINVAL; } -#endif - /* * Warnings shouldn't be reported for ignored functions. */ @@ -3672,153 +3618,6 @@ static bool skip_alt_group(struct instruction *insn) return alt_insn->type =3D=3D INSN_CLAC || alt_insn->type =3D=3D INSN_STAC; } =20 -#ifdef BUILD_KLP -static int checksum_debug_init(struct objtool_file *file) -{ - char *dup, *s; - - if (!opts.debug_checksum) - return 0; - - dup =3D strdup(opts.debug_checksum); - if (!dup) { - ERROR_GLIBC("strdup"); - return -1; - } - - s =3D dup; - while (*s) { - bool found =3D false; - struct symbol *sym; - char *comma; - - comma =3D strchr(s, ','); - if (comma) - *comma =3D '\0'; - - for_each_sym_by_name(file->elf, s, sym) { - if (!is_func_sym(sym)) - continue; - sym->debug_checksum =3D 1; - found =3D true; - } - - if (!found) - WARN("--debug-checksum: can't find '%s'", s); - - if (!comma) - break; - - s =3D comma + 1; - } - - free(dup); - return 0; -} - -static void checksum_update_insn(struct objtool_file *file, struct symbol = *func, - struct instruction *insn) -{ - struct reloc *reloc =3D insn_reloc(file, insn); - struct alternative *alt; - unsigned long offset; - struct symbol *sym; - static bool in_alt; - - if (insn->fake) - return; - - checksum_update(func, insn, insn->sec->data->d_buf + insn->offset, insn->= len); - - if (!reloc) { - struct symbol *call_dest =3D insn_call_dest(insn); - - if (call_dest) - checksum_update(func, insn, call_dest->demangled_name, - strlen(call_dest->demangled_name)); - goto alts; - } - - sym =3D reloc->sym; - offset =3D arch_insn_adjusted_addend(insn, reloc); - - if (is_string_sec(sym->sec)) { - char *str; - - str =3D sym->sec->data->d_buf + sym->offset + offset; - checksum_update(func, insn, str, strlen(str)); - goto alts; - } - - if (is_sec_sym(sym)) { - sym =3D find_symbol_containing(reloc->sym->sec, offset); - if (!sym) - goto alts; - - offset -=3D sym->offset; - } - - checksum_update(func, insn, sym->demangled_name, strlen(sym->demangled_na= me)); - checksum_update(func, insn, &offset, sizeof(offset)); - -alts: - for (alt =3D insn->alts; alt; alt =3D alt->next) { - struct alt_group *alt_group =3D alt->insn->alt_group; - - /* Prevent __ex_table recursion, e.g. LOAD_SEGMENT() */ - if (in_alt) - break; - in_alt =3D true; - - checksum_update(func, insn, &alt->type, sizeof(alt->type)); - - if (alt_group && alt_group->orig_group) { - struct instruction *alt_insn; - - checksum_update(func, insn, &alt_group->feature, sizeof(alt_group->feat= ure)); - - for (alt_insn =3D alt->insn; alt_insn; alt_insn =3D next_insn_same_sec(= file, alt_insn)) { - checksum_update_insn(file, func, alt_insn); - if (!alt_group->last_insn || alt_insn =3D=3D alt_group->last_insn) - break; - } - } else { - checksum_update_insn(file, func, alt->insn); - } - - in_alt =3D false; - } -} - -static int calculate_checksums(struct objtool_file *file) -{ - struct instruction *insn; - struct symbol *func; - - if (checksum_debug_init(file)) - return -1; - - for_each_sym(file->elf, func) { - /* - * Skip cold subfunctions and aliases: they share the - * parent's checksum via func_for_each_insn() which - * follows func->cfunc into the cold subfunction. - */ - if (!is_func_sym(func) || is_cold_func(func) || - is_alias_sym(func) || !func->len) - continue; - - checksum_init(func); - - func_for_each_insn(file, func, insn) - checksum_update_insn(file, func, insn); - - checksum_finish(func); - } - return 0; -} -#endif /* BUILD_KLP */ - static int validate_branch(struct objtool_file *file, struct symbol *func, struct instruction *insn, struct insn_state state); static int do_validate_branch(struct objtool_file *file, struct symbol *fu= nc, diff --git a/tools/objtool/include/objtool/check.h b/tools/objtool/include/= objtool/check.h index 6489e52ea2f2..eea64728d39b 100644 --- a/tools/objtool/include/objtool/check.h +++ b/tools/objtool/include/objtool/check.h @@ -144,6 +144,12 @@ struct instruction *find_insn(struct objtool_file *fil= e, struct section *sec, unsigned long offset); =20 struct instruction *next_insn_same_sec(struct objtool_file *file, struct i= nstruction *insn); +struct instruction *next_insn_same_func(struct objtool_file *file, struct = instruction *insn); + +#define func_for_each_insn(file, func, insn) \ + for (insn =3D find_insn(file, func->sec, func->offset); \ + insn; \ + insn =3D next_insn_same_func(file, insn)) =20 #define sec_for_each_insn(file, _sec, insn) \ for (insn =3D find_insn(file, _sec, 0); \ diff --git a/tools/objtool/include/objtool/checksum.h b/tools/objtool/inclu= de/objtool/checksum.h index 3f25df90305d..be4eb7dfe6f2 100644 --- a/tools/objtool/include/objtool/checksum.h +++ b/tools/objtool/include/objtool/checksum.h @@ -31,9 +31,13 @@ static inline void checksum_finish(struct symbol *func) } } =20 +int calculate_checksums(struct objtool_file *file); +int create_sym_checksum_section(struct objtool_file *file); + #else /* !BUILD_KLP */ =20 static inline int calculate_checksums(struct objtool_file *file) { return = -ENOSYS; } +static inline int create_sym_checksum_section(struct objtool_file *file) {= return -EINVAL; } =20 #endif /* !BUILD_KLP */ =20 diff --git a/tools/objtool/include/objtool/klp.h b/tools/objtool/include/ob= jtool/klp.h index e32e5e8bc631..6f60cf05db86 100644 --- a/tools/objtool/include/objtool/klp.h +++ b/tools/objtool/include/objtool/klp.h @@ -29,6 +29,7 @@ struct klp_reloc { u32 type; }; =20 +int cmd_klp_checksum(int argc, const char **argv); int cmd_klp_diff(int argc, const char **argv); int cmd_klp_post_link(int argc, const char **argv); =20 diff --git a/tools/objtool/klp-checksum.c b/tools/objtool/klp-checksum.c new file mode 100644 index 000000000000..e4a910f3211c --- /dev/null +++ b/tools/objtool/klp-checksum.c @@ -0,0 +1,253 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +static int checksum_debug_init(struct objtool_file *file) +{ + char *dup, *s; + + if (!opts.debug_checksum) + return 0; + + dup =3D strdup(opts.debug_checksum); + if (!dup) { + ERROR_GLIBC("strdup"); + return -1; + } + + s =3D dup; + while (*s) { + bool found =3D false; + struct symbol *sym; + char *comma; + + comma =3D strchr(s, ','); + if (comma) + *comma =3D '\0'; + + for_each_sym_by_name(file->elf, s, sym) { + if (!is_func_sym(sym)) + continue; + sym->debug_checksum =3D 1; + found =3D true; + } + + if (!found) + WARN("--debug-checksum: can't find '%s'", s); + + if (!comma) + break; + + s =3D comma + 1; + } + + free(dup); + return 0; +} + +static void checksum_update_insn(struct objtool_file *file, struct symbol = *func, + struct instruction *insn) +{ + struct reloc *reloc =3D insn_reloc(file, insn); + struct alternative *alt; + unsigned long offset; + struct symbol *sym; + static bool in_alt; + + if (insn->fake) + return; + + checksum_update(func, insn, insn->sec->data->d_buf + insn->offset, insn->= len); + + if (!reloc) { + struct symbol *call_dest =3D insn_call_dest(insn); + + if (call_dest) + checksum_update(func, insn, call_dest->demangled_name, + strlen(call_dest->demangled_name)); + goto alts; + } + + sym =3D reloc->sym; + offset =3D arch_insn_adjusted_addend(insn, reloc); + + if (is_string_sec(sym->sec)) { + char *str; + + str =3D sym->sec->data->d_buf + sym->offset + offset; + checksum_update(func, insn, str, strlen(str)); + goto alts; + } + + if (is_sec_sym(sym)) { + sym =3D find_symbol_containing(reloc->sym->sec, offset); + if (!sym) + goto alts; + + offset -=3D sym->offset; + } + + checksum_update(func, insn, sym->demangled_name, strlen(sym->demangled_na= me)); + checksum_update(func, insn, &offset, sizeof(offset)); + +alts: + for (alt =3D insn->alts; alt; alt =3D alt->next) { + struct alt_group *alt_group =3D alt->insn->alt_group; + + /* Prevent __ex_table recursion, e.g. LOAD_SEGMENT() */ + if (in_alt) + break; + in_alt =3D true; + + checksum_update(func, insn, &alt->type, sizeof(alt->type)); + + if (alt_group && alt_group->orig_group) { + struct instruction *alt_insn; + + checksum_update(func, insn, &alt_group->feature, sizeof(alt_group->feat= ure)); + + for (alt_insn =3D alt->insn; alt_insn; alt_insn =3D next_insn_same_sec(= file, alt_insn)) { + checksum_update_insn(file, func, alt_insn); + if (!alt_group->last_insn || alt_insn =3D=3D alt_group->last_insn) + break; + } + } else { + checksum_update_insn(file, func, alt->insn); + } + + in_alt =3D false; + } +} + +int calculate_checksums(struct objtool_file *file) +{ + struct instruction *insn; + struct symbol *func; + + if (checksum_debug_init(file)) + return -1; + + for_each_sym(file->elf, func) { + /* + * Skip cold subfunctions and aliases: they share the + * parent's checksum via func_for_each_insn() which + * follows func->cfunc into the cold subfunction. + */ + if (!is_func_sym(func) || is_cold_func(func) || + is_alias_sym(func) || !func->len) + continue; + + checksum_init(func); + + func_for_each_insn(file, func, insn) + checksum_update_insn(file, func, insn); + + checksum_finish(func); + } + return 0; +} + +int create_sym_checksum_section(struct objtool_file *file) +{ + struct section *sec; + struct symbol *sym; + unsigned int idx =3D 0; + struct sym_checksum *checksum; + size_t entsize =3D sizeof(struct sym_checksum); + + sec =3D find_section_by_name(file->elf, ".discard.sym_checksum"); + if (sec) { + if (!opts.dryrun) + WARN("file already has .discard.sym_checksum section, skipping"); + + return 0; + } + + for_each_sym(file->elf, sym) + if (sym->csum.checksum) + idx++; + + sec =3D elf_create_section_pair(file->elf, ".discard.sym_checksum", entsi= ze, + idx, idx); + if (!sec) + return -1; + + idx =3D 0; + for_each_sym(file->elf, sym) { + if (!sym->csum.checksum) + continue; + + if (!elf_init_reloc(file->elf, sec->rsec, idx, idx * entsize, + sym, 0, R_TEXT64)) + return -1; + + checksum =3D (struct sym_checksum *)sec->data->d_buf + idx; + checksum->addr =3D 0; /* reloc */ + checksum->checksum =3D sym->csum.checksum; + + mark_sec_changed(file->elf, sec, true); + + idx++; + } + + return 0; +} + +static const char * const klp_checksum_usage[] =3D { + "objtool klp checksum [] file.o", + NULL, +}; + +int cmd_klp_checksum(int argc, const char **argv) +{ + struct objtool_file *file; + int ret; + + const struct option options[] =3D { + OPT_STRING(0, "debug-checksum", &opts.debug_checksum, "funcs", "enable c= hecksum debug output"), + OPT_BOOLEAN(0, "dry-run", &opts.dryrun, "don't write modifications"), + OPT_END(), + }; + + argc =3D parse_options(argc, argv, options, klp_checksum_usage, 0); + if (argc !=3D 1) + usage_with_options(klp_checksum_usage, options); + + opts.checksum =3D true; + + objname =3D argv[0]; + + file =3D objtool_open_read(objname); + if (!file) + return 1; + + ret =3D decode_file(file); + if (ret) + goto out; + + ret =3D calculate_checksums(file); + if (ret) + goto out; + + ret =3D create_sym_checksum_section(file); + +out: + free_insns(file); + + if (ret) + return ret; + + if (!opts.dryrun && file->elf->changed && elf_write(file->elf)) + return 1; + + return elf_close(file->elf); +} diff --git a/tools/objtool/klp-diff.c b/tools/objtool/klp-diff.c index 8728dda1e08c..95359ad336bb 100644 --- a/tools/objtool/klp-diff.c +++ b/tools/objtool/klp-diff.c @@ -166,7 +166,7 @@ static int read_sym_checksums(struct elf *elf) =20 sec =3D find_section_by_name(elf, ".discard.sym_checksum"); if (!sec) { - ERROR("'%s' missing .discard.sym_checksum section, file not processed by= 'objtool --checksum'?", + ERROR("'%s' missing .discard.sym_checksum section, file not processed by= 'objtool klp checksum'?", elf->name); return -1; } --=20 2.53.0 From nobody Thu Jun 18 07:54:40 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 081FF2F3632; Fri, 1 May 2026 04:09:10 +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=1777608550; cv=none; b=BT5YIS+YVm1rOOrhNoMPvzdMlHBqaUkepO7WyywGFml2zsGC1A0ihKqqXu0G2nVzt3hVlrELhTCDTn8zUEQW271XSaYxADZkK4AfDhnYRH1cWQu/yynYJ6LruvHi4GP5Ty+CEEYMe6KVj47bfsul+tXMZ9MNWQGF2Vmo7pdqFbE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777608550; c=relaxed/simple; bh=HiI3fx7jbK+AIkSfcmy4WLjZ+5lxWSUpcGfEGZlpvDs=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=N1wFwCXvKAP+nzWHJ79+KjxaqkPdae5/A90Mxxs3+VEguqAGDhSmOgbk2d6+Pyul43NJK9bxVxQ702ulN5O5/DYiFhSIWWLV95wsA+ffTcHGGYl7ALGDOLRtGQYDdI09ACxtC1zfq/EzmQTb1AUB1NsYycA/zxagZAglahmwtsA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=u0Okok9a; 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="u0Okok9a" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 98927C2BCB7; Fri, 1 May 2026 04:09:09 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1777608549; bh=HiI3fx7jbK+AIkSfcmy4WLjZ+5lxWSUpcGfEGZlpvDs=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=u0Okok9a0HHVDs/hwW5AFAlcQN02n0CLq6HACkOraN30wUDGlAgTeznts1nSdylgq 0kUAOeExY4IgVovaLkA+I+ZZgYkEi8HUp5vpS/PrUjlmelN5nkgI9Zucw79lORxlRK NNyq39QUqTHADE4DwXzOYZcr2uRuPv4jG21uNTqH5NQOLTlDGvb1sh5mXfsiNakf98 ul0ZKn2ZEgaUVgeRkJGdw0INrtgHHQKJuSXuLj74Prs1ufTQ8bD936KVNXX9pTy42E HA0rNYBAMDYiVjdUoAPxGmjvUG/F0xqWCxPJb6BdgnoIk2LTFwCSJ6oJEz2FsP8okN 1OwYh/Q2o3K/Q== From: Josh Poimboeuf To: x86@kernel.org Cc: linux-kernel@vger.kernel.org, live-patching@vger.kernel.org, Peter Zijlstra , Joe Lawrence , Song Liu , Miroslav Benes , Petr Mladek Subject: [PATCH v2 42/53] klp-build: Use "objtool klp checksum" subcommand Date: Thu, 30 Apr 2026 21:08:30 -0700 Message-ID: <1c4f6e2a4e0a3490947111970f2d8e884afa2588.1777575752.git.jpoimboe@kernel.org> X-Mailer: git-send-email 2.53.0 In-Reply-To: References: 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" Use the new "objtool klp checksum" subcommand instead of injecting --checksum into every objtool invocation via OBJTOOL_ARGS during the kernel build. This decouples checksum generation from the build, running it in separate post-build passes, making the code (and the patch generation pipeline itself) more modular. Acked-by: Song Liu Signed-off-by: Josh Poimboeuf Reviewed-by: Miroslav Benes --- scripts/livepatch/klp-build | 93 +++++++++++++++++++++++++------------ 1 file changed, 64 insertions(+), 29 deletions(-) diff --git a/scripts/livepatch/klp-build b/scripts/livepatch/klp-build index 34a46bafdaec..8a4b268261a6 100755 --- a/scripts/livepatch/klp-build +++ b/scripts/livepatch/klp-build @@ -37,10 +37,12 @@ OBJTOOL=3D"$PWD/tools/objtool/objtool" CONFIG=3D"$PWD/.config" TMP_DIR=3D"$PWD/klp-tmp" =20 -ORIG_DIR=3D"$TMP_DIR/orig" -PATCHED_DIR=3D"$TMP_DIR/patched" -DIFF_DIR=3D"$TMP_DIR/diff" -KMOD_DIR=3D"$TMP_DIR/kmod" +ORIG_DIR=3D"$TMP_DIR/1-orig" +PATCHED_DIR=3D"$TMP_DIR/2-patched" +ORIG_CSUM_DIR=3D"$TMP_DIR/3-checksum-orig" +PATCHED_CSUM_DIR=3D"$TMP_DIR/3-checksum-patched" +DIFF_DIR=3D"$TMP_DIR/4-diff" +KMOD_DIR=3D"$TMP_DIR/5-kmod" =20 STASH_DIR=3D"$TMP_DIR/stash" TIMESTAMP=3D"$TMP_DIR/timestamp" @@ -136,10 +138,11 @@ Options: Advanced Options: -d, --debug Show symbol/reloc cloning decisions -S, --short-circuit=3DSTEP Start at build step (requires prior --keep-t= mp) - 1|orig Build original kernel (default) - 2|patched Build patched kernel - 3|diff Diff objects - 4|kmod Build patch module + 1|orig Build original kernel (default) + 2|patched Build patched kernel + 3|checksum Generate checksums + 4|diff Diff objects + 5|kmod Build patch module -T, --keep-tmp Preserve tmp dir on exit =20 EOF @@ -203,10 +206,11 @@ process_args() { [[ ! -d "$TMP_DIR" ]] && die "--short-circuit requires preserved klp-t= mp dir" keep_tmp=3D1 case "$2" in - 1 | orig) SHORT_CIRCUIT=3D1; ;; - 2 | patched) SHORT_CIRCUIT=3D2; ;; - 3 | diff) SHORT_CIRCUIT=3D3; ;; - 4 | mod) SHORT_CIRCUIT=3D4; ;; + 1 | orig) SHORT_CIRCUIT=3D1; ;; + 2 | patched) SHORT_CIRCUIT=3D2; ;; + 3 | checksum) SHORT_CIRCUIT=3D3; ;; + 4 | diff) SHORT_CIRCUIT=3D4; ;; + 5 | kmod) SHORT_CIRCUIT=3D5; ;; *) die "invalid short-circuit step '$2'" ;; esac shift 2 @@ -513,11 +517,8 @@ clean_kernel() { build_kernel() { local build=3D"$1" local log=3D"$TMP_DIR/build.log" - local objtool_args=3D() local cmd=3D() =20 - objtool_args=3D("--checksum") - cmd=3D("make") =20 # When a patch to a kernel module references a newly created unexported @@ -544,7 +545,6 @@ build_kernel() { fi cmd+=3D("-j$JOBS") cmd+=3D("KCFLAGS=3D-ffunction-sections -fdata-sections") - cmd+=3D("OBJTOOL_ARGS=3D${objtool_args[*]}") cmd+=3D("vmlinux") cmd+=3D("modules") =20 @@ -574,7 +574,7 @@ copy_orig_objects() { =20 find_objects | mapfile -t files =20 - xtrace_save "copying orig objects" + xtrace_save "copying original objects" for _file in "${files[@]}"; do local rel_file=3D"${_file/.ko/.o}" local file=3D"$PWD/$rel_file" @@ -630,6 +630,35 @@ copy_patched_objects() { mv -f "$TMP_DIR/build.log" "$PATCHED_DIR" } =20 +# Copy .o files to a separate directory and run "objtool klp checksum" on = each +# copy. The checksums are written to a .discard.sym_checksum section. +# +# If match_dir is given, only process files which also exist there. +generate_checksums() { + local src_dir=3D"$1" + local dest_dir=3D"$2" + local match_dir=3D"${3:-}" + local files=3D() + local file + + rm -rf "$dest_dir" + mkdir -p "$dest_dir" + + find "$src_dir" -type f -name "*.o" | mapfile -t files + for file in "${files[@]}"; do + local rel=3D"${file#"$src_dir"/}" + local dest=3D"$dest_dir/$rel" + + [[ -n "$match_dir" && ! -f "$match_dir/$rel" ]] && continue + + mkdir -p "$(dirname "$dest")" + cp -f "$file" "$dest" + "$SRC/tools/objtool/objtool" klp checksum "$dest" + done + + touch "$dest_dir/.complete" +} + # Diff changed objects, writing output object to $DIFF_DIR diff_objects() { local log=3D"$KLP_DIFF_LOG" @@ -639,16 +668,16 @@ diff_objects() { rm -rf "$DIFF_DIR" mkdir -p "$DIFF_DIR" =20 - find "$PATCHED_DIR" -type f -name "*.o" | mapfile -t files + find "$PATCHED_CSUM_DIR" -type f -name "*.o" | mapfile -t files [[ ${#files[@]} -eq 0 ]] && die "no changes detected" =20 [[ -v DEBUG_CLONE ]] && opts=3D("--debug") =20 # Diff all changed objects for file in "${files[@]}"; do - local rel_file=3D"${file#"$PATCHED_DIR"/}" + local rel_file=3D"${file#"$PATCHED_CSUM_DIR"/}" local orig_file=3D"$rel_file" - local patched_file=3D"$PATCHED_DIR/$rel_file" + local patched_file=3D"$PATCHED_CSUM_DIR/$rel_file" local out_file=3D"$DIFF_DIR/$rel_file" local filter=3D() local cmd=3D() @@ -672,7 +701,7 @@ diff_objects() { fi =20 ( - cd "$ORIG_DIR" + cd "$ORIG_CSUM_DIR" [[ -v VERBOSE ]] && echo "${cmd[@]}" "${cmd[@]}" \ 1> >(tee -a "$log") \ @@ -682,9 +711,9 @@ diff_objects() { done } =20 -# For each changed object, run objtool with --debug-checksum to get the -# per-instruction checksums, and then diff those to find the first changed -# instruction for each function. +# For each changed object, run "objtool klp checksum" with --debug-checksu= m to +# get the per-instruction checksums, and then diff those to find the first +# changed instruction for each function. diff_checksums() { local orig_log=3D"$ORIG_DIR/checksum.log" local patched_log=3D"$PATCHED_DIR/checksum.log" @@ -709,8 +738,7 @@ diff_checksums() { done =20 cmd=3D("$OBJTOOL") - cmd+=3D("--checksum") - cmd+=3D("--link") + cmd+=3D("klp" "checksum") cmd+=3D("--dry-run") =20 for file in "${!funcs[@]}"; do @@ -719,11 +747,11 @@ diff_checksums() { ( cd "$ORIG_DIR" "${cmd[@]}" "$opt" "$file" &> "$orig_log" || \ - ( cat "$orig_log" >&2; die "objtool --debug-checksum failed" ) + ( cat "$orig_log" >&2; die "objtool klp checksum failed" ) =20 cd "$PATCHED_DIR" "${cmd[@]}" "$opt" "$file" &> "$patched_log" || \ - ( cat "$patched_log" >&2; die "objtool --debug-checksum failed" ) + ( cat "$patched_log" >&2; die "objtool klp checksum failed" ) ) =20 for func in ${funcs[$file]}; do @@ -861,6 +889,13 @@ if (( SHORT_CIRCUIT <=3D 2 )); then fi =20 if (( SHORT_CIRCUIT <=3D 3 )); then + status "Generating original checksums" + generate_checksums "$ORIG_DIR" "$ORIG_CSUM_DIR" "$PATCHED_DIR" + status "Generating patched checksums" + generate_checksums "$PATCHED_DIR" "$PATCHED_CSUM_DIR" +fi + +if (( SHORT_CIRCUIT <=3D 4 )); then status "Diffing objects" diff_objects if [[ -v DIFF_CHECKSUM ]]; then @@ -869,7 +904,7 @@ if (( SHORT_CIRCUIT <=3D 3 )); then fi fi =20 -if (( SHORT_CIRCUIT <=3D 4 )); then +if (( SHORT_CIRCUIT <=3D 5 )); then status "Building patch module: $OUTFILE" build_patch_module fi --=20 2.53.0 From nobody Thu Jun 18 07:54:40 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 747723612E2; Fri, 1 May 2026 04:09:10 +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=1777608550; cv=none; b=hbykSWWD8/rr7y9f4mdvUL7yNv71SJQW3UQGl+/88n23SFm1hVeojQiDAKylbowVHMAIt2Ifyzkwr72MvcqcWbETTYGf26mXNC+X6zmsqvZIis1EiZYtWawec2KeZqUualtjN1aBTCz8SlC3i4xn8OZ48BnW8SOeCGmMMWjD7CQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777608550; c=relaxed/simple; bh=4N7t6lLPbZ7r+YTwJIsIBMNFNEnAzrAQ250jpr6o898=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=HxQf2N4fXhCeVQfnb3Xstf9s/prjTTMmI8F+BlEILCxwnjkv46+I9XwGGbC4RcgMlBIHD6tyOhK0K1P2XiKZJYxjSbZsO9tvdkGzyXm90pjfsK5IepnuQpldO0v1/Bqsx5hYgOkVSRFQDfGeBjT4bR4s1o9uPGVE4LGVDDcbnnU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=An+7uNDJ; 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="An+7uNDJ" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 12E79C2BCB8; Fri, 1 May 2026 04:09:10 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1777608550; bh=4N7t6lLPbZ7r+YTwJIsIBMNFNEnAzrAQ250jpr6o898=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=An+7uNDJmwufwqi3pgpGyCP2eCJ+gu2Bg/xYhmwbDUSnH9SkrZ7v9InWuo9wOb4u4 Us5BykwpFbYo1W3PifRsN9U2W7zcSf5zeQNNWLOIK/I8+oU/GFgct3tDgxv0XZPwVJ PbKev/jcyqHsZBFa9DKf0OCB62u4I9z0rDyXIFZpoAm9D10qURCWCmMZoVNIGt0GMP kwUpK66DorTS5yehZQGJIdoPakq/1Z62EejBtrpQf5Dn858EC+v5HyDy0Uc2vJf3PY G2onw1SGrKtgaX0SfcoICkHypG5BYoKrZ/CVRhzvV+5X2FZnfgWBJVlNEGbrmcY22n Hs1vuLWZLhUKQ== From: Josh Poimboeuf To: x86@kernel.org Cc: linux-kernel@vger.kernel.org, live-patching@vger.kernel.org, Peter Zijlstra , Joe Lawrence , Song Liu , Miroslav Benes , Petr Mladek Subject: [PATCH v2 43/53] objtool/klp: Remove "objtool --checksum" Date: Thu, 30 Apr 2026 21:08:31 -0700 Message-ID: <9bf05c10e47f711dc2f3b00d728b725618cec5d0.1777575752.git.jpoimboe@kernel.org> X-Mailer: git-send-email 2.53.0 In-Reply-To: References: 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" The checksum functionality has been moved to "objtool klp checksum" which is now used by klp-build. Remove the now-dead --checksum and --debug-checksum options from the default objtool command. Acked-by: Song Liu Signed-off-by: Josh Poimboeuf --- scripts/livepatch/klp-build | 5 ++++- tools/objtool/builtin-check.c | 17 +---------------- tools/objtool/check.c | 10 ---------- 3 files changed, 5 insertions(+), 27 deletions(-) diff --git a/scripts/livepatch/klp-build b/scripts/livepatch/klp-build index 8a4b268261a6..f8a80ad0f829 100755 --- a/scripts/livepatch/klp-build +++ b/scripts/livepatch/klp-build @@ -275,6 +275,9 @@ validate_config() { [[ "$CONFIG_AS_VERSION" -lt 200000 ]] && \ die "Clang assembler version < 20 not supported" =20 + "$OBJTOOL" klp 2>&1 | command grep -q "not implemented" && \ + die "objtool not built with KLP support; install xxhash-devel/libxxhash-= dev (version >=3D 0.8) and recompile" + return 0 } =20 @@ -653,7 +656,7 @@ generate_checksums() { =20 mkdir -p "$(dirname "$dest")" cp -f "$file" "$dest" - "$SRC/tools/objtool/objtool" klp checksum "$dest" + "$OBJTOOL" klp checksum "$dest" done =20 touch "$dest_dir/.complete" diff --git a/tools/objtool/builtin-check.c b/tools/objtool/builtin-check.c index b780df513715..ec7f10a5ef19 100644 --- a/tools/objtool/builtin-check.c +++ b/tools/objtool/builtin-check.c @@ -73,7 +73,6 @@ static int parse_hacks(const struct option *opt, const ch= ar *str, int unset) =20 static const struct option check_options[] =3D { OPT_GROUP("Actions:"), - OPT_BOOLEAN(0, "checksum", &opts.checksum, "generate per-function check= sums"), OPT_BOOLEAN(0, "cfi", &opts.cfi, "annotate kernel control flow integrit= y (kCFI) function preambles"), OPT_STRING_OPTARG('d', "disas", &opts.disas, "function-pattern", "disass= emble functions", "*"), OPT_CALLBACK_OPTARG('h', "hacks", NULL, NULL, "jump_label,noinstr,skylake= ", "patch toolchain bugs/limitations", parse_hacks), @@ -95,7 +94,6 @@ static const struct option check_options[] =3D { OPT_GROUP("Options:"), OPT_BOOLEAN(0, "backtrace", &opts.backtrace, "unwind on error"), OPT_BOOLEAN(0, "backup", &opts.backup, "create backup (.orig) file on w= arning/error"), - OPT_STRING(0, "debug-checksum", &opts.debug_checksum, "funcs", "enable= checksum debug output"), OPT_BOOLEAN(0, "dry-run", &opts.dryrun, "don't write modifications"), OPT_BOOLEAN(0, "link", &opts.link, "object is a linked object"), OPT_BOOLEAN(0, "module", &opts.module, "object is part of a kernel modu= le"), @@ -165,20 +163,7 @@ static bool opts_valid(void) return false; } =20 -#ifndef BUILD_KLP - if (opts.checksum) { - ERROR("--checksum not supported; install xxhash-devel/libxxhash-dev (ver= sion >=3D 0.8) and recompile"); - return false; - } -#endif - - if (opts.debug_checksum && !opts.checksum) { - ERROR("--debug-checksum requires --checksum"); - return false; - } - - if (opts.checksum || - opts.disas || + if (opts.disas || opts.hack_jump_label || opts.hack_noinstr || opts.ibt || diff --git a/tools/objtool/check.c b/tools/objtool/check.c index 3e5d335d0e29..ae047be919c5 100644 --- a/tools/objtool/check.c +++ b/tools/objtool/check.c @@ -18,7 +18,6 @@ #include #include #include -#include #include =20 #include @@ -4946,15 +4945,6 @@ int check(struct objtool_file *file) if (opts.noabs) warnings +=3D check_abs_references(file); =20 - if (opts.checksum) { - ret =3D calculate_checksums(file); - if (ret) - goto out; - ret =3D create_sym_checksum_section(file); - if (ret) - goto out; - } - if (opts.orc && nr_insns) { ret =3D orc_create(file); if (ret) --=20 2.53.0 From nobody Thu Jun 18 07:54:40 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 E2D95371860; Fri, 1 May 2026 04:09:10 +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=1777608551; cv=none; b=IYxOTljLKfkuGupWNw37J5JyYsYQUmCYx1m3cNmRgJKNw1H9EslSRETkladAdLg6VLinjXyr5mMuSbFOUFdzdnsUENNInJCosRMzYy6OVmNXVIkIHVZ+vXYQPfYTIiWwGuJk+8mh6yMQLg/0W3h9PAABo0Xk7Ir5yifM4DY5zcE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777608551; c=relaxed/simple; bh=skBrr+d0x5OlbzSPiRUmEpwwkkQKh50vJi5udw4p/z4=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=PPikooPbk94xAlfxn0NfK7JzU1sRbsDdTZiDhj5f8NE7qWt6eZ5W5JtSYIzIgOytoGP70tGGxK8d7tv4py1c318D6R5GaR9M8t6FcShzQHSiFvLKO/Ycr0gUZiVUmuAyBqVDqemVXsaCIR1/yVv7WRu3B6C7IFWXqptwEEbPbbo= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=k7DBzBml; 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="k7DBzBml" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 81F25C2BCC6; Fri, 1 May 2026 04:09:10 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1777608550; bh=skBrr+d0x5OlbzSPiRUmEpwwkkQKh50vJi5udw4p/z4=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=k7DBzBmly+j4UDzTMfYvTIabhC7DUTV8tZaJtqq0peOSDZIzmTUHiFMXr/3qeXUk+ uW6cxD8N+/6N1yOiwE/kfbQgDxkRAKkU7FjoJEnspdS8YO3jWuaAnuj/8PS+zYC7xv OwlJFN+roWHEE9sDpsGqr4hc8cEMDRUmpHac8KRh9nCOuWtqge6g9IN57TxK1/tmLo sMwp57+crUzcrnYlGPc6dBwuLcu2HCEnx+TfOOEZmv0cFMnusrjcbe83MZAYO26pj/ tBzjCiOOL7cqqGFuLn3biZFNM+A199yQay9ebcjOOcYjzfmX9cHgRspQ3QppC4RyVB PcVBUd+dhlQHA== From: Josh Poimboeuf To: x86@kernel.org Cc: linux-kernel@vger.kernel.org, live-patching@vger.kernel.org, Peter Zijlstra , Joe Lawrence , Song Liu , Miroslav Benes , Petr Mladek Subject: [PATCH v2 44/53] klp-build: Validate short-circuit prerequisites Date: Thu, 30 Apr 2026 21:08:32 -0700 Message-ID: X-Mailer: git-send-email 2.53.0 In-Reply-To: References: 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" The --short-circuit option implicitly requires that certain directories are already in klp-tmp. Enforce that to prevent confusing errors. Signed-off-by: Josh Poimboeuf --- scripts/livepatch/klp-build | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/scripts/livepatch/klp-build b/scripts/livepatch/klp-build index f8a80ad0f829..3adb2a7fd9c1 100755 --- a/scripts/livepatch/klp-build +++ b/scripts/livepatch/klp-build @@ -437,6 +437,20 @@ do_init() { # builds in pwd. [[ ! "$PWD" -ef "$SCRIPT_DIR/../.." ]] && die "please run from the kernel= root directory" =20 + if (( SHORT_CIRCUIT >=3D 2 )); then + [[ -f "$ORIG_DIR/.complete" ]] || die "-S $SHORT_CIRCUIT requires comple= ted $ORIG_DIR" + fi + if (( SHORT_CIRCUIT >=3D 3 )); then + [[ -f "$PATCHED_DIR/.complete" ]] || die "-S $SHORT_CIRCUIT requires com= pleted $PATCHED_DIR" + fi + if (( SHORT_CIRCUIT >=3D 4 )); then + [[ -f "$ORIG_CSUM_DIR/.complete" ]] || die "-S $SHORT_CIRCUIT requires c= ompleted $ORIG_CSUM_DIR" + [[ -f "$PATCHED_CSUM_DIR/.complete" ]] || die "-S $SHORT_CIRCUIT require= s completed $PATCHED_CSUM_DIR" + fi + if (( SHORT_CIRCUIT >=3D 5 )); then + [[ -f "$DIFF_DIR/.complete" ]] || die "-S $SHORT_CIRCUIT requires comple= ted $DIFF_DIR" + fi + (( SHORT_CIRCUIT <=3D 1 )) && rm -rf "$TMP_DIR" mkdir -p "$TMP_DIR" =20 @@ -593,6 +607,7 @@ copy_orig_objects() { =20 mv -f "$TMP_DIR/build.log" "$ORIG_DIR" touch "$TIMESTAMP" + touch "$ORIG_DIR/.complete" } =20 # Copy all changed objects to $PATCHED_DIR @@ -631,6 +646,7 @@ copy_patched_objects() { (( found =3D=3D 0 )) && die "no changes detected" =20 mv -f "$TMP_DIR/build.log" "$PATCHED_DIR" + touch "$PATCHED_DIR/.complete" } =20 # Copy .o files to a separate directory and run "objtool klp checksum" on = each @@ -712,6 +728,8 @@ diff_objects() { die "objtool klp diff failed" ) done + + touch "$DIFF_DIR/.complete" } =20 # For each changed object, run "objtool klp checksum" with --debug-checksu= m to --=20 2.53.0 From nobody Thu Jun 18 07:54:40 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 39960374192; Fri, 1 May 2026 04:09:11 +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=1777608552; cv=none; b=EDQJkmwIEg/VMrhDW3zg9p/sJCfVvldV7O48dXLMuB94v7NA1guC7x4YIA9c5lWyvyYYXrerpA9lhLqe9aOu6DgDR7JX++WuZBkOUR47RkrFlRte7nytBFW54KnA+Q9B2LwTvBhNw9b3Mnw8nURCMaQQ2UdDA/00eeEx0jR/Th0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777608552; c=relaxed/simple; bh=ZOp4lg30bCe82KO2EegcVeytW9zoOZI2TN07/1MGzQY=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=uRGOvdf1dvljUaDqnVrmGkYfRkBtUGyjoU+hpENTkS+7s9nL76hT/Xbq14TwOyGE+YGTya9rMueybAmpS8GujgPYqx26F93ujs5YSCtLpk1z+l06Yds/d3VPj7y+8hPLrQYdCrdeGI5DJ152Lt8nAW8V71xpSvna6n18U7QBRwg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=BED08QUJ; 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="BED08QUJ" Received: by smtp.kernel.org (Postfix) with ESMTPSA id F1043C2BCB8; Fri, 1 May 2026 04:09:10 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1777608551; bh=ZOp4lg30bCe82KO2EegcVeytW9zoOZI2TN07/1MGzQY=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=BED08QUJMr/JoUNZ9HkaIengOy0/vx2H2zX7ar9L3DO2z4gcvHXWsOIhPBE544Jr3 LbyBtJGWZnleJI4ruFSXGOqk4TlKqZQIiFU3xcyZmsxUR6s4f5fIkBtnib0WsGPsSX nIKF3aKrKe6P335GxSTSU214sl39aDCEXsp6aI7xL7eytmelw/djuiG1iSXum/Asvs 1Eikh10j1BM5DEQ0oG1LGTJECvZsEKXL7SrU2kbkGhWtM1pjODnlL440pV3xpv8r/u DjjDFzgyE77mHdM5+LFXbSgsueGEd0lWP00I6SMNOmj0NnabZknq6Y/bPNZCj3DYtn Nrf8BL7LAcAnw== From: Josh Poimboeuf To: x86@kernel.org Cc: linux-kernel@vger.kernel.org, live-patching@vger.kernel.org, Peter Zijlstra , Joe Lawrence , Song Liu , Miroslav Benes , Petr Mladek Subject: [PATCH v2 45/53] objtool/klp: Calculate object checksums Date: Thu, 30 Apr 2026 21:08:33 -0700 Message-ID: <88ebcc903a3c534f2c7d35b95f62d845105d40af.1777575752.git.jpoimboe@kernel.org> X-Mailer: git-send-email 2.53.0 In-Reply-To: References: 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" Start checksumming data objects in preparation for revamping the correlation algorithm. Signed-off-by: Josh Poimboeuf --- tools/objtool/include/objtool/checksum.h | 44 ++++++++---- tools/objtool/include/objtool/warn.h | 29 ++++---- tools/objtool/klp-checksum.c | 89 +++++++++++++++++++----- tools/objtool/klp-diff.c | 2 +- 4 files changed, 117 insertions(+), 47 deletions(-) diff --git a/tools/objtool/include/objtool/checksum.h b/tools/objtool/inclu= de/objtool/checksum.h index be4eb7dfe6f2..d46293f54716 100644 --- a/tools/objtool/include/objtool/checksum.h +++ b/tools/objtool/include/objtool/checksum.h @@ -6,28 +6,44 @@ =20 #ifdef BUILD_KLP =20 -static inline void checksum_init(struct symbol *func) +static inline void checksum_init(struct symbol *sym) { - if (func && !func->csum.state) { - func->csum.state =3D XXH3_createState(); - XXH3_64bits_reset(func->csum.state); + if (sym && !sym->csum.state) { + sym->csum.state =3D XXH3_createState(); + XXH3_64bits_reset(sym->csum.state); } } =20 -static inline void checksum_update(struct symbol *func, - struct instruction *insn, - const void *data, size_t size) +static inline void __checksum_update(struct symbol *sym, const void *data, + size_t size) { - XXH3_64bits_update(func->csum.state, data, size); - dbg_checksum(func, insn, XXH3_64bits_digest(func->csum.state)); + XXH3_64bits_update(sym->csum.state, data, size); } =20 -static inline void checksum_finish(struct symbol *func) +static inline void __checksum_update_insn(struct symbol *sym, + struct instruction *insn, + const void *data, size_t size) { - if (func && func->csum.state) { - func->csum.checksum =3D XXH3_64bits_digest(func->csum.state); - XXH3_freeState(func->csum.state); - func->csum.state =3D NULL; + __checksum_update(sym, data, size); + dbg_checksum_insn(sym, insn, XXH3_64bits_digest(sym->csum.state)); +} + +static inline void __checksum_update_object(struct symbol *sym, + unsigned long offset, + const char *what, const void *data, + size_t size) +{ + __checksum_update(sym, &offset, sizeof(offset)); + __checksum_update(sym, data, size); + dbg_checksum_object(sym, offset, what, XXH3_64bits_digest(sym->csum.state= )); +} + +static inline void checksum_finish(struct symbol *sym) +{ + if (sym && sym->csum.state) { + sym->csum.checksum =3D XXH3_64bits_digest(sym->csum.state); + XXH3_freeState(sym->csum.state); + sym->csum.state =3D NULL; } } =20 diff --git a/tools/objtool/include/objtool/warn.h b/tools/objtool/include/o= bjtool/warn.h index fa8b7d292e83..595ee8009667 100644 --- a/tools/objtool/include/objtool/warn.h +++ b/tools/objtool/include/objtool/warn.h @@ -130,10 +130,22 @@ static inline void unindent(int *unused) { indent--; } objname ? ": " : "", \ ##__VA_ARGS__) =20 -#define dbg(args...) \ +#define dbg_checksum_insn(func, insn, checksum) \ ({ \ - if (unlikely(debug)) \ - __dbg(args); \ + if (unlikely(func->debug_checksum)) { \ + char *insn_off =3D offstr(insn->sec, insn->offset); \ + __dbg("checksum: %s(): %s %016llx", \ + func->name, insn_off, (unsigned long long)checksum);\ + free(insn_off); \ + } \ +}) + +#define dbg_checksum_object(sym, offset, what, checksum) \ +({ \ + if (unlikely(sym->debug_checksum)) \ + __dbg("checksum: %s+0x%lx: %s %016llx", \ + sym->name, offset, what, \ + (unsigned long long)checksum); \ }) =20 #define __dbg_indent(format, ...) \ @@ -147,15 +159,4 @@ static inline void unindent(int *unused) { indent--; } __dbg_indent(args); \ indent++ =20 -#define dbg_checksum(func, insn, checksum) \ -({ \ - if (unlikely(insn->sym && insn->sym->pfunc && \ - insn->sym->pfunc->debug_checksum)) { \ - char *insn_off =3D offstr(insn->sec, insn->offset); \ - __dbg("checksum: %s %s %016llx", \ - func->name, insn_off, (unsigned long long)checksum);\ - free(insn_off); \ - } \ -}) - #endif /* _WARN_H */ diff --git a/tools/objtool/klp-checksum.c b/tools/objtool/klp-checksum.c index e4a910f3211c..19653dbe109d 100644 --- a/tools/objtool/klp-checksum.c +++ b/tools/objtool/klp-checksum.c @@ -35,7 +35,7 @@ static int checksum_debug_init(struct objtool_file *file) *comma =3D '\0'; =20 for_each_sym_by_name(file->elf, s, sym) { - if (!is_func_sym(sym)) + if (!is_func_sym(sym) && !is_object_sym(sym)) continue; sym->debug_checksum =3D 1; found =3D true; @@ -66,14 +66,14 @@ static void checksum_update_insn(struct objtool_file *f= ile, struct symbol *func, if (insn->fake) return; =20 - checksum_update(func, insn, insn->sec->data->d_buf + insn->offset, insn->= len); + __checksum_update_insn(func, insn, insn->sec->data->d_buf + insn->offset,= insn->len); =20 if (!reloc) { struct symbol *call_dest =3D insn_call_dest(insn); =20 if (call_dest) - checksum_update(func, insn, call_dest->demangled_name, - strlen(call_dest->demangled_name)); + __checksum_update_insn(func, insn, call_dest->demangled_name, + strlen(call_dest->demangled_name)); goto alts; } =20 @@ -84,7 +84,7 @@ static void checksum_update_insn(struct objtool_file *fil= e, struct symbol *func, char *str; =20 str =3D sym->sec->data->d_buf + sym->offset + offset; - checksum_update(func, insn, str, strlen(str)); + __checksum_update_insn(func, insn, str, strlen(str)); goto alts; } =20 @@ -96,8 +96,9 @@ static void checksum_update_insn(struct objtool_file *fil= e, struct symbol *func, offset -=3D sym->offset; } =20 - checksum_update(func, insn, sym->demangled_name, strlen(sym->demangled_na= me)); - checksum_update(func, insn, &offset, sizeof(offset)); + __checksum_update_insn(func, insn, sym->demangled_name, + strlen(sym->demangled_name)); + __checksum_update_insn(func, insn, &offset, sizeof(offset)); =20 alts: for (alt =3D insn->alts; alt; alt =3D alt->next) { @@ -108,12 +109,13 @@ static void checksum_update_insn(struct objtool_file = *file, struct symbol *func, break; in_alt =3D true; =20 - checksum_update(func, insn, &alt->type, sizeof(alt->type)); + __checksum_update_insn(func, insn, &alt->type, + sizeof(alt->type)); =20 if (alt_group && alt_group->orig_group) { struct instruction *alt_insn; =20 - checksum_update(func, insn, &alt_group->feature, sizeof(alt_group->feat= ure)); + __checksum_update_insn(func, insn, &alt_group->feature,sizeof(alt_group= ->feature)); =20 for (alt_insn =3D alt->insn; alt_insn; alt_insn =3D next_insn_same_sec(= file, alt_insn)) { checksum_update_insn(file, func, alt_insn); @@ -128,31 +130,82 @@ static void checksum_update_insn(struct objtool_file = *file, struct symbol *func, } } =20 +static void checksum_update_object(struct objtool_file *file, struct symbo= l *sym) +{ + struct reloc *reloc; + + __checksum_update_object(sym, 0, "len", &sym->len, sizeof(sym->len)); + + if (sym->sec->data->d_buf) + __checksum_update_object(sym, 0, "data", + sym->sec->data->d_buf + sym->offset, + sym->len); + + sym_for_each_reloc(file->elf, sym, reloc) { + unsigned long sym_offset =3D reloc_offset(reloc) - sym->offset; + struct symbol *target =3D reloc->sym; + s64 offset; + + offset =3D reloc_addend(reloc); + + if (is_string_sec(target->sec)) { + char *str; + + str =3D target->sec->data->d_buf + target->offset + offset; + __checksum_update_object(sym, sym_offset, + "reloc string", str, strlen(str)); + continue; + } + + if (is_sec_sym(target)) { + target =3D find_symbol_containing(reloc->sym->sec, offset); + if (!target) + continue; + + offset -=3D target->offset; + } + + __checksum_update_object(sym, sym_offset, "reloc name", + target->demangled_name, + strlen(target->demangled_name)); + __checksum_update_object(sym, sym_offset, "reloc addend", + &offset, sizeof(offset)); + } +} + int calculate_checksums(struct objtool_file *file) { struct instruction *insn; - struct symbol *func; + struct symbol *sym; =20 if (checksum_debug_init(file)) return -1; =20 - for_each_sym(file->elf, func) { + for_each_sym(file->elf, sym) { + /* * Skip cold subfunctions and aliases: they share the * parent's checksum via func_for_each_insn() which * follows func->cfunc into the cold subfunction. */ - if (!is_func_sym(func) || is_cold_func(func) || - is_alias_sym(func) || !func->len) + if (is_cold_func(sym) || is_alias_sym(sym) || !sym->len || + !sym->sec || !sym->sec->data) continue; =20 - checksum_init(func); + if (is_func_sym(sym)) { + checksum_init(sym); + func_for_each_insn(file, sym, insn) + checksum_update_insn(file, sym, insn); + checksum_finish(sym); =20 - func_for_each_insn(file, func, insn) - checksum_update_insn(file, func, insn); + } else if (is_object_sym(sym)) { + checksum_init(sym); + checksum_update_object(file, sym); + checksum_finish(sym); + } =20 - checksum_finish(func); } + return 0; } =20 @@ -213,7 +266,7 @@ int cmd_klp_checksum(int argc, const char **argv) int ret; =20 const struct option options[] =3D { - OPT_STRING(0, "debug-checksum", &opts.debug_checksum, "funcs", "enable c= hecksum debug output"), + OPT_STRING(0, "debug-checksum", &opts.debug_checksum, "syms", "enable ch= ecksum debug output"), OPT_BOOLEAN(0, "dry-run", &opts.dryrun, "don't write modifications"), OPT_END(), }; diff --git a/tools/objtool/klp-diff.c b/tools/objtool/klp-diff.c index 95359ad336bb..5f13d759e02f 100644 --- a/tools/objtool/klp-diff.c +++ b/tools/objtool/klp-diff.c @@ -201,7 +201,7 @@ static int read_sym_checksums(struct elf *elf) return -1; } =20 - if (is_func_sym(sym)) + if (is_func_sym(sym) || is_object_sym(sym)) sym->csum.checksum =3D sym_checksum->checksum; } =20 --=20 2.53.0 From nobody Thu Jun 18 07:54:40 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 6EAFA37EFF1; Fri, 1 May 2026 04:09:12 +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=1777608556; cv=none; b=nYwYM+LN2rvjIczeq1Wt91ZCqrWpqbygdhsu0NmcV6Kx/Lb30YOJWlNkSkEKBvFaerxR+ibasNq0RoMJkBT+Kew/YHA1CB8NuWUHEvavMoDFqjFn+JK/oWr00MuCKVauD9wZnoE3mTYj9nCQQ/2vVAoeuM1PukXV3qQ92RpcQ8E= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777608556; c=relaxed/simple; bh=IElXgJmc6dJDI5FQQsbAZ9PJdfM+WYcWwhnrQjlOoRM=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=jTMCmMQWAopLhrAqWR1rG+ajsCdtHUA/zMoFNblKv4l8Y2JyqWK/1eZX3p+o5432B585ScNHX8jgEf8IT82r+aascji7OMNkYYAy7ABJTcTArtbcoatxdIC0Nz8unVvROxvvpoRfAGq5LjJOIjfTBB148u+ZptvE9/DFumeBO6U= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=Hf4JCWZ+; 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="Hf4JCWZ+" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 74424C2BCB7; Fri, 1 May 2026 04:09:11 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1777608552; bh=IElXgJmc6dJDI5FQQsbAZ9PJdfM+WYcWwhnrQjlOoRM=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=Hf4JCWZ+M4swIr8ONTmavLUEGJk6fqVLsMPoE0uarZWXuBXDu3WeQ902+GNhwU2no tgze/wUXqUkypF+byF1GJjLI3wXsJ7ttdwBrKbd660cMRGTdGOv0u5ckp+jASJU/NZ pi+7fzmWWnpGgbpCJpe0ixDLSTVRDqKwKO8lB3kTV2GwBsPLo0Y4x7FgQXLNV6J6R7 UamCB2jySOgFOOGR+mXMpz7/IxOoZLPV7zMdiYijRPrLZur6tezhsH96eV4cLdaq8n was3VQZ6i2zQCvlhoh+1wq57yHKUXdBFYaTfx1eBTxnfqUc/FDR5Wy5tGwvaahJ3NR W+kk6Ne2rIFZA== From: Josh Poimboeuf To: x86@kernel.org Cc: linux-kernel@vger.kernel.org, live-patching@vger.kernel.org, Peter Zijlstra , Joe Lawrence , Song Liu , Miroslav Benes , Petr Mladek Subject: [PATCH v2 46/53] objtool/klp: Rewrite symbol correlation algorithm Date: Thu, 30 Apr 2026 21:08:34 -0700 Message-ID: <27fcb5a17cc7b6821d8b1c4b9812ebb5b4ee6a5c.1777575752.git.jpoimboe@kernel.org> X-Mailer: git-send-email 2.53.0 In-Reply-To: References: 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" Rewrite the symbol correlation code, using a tiered list of deterministic strategies in a loop. For duplicately named symbols, each tier applies a filter with the goal of finding a 1:1 deterministic correlation between the original and patched version of the symbol. The three matching strategies are: find_twin(): A funnel of progressively tighter filters. Candidates with the same demangled name are counted at four levels: name, scope (local-vs-global), file (strict file association), and checksum (unchanged functions). The widest level that yields a 1:1 match wins, narrower levels are only tried when the wider level is ambiguous. find_twin_suffixed(): Uses already-correlated LLVM symbol pairs to map .llvm. suffixes from orig to patched. Because all promoted symbols from the same TU share the same hash, one correlated pair seeds the mapping for the entire TU. find_twin_positional(): Last resort, matches symbols by position among same-named candidates, similar to livepatch sympos. Used for data objects like __quirk variables where no deterministic filter can distinguish the candidates. Overall this works much better than the existing algorithm, particularly with LTO kernels. Signed-off-by: Josh Poimboeuf --- tools/objtool/klp-diff.c | 521 +++++++++++++++++++++++++++++---------- 1 file changed, 385 insertions(+), 136 deletions(-) diff --git a/tools/objtool/klp-diff.c b/tools/objtool/klp-diff.c index 5f13d759e02f..a9c993298b82 100644 --- a/tools/objtool/klp-diff.c +++ b/tools/objtool/klp-diff.c @@ -408,78 +408,358 @@ static bool dont_correlate(struct symbol *sym) is_special_section_aux(sym->sec); } =20 -/* - * When there is no full name match, try match demangled_name. This would - * match original foo.llvm.123 to patched foo.llvm.456. - * - * Note that, in very rare cases, it is possible to have multiple - * foo.llvm. in the same kernel. When this happens, report error and - * fail the diff. - */ -static int find_global_symbol_by_demangled_name(struct elf *elf, struct sy= mbol *sym, - struct symbol **out_sym) +static const char *llvm_suffix(const char *name) { - struct symbol *sym2, *result =3D NULL; - int count =3D 0; + return strstr(name, ".llvm."); +} =20 - for_each_sym_by_demangled_name(elf, sym->demangled_name, sym2) { - if (is_local_sym(sym2) || sym2->twin) +static bool is_llvm_sym(struct symbol *sym) +{ + return llvm_suffix(sym->name); +} + +/* + * Determine if two symbols have compatible source file origins: + * + * - If both symbols are local, only return true if they belong to the s= ame + * ELF file symbol. + * + * - If both symbols are global, always return true, as globals don't ha= ve + * file associations. + * + * - If they have different scopes, also return true, as the patch might= have + * changed the symbol's scope. + * + * Works for both same-ELF (direct pointer compare) and cross-ELF + * (compare via file->twin) cases. + */ +static bool maybe_same_file(struct symbol *sym1, struct symbol *sym2) +{ + if (!sym1->file || !sym2->file) + return true; + if (sym1->file =3D=3D sym2->file) + return true; + return sym1->file->twin =3D=3D sym2->file; +} + +/* + * Similar to maybe_same_file(), but strict: no scope changes allowed. + * + * Works for both same-ELF (direct pointer compare) and cross-ELF + * (compare via file->twin) cases. + */ +static bool same_file(struct symbol *sym1, struct symbol *sym2) +{ + if (llvm_suffix(sym1->name) && llvm_suffix(sym2->name)) + return true; + if (!sym1->file && !sym2->file) + return true; + if (!sym1->file || !sym2->file) + return false; + if (sym1->file =3D=3D sym2->file) + return true; + return sym1->file->twin =3D=3D sym2->file; +} + +/* + * Is it a local symbol, or at least was it local in the translation unit + * before LLVM promoted it? + */ +static bool is_tu_local_sym(struct symbol *sym) +{ + return is_local_sym(sym) || is_llvm_sym(sym); +} + +/* + * Try to find sym1's twin in patched using deterministic matching. + * + * Multiple symbols can share a demangled name (e.g., static functions in + * different TUs). This function counts same-named candidates through a + * funnel of progressively tighter filters. Each level is a strict subset + * of the previous one. + * + * The widest level that yields a 1:1 match wins. Narrower levels are only + * needed when the wider level is ambiguous (count > 1). + * + * Candidates are pre-filtered by maybe_same_file(), which narrows most + * local symbols to their own TU. For example, 19 different static + * type_show() functions across vmlinux.o each see only one candidate after + * pre-filtering, so they match immediately at Level 1. + * + * Level 1 (name): Works when the demangled name is unique after + * pre-filtering. Handles most symbols: unique globals like copy_signal(), + * or per-TU locals like pcspkr_probe(). + * + * Level 2 (scope): Filters by local-vs-global (TU-local-vs-not). Example: + * parse_header() exists as both a static and a global function. Level 1 + * sees both (same demangled name), but Level 2 separates them by scope. + * + * Level 3 (file): Strict file matching via same_file(), which rejects sco= pe + * changes. Example: LLVM-promoted foo.llvm.12345 (global, no FILE symbol) + * vs genuine local foo (has FILE symbol). Both are TU-local so Level 2 + * can't distinguish them, but same_file() rejects the pair because one has + * a file association and the other doesn't. + * + * Level 4 (checksum): Distinguishes by function checksum. Example: + * usb_devnode.llvm.AAA and usb_devnode.llvm.BBB are two LLVM-promoted + * functions from different TUs with the same demangled name. After a TU + * change, the .llvm. hashes change but the functions themselves may be + * unchanged. Level 4 matches each to the patched candidate with the + * same checksum. + */ +static struct symbol *find_twin(struct elfs *e, struct symbol *sym1) +{ + struct symbol *name_last =3D NULL, *scope_last =3D NULL, + *file_last =3D NULL, *csum_last =3D NULL; + unsigned int name_orig =3D 0, name_patched =3D 0; + unsigned int scope_orig =3D 0, scope_patched =3D 0; + unsigned int file_orig =3D 0, file_patched =3D 0; + unsigned int csum_orig =3D 0, csum_patched =3D 0; + struct symbol *sym2, *match =3D NULL; + + /* Count orig candidates */ + for_each_sym_by_demangled_name(e->orig, sym1->demangled_name, sym2) { + if (sym2->twin || sym1->type !=3D sym2->type || dont_correlate(sym2) || + (!maybe_same_file(sym1, sym2))) continue; =20 - count++; - result =3D sym2; + /* Level 1: name match (widest filter) */ + name_orig++; + + /* Level 2: scope (scope changes allowed) */ + if (is_tu_local_sym(sym1) !=3D is_tu_local_sym(sym2)) + continue; + scope_orig++; + + /* Level 3: file (scope changes disallowed) */ + if (!same_file(sym1, sym2)) + continue; + file_orig++; + + /* Level 4: checksum (unchanged symbols) */ + if (sym1->len !=3D sym2->len || !sym1->csum.checksum || + sym1->csum.checksum !=3D sym2->csum.checksum) + continue; + csum_orig++; } =20 - if (count > 1) { - ERROR("Multiple (%d) correlation candidates for %s", count, sym->name); - return -1; + /* Count patched candidates */ + for_each_sym_by_demangled_name(e->patched, sym1->demangled_name, sym2) { + if (sym2->twin || sym1->type !=3D sym2->type || dont_correlate(sym2) || + !maybe_same_file(sym1, sym2)) + continue; + + /* Level 1 */ + name_patched++; + name_last =3D sym2; + + /* Level 2 */ + if (is_tu_local_sym(sym1) !=3D is_tu_local_sym(sym2)) + continue; + scope_patched++; + scope_last =3D sym2; + + /* Level 3 */ + if (!same_file(sym1, sym2)) + continue; + file_patched++; + file_last =3D sym2; + + /* Level 4 */ + if (sym1->len !=3D sym2->len || !sym1->csum.checksum || + sym1->csum.checksum !=3D sym2->csum.checksum) + continue; + csum_patched++; + csum_last =3D sym2; + } + + /* Return the widest level that yields a unique (1:1) match */ + if (name_orig =3D=3D 1 && name_patched =3D=3D 1) + match =3D name_last; + else if (scope_orig =3D=3D 1 && scope_patched =3D=3D 1) + match =3D scope_last; + else if (file_orig =3D=3D 1 && file_patched =3D=3D 1) + match =3D file_last; + else if (csum_orig =3D=3D 1 && csum_patched =3D=3D 1) + match =3D csum_last; + + return match; +} + +struct llvm_suffix_pair { + struct hlist_node hash; + const char *orig; + const char *patched; +}; + +static DECLARE_HASHTABLE(suffix_map, 7); + +/* + * Build a mapping of known orig-to-patched LLVM suffixes based on + * already-correlated symbol pairs. All promoted symbols from the same TU + * share the same .llvm. suffix, so one correlated pair seeds the map + * for the entire TU. + */ +static int update_suffix_map(struct elf *elf) +{ + struct llvm_suffix_pair *entry; + struct symbol *sym; + + for_each_sym(elf, sym) { + const char *s1, *s2; + bool found; + + if (!sym->twin) + continue; + + s1 =3D llvm_suffix(sym->name); + s2 =3D llvm_suffix(sym->twin->name); + + if (!s1 || !s2) + continue; + + found =3D false; + hash_for_each_possible(suffix_map, entry, hash, str_hash(s1)) { + if (!strcmp(entry->orig, s1)) { + found =3D true; + break; + } + } + if (found) + continue; + + entry =3D calloc(1, sizeof(*entry)); + if (!entry) { + ERROR_GLIBC("calloc"); + return -1; + } + + entry->orig =3D s1; + entry->patched =3D s2; + hash_add(suffix_map, &entry->hash, str_hash(s1)); } =20 - *out_sym =3D result; return 0; } =20 /* - * For each symbol in the original kernel, find its corresponding "twin" i= n the - * patched kernel. + * Match by translating the symbol's .llvm. suffix through the suffix + * map to find the corresponding hash suffix for the patched object. + * + * Example: In the original kernel, TU drivers/base/core.c contains + * foo.llvm.12345 and bar.llvm.12345 (same TU, same hash). After patching, + * they become foo.llvm.67890 and bar.llvm.67890. If foo was already + * correlated by find_twin() (e.g., unique by name), the suffix map records + * .llvm.12345 -> .llvm.67890. When processing bar.llvm.12345, this + * function looks up .llvm.12345, gets .llvm.67890, constructs the name + * bar.llvm.67890, and finds the match. + */ +static struct symbol *find_twin_suffixed(struct elf *elf, struct symbol *s= ym1) +{ + const char *suffix, *patched_suffix =3D NULL; + struct symbol *sym2, *match =3D NULL; + char name[SYM_NAME_LEN]; + struct llvm_suffix_pair *entry; + int count =3D 0; + + suffix =3D llvm_suffix(sym1->name); + if (!suffix) + return NULL; + + hash_for_each_possible(suffix_map, entry, hash, str_hash(suffix)) { + if (!strcmp(entry->orig, suffix)) { + patched_suffix =3D entry->patched; + break; + } + } + if (!patched_suffix) + return NULL; + + if (snprintf_check(name, SYM_NAME_LEN, "%s%s", + sym1->demangled_name, patched_suffix)) + return NULL; + + for_each_sym_by_name(elf, name, sym2) { + if (sym2->twin || sym1->type !=3D sym2->type || dont_correlate(sym2)) + continue; + count++; + match =3D sym2; + } + + if (count =3D=3D 1) + return match; + + return NULL; +} + +/* + * Last-resort positional matching. + * + * Finds a symbol with the same position in the symbol table among + * same-demangled-name candidates, similar to livepatch sympos. Note that + * LLVM-promoted symbols are globals, which come after locals in the symbol + * table, so we have to be careful not to compare different scopes. + * + * Example: arch/x86/events/intel/core.c defines many __quirk variables via + * X86_MATCH_*() macros. In the symbol table they appear as __quirk.90, + * __quirk.97, __quirk.101, etc., all with demangled name __quirk, same + * scope, and same FILE symbol. No deterministic filter can distinguish + * them, so they're matched by position: the 1st __quirk in orig matches t= he + * 1st in patched, the 2nd matches the 2nd, etc. + * + * This is less deterministic than the other strategies, so it's done last. + */ +static struct symbol *find_twin_positional(struct elfs *e, struct symbol *= sym1) +{ + unsigned int idx_orig =3D 0, idx_patched =3D 0; + unsigned int sym1_pos =3D 0; + struct symbol *sym2, *match =3D NULL; + + for_each_sym_by_demangled_name(e->orig, sym1->demangled_name, sym2) { + if (sym2->twin || sym1->type !=3D sym2->type || dont_correlate(sym2) || + !maybe_same_file(sym1, sym2)) + continue; + if (is_tu_local_sym(sym1) !=3D is_tu_local_sym(sym2) || + is_llvm_sym(sym1) !=3D is_llvm_sym(sym2)) + continue; + if (sym1 =3D=3D sym2) + sym1_pos =3D idx_orig; + idx_orig++; + } + + for_each_sym_by_demangled_name(e->patched, sym1->demangled_name, sym2) { + if (sym2->twin || sym1->type !=3D sym2->type || dont_correlate(sym2) || + !maybe_same_file(sym1, sym2)) + continue; + if (is_tu_local_sym(sym1) !=3D is_tu_local_sym(sym2) || + is_llvm_sym(sym1) !=3D is_llvm_sym(sym2)) + continue; + if (idx_patched =3D=3D sym1_pos) + match =3D sym2; + idx_patched++; + } + + if (idx_orig !=3D idx_patched) + return NULL; + + return match; +} + +/* + * Correlate symbols between the orig and patched objects. This is a + * prerequisite for detecting changed functions, as well as for properly + * translating relocations so they point to the correct symbol. */ static int correlate_symbols(struct elfs *e) { struct symbol *file1_sym, *file2_sym; struct symbol *sym1, *sym2; + bool progress; =20 + /* Correlate FILE symbols */ file1_sym =3D first_file_symbol(e->orig); file2_sym =3D first_file_symbol(e->patched); =20 - /* - * Correlate any locals before the first FILE symbol. This has been - * seen when LTO inexplicably strips the initramfs_data.o FILE symbol - * due to the file only containing data and no code. - */ - for_each_sym(e->orig, sym1) { - if (sym1 =3D=3D file1_sym || !is_local_sym(sym1)) - break; - - if (dont_correlate(sym1)) - continue; - - for_each_sym(e->patched, sym2) { - if (sym2 =3D=3D file2_sym || !is_local_sym(sym2)) - break; - - if (sym2->twin || dont_correlate(sym2)) - continue; - - if (strcmp(sym1->demangled_name, sym2->demangled_name)) - continue; - - sym1->twin =3D sym2; - sym2->twin =3D sym1; - break; - } - } - - /* Correlate locals after the first FILE symbol */ for (; ; file1_sym =3D next_file_symbol(e->orig, file1_sym), file2_sym =3D next_file_symbol(e->patched, file2_sym)) { =20 @@ -503,92 +783,52 @@ static int correlate_symbols(struct elfs *e) =20 file1_sym->twin =3D file2_sym; file2_sym->twin =3D file1_sym; - - sym1 =3D file1_sym; - - for_each_sym_continue(e->orig, sym1) { - if (is_file_sym(sym1) || !is_local_sym(sym1)) - break; - - if (dont_correlate(sym1)) - continue; - - sym2 =3D file2_sym; - for_each_sym_continue(e->patched, sym2) { - if (is_file_sym(sym2) || !is_local_sym(sym2)) - break; - - if (sym2->twin || dont_correlate(sym2)) - continue; - - if (strcmp(sym1->demangled_name, sym2->demangled_name)) - continue; - - sym1->twin =3D sym2; - sym2->twin =3D sym1; - break; - } - } } =20 - /* Correlate globals */ - for_each_sym(e->orig, sym1) { - if (sym1->bind =3D=3D STB_LOCAL) - continue; - - sym2 =3D find_global_symbol_by_name(e->patched, sym1->name); - if (sym2 && !sym2->twin) { - sym1->twin =3D sym2; - sym2->twin =3D sym1; - } - } =20 /* - * Correlate globals with demangled_name. - * A separate loop is needed because we want to finish all the - * full name correlations first. + * Correlate in two phases: loop deterministic levels until no more + * progress, then use positional fallback for the rest. This prevents + * the nondeterministic positional matching from stealing symbols that + * have deterministic matches. */ + hash_init(suffix_map); + do { + progress =3D false; + for_each_sym(e->orig, sym1) { + if (sym1->twin || dont_correlate(sym1)) + continue; + sym2 =3D find_twin(e, sym1); + if (!sym2) + continue; + sym1->twin =3D sym2; + sym2->twin =3D sym1; + progress =3D true; + } + + if (update_suffix_map(e->orig)) + return -1; + + for_each_sym(e->orig, sym1) { + if (sym1->twin || dont_correlate(sym1)) + continue; + sym2 =3D find_twin_suffixed(e->patched, sym1); + if (!sym2) + continue; + sym1->twin =3D sym2; + sym2->twin =3D sym1; + progress =3D true; + } + } while (progress); + for_each_sym(e->orig, sym1) { - if (sym1->bind =3D=3D STB_LOCAL || sym1->twin) + if (sym1->twin || dont_correlate(sym1)) continue; - - if (find_global_symbol_by_demangled_name(e->patched, sym1, &sym2)) - return -1; - - if (sym2 && !sym2->twin) { - sym1->twin =3D sym2; - sym2->twin =3D sym1; - } - } - - /* Correlate original locals with patched globals */ - for_each_sym(e->orig, sym1) { - if (sym1->twin || dont_correlate(sym1) || !is_local_sym(sym1)) + sym2 =3D find_twin_positional(e, sym1); + if (!sym2) continue; - - sym2 =3D find_global_symbol_by_name(e->patched, sym1->name); - if (!sym2 && find_global_symbol_by_demangled_name(e->patched, sym1, &sym= 2)) - return -1; - - if (sym2 && !sym2->twin) { - sym1->twin =3D sym2; - sym2->twin =3D sym1; - } - } - - /* Correlate original globals with patched locals */ - for_each_sym(e->patched, sym2) { - if (sym2->twin || dont_correlate(sym2) || !is_local_sym(sym2)) - continue; - - sym1 =3D find_global_symbol_by_name(e->orig, sym2->name); - if (!sym1 && find_global_symbol_by_demangled_name(e->orig, sym2, &sym1)) - return -1; - - if (sym1 && !sym1->twin) { - sym2->twin =3D sym1; - sym1->twin =3D sym2; - } + sym1->twin =3D sym2; + sym2->twin =3D sym1; } =20 for_each_sym(e->orig, sym1) { @@ -800,19 +1040,24 @@ static void mark_included_function(struct symbol *fu= nc) */ static int mark_changed_functions(struct elfs *e) { - struct symbol *sym_orig, *patched_sym; + struct symbol *orig_sym, *patched_sym; bool changed =3D false; =20 /* Find changed functions */ - for_each_sym(e->orig, sym_orig) { - if (!is_func_sym(sym_orig) || dont_correlate(sym_orig)) + for_each_sym(e->orig, orig_sym) { + if (dont_correlate(orig_sym)) continue; =20 - patched_sym =3D sym_orig->twin; + patched_sym =3D orig_sym->twin; if (!patched_sym) continue; =20 - if (sym_orig->csum.checksum !=3D patched_sym->csum.checksum) { + if (orig_sym->csum.checksum !=3D patched_sym->csum.checksum) { + if (!is_func_sym(orig_sym)) { + ERROR("changed data: %s", orig_sym->name); + return -1; + } + patched_sym->changed =3D 1; mark_included_function(patched_sym); changed =3D true; @@ -837,7 +1082,7 @@ static int mark_changed_functions(struct elfs *e) printf("%s: changed function: %s\n", objname, patched_sym->name); } =20 - return !changed ? -1 : 0; + return !changed ? 1 : 0; } =20 static int clone_included_functions(struct elfs *e) @@ -1870,6 +2115,7 @@ static int copy_import_ns(struct elfs *e) int cmd_klp_diff(int argc, const char **argv) { struct elfs e =3D {0}; + int ret; =20 argc =3D parse_options(argc, argv, klp_diff_options, klp_diff_usage, 0); if (argc !=3D 3) @@ -1896,7 +2142,10 @@ int cmd_klp_diff(int argc, const char **argv) if (correlate_symbols(&e)) return -1; =20 - if (mark_changed_functions(&e)) + ret =3D mark_changed_functions(&e); + if (ret < 0) + return -1; + if (ret > 0) return 0; =20 e.out =3D elf_create_file(&e.orig->ehdr, argv[2]); --=20 2.53.0 From nobody Thu Jun 18 07:54:40 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 ED2F9369236; Fri, 1 May 2026 04:09:12 +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=1777608553; cv=none; b=M9D8+3PGj+lrOLgzg9rLy+XKQbqHm6OpeRzlp10RDcNcUoqcFi8W8sVY8gSo1O1RYhjbMUqV9QmBpWfgz093p5yTlApgIY+iCpCr+6UmaxpO1ufnY+NiMGiKnirOiZT0V443PSrf1wK/fWGUCfRLgLl6Lr328VnIZYPQFw6KAS0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777608553; c=relaxed/simple; bh=lo6GpX+iMG++Wc5TUiO8JZExXrF1M4ogiT6wLx59wQQ=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=jaC1skYh7TqrJMulGPdsweRursqWIh+Qx2obXgsky6yJJC0RXzQQ7lN31ixLImOoVw5GHUQEkUH9fitDVKEA4KQufRBGW1G6sX/MPRd9jaEzuUj5OIpsX5i4GQDe8dxMncxAPT1oLt6oXlKrNBM2lFWbqvzTPCyXYUkhKN1mGKo= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=EGiVhj3d; 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="EGiVhj3d" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 4DB7EC2BCB9; Fri, 1 May 2026 04:09:12 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1777608552; bh=lo6GpX+iMG++Wc5TUiO8JZExXrF1M4ogiT6wLx59wQQ=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=EGiVhj3de0xs4C0owfrNxXgvbMZa7GdTt8zaxYAo0Lm3Hbu+4aU2LBPKzsHTWadi7 O+509MvTvAtVxKCAO9YNrVI3LKZKnnSuB2A+U2cI0uq65yP8j18uhtkfk/ji4mQxh6 gPp+hNXfgn3LOZcJauIdf6ZDeqNfokYxQK77V9pIHMMA/K7BNcc8mb1fT9TC2dGUYN pvqKjurIp0GSFzAw0YhkGt595YE6sWrSC/9Mxoc8su/XAhEnEGaqPtumk/ZrZoGEX3 FUV005dP3zIeOP7ICb9+vTfDCNwL+eTHHh8PdjKojUe6af3GH0BxMxwjyrN87RucTC ZlwiepMIWmkFQ== From: Josh Poimboeuf To: x86@kernel.org Cc: linux-kernel@vger.kernel.org, live-patching@vger.kernel.org, Peter Zijlstra , Joe Lawrence , Song Liu , Miroslav Benes , Petr Mladek Subject: [PATCH v2 47/53] objtool/klp: Add correlation debugging output Date: Thu, 30 Apr 2026 21:08:35 -0700 Message-ID: <492432266706503947483b831a17a1c118dc5007.1777575752.git.jpoimboe@kernel.org> X-Mailer: git-send-email 2.53.0 In-Reply-To: References: 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" Add debugging messages to show how duplicate symbols get correlated, and split the --debug feature into --debug-correlate and --debug-clone. Acked-by: Song Liu Signed-off-by: Josh Poimboeuf --- tools/objtool/include/objtool/warn.h | 16 +++++++---- tools/objtool/klp-diff.c | 42 ++++++++++++++++++++++------ tools/objtool/objtool.c | 3 -- 3 files changed, 45 insertions(+), 16 deletions(-) diff --git a/tools/objtool/include/objtool/warn.h b/tools/objtool/include/o= bjtool/warn.h index 595ee8009667..a9936d60980c 100644 --- a/tools/objtool/include/objtool/warn.h +++ b/tools/objtool/include/objtool/warn.h @@ -109,7 +109,7 @@ static inline char *offstr(struct section *sec, unsigne= d long offset) #define ERROR_FUNC(sec, offset, format, ...) __WARN_FUNC(ERROR_STR, sec, o= ffset, format, ##__VA_ARGS__) #define ERROR_INSN(insn, format, ...) ERROR_FUNC(insn->sec, insn->offset, = format, ##__VA_ARGS__) =20 -extern bool debug; +extern bool debug, debug_correlate, debug_clone; extern int indent; =20 static inline void unindent(int *unused) { indent--; } @@ -148,15 +148,21 @@ static inline void unindent(int *unused) { indent--; } (unsigned long long)checksum); \ }) =20 -#define __dbg_indent(format, ...) \ +#define dbg_correlate(args...) \ ({ \ - if (unlikely(debug)) \ + if (unlikely(debug_correlate)) \ + __dbg(args); \ +}) + +#define __dbg_clone(format, ...) \ +({ \ + if (unlikely(debug_clone)) \ __dbg("%*s" format, indent * 8, "", ##__VA_ARGS__); \ }) =20 -#define dbg_indent(args...) \ +#define dbg_clone(args...) \ int __cleanup(unindent) __dummy_##__COUNTER__; \ - __dbg_indent(args); \ + __dbg_clone(args); \ indent++ =20 #endif /* _WARN_H */ diff --git a/tools/objtool/klp-diff.c b/tools/objtool/klp-diff.c index a9c993298b82..ed3bf1c55001 100644 --- a/tools/objtool/klp-diff.c +++ b/tools/objtool/klp-diff.c @@ -33,6 +33,9 @@ struct export { char *mod, *sym; }; =20 +bool debug, debug_correlate, debug_clone; +int indent; + static const char * const klp_diff_usage[] =3D { "objtool klp diff [] ", NULL, @@ -40,7 +43,9 @@ static const char * const klp_diff_usage[] =3D { =20 static const struct option klp_diff_options[] =3D { OPT_GROUP("Options:"), - OPT_BOOLEAN('d', "debug", &debug, "enable debug output"), + OPT_BOOLEAN('d', "debug", &debug, "enable all debug output"), + OPT_BOOLEAN(0, "debug-correlate", &debug_correlate, "enable correlation d= ebug output"), + OPT_BOOLEAN(0, "debug-clone", &debug_clone, "enable cloning debug output"= ), OPT_END(), }; =20 @@ -583,6 +588,14 @@ static struct symbol *find_twin(struct elfs *e, struct= symbol *sym1) else if (csum_orig =3D=3D 1 && csum_patched =3D=3D 1) match =3D csum_last; =20 + if (!match) + return NULL; + + if (name_orig !=3D 1 || name_patched !=3D 1) + dbg_correlate("find_twin(): %s%s -> %s%s", + sym1->name, is_func_sym(sym1) ? "()" : "", + match->name, is_func_sym(match) ? "()" : ""); + return match; } =20 @@ -686,10 +699,14 @@ static struct symbol *find_twin_suffixed(struct elf *= elf, struct symbol *sym1) match =3D sym2; } =20 - if (count =3D=3D 1) - return match; + if (count !=3D 1) + return NULL; =20 - return NULL; + dbg_correlate("find_suffixed_twin(): %s%s -> %s%s", + sym1->name, is_func_sym(sym1) ? "()" : "", + match->name, is_func_sym(match) ? "()" : ""); + + return match; } =20 /* @@ -742,6 +759,10 @@ static struct symbol *find_twin_positional(struct elfs= *e, struct symbol *sym1) if (idx_orig !=3D idx_patched) return NULL; =20 + dbg_correlate("find_twin_positional(): %s%s -> %s%s", + sym1->name, is_func_sym(sym1) ? "()" : "", + match->name, is_func_sym(match) ? "()" : ""); + return match; } =20 @@ -998,7 +1019,7 @@ static struct symbol *clone_symbol(struct elfs *e, str= uct symbol *patched_sym, if (patched_sym->clone) return patched_sym->clone; =20 - dbg_indent("%s%s", patched_sym->name, data_too ? " [+DATA]" : ""); + dbg_clone("%s%s", patched_sym->name, data_too ? " [+DATA]" : ""); =20 /* Make sure the prefix gets cloned first */ if (is_func_sym(patched_sym) && data_too) { @@ -1375,7 +1396,7 @@ static int clone_reloc_klp(struct elfs *e, struct rel= oc *patched_reloc, =20 klp_sym =3D find_symbol_by_name(e->out, sym_name); if (!klp_sym) { - __dbg_indent("%s", sym_name); + __dbg_clone("%s", sym_name); =20 /* STB_WEAK: avoid modpost undefined symbol warnings */ klp_sym =3D elf_create_symbol(e->out, sym_name, NULL, @@ -1426,7 +1447,7 @@ static int clone_reloc_klp(struct elfs *e, struct rel= oc *patched_reloc, } =20 #define dbg_clone_reloc(sec, offset, patched_sym, addend, export, klp) \ - dbg_indent("%s+0x%lx: %s%s0x%lx [%s%s%s%s%s%s]", \ + dbg_clone("%s+0x%lx: %s%s0x%lx [%s%s%s%s%s%s]", \ sec->name, offset, patched_sym->name, \ addend >=3D 0 ? "+" : "-", labs(addend), \ sym_type(patched_sym), \ @@ -1481,7 +1502,7 @@ static int clone_reloc(struct elfs *e, struct reloc *= patched_reloc, if (is_string_sec(patched_sym->sec)) { const char *str =3D patched_sym->sec->data->d_buf + addend; =20 - __dbg_indent("\"%s\"", escape_str(str)); + __dbg_clone("\"%s\"", escape_str(str)); =20 addend =3D elf_add_string(e->out, out_sym->sec, str); if (addend =3D=3D -1) @@ -2121,6 +2142,11 @@ int cmd_klp_diff(int argc, const char **argv) if (argc !=3D 3) usage_with_options(klp_diff_usage, klp_diff_options); =20 + if (debug) { + debug_correlate =3D true; + debug_clone =3D true; + } + objname =3D argv[0]; =20 e.orig =3D elf_open_read(argv[0], O_RDONLY); diff --git a/tools/objtool/objtool.c b/tools/objtool/objtool.c index 1c3622117c33..a4e139dee7e9 100644 --- a/tools/objtool/objtool.c +++ b/tools/objtool/objtool.c @@ -16,9 +16,6 @@ #include #include =20 -bool debug; -int indent; - static struct objtool_file file; =20 struct objtool_file *objtool_open_read(const char *filename) --=20 2.53.0 From nobody Thu Jun 18 07:54:40 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 6FCC3377009; Fri, 1 May 2026 04:09:13 +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=1777608553; cv=none; b=eWF8xtrxbkuZMvYLnyCLvdMCDAxKR9zf0HrF6YBBar++4tcElCIRf64sZpAu7lUSPugvXUm63lWj8EdRhPpSYlwPkYcShrMmUzF31+kNcCSA1F4SP4YWW4CqC70a6JraX18Y6o3pAmp0ZqU6zuTTvIajPv/s3kuhN3+Mpa5FPlc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777608553; c=relaxed/simple; bh=P0MaWoXei4QXxRNgMPz3urNwgaUfcNbE/81k0UNZncg=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=uJ+Qzk47Jc6ShbNDyvgcSQjL9cJZ68TbNs+shNO9RfysLQltKA1buYN4YhRr75T8jDu46rA9QsQUIkI9wxwyjwUi2UJ1Yg38B0pWCHsq1ozbXMrZP7JM9gukEsr1IAO3Q/9xCtdLBgphvHlf9fJrIAlnNoXNGbpLfGVZHPA7JRU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=HmiY2UaY; 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="HmiY2UaY" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 0673DC2BCB8; Fri, 1 May 2026 04:09:12 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1777608553; bh=P0MaWoXei4QXxRNgMPz3urNwgaUfcNbE/81k0UNZncg=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=HmiY2UaYX0Ljq0p8osaiJNLWP/UlHrpx23wlnj6fOKxsvYDam0vlc+SH/6HN2cvoR A+podxTPUNbgupsfPWHw1av0ivplL+MC718VFKGldVSCHM7H9i+RL9zZbWlcrFaQaJ Og5q+eJpY7scacUHFeQHFHPjWpnI0onrWGjg7yzqVYhpaeWVTeXO6TgSEXZ8tJ/VWg kWAytOW3UofKIMhqqy1CMP66fmnOvVaf5Be8KWJJcNZJ47svXWl/982PrbBTdeJ5EQ gWaSTgxoOuCDnKJUjUqckfaBCAZ4CETBVTY810PMjVxbz3pczu168gda8nDjH8oKZc O0MHp3ixHCrPQ== From: Josh Poimboeuf To: x86@kernel.org Cc: linux-kernel@vger.kernel.org, live-patching@vger.kernel.org, Peter Zijlstra , Joe Lawrence , Song Liu , Miroslav Benes , Petr Mladek Subject: [PATCH v2 48/53] objtool: Add insn_sym() helper Date: Thu, 30 Apr 2026 21:08:36 -0700 Message-ID: <52633c62366f87d9b78ebd77873a08b9ac6d31c8.1777575752.git.jpoimboe@kernel.org> X-Mailer: git-send-email 2.53.0 In-Reply-To: References: 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" Alternative replacement instructions awkwardly have insn->sym set to the function they get patched to rather than the symbol (or rather lack thereof) they belong to in the file. This makes it difficult to know where a given instruction actually lives. Add a new insn_sym() helper which preserves the existing semantic of insn->sym. Rename insn->sym to insn->_sym, which contains the actual ELF binary symbol (or NULL, for alternative replacements) an instruction lives in. The private insn->_sym value will be needed for a subsequent patch. Signed-off-by: Josh Poimboeuf --- tools/objtool/check.c | 31 ++++++++++++--------------- tools/objtool/disas.c | 22 +++++++++---------- tools/objtool/include/objtool/check.h | 20 +++++++++++++++-- tools/objtool/include/objtool/warn.h | 6 +++--- tools/objtool/trace.c | 8 +++---- 5 files changed, 49 insertions(+), 38 deletions(-) diff --git a/tools/objtool/check.c b/tools/objtool/check.c index ae047be919c5..410061aeed26 100644 --- a/tools/objtool/check.c +++ b/tools/objtool/check.c @@ -495,7 +495,7 @@ static int decode_instructions(struct objtool_file *fil= e) } =20 sym_for_each_insn(file, func, insn) { - insn->sym =3D func; + insn->_sym =3D func; if (is_func_sym(func) && insn->type =3D=3D INSN_ENDBR && list_empty(&insn->call_node)) { @@ -859,15 +859,14 @@ static int create_ibt_endbr_seal_sections(struct objt= ool_file *file) list_for_each_entry(insn, &file->endbr_list, call_node) { =20 int *site =3D (int *)sec->data->d_buf + idx; - struct symbol *sym =3D insn->sym; + struct symbol *func =3D insn_func(insn); *site =3D 0; =20 - if (opts.module && sym && is_func_sym(sym) && - insn->offset =3D=3D sym->offset && - (!strcmp(sym->name, "init_module") || - !strcmp(sym->name, "cleanup_module"))) { + if (opts.module && func && insn->offset =3D=3D func->offset && + (!strcmp(func->name, "init_module") || + !strcmp(func->name, "cleanup_module"))) { ERROR("%s(): Magic init_module() function name is deprecated, use modul= e_init(fn) instead", - sym->name); + func->name); return -1; } =20 @@ -1581,7 +1580,7 @@ static int add_jump_destinations(struct objtool_file = *file) } =20 if (!dest_sym || is_sec_sym(dest_sym)) { - dest_sym =3D dest_insn->sym; + dest_sym =3D insn_sym(dest_insn); if (!dest_sym) goto set_jump_dest; } @@ -1597,7 +1596,7 @@ static int add_jump_destinations(struct objtool_file = *file) continue; } =20 - if (!insn->sym || insn->sym->pfunc =3D=3D dest_sym->pfunc) + if (!insn_sym(insn) || insn_sym(insn)->pfunc =3D=3D dest_sym->pfunc) goto set_jump_dest; =20 /* @@ -1770,7 +1769,6 @@ static int handle_group_alt(struct objtool_file *file, nop->offset =3D special_alt->new_off + special_alt->new_len; nop->len =3D special_alt->orig_len - special_alt->new_len; nop->type =3D INSN_NOP; - nop->sym =3D orig_insn->sym; nop->alt_group =3D new_alt_group; nop->fake =3D 1; } @@ -1789,7 +1787,6 @@ static int handle_group_alt(struct objtool_file *file, =20 last_new_insn =3D insn; =20 - insn->sym =3D orig_insn->sym; insn->alt_group =3D new_alt_group; =20 /* @@ -2432,12 +2429,12 @@ static int __annotate_late(struct objtool_file *fil= e, int type, struct instructi break; =20 case ANNOTYPE_NOCFI: - sym =3D insn->sym; + sym =3D insn_sym(insn); if (!sym) { ERROR_INSN(insn, "dodgy NOCFI annotation"); return -1; } - insn->sym->nocfi =3D 1; + insn_sym(insn)->nocfi =3D 1; break; =20 default: @@ -2538,7 +2535,7 @@ static void mark_holes(struct objtool_file *file) * favour of a regular symbol, but leaves the code in place. */ for_each_insn(file, insn) { - if (insn->sym || !find_symbol_hole_containing(insn->sec, insn->offset)) { + if (insn_sym(insn) || !find_symbol_hole_containing(insn->sec, insn->offs= et)) { in_hole =3D false; continue; } @@ -2982,7 +2979,7 @@ static int update_cfi_state(struct instruction *insn, } =20 if (op->dest.reg =3D=3D CFI_BP && op->src.reg =3D=3D CFI_SP && - insn->sym->frame_pointer) { + insn_sym(insn)->frame_pointer) { /* addi.d fp,sp,imm on LoongArch */ if (cfa->base =3D=3D CFI_SP && cfa->offset =3D=3D op->src.offset) { cfa->base =3D CFI_BP; @@ -2994,7 +2991,7 @@ static int update_cfi_state(struct instruction *insn, if (op->dest.reg =3D=3D CFI_SP && op->src.reg =3D=3D CFI_BP) { /* addi.d sp,fp,imm on LoongArch */ if (cfa->base =3D=3D CFI_BP && cfa->offset =3D=3D 0) { - if (insn->sym->frame_pointer) { + if (insn_sym(insn)->frame_pointer) { cfa->base =3D CFI_SP; cfa->offset =3D -op->src.offset; } @@ -4171,7 +4168,7 @@ static int validate_retpoline(struct objtool_file *fi= le) * broken. */ list_for_each_entry(insn, &file->retpoline_call_list, call_node) { - struct symbol *sym =3D insn->sym; + struct symbol *sym =3D insn_sym(insn); =20 if (sym && (is_notype_sym(sym) || is_func_sym(sym)) && !sym->nocfi) { diff --git a/tools/objtool/disas.c b/tools/objtool/disas.c index 59090234af19..e6a54a83605c 100644 --- a/tools/objtool/disas.c +++ b/tools/objtool/disas.c @@ -210,7 +210,7 @@ static bool disas_print_addr_alt(bfd_vma addr, struct d= isassemble_info *dinfo) offset =3D addr - alt_group->first_insn->offset; =20 addr =3D orig_first_insn->offset + offset; - sym =3D orig_first_insn->sym; + sym =3D insn_sym(orig_first_insn); =20 disas_print_addr_sym(orig_first_insn->sec, sym, addr, dinfo); =20 @@ -222,15 +222,13 @@ static void disas_print_addr_noreloc(bfd_vma addr, { struct disas_context *dctx =3D dinfo->application_data; struct instruction *insn =3D dctx->insn; - struct symbol *sym =3D NULL; + struct symbol *sym =3D insn_sym(insn); =20 if (disas_print_addr_alt(addr, dinfo)) return; =20 - if (insn->sym && addr >=3D insn->sym->offset && - addr < insn->sym->offset + insn->sym->len) { - sym =3D insn->sym; - } + if (sym && (addr < sym->offset || addr >=3D sym->offset + sym->len)) + sym =3D NULL; =20 disas_print_addr_sym(insn->sec, sym, addr, dinfo); } @@ -291,9 +289,9 @@ static void disas_print_address(bfd_vma addr, struct di= sassemble_info *dinfo) * up. So check it first. */ jump_dest =3D insn->jump_dest; - if (jump_dest && jump_dest->sym && jump_dest->offset =3D=3D addr) { + if (jump_dest && insn_sym(jump_dest) && jump_dest->offset =3D=3D addr) { if (!disas_print_addr_alt(addr, dinfo)) - disas_print_addr_sym(jump_dest->sec, jump_dest->sym, + disas_print_addr_sym(jump_dest->sec, insn_sym(jump_dest), addr, dinfo); return; } @@ -768,8 +766,8 @@ static int disas_alt_jump(struct disas_alt *dalt) if (orig_insn->len =3D=3D 5) suffix[0] =3D 'q'; str =3D strfmt("jmp%-3s %lx <%s+0x%lx>", suffix, - dest_insn->offset, dest_insn->sym->name, - dest_insn->offset - dest_insn->sym->offset); + dest_insn->offset, insn_sym(dest_insn)->name, + dest_insn->offset - insn_sym(dest_insn)->offset); nops =3D 0; } else { str =3D strfmt("nop%d", orig_insn->len); @@ -794,8 +792,8 @@ static int disas_alt_extable(struct disas_alt *dalt) =20 alt_insn =3D dalt->alt->insn; str =3D strfmt("resume at 0x%lx <%s+0x%lx>", - alt_insn->offset, alt_insn->sym->name, - alt_insn->offset - alt_insn->sym->offset); + alt_insn->offset, insn_sym(alt_insn)->name, + alt_insn->offset - insn_sym(alt_insn)->offset); if (!str) return -1; =20 diff --git a/tools/objtool/include/objtool/check.h b/tools/objtool/include/= objtool/check.h index eea64728d39b..fe08205d8eb1 100644 --- a/tools/objtool/include/objtool/check.h +++ b/tools/objtool/include/objtool/check.h @@ -94,14 +94,30 @@ struct instruction { }; }; struct alternative *alts; - struct symbol *sym; + struct symbol *_sym; struct stack_op *stack_ops; struct cfi_state *cfi; }; =20 +/* + * Return the symbol associated with an instruction. For alternative + * replacements, return the symbol of the original code being replaced rat= her + * than NULL. insn->_sym reflects the actual location in the ELF file. + */ +static inline struct symbol *insn_sym(struct instruction *insn) +{ + struct symbol *sym =3D insn->_sym; + + if ((!sym || !is_func_sym(sym)) && + insn->alt_group && insn->alt_group->orig_group) + sym =3D insn->alt_group->orig_group->first_insn->_sym; + + return sym; +} + static inline struct symbol *insn_func(struct instruction *insn) { - struct symbol *sym =3D insn->sym; + struct symbol *sym =3D insn_sym(insn); =20 if (sym && sym->type !=3D STT_FUNC) sym =3D NULL; diff --git a/tools/objtool/include/objtool/warn.h b/tools/objtool/include/o= bjtool/warn.h index a9936d60980c..870e147f3a56 100644 --- a/tools/objtool/include/objtool/warn.h +++ b/tools/objtool/include/objtool/warn.h @@ -77,13 +77,13 @@ static inline char *offstr(struct section *sec, unsigne= d long offset) #define WARN_INSN(insn, format, ...) \ ({ \ struct instruction *_insn =3D (insn); \ - if (!_insn->sym || !_insn->sym->warned) { \ + if (!insn_sym(_insn) || !insn_sym(_insn)->warned) { \ WARN_FUNC(_insn->sec, _insn->offset, format, \ ##__VA_ARGS__); \ BT_INSN(_insn, ""); \ } \ - if (_insn->sym) \ - _insn->sym->warned =3D 1; \ + if (insn_sym(_insn)) \ + insn_sym(_insn)->warned =3D 1; \ }) =20 #define BT_INSN(insn, format, ...) \ diff --git a/tools/objtool/trace.c b/tools/objtool/trace.c index 5dec44dab781..61c6aa302bc3 100644 --- a/tools/objtool/trace.c +++ b/tools/objtool/trace.c @@ -169,8 +169,8 @@ void trace_alt_begin(struct instruction *orig_insn, str= uct alternative *alt, */ TRACE_ALT_INFO_NOADDR(orig_insn, "/ ", "%s for instruction at 0x%lx <%s+= 0x%lx>", alt_name, - orig_insn->offset, orig_insn->sym->name, - orig_insn->offset - orig_insn->sym->offset); + orig_insn->offset, insn_sym(orig_insn)->name, + orig_insn->offset - insn_sym(orig_insn)->offset); } else { TRACE_ALT_INFO_NOADDR(orig_insn, "/ ", "%s", alt_name); } @@ -185,8 +185,8 @@ void trace_alt_begin(struct instruction *orig_insn, str= uct alternative *alt, if (orig_insn->type =3D=3D INSN_NOP) { suffix[0] =3D (orig_insn->len =3D=3D 5) ? 'q' : '\0'; TRACE_ADDR(orig_insn, "jmp%-3s %lx <%s+0x%lx>", suffix, - alt_insn->offset, alt_insn->sym->name, - alt_insn->offset - alt_insn->sym->offset); + alt_insn->offset, insn_sym(alt_insn)->name, + alt_insn->offset - insn_sym(alt_insn)->offset); } else { TRACE_ADDR(orig_insn, "nop%d", orig_insn->len); trace_depth--; --=20 2.53.0 From nobody Thu Jun 18 07:54:40 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 4F0B531D74B; Fri, 1 May 2026 04:09:14 +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=1777608554; cv=none; b=aD4hzFLE1732Q+ybY1YMjK5zUWKzO+0RQHnC7CEDuMoDHmI8sBkElZymXEB7PhkF8lvFnI1eGo1IxrCHASsdKG9gCHnXGGdHCJfPvgjPjToLBASol28DFjgX+ViT9oTl3yz0CtVjLV6jQrhg/P+EaMUCvMXYQoAZNY50u/o3Nzc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777608554; c=relaxed/simple; bh=4sZ9od17f5P1PS5M6howR79GuYi+ntpQw6uTUlGfUxY=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=Rz9bPjZps6tT3t8R1fNT53FV2qMxr5RgTFrmwFDedXygh1mA4Yqf40FFJd+yqFBvklm2omMxV/KUKmmg1n8jEKAqyI7byLcb8/JCg9BgSoDoRfwDJkwsccbeXnPRBiPjLhD6CEJl7UJkmETkegEB0aD4Q67Hvl4vzMSReruSgqg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=X/nYocX6; 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="X/nYocX6" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 86033C2BCC6; Fri, 1 May 2026 04:09:13 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1777608554; bh=4sZ9od17f5P1PS5M6howR79GuYi+ntpQw6uTUlGfUxY=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=X/nYocX6YDEhopf51+IO3sYh/KAEBEWPikCnugtF/Mw3BIDfBGp60xnScOG7aZ6iX dZtEa1PmxHXXjjnYs2PbZYNj/xw5FI5wu/TqitxWg8HWkNJm9DxEaPFl+U/945yNfn uZvD6ew6UiF3eFDbsh1XMOYEk9sifOZGFhAx1Lz7Giue/jUgPlcIcWCg6920e0XgV6 38wftTWzl63kpLE5AjxDJ7LW+Rt4pNh21mmEWQH5grfJCAf0QwINVoxXuO+jOQt2ns oET+4vkpDpJ95RcNxE/+lHaKn2icqwFF8tMrFesFUbfuJx/p03YwBv9ly70j2YXNDE pNpBFH4eWHnoA== From: Josh Poimboeuf To: x86@kernel.org Cc: linux-kernel@vger.kernel.org, live-patching@vger.kernel.org, Peter Zijlstra , Joe Lawrence , Song Liu , Miroslav Benes , Petr Mladek Subject: [PATCH v2 49/53] objtool/klp: Fix position-dependent checksums for non-relocated jumps/calls Date: Thu, 30 Apr 2026 21:08:37 -0700 Message-ID: X-Mailer: git-send-email 2.53.0 In-Reply-To: References: 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" When computing klp checksums, instructions with non-relocated jump/call destination offsets are problematic because the offset values can change when surrounding code has moved, causing the function to be incorrectly marked as changed. Specifically, that includes jumps from alternatives to the end of the alternative, which from objtool's perspective are jumps to the end of the alternative instruction block in the original function. Note that 'jump_dest' jumps don't include sibling calls (those use call_dest), nor do they include jumps to/from .cold sub functions (those are cross-section and need a reloc). Fix it by hashing the opcode bytes (excluding the immediate operand) along with a position-independent representation of the destination. For calls, use the function name, and for jumps, use the destination's offset within its function. [Note the "9 bit hole" comment was wrong: it has been 8 bits since commit 70589843b36f ("objtool: Add option to trace function validation") added the 'trace' field. Adding the 4-bit 'immediate_len' field now leaves a 4-bit hole.] Fixes: 0d83da43b1e1 ("objtool/klp: Add --checksum option to generate per-fu= nction checksums") Signed-off-by: Josh Poimboeuf --- tools/objtool/arch/x86/decode.c | 17 ++++++++- tools/objtool/include/objtool/arch.h | 3 ++ tools/objtool/include/objtool/check.h | 3 +- tools/objtool/klp-checksum.c | 53 ++++++++++++++++++++++++--- 4 files changed, 67 insertions(+), 9 deletions(-) diff --git a/tools/objtool/arch/x86/decode.c b/tools/objtool/arch/x86/decod= e.c index 350b8ee6e776..1b387d5a195b 100644 --- a/tools/objtool/arch/x86/decode.c +++ b/tools/objtool/arch/x86/decode.c @@ -805,14 +805,27 @@ int arch_decode_instruction(struct objtool_file *file= , const struct section *sec break; } =20 - if (ins.immediate.nbytes) + if (ins.immediate.nbytes) { insn->immediate =3D ins.immediate.value; - else if (ins.displacement.nbytes) + insn->immediate_len =3D ins.immediate.nbytes; + } else if (ins.displacement.nbytes) { insn->immediate =3D ins.displacement.value; + insn->immediate_len =3D ins.displacement.nbytes; + } =20 return 0; } =20 +size_t arch_jump_opcode_bytes(struct objtool_file *file, struct instructio= n *insn, + unsigned char *buf) +{ + size_t len; + + len =3D insn->len - insn->immediate_len; + memcpy(buf, insn->sec->data->d_buf + insn->offset, len); + return len; +} + void arch_initial_func_cfi_state(struct cfi_init_state *state) { int i; diff --git a/tools/objtool/include/objtool/arch.h b/tools/objtool/include/o= bjtool/arch.h index 8866158975fc..96d828a8401f 100644 --- a/tools/objtool/include/objtool/arch.h +++ b/tools/objtool/include/objtool/arch.h @@ -79,6 +79,9 @@ int arch_decode_instruction(struct objtool_file *file, co= nst struct section *sec unsigned long offset, unsigned int maxlen, struct instruction *insn); =20 +size_t arch_jump_opcode_bytes(struct objtool_file *file, struct instructio= n *insn, + unsigned char *buf); + bool arch_callee_saved_reg(unsigned char reg); =20 unsigned long arch_jump_destination(struct instruction *insn); diff --git a/tools/objtool/include/objtool/check.h b/tools/objtool/include/= objtool/check.h index fe08205d8eb1..063f5985fecd 100644 --- a/tools/objtool/include/objtool/check.h +++ b/tools/objtool/include/objtool/check.h @@ -68,6 +68,7 @@ struct instruction { s8 instr; =20 u32 idx : INSN_CHUNK_BITS, + immediate_len : 4, dead_end : 1, ignore_alts : 1, hint : 1, @@ -81,7 +82,7 @@ struct instruction { hole : 1, fake : 1, trace : 1; - /* 9 bit hole */ + /* 4 bit hole */ =20 struct alt_group *alt_group; struct instruction *jump_dest; diff --git a/tools/objtool/klp-checksum.c b/tools/objtool/klp-checksum.c index 19653dbe109d..b8e47f28997e 100644 --- a/tools/objtool/klp-checksum.c +++ b/tools/objtool/klp-checksum.c @@ -66,17 +66,58 @@ static void checksum_update_insn(struct objtool_file *f= ile, struct symbol *func, if (insn->fake) return; =20 - __checksum_update_insn(func, insn, insn->sec->data->d_buf + insn->offset,= insn->len); - if (!reloc) { struct symbol *call_dest =3D insn_call_dest(insn); + struct instruction *jump_dest =3D insn->jump_dest; =20 - if (call_dest) - __checksum_update_insn(func, insn, call_dest->demangled_name, - strlen(call_dest->demangled_name)); - goto alts; + /* + * For a jump/call non-relocated dest offset embedded in the + * instruction, the offset may vary due to changes in + * surrounding code. Just hash the opcode and a + * position-independent representation of the destination. + */ + + if (call_dest || jump_dest) { + unsigned char buf[16]; + size_t len; + + len =3D arch_jump_opcode_bytes(file, insn, buf); + __checksum_update_insn(func, insn, buf, len); + + if (call_dest) { + __checksum_update_insn(func, insn, call_dest->demangled_name, + strlen(call_dest->demangled_name)); + + } else if (jump_dest) { + struct symbol *dest_sym; + unsigned long offset; + + /* + * use insn->_sym instead of insn_sym() here. + * For alternative replacements, the latter + * would give the function of the code being + * replaced. + */ + dest_sym =3D jump_dest->_sym; + if (!dest_sym) + goto alts; + + __checksum_update_insn(func, insn, dest_sym->demangled_name, + strlen(dest_sym->demangled_name)); + + offset =3D jump_dest->offset - dest_sym->offset; + __checksum_update_insn(func, insn, &offset, sizeof(offset)); + } + + goto alts; + } } =20 + __checksum_update_insn(func, insn, insn->sec->data->d_buf + insn->offset,= insn->len); + + if (!reloc) + goto alts; + sym =3D reloc->sym; offset =3D arch_insn_adjusted_addend(insn, reloc); =20 --=20 2.53.0 From nobody Thu Jun 18 07:54:40 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 BAAF031E83A; Fri, 1 May 2026 04:09:14 +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=1777608554; cv=none; b=lGSSYXve+4DzUpBlNR3DZLZzhb+YAo1oBwiLjQhaEgaOj2JU4a2abD/zzGXu0baDe5f7+Z3c6YdpqTcfTd9YaUuCYTB0tyywLYAd26rMOFcGq2IDxEgZPcZIUpa0DuzSa7GNRw9FxMZ+PVGQh93LY5oZ/myHWGAaZMd13c0IWvc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777608554; c=relaxed/simple; bh=Io0p+N+f7/re/QtdLy2xkr+VYDcZLNkvDOWreGLhkck=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=spHQUyYnK8AGLfpxz0G5pO5NLaTlpED+Ysx+gFT/cbsNP9XlZ0nkxOcuQnFfe8XSOwsYLellokAmbxsJ9OKCxNTLgXW4JdNfBWJXBBOmovTwNe2y8eDjifUr/GiJDklawM2/4cPixEgYYhCtiD96IwxSNQjx6+ZSTgZH1LoxTlc= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=MH1rJOw0; 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="MH1rJOw0" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 5ACDCC2BCB9; Fri, 1 May 2026 04:09:14 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1777608554; bh=Io0p+N+f7/re/QtdLy2xkr+VYDcZLNkvDOWreGLhkck=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=MH1rJOw0MABgA36SshYNl3q+A/faPnfJM3FoRoxQrernF4pDEkm4V115WnM1NzPxe yuoOncjfhOJv6DJmDOf5LWh+6auEGht+YhTEqkzikW3ky2ZTNMCxY2yTpQ6nhGZj3o mqFC07f2y5nL+a8t4dVP370SDgtv5t80FRhDN9LD8goSPkl+c5osx9BIJ/dsDqa9Vy s27BZctC7FPeKJ8tPzz22heY1vyL4/zuoISz5MeE8RLWtTv3wnpZMmxE/j2Yzoc0IB Jf6IvRDYrZiuEeFqmREvAhEg/cPm/i660B+VBUTi1FEK/z2J9LMuGFfk88piGZwe2w HkjfID710DsYQ== From: Josh Poimboeuf To: x86@kernel.org Cc: linux-kernel@vger.kernel.org, live-patching@vger.kernel.org, Peter Zijlstra , Joe Lawrence , Song Liu , Miroslav Benes , Petr Mladek Subject: [PATCH v2 50/53] objtool: Grow __cfi_* prefix symbols for all CFI+CALL_PADDING Date: Thu, 30 Apr 2026 21:08:38 -0700 Message-ID: <089348f37d6d4a32827e8d94d9dbe10c9985789a.1777575752.git.jpoimboe@kernel.org> X-Mailer: git-send-email 2.53.0 In-Reply-To: References: 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" For all CONFIG_CFI+CONFIG_CALL_PADDING configs, for C functions, the __cfi_ symbols only cover the 5-byte kCFI type hash. After that there also N bytes of NOP padding between the hash and the function entry which aren't associated with any symbol. The NOPs can be replaced with actual code at runtime. Without a symbol, unwinders and tooling have no way of knowing where those bytes belong. Grow the existing __cfi_* symbols to fill that gap. Note that assembly functions with SYM_TYPED_FUNC_START() aren't affected by this issue, their __cfi_ symbols also cover the padding. Also, CONFIG_PREFIX_SYMBOLS has no reason to exist: CONFIG_CALL_PADDING is what causes the compiler to emit NOP padding before function entry (via -fpatchable-function-entry), so it's the right condition for creating prefix symbols. Remove CONFIG_PREFIX_SYMBOLS, as it's no longer needed. Simplify the LONGEST_SYM_KUNIT_TEST dependency accordingly. Rework objtool's arguments a bit to handle the variety of prefix/cfi-related cases. Suggested-by: Peter Zijlstra Signed-off-by: Josh Poimboeuf --- arch/x86/Kconfig | 4 -- lib/Kconfig.debug | 2 +- scripts/Makefile.lib | 7 +++- tools/objtool/builtin-check.c | 15 +++++++- tools/objtool/check.c | 49 ++++++++++++++++++++----- tools/objtool/elf.c | 20 ++++++++++ tools/objtool/include/objtool/builtin.h | 7 ++-- tools/objtool/include/objtool/elf.h | 1 + 8 files changed, 84 insertions(+), 21 deletions(-) diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index f3f7cb01d69d..3eb3c48d764a 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -2437,10 +2437,6 @@ config CALL_THUNKS def_bool n select CALL_PADDING =20 -config PREFIX_SYMBOLS - def_bool y - depends on CALL_PADDING && !CFI - menuconfig CPU_MITIGATIONS bool "Mitigations for CPU vulnerabilities" default y diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug index 8ff5adcfe1e0..4f7496b3268d 100644 --- a/lib/Kconfig.debug +++ b/lib/Kconfig.debug @@ -3070,7 +3070,7 @@ config FORTIFY_KUNIT_TEST config LONGEST_SYM_KUNIT_TEST tristate "Test the longest symbol possible" if !KUNIT_ALL_TESTS depends on KUNIT && KPROBES - depends on !PREFIX_SYMBOLS && !CFI && !GCOV_KERNEL + depends on !CALL_PADDING && !CFI && !GCOV_KERNEL default KUNIT_ALL_TESTS help Tests the longest symbol possible diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib index 0718e39cedda..7e216d82e988 100644 --- a/scripts/Makefile.lib +++ b/scripts/Makefile.lib @@ -187,7 +187,11 @@ objtool-args-$(CONFIG_HAVE_JUMP_LABEL_HACK) +=3D --ha= cks=3Djump_label objtool-args-$(CONFIG_HAVE_NOINSTR_HACK) +=3D --hacks=3Dnoinstr objtool-args-$(CONFIG_MITIGATION_CALL_DEPTH_TRACKING) +=3D --hacks=3Dskyla= ke objtool-args-$(CONFIG_X86_KERNEL_IBT) +=3D --ibt -objtool-args-$(CONFIG_FINEIBT) +=3D --cfi +objtool-args-$(CONFIG_CALL_PADDING) +=3D --prefix=3D$(CONFIG_FUNCTION_PA= DDING_BYTES) +ifdef CONFIG_CALL_PADDING +objtool-args-$(CONFIG_CFI) +=3D --cfi +objtool-args-$(CONFIG_FINEIBT) +=3D --fineibt +endif objtool-args-$(CONFIG_FTRACE_MCOUNT_USE_OBJTOOL) +=3D --mcount ifdef CONFIG_FTRACE_MCOUNT_USE_OBJTOOL objtool-args-$(CONFIG_HAVE_OBJTOOL_NOP_MCOUNT) +=3D --mnop @@ -200,7 +204,6 @@ objtool-args-$(CONFIG_STACK_VALIDATION) +=3D --stackv= al objtool-args-$(CONFIG_HAVE_STATIC_CALL_INLINE) +=3D --static-call objtool-args-$(CONFIG_HAVE_UACCESS_VALIDATION) +=3D --uaccess objtool-args-$(or $(CONFIG_GCOV_KERNEL),$(CONFIG_KCOV)) +=3D --no-unreacha= ble -objtool-args-$(CONFIG_PREFIX_SYMBOLS) +=3D --prefix=3D$(CONFIG_FUNCTION_= PADDING_BYTES) objtool-args-$(CONFIG_OBJTOOL_WERROR) +=3D --werror =20 objtool-args =3D $(objtool-args-y) \ diff --git a/tools/objtool/builtin-check.c b/tools/objtool/builtin-check.c index ec7f10a5ef19..118c3de2f293 100644 --- a/tools/objtool/builtin-check.c +++ b/tools/objtool/builtin-check.c @@ -73,7 +73,6 @@ static int parse_hacks(const struct option *opt, const ch= ar *str, int unset) =20 static const struct option check_options[] =3D { OPT_GROUP("Actions:"), - OPT_BOOLEAN(0, "cfi", &opts.cfi, "annotate kernel control flow integrit= y (kCFI) function preambles"), OPT_STRING_OPTARG('d', "disas", &opts.disas, "function-pattern", "disass= emble functions", "*"), OPT_CALLBACK_OPTARG('h', "hacks", NULL, NULL, "jump_label,noinstr,skylake= ", "patch toolchain bugs/limitations", parse_hacks), OPT_BOOLEAN('i', "ibt", &opts.ibt, "validate and annotate IBT"), @@ -84,7 +83,7 @@ static const struct option check_options[] =3D { OPT_BOOLEAN('r', "retpoline", &opts.retpoline, "validate and annotate re= tpoline usage"), OPT_BOOLEAN(0, "rethunk", &opts.rethunk, "validate and annotate rethunk= usage"), OPT_BOOLEAN(0, "unret", &opts.unret, "validate entry unret placement"), - OPT_INTEGER(0, "prefix", &opts.prefix, "generate prefix symbols"), + OPT_INTEGER(0, "prefix", &opts.prefix, "generate or grow prefix symbols= for N-byte function padding"), OPT_BOOLEAN('l', "sls", &opts.sls, "validate straight-line-speculation m= itigations"), OPT_BOOLEAN('s', "stackval", &opts.stackval, "validate frame pointer rul= es"), OPT_BOOLEAN('t', "static-call", &opts.static_call, "annotate static call= s"), @@ -92,6 +91,8 @@ static const struct option check_options[] =3D { OPT_CALLBACK_OPTARG(0, "dump", NULL, NULL, "orc", "dump metadata", parse= _dump), =20 OPT_GROUP("Options:"), + OPT_BOOLEAN(0, "cfi", &opts.cfi, "grow kCFI preamble symbols (use with = --prefix)"), + OPT_BOOLEAN(0, "fineibt", &opts.fineibt, "create .cfi_sites section for= FineIBT"), OPT_BOOLEAN(0, "backtrace", &opts.backtrace, "unwind on error"), OPT_BOOLEAN(0, "backup", &opts.backup, "create backup (.orig) file on w= arning/error"), OPT_BOOLEAN(0, "dry-run", &opts.dryrun, "don't write modifications"), @@ -163,6 +164,16 @@ static bool opts_valid(void) return false; } =20 + if (opts.cfi && !opts.prefix) { + ERROR("--cfi requires --prefix"); + return false; + } + + if (opts.fineibt && !opts.cfi) { + ERROR("--fineibt requires --cfi"); + return false; + } + if (opts.disas || opts.hack_jump_label || opts.hack_noinstr || diff --git a/tools/objtool/check.c b/tools/objtool/check.c index 410061aeed26..0d9b859b006e 100644 --- a/tools/objtool/check.c +++ b/tools/objtool/check.c @@ -881,6 +881,31 @@ static int create_ibt_endbr_seal_sections(struct objto= ol_file *file) return 0; } =20 +/* +* Grow __cfi_ symbols to fill the NOP gap between the 'mov , %rax' a= nd +* the start of the function. +*/ +static int grow_cfi_symbols(struct objtool_file *file) +{ + struct symbol *sym; + + for_each_sym(file->elf, sym) { + if (!is_func_sym(sym) || !strstarts(sym->name, "__cfi_") || + sym->len !=3D 5) + continue; + + if (!find_func_by_offset(sym->sec, sym->offset + sym->len + opts.prefix)) + continue; + + sym->len +=3D opts.prefix; + sym->sym.st_size =3D sym->len; + if (elf_write_symbol(file->elf, sym)) + return -1; + } + + return 0; +} + static int create_cfi_sections(struct objtool_file *file) { struct section *sec; @@ -4903,12 +4928,6 @@ int check(struct objtool_file *file) goto out; } =20 - if (opts.cfi) { - ret =3D create_cfi_sections(file); - if (ret) - goto out; - } - if (opts.rethunk) { ret =3D create_return_sites_sections(file); if (ret) @@ -4928,9 +4947,21 @@ int check(struct objtool_file *file) } =20 if (opts.prefix) { - ret =3D create_prefix_symbols(file); - if (ret) - goto out; + if (!opts.cfi) { + ret =3D create_prefix_symbols(file); + if (ret) + goto out; + } else { + ret =3D grow_cfi_symbols(file); + if (ret) + goto out; + + if (opts.fineibt) { + ret =3D create_cfi_sections(file); + if (ret) + goto out; + } + } } =20 if (opts.ibt) { diff --git a/tools/objtool/elf.c b/tools/objtool/elf.c index d9cee8d5d9e8..33c95a74a51b 100644 --- a/tools/objtool/elf.c +++ b/tools/objtool/elf.c @@ -997,6 +997,26 @@ struct symbol *elf_create_symbol(struct elf *elf, cons= t char *name, return sym; } =20 +int elf_write_symbol(struct elf *elf, struct symbol *sym) +{ + struct section *symtab, *symtab_shndx; + + symtab =3D find_section_by_name(elf, ".symtab"); + if (!symtab) { + ERROR("no .symtab"); + return -1; + } + + symtab_shndx =3D find_section_by_name(elf, ".symtab_shndx"); + + if (elf_update_symbol(elf, symtab, symtab_shndx, sym)) + return -1; + + mark_sec_changed(elf, symtab, true); + + return 0; +} + struct symbol *elf_create_section_symbol(struct elf *elf, struct section *= sec) { struct symbol *sym =3D calloc(1, sizeof(*sym)); diff --git a/tools/objtool/include/objtool/builtin.h b/tools/objtool/includ= e/objtool/builtin.h index b9e229ed4dc0..e844e9c82b7b 100644 --- a/tools/objtool/include/objtool/builtin.h +++ b/tools/objtool/include/objtool/builtin.h @@ -9,8 +9,8 @@ =20 struct opts { /* actions: */ - bool cfi; bool checksum; + const char *disas; bool dump_orc; bool hack_jump_label; bool hack_noinstr; @@ -20,6 +20,7 @@ struct opts { bool noabs; bool noinstr; bool orc; + int prefix; bool retpoline; bool rethunk; bool unret; @@ -27,14 +28,14 @@ struct opts { bool stackval; bool static_call; bool uaccess; - int prefix; - const char *disas; =20 /* options: */ bool backtrace; bool backup; + bool cfi; const char *debug_checksum; bool dryrun; + bool fineibt; bool link; bool mnop; bool module; diff --git a/tools/objtool/include/objtool/elf.h b/tools/objtool/include/ob= jtool/elf.h index e452784df702..305183f30a33 100644 --- a/tools/objtool/include/objtool/elf.h +++ b/tools/objtool/include/objtool/elf.h @@ -199,6 +199,7 @@ struct reloc *elf_init_reloc_data_sym(struct elf *elf, = struct section *sec, struct symbol *sym, s64 addend); =20 +int elf_write_symbol(struct elf *elf, struct symbol *sym); int elf_write_insn(struct elf *elf, struct section *sec, unsigned long off= set, unsigned int len, const char *insn); =20 --=20 2.53.0 From nobody Thu Jun 18 07:54:40 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 34F9A37C0E6; Fri, 1 May 2026 04:09:15 +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=1777608555; cv=none; b=jmqCYUzLsu8EFi9bQoU+yqonEOdtMJbgbY3wbpLuPf0cN64T+uZ+kijNNCohW6MST/whMlbP7fZuI1PQTYJ2TQ3wC6BMCFrVMUOErEBIPl4Gdld/xbR3rZVrNra/YxHCiJOhQpUOduEzBDvVsKsoHgd6dm4/lVjhhD0CE5Zb58s= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777608555; c=relaxed/simple; bh=3Ee18BmC2EF5jPRLr05L4egEX4DInJIDJhkmjz45QV4=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=HLjVqx4LRvyZlaifgDxhJoovqeOK1lyifsoiIMbVeS2TaZhebEEcSz0cAYxogueh9o6UG8Z9usm4Pj5uap7SBxoy1ofz/O4tFFCL4LAC2ZOpj76FE6TVXYWUOn20rkORcXir2ePjck2DpAyvITBaP+Uyf1hNdPKto0Z4GDK2tUc= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=uPJk0ruk; 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="uPJk0ruk" Received: by smtp.kernel.org (Postfix) with ESMTPSA id C96ABC2BCB8; Fri, 1 May 2026 04:09:14 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1777608555; bh=3Ee18BmC2EF5jPRLr05L4egEX4DInJIDJhkmjz45QV4=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=uPJk0rukZeOpeNbhHRBUsM24NecfFTN9tO44rWPdKI7h/IMit0RRPz/nBChViHcYH 3M0VSkig+cX8lt0inU28+wHGgwwwUQYjJbjpjvLMo+yFjlyM/gBvFdp0dCaCkUmHl4 FqnAbW3fGKeuGKYjd1+JAE6cmLenqA0aI1FPNmh/xMiI1dcPo8MVBTVscbqCqrDwe3 wQY6v2XtrTJdOrSYX66eWYyCsi+9gwY4/BkEMW5Gb/p3bQf12iXdGsvboAfUEIHM2J GOhrrZYJ8NeQmqPHnf2EtqMwVH4YDV1UDQCGN0jDKoMl8Nd+pb/szo6t+cnfCBz7Fw Om76xwpW8zsTA== From: Josh Poimboeuf To: x86@kernel.org Cc: linux-kernel@vger.kernel.org, live-patching@vger.kernel.org, Peter Zijlstra , Joe Lawrence , Song Liu , Miroslav Benes , Petr Mladek Subject: [PATCH v2 51/53] objtool/klp: Fix kCFI prefix finding/cloning Date: Thu, 30 Apr 2026 21:08:39 -0700 Message-ID: <3a6674fa08e32ea6b02adf3e2de185b8ad99b01f.1777575753.git.jpoimboe@kernel.org> X-Mailer: git-send-email 2.53.0 In-Reply-To: References: 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" With CFI+CALL_PADDING, Clang places .Ltmp labels at the start of the NOP padding (offset 5) between the __cfi_ prefix and the function entry point. get_func_prefix() only checks the immediately previous symbol, so the intervening .Ltmp label causes it to miss the __cfi_ prefix symbol. This results in klp-diff not cloning the kCFI type hash into the livepatch module, causing a CFI failure at module load when calling callback functions through indirect calls: CFI failure at __klp_enable_patch+0xab/0x140 (target: pre_patch_callback+0x0/0x80 [livepatch_combined]; expected type: 0xde073954) Instead of walking backward through the section's symbol list, just use find_func_containing() for the byte before the function. This works now that __cfi_ symbols are being grown by objtool to fill the padding. Signed-off-by: Josh Poimboeuf --- tools/objtool/include/objtool/elf.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/objtool/include/objtool/elf.h b/tools/objtool/include/ob= jtool/elf.h index 305183f30a33..fccf72cbd343 100644 --- a/tools/objtool/include/objtool/elf.h +++ b/tools/objtool/include/objtool/elf.h @@ -539,10 +539,10 @@ static inline struct symbol *get_func_prefix(struct s= ymbol *func) { struct symbol *prev; =20 - if (!is_func_sym(func)) + if (!is_func_sym(func) || !func->offset) return NULL; =20 - prev =3D sec_prev_sym(func); + prev =3D find_func_containing(func->sec, func->offset - 1); if (prev && is_prefix_func(prev)) return prev; =20 --=20 2.53.0 From nobody Thu Jun 18 07:54:40 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 A594737CD4E; Fri, 1 May 2026 04:09:15 +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=1777608556; cv=none; b=oDNobvkJwnoznzxsGB/dkdvCuc+D3EdJZu2zFMgjlM52y4//0mdHeiGq+AZNDErinbeatmk+ne3BH2E1rcLc5OCGlaqh3Vt9nPmAIYxU9DnBcvpRaU/tgW3GK/zaVQEh30JpkOLpexkOa1qI+w3kbZMqPVo9AWv4CiIGOsJ5Nnw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777608556; c=relaxed/simple; bh=QM3Sy43j93J1jjno7s1BKyzci2eruNBPlvhQNf4ekrw=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=o0e0T/csnIldNHO8/BU39B9Ey4ipiA1ZZ86Tk6depdectwtrT6Tb1lV3OFernhlUs571DW4XZOWqz6suW5vRq0RHPmzhhPS91NtL9Yw9pT9K4nqn6zmNhsF9uIcwH4Hq0N5Gp97seE70LeL9KavCq30eaMIGukJqblAdKFeD3UQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=L6G871RT; 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="L6G871RT" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 435DEC2BCC7; Fri, 1 May 2026 04:09:15 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1777608555; bh=QM3Sy43j93J1jjno7s1BKyzci2eruNBPlvhQNf4ekrw=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=L6G871RTLzKkbu/R9WX6ECusV4gfsxWYo4oQv19jQCbeW/8ygMcaLA+TbLmZlv4tz TXUum0Se+IXZ9ZioyJKWYfB1+6AEQlIbRO0wuXREsbq4yshSRYB3MxIifCpaZpEF+Y u0hTosZXzNf4xZ62/NN3E+oMspO2y1WOZj7fECAt2XiROrBDOii6XmbL5o4YrH07yp ZhQFhg7lOULhY/LeUaBagw29rl0PMRY0zi60A2KU8Vm1GTezbT83vmNCsZeyuKdVlm aYshgu8vy916n7fEZ8JRsw3l1eA8TCA3o66iw7ZWHw7QLwaD+S+W14NR5RKvIWDVdE 53w5izTNKlz9w== From: Josh Poimboeuf To: x86@kernel.org Cc: linux-kernel@vger.kernel.org, live-patching@vger.kernel.org, Peter Zijlstra , Joe Lawrence , Song Liu , Miroslav Benes , Petr Mladek Subject: [PATCH v2 52/53] objtool: Improve and simplify prefix symbol detection Date: Thu, 30 Apr 2026 21:08:40 -0700 Message-ID: <45078e9521b1c36da7e64a6a22153b7433711b51.1777575753.git.jpoimboe@kernel.org> X-Mailer: git-send-email 2.53.0 In-Reply-To: References: 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" Only create prefix symbols for functions that have __patchable_function_entries entries, since those are the only C functions where prefix NOPs are intentional. This both simplifies the detection and makes it more accurate. Note that assembly functions using SYM_TYPED_FUNC_START() can also have prefixed NOPs, but that macro already creates their __cfi_ symbols. Signed-off-by: Josh Poimboeuf --- tools/objtool/check.c | 90 ++++++++++--------------------------------- 1 file changed, 21 insertions(+), 69 deletions(-) diff --git a/tools/objtool/check.c b/tools/objtool/check.c index 0d9b859b006e..1635c87a4ac8 100644 --- a/tools/objtool/check.c +++ b/tools/objtool/check.c @@ -4296,17 +4296,6 @@ static bool ignore_unreachable_insn(struct objtool_f= ile *file, struct instructio * For FineIBT or kCFI, a certain number of bytes preceding the function m= ay be * NOPs. Those NOPs may be rewritten at runtime and executed, so give the= m a * proper function name: __pfx_. - * - * The NOPs may not exist for the following cases: - * - * - compiler cloned functions (*.cold, *.part0, etc) - * - asm functions created with inline asm or without SYM_FUNC_START() - * - * Also, the function may already have a prefix from a previous objtool run - * (livepatch extracted functions, or manually running objtool multiple ti= mes). - * - * So return 0 if the NOPs are missing or the function already has a prefix - * symbol. */ static int create_prefix_symbol(struct objtool_file *file, struct symbol *= func) { @@ -4314,10 +4303,6 @@ static int create_prefix_symbol(struct objtool_file = *file, struct symbol *func) char name[SYM_NAME_LEN]; struct cfi_state *cfi; =20 - if (!is_func_sym(func) || is_prefix_func(func) || is_cold_func(func) || - func->static_call_tramp) - return 0; - if ((strlen(func->name) + sizeof("__pfx_") > SYM_NAME_LEN)) { WARN("%s: symbol name too long, can't create __pfx_ symbol", func->name); @@ -4327,59 +4312,21 @@ static int create_prefix_symbol(struct objtool_file= *file, struct symbol *func) if (snprintf_check(name, SYM_NAME_LEN, "__pfx_%s", func->name)) return -1; =20 - if (file->klp) { - struct symbol *pfx; - - pfx =3D find_symbol_by_offset(func->sec, func->offset - opts.prefix); - if (pfx && is_prefix_func(pfx) && !strcmp(pfx->name, name)) - return 0; - } - - insn =3D find_insn(file, func->sec, func->offset); - if (!insn) { - WARN("%s: can't find starting instruction", func->name); + if (!elf_create_symbol(file->elf, name, func->sec, + GELF_ST_BIND(func->sym.st_info), + GELF_ST_TYPE(func->sym.st_info), + func->offset - opts.prefix, opts.prefix)) return -1; - } - - for (prev =3D prev_insn_same_sec(file, insn); - prev; - prev =3D prev_insn_same_sec(file, prev)) { - u64 offset; - - if (prev->type !=3D INSN_NOP) - return 0; - - offset =3D func->offset - prev->offset; - - if (offset > opts.prefix) - return 0; - - if (offset < opts.prefix) - continue; - - if (!elf_create_symbol(file->elf, name, func->sec, - GELF_ST_BIND(func->sym.st_info), - GELF_ST_TYPE(func->sym.st_info), - prev->offset, opts.prefix)) - return -1; - - break; - } - - if (!prev) - return 0; - - if (!insn->cfi) { - /* - * This can happen if stack validation isn't enabled or the - * function is annotated with STACK_FRAME_NON_STANDARD. - */ - return 0; - } =20 /* Propagate insn->cfi to the prefix code */ + insn =3D find_insn(file, func->sec, func->offset); + if (!insn || !insn->cfi) + return 0; + cfi =3D cfi_hash_find_or_add(insn->cfi); - for (; prev !=3D insn; prev =3D next_insn_same_sec(file, prev)) + for (prev =3D find_insn(file, func->sec, func->offset - opts.prefix); + prev && prev !=3D insn; + prev =3D next_insn_same_sec(file, prev)) prev->cfi =3D cfi; =20 return 0; @@ -4387,15 +4334,20 @@ static int create_prefix_symbol(struct objtool_file= *file, struct symbol *func) =20 static int create_prefix_symbols(struct objtool_file *file) { - struct section *sec; + struct section *pfe_sec; struct symbol *func; + struct reloc *reloc; =20 - for_each_sec(file->elf, sec) { - if (!is_text_sec(sec)) + for_each_sec(file->elf, pfe_sec) { + if (strcmp(pfe_sec->name, "__patchable_function_entries")) + continue; + if (!pfe_sec->rsec) continue; =20 - sec_for_each_sym(sec, func) { - if (create_prefix_symbol(file, func)) + for_each_reloc(pfe_sec->rsec, reloc) { + func =3D find_func_by_offset(reloc->sym->sec, + reloc->sym->offset + reloc_addend(reloc) + opts.prefix); + if (func && create_prefix_symbol(file, func)) return -1; } } --=20 2.53.0 From nobody Thu Jun 18 07:54:40 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 2410637DE8E; Fri, 1 May 2026 04:09:16 +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=1777608556; cv=none; b=fXfQbYUxS7EhGSC3/tO+nCwPz982R7eBZD3E/U97cp+fbcU0gLj3iosY2P5pmIbsIFv+kI1nj3vU1JxTSmeZsKyCZlNprgcF7mZpwQvn6bG6OgRFnZzHS5DyABdeMqT84nniM92vMon0Pvm6JnETr013/e1wPv5dMAZ3toJjQBY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777608556; c=relaxed/simple; bh=GF28pI1dFS/n6Z9A4UM/rCVDz8QhPIV1HAHHVKcRD2k=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=rZzXsu9RHwa5qGALEkl4mSsu4rR+FZiVjViM8/jlnjJ381vKufw1K6yAjmr9H+YehVuKOnilohHvIfy1dAVz/QcSiWk1tanywnFFfMgRgpbgXprzyNOLpMAvgT5G1ZBtvIHDuhRCPMRCCYhZ9LW0miaXXJAaLFfjQkrhcexYIwU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=Fb03TBxR; 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="Fb03TBxR" Received: by smtp.kernel.org (Postfix) with ESMTPSA id B28C4C2BCB9; Fri, 1 May 2026 04:09:15 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1777608556; bh=GF28pI1dFS/n6Z9A4UM/rCVDz8QhPIV1HAHHVKcRD2k=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=Fb03TBxR69SS0/X2CYZAQnq+qKnZnfZD7FGOkwpdDBVAyJpKUz8/fK4xJq3Gs+2a0 0nU23QtD1ffjeMtLEXTVG1Sfcts7hwA9TiN9/rwJ9rqMBnVmqCYraKAq02B9CxLzcv ihHS6uocB2/1i+tx438IGbScAdKVn9C9w/6Fzpvjo6TP/SMXul29FVojJ7xkI92KF+ fLPTe9PJeQcgOeRYzS3K/4wFOmq7RUjmMLLVz9jhN0dYwgHdGMtfgtwujKwO48UwkK JmvtHEKNwk57/ABZPpTkoZKjcplyyFVyRFm7Oh1y1OBBC58A4w1uQkwXg9/uDUQfmb XVLAhnHFkjgPA== From: Josh Poimboeuf To: x86@kernel.org Cc: linux-kernel@vger.kernel.org, live-patching@vger.kernel.org, Peter Zijlstra , Joe Lawrence , Song Liu , Miroslav Benes , Petr Mladek Subject: [PATCH v2 53/53] objtool/klp: Cache dont_correlate() result Date: Thu, 30 Apr 2026 21:08:41 -0700 Message-ID: X-Mailer: git-send-email 2.53.0 In-Reply-To: References: 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" Cache the dont_correlate() result once per symbol at the start of correlate_symbols(). This reduces klp diff time on an arm64 LTO vmlinux.o from 2m51s to 35s. Acked-by: Song Liu Signed-off-by: Josh Poimboeuf --- tools/objtool/include/objtool/elf.h | 1 + tools/objtool/klp-diff.c | 29 +++++++++++++++++------------ 2 files changed, 18 insertions(+), 12 deletions(-) diff --git a/tools/objtool/include/objtool/elf.h b/tools/objtool/include/ob= jtool/elf.h index fccf72cbd343..d9c44df9cc76 100644 --- a/tools/objtool/include/objtool/elf.h +++ b/tools/objtool/include/objtool/elf.h @@ -96,6 +96,7 @@ struct symbol { u8 changed : 1; u8 included : 1; u8 klp : 1; + u8 dont_correlate : 1; struct list_head pv_target; struct reloc *relocs; struct section *group_sec; diff --git a/tools/objtool/klp-diff.c b/tools/objtool/klp-diff.c index ed3bf1c55001..f8787d7d1454 100644 --- a/tools/objtool/klp-diff.c +++ b/tools/objtool/klp-diff.c @@ -524,7 +524,7 @@ static struct symbol *find_twin(struct elfs *e, struct = symbol *sym1) =20 /* Count orig candidates */ for_each_sym_by_demangled_name(e->orig, sym1->demangled_name, sym2) { - if (sym2->twin || sym1->type !=3D sym2->type || dont_correlate(sym2) || + if (sym2->twin || sym1->type !=3D sym2->type || sym2->dont_correlate || (!maybe_same_file(sym1, sym2))) continue; =20 @@ -550,7 +550,7 @@ static struct symbol *find_twin(struct elfs *e, struct = symbol *sym1) =20 /* Count patched candidates */ for_each_sym_by_demangled_name(e->patched, sym1->demangled_name, sym2) { - if (sym2->twin || sym1->type !=3D sym2->type || dont_correlate(sym2) || + if (sym2->twin || sym1->type !=3D sym2->type || sym2->dont_correlate || !maybe_same_file(sym1, sym2)) continue; =20 @@ -693,7 +693,7 @@ static struct symbol *find_twin_suffixed(struct elf *el= f, struct symbol *sym1) return NULL; =20 for_each_sym_by_name(elf, name, sym2) { - if (sym2->twin || sym1->type !=3D sym2->type || dont_correlate(sym2)) + if (sym2->twin || sym1->type !=3D sym2->type || sym2->dont_correlate) continue; count++; match =3D sym2; @@ -733,7 +733,7 @@ static struct symbol *find_twin_positional(struct elfs = *e, struct symbol *sym1) struct symbol *sym2, *match =3D NULL; =20 for_each_sym_by_demangled_name(e->orig, sym1->demangled_name, sym2) { - if (sym2->twin || sym1->type !=3D sym2->type || dont_correlate(sym2) || + if (sym2->twin || sym1->type !=3D sym2->type || sym2->dont_correlate || !maybe_same_file(sym1, sym2)) continue; if (is_tu_local_sym(sym1) !=3D is_tu_local_sym(sym2) || @@ -745,7 +745,7 @@ static struct symbol *find_twin_positional(struct elfs = *e, struct symbol *sym1) } =20 for_each_sym_by_demangled_name(e->patched, sym1->demangled_name, sym2) { - if (sym2->twin || sym1->type !=3D sym2->type || dont_correlate(sym2) || + if (sym2->twin || sym1->type !=3D sym2->type || sym2->dont_correlate || !maybe_same_file(sym1, sym2)) continue; if (is_tu_local_sym(sym1) !=3D is_tu_local_sym(sym2) || @@ -777,6 +777,11 @@ static int correlate_symbols(struct elfs *e) struct symbol *sym1, *sym2; bool progress; =20 + for_each_sym(e->orig, sym1) + sym1->dont_correlate =3D dont_correlate(sym1); + for_each_sym(e->patched, sym2) + sym2->dont_correlate =3D dont_correlate(sym2); + /* Correlate FILE symbols */ file1_sym =3D first_file_symbol(e->orig); file2_sym =3D first_file_symbol(e->patched); @@ -817,7 +822,7 @@ static int correlate_symbols(struct elfs *e) do { progress =3D false; for_each_sym(e->orig, sym1) { - if (sym1->twin || dont_correlate(sym1)) + if (sym1->twin || sym1->dont_correlate) continue; sym2 =3D find_twin(e, sym1); if (!sym2) @@ -831,7 +836,7 @@ static int correlate_symbols(struct elfs *e) return -1; =20 for_each_sym(e->orig, sym1) { - if (sym1->twin || dont_correlate(sym1)) + if (sym1->twin || sym1->dont_correlate) continue; sym2 =3D find_twin_suffixed(e->patched, sym1); if (!sym2) @@ -843,7 +848,7 @@ static int correlate_symbols(struct elfs *e) } while (progress); =20 for_each_sym(e->orig, sym1) { - if (sym1->twin || dont_correlate(sym1)) + if (sym1->twin || sym1->dont_correlate) continue; sym2 =3D find_twin_positional(e, sym1); if (!sym2) @@ -853,7 +858,7 @@ static int correlate_symbols(struct elfs *e) } =20 for_each_sym(e->orig, sym1) { - if (sym1->twin || dont_correlate(sym1)) + if (sym1->twin || sym1->dont_correlate) continue; WARN("no correlation: %s", sym1->name); } @@ -1066,7 +1071,7 @@ static int mark_changed_functions(struct elfs *e) =20 /* Find changed functions */ for_each_sym(e->orig, orig_sym) { - if (dont_correlate(orig_sym)) + if (orig_sym->dont_correlate) continue; =20 patched_sym =3D orig_sym->twin; @@ -1087,7 +1092,7 @@ static int mark_changed_functions(struct elfs *e) =20 /* Find added functions and print them */ for_each_sym(e->patched, patched_sym) { - if (!is_func_sym(patched_sym) || dont_correlate(patched_sym)) + if (!is_func_sym(patched_sym) || patched_sym->dont_correlate) continue; =20 if (!patched_sym->twin) { @@ -1193,7 +1198,7 @@ static bool klp_reloc_needed(struct reloc *patched_re= loc) struct export *export; =20 /* no external symbol to reference */ - if (dont_correlate(patched_sym)) + if (patched_sym->dont_correlate) return false; =20 /* For included functions, a regular reloc will do. */ --=20 2.53.0