From nobody Tue Apr 7 00:44:19 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 6B4D93F880A; Tue, 17 Mar 2026 22:51:35 +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=1773787895; cv=none; b=dfMsMV+G1UEb+gQYVpKhduki/s9co9JknLrSu+/oWTiM7+cE1XnEReXWhrnEiG8rOBXve9lXtHRdOXcyrd4i2L3X/7Rjkwk2+Ojobb30IoZw/pv0ZYVUnB5eSeWf7yPoQYiA7Z4WhQ3ijc6t7844XXG8MQg7U+bSwkj47Bu2xnY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1773787895; c=relaxed/simple; bh=TUaxduyimKBy3VNMssZhboEIRmy6Myd8d1LMjCjwrEk=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=Et7I/GcjdznP2IZRZUwj7Dftwz/o5X3RIcCgcGLnH5NaPsFoKTDJSlpkZW2E/XSkP3RkuKcfWivJ1R9/Ky47i+ef5LFq6V/XA/tFBe/jlo9KctkYSUHFZ99spbnAJY9OtH1oOwi+dOXm15FJSIToUXS+BKJPkUyPOHIPLdihyqs= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=H25Tzxbc; 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="H25Tzxbc" Received: by smtp.kernel.org (Postfix) with ESMTPSA id A0D88C4AF0D; Tue, 17 Mar 2026 22:51:34 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1773787895; bh=TUaxduyimKBy3VNMssZhboEIRmy6Myd8d1LMjCjwrEk=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=H25Tzxbcj2msmLBn45caCXnQrfG0h5THrjah7LuGH/RigZ62FA6ZRLfHZatejHhnW 3ePSGRyBhccA7SVXuomFM4uRyiyeio9tK/5fNn70V68Or0gYagpHoseu8E6sgd/tcI rdrh4T7NERJ83IeyBlxHAbkFuN2DWs2q11f5s3J2qxpkZIvKAWZCfmJKV8Ooekwe/H bpok87dt3Ii5gFBviWjBoThvChQ7I2TcYaKRhl7Wd3pzJpTmH75AgaeLDi7YX73JGJ 5VZz7j1JzzhwNgOUG/r33yri9wUuJUoLgFDMJhNls/w/lNRaPUFcp9eBu87115d07d i1ChgY7HZiAGA== From: Josh Poimboeuf To: x86@kernel.org Cc: linux-kernel@vger.kernel.org, live-patching@vger.kernel.org, Peter Zijlstra , Joe Lawrence , Song Liu , Catalin Marinas , Will Deacon , linux-arm-kernel@lists.infradead.org, Mark Rutland , Nathan Chancellor , Nicolas Schier , Herbert Xu Subject: [PATCH v2 05/12] objtool: Extricate checksum calculation from validate_branch() Date: Tue, 17 Mar 2026 15:51:05 -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. Now that it's no longer called by validate_insn(), checksum_update_insn() has to manually iterate the alternatives. Signed-off-by: Josh Poimboeuf --- tools/objtool/check.c | 71 +++++++++++++++++------- tools/objtool/include/objtool/checksum.h | 6 +- 2 files changed, 53 insertions(+), 24 deletions(-) diff --git a/tools/objtool/check.c b/tools/objtool/check.c index 2301fb7ff3c8..d428d63b29c6 100644 --- a/tools/objtool/check.c +++ b/tools/objtool/check.c @@ -2633,8 +2633,7 @@ static bool validate_branch_enabled(void) { return opts.stackval || opts.orc || - opts.uaccess || - opts.checksum; + opts.uaccess; } =20 static int decode_sections(struct objtool_file *file) @@ -3663,6 +3662,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; @@ -3705,9 +3705,30 @@ 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; =20 + for (alt =3D insn->alts; alt; alt =3D alt->next) { + struct alt_group *alt_group =3D alt->insn->alt_group; + + 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_insn =3D=3D alt_group->last_insn) + break; + } + } else { + checksum_update(func, insn, &alt->insn->offset, sizeof(alt->insn->offse= t)); + } + } + if (insn->fake) return; =20 @@ -3716,9 +3737,11 @@ static void checksum_update_insn(struct objtool_file= *file, struct symbol *func, if (!reloc) { struct symbol *call_dest =3D insn_call_dest(insn); =20 - if (call_dest) + if (call_dest) { + /* intra-TU call without reloc */ checksum_update(func, insn, call_dest->demangled_name, strlen(call_dest->demangled_name)); + } return; } =20 @@ -3745,6 +3768,29 @@ static void checksum_update_insn(struct objtool_file= *file, struct symbol *func, checksum_update(func, insn, &offset, sizeof(offset)); } =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) { + if (!is_func_sym(func)) + 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, @@ -4026,9 +4072,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)) @@ -4094,9 +4137,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)"); @@ -4539,9 +4579,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); @@ -4554,9 +4591,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 @@ -5011,10 +5045,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; @@ -5105,6 +5135,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 7fe21608722a..36a17688c716 100644 --- a/tools/objtool/include/objtool/checksum.h +++ b/tools/objtool/include/objtool/checksum.h @@ -32,11 +32,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