Live Patching
 help / color / mirror / Atom feed
From: Josh Poimboeuf <jpoimboe@kernel.org>
To: x86@kernel.org
Cc: linux-kernel@vger.kernel.org, live-patching@vger.kernel.org,
	Peter Zijlstra <peterz@infradead.org>,
	Joe Lawrence <joe.lawrence@redhat.com>,
	Song Liu <song@kernel.org>, Miroslav Benes <mbenes@suse.cz>,
	Petr Mladek <pmladek@suse.com>
Subject: [PATCH v2 39/53] objtool/klp: Extricate checksum calculation from validate_branch()
Date: Thu, 30 Apr 2026 21:08:27 -0700	[thread overview]
Message-ID: <a455b47ef57dcc3506cd97e3c2027ac744941cf1.1777575752.git.jpoimboe@kernel.org> (raw)
In-Reply-To: <cover.1777575752.git.jpoimboe@kernel.org>

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 <song@kernel.org>
Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org>
---
 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;
 
-	if (insn->no_reloc)
-		return NULL;
-
-	if (!file)
+	if (!file || insn->no_reloc || insn->fake)
 		return NULL;
 
 	reloc = find_reloc_by_dest_range(file->elf, insn->sec,
@@ -2622,9 +2619,17 @@ static void mark_holes(struct objtool_file *file)
 
 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;
 }
 
@@ -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 == INSN_CLAC || alt_insn->type == INSN_STAC;
 }
 
+#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 = insn_reloc(file, insn);
+	struct alternative *alt;
 	unsigned long offset;
 	struct symbol *sym;
+	static bool in_alt;
 
 	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;
 	}
 
 	sym = reloc->sym;
@@ -3726,21 +3734,78 @@ static void checksum_update_insn(struct objtool_file *file, struct symbol *func,
 
 		str = sym->sec->data->d_buf + sym->offset + offset;
 		checksum_update(func, insn, str, strlen(str));
-		return;
+		goto alts;
 	}
 
 	if (is_sec_sym(sym)) {
 		sym = find_symbol_containing(reloc->sym->sec, offset);
 		if (!sym)
-			return;
+			goto alts;
 
 		offset -= sym->offset;
 	}
 
 	checksum_update(func, insn, sym->demangled_name, strlen(sym->demangled_name));
 	checksum_update(func, insn, &offset, sizeof(offset));
+
+alts:
+	for (alt = insn->alts; alt; alt = alt->next) {
+		struct alt_group *alt_group = alt->insn->alt_group;
+
+		/* Prevent __ex_table recursion, e.g. LOAD_SEGMENT() */
+		if (in_alt)
+			break;
+		in_alt = 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->feature));
+
+			for (alt_insn = alt->insn; alt_insn; alt_insn = next_insn_same_sec(file, alt_insn)) {
+				checksum_update_insn(file, func, alt_insn);
+				if (!alt_group->last_insn || alt_insn == alt_group->last_insn)
+					break;
+			}
+		} else {
+			checksum_update_insn(file, func, alt->insn);
+		}
+
+		in_alt = 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 *func,
@@ -4022,9 +4087,6 @@ static int do_validate_branch(struct objtool_file *file, struct symbol *func,
 		insn->trace = 0;
 		next_insn = next_insn_to_validate(file, insn);
 
-		if (opts.checksum && func && insn->sec)
-			checksum_update_insn(file, func, insn);
-
 		if (func && insn_func(insn) && func != 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 = insn_func(insn);
 		int ret;
 
-		if (opts.checksum)
-			checksum_init(func);
-
 		ret = validate_branch(file, func, insn, *state);
 		if (ret)
 			BT_INSN(insn, "<=== (hint)");
@@ -4535,9 +4594,6 @@ static int validate_symbol(struct objtool_file *file, struct section *sec,
 
 	func = insn_func(insn);
 
-	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();
 
-	if (opts.checksum)
-		checksum_finish(func);
-
 	return ret;
 }
 
@@ -5007,10 +5060,6 @@ int check(struct objtool_file *file)
 	cfi_hash_add(&init_cfi);
 	cfi_hash_add(&func_cfi);
 
-	ret = checksum_debug_init(file);
-	if (ret)
-		goto out;
-
 	ret = decode_sections(file);
 	if (ret)
 		goto out;
@@ -5101,6 +5150,9 @@ int check(struct objtool_file *file)
 		warnings += check_abs_references(file);
 
 	if (opts.checksum) {
+		ret = calculate_checksums(file);
+		if (ret)
+			goto out;
 		ret = create_sym_checksum_section(file);
 		if (ret)
 			goto out;
diff --git a/tools/objtool/include/objtool/checksum.h b/tools/objtool/include/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)
 
 #else /* !BUILD_KLP */
 
-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; }
 
 #endif /* !BUILD_KLP */
 
-- 
2.53.0


  parent reply	other threads:[~2026-05-01  4:09 UTC|newest]

Thread overview: 103+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-05-01  4:07 [PATCH v2 00/53] objtool/klp: Some klp-build fixes and improvements Josh Poimboeuf
2026-05-01  4:07 ` [PATCH v2 01/53] objtool/klp: Fix is_uncorrelated_static_local() for Clang Josh Poimboeuf
2026-05-01  4:07 ` [PATCH v2 02/53] objtool/klp: Fix .data..once static local non-correlation Josh Poimboeuf
2026-05-01  4:07 ` [PATCH v2 03/53] objtool/klp: Don't correlate __ADDRESSABLE() symbols Josh Poimboeuf
2026-05-01 10:26   ` Song Liu
2026-05-01  4:07 ` [PATCH v2 04/53] objtool/klp: Don't correlate absolute symbols Josh Poimboeuf
2026-05-01  4:07 ` [PATCH v2 05/53] objtool/klp: Don't correlate __initstub__ symbols Josh Poimboeuf
2026-05-01  4:07 ` [PATCH v2 06/53] objtool/klp: Don't report uncorrelated functions as new Josh Poimboeuf
2026-05-01  4:07 ` [PATCH v2 07/53] objtool/klp: Improve local label check Josh Poimboeuf
2026-05-01 10:27   ` Song Liu
2026-05-01  4:07 ` [PATCH v2 08/53] objtool/klp: Fix create_fake_symbols() skipping entsize-based sections Josh Poimboeuf
2026-05-01  4:07 ` [PATCH v2 09/53] objtool: Replace iterator callback with for_each_sym_by_mangled_name() Josh Poimboeuf
2026-05-01 10:28   ` Song Liu
2026-05-04 13:59   ` Miroslav Benes
2026-05-01  4:07 ` [PATCH v2 10/53] objtool/klp: Fix --debug-checksum for duplicate symbol names Josh Poimboeuf
2026-05-04 14:04   ` Miroslav Benes
2026-05-01  4:07 ` [PATCH v2 11/53] objtool/klp: Fix handling of zero-length .altinstr_replacement sections Josh Poimboeuf
2026-05-01  4:08 ` [PATCH v2 12/53] objtool/klp: Fix cloning of zero-length section symbols Josh Poimboeuf
2026-05-01  4:08 ` [PATCH v2 13/53] objtool/klp: Fix XXH3 state memory leak Josh Poimboeuf
2026-05-01  4:08 ` [PATCH v2 14/53] objtool/klp: Fix extraction of text annotations for alternatives Josh Poimboeuf
2026-05-01  4:08 ` [PATCH v2 15/53] objtool/klp: Fix kCFI trap handling Josh Poimboeuf
2026-05-01  4:08 ` [PATCH v2 16/53] objtool/klp: Fix relocation conversion failures for R_X86_64_NONE Josh Poimboeuf
2026-05-01  4:08 ` [PATCH v2 17/53] objtool: Move mark_rodata() to elf.c Josh Poimboeuf
2026-05-01  4:08 ` [PATCH v2 18/53] objtool/klp: Simplify reloc symbol conversion Josh Poimboeuf
2026-05-01 10:31   ` Song Liu
2026-05-04 14:04   ` Miroslav Benes
2026-05-01  4:08 ` [PATCH v2 19/53] objtool/klp: Fix pointer comparisons for rodata objects Josh Poimboeuf
2026-05-01 10:35   ` Song Liu
2026-05-05  9:44   ` Miroslav Benes
2026-05-01  4:08 ` [PATCH v2 20/53] objtool/klp: Don't correlate .rodata.cst* constant pool objects Josh Poimboeuf
2026-05-01 10:37   ` Song Liu
2026-05-01 17:04     ` Josh Poimboeuf
2026-05-01 17:31       ` Song Liu
2026-05-05  9:44   ` Miroslav Benes
2026-05-01  4:08 ` [PATCH v2 21/53] objtool/klp: Fix reloc corruption in convert_reloc_sym_to_secsym() Josh Poimboeuf
2026-05-01 10:38   ` Song Liu
2026-05-05  9:44   ` Miroslav Benes
2026-05-01  4:08 ` [PATCH v2 22/53] objtool: Fix reloc hash collision in find_reloc_by_dest_range() Josh Poimboeuf
2026-05-01  4:08 ` [PATCH v2 23/53] klp-build: Fix hang on out-of-date .config Josh Poimboeuf
2026-05-01 10:39   ` Song Liu
2026-05-05  9:44   ` Miroslav Benes
2026-05-01  4:08 ` [PATCH v2 24/53] klp-build: Fix checksum comparison for changed offsets Josh Poimboeuf
2026-05-01 10:41   ` Song Liu
2026-05-05 10:05   ` Miroslav Benes
2026-05-01  4:08 ` [PATCH v2 25/53] klp-build: Don't use errexit Josh Poimboeuf
2026-05-01  4:08 ` [PATCH v2 26/53] klp-build: Validate patch file existence Josh Poimboeuf
2026-05-01  4:08 ` [PATCH v2 27/53] klp-build: Suppress excessive fuzz output by default Josh Poimboeuf
2026-05-01  4:08 ` [PATCH v2 28/53] klp-build: Fix patch cleanup on interrupt Josh Poimboeuf
2026-05-05 11:31   ` Miroslav Benes
2026-05-01  4:08 ` [PATCH v2 29/53] klp-build: Reject patches to vDSO Josh Poimboeuf
2026-05-05 11:31   ` Miroslav Benes
2026-05-01  4:08 ` [PATCH v2 30/53] klp-build: Reject patches to realmode Josh Poimboeuf
2026-05-05 11:31   ` Miroslav Benes
2026-05-01  4:08 ` [PATCH v2 31/53] klp-build: Print "objtool klp diff" command in verbose mode Josh Poimboeuf
2026-05-05 11:31   ` Miroslav Benes
2026-05-01  4:08 ` [PATCH v2 32/53] klp-build: Remove redundant SRC and OBJ variables Josh Poimboeuf
2026-05-01 10:42   ` Song Liu
2026-05-05 11:26   ` Miroslav Benes
2026-05-01  4:08 ` [PATCH v2 33/53] objtool/klp: Don't set sym->file for section symbols Josh Poimboeuf
2026-05-05 11:31   ` Miroslav Benes
2026-05-01  4:08 ` [PATCH v2 34/53] objtool: Include libsubcmd headers directly from source tree Josh Poimboeuf
2026-05-05 11:31   ` Miroslav Benes
2026-05-01  4:08 ` [PATCH v2 35/53] objtool/klp: Create empty checksum sections for function-less object files Josh Poimboeuf
2026-05-05 11:31   ` Miroslav Benes
2026-05-01  4:08 ` [PATCH v2 36/53] objtool/klp: Handle Clang .data..Lanon anonymous data sections Josh Poimboeuf
2026-05-05 11:26   ` Miroslav Benes
2026-05-01  4:08 ` [PATCH v2 37/53] objtool: Add is_alias_sym() helper Josh Poimboeuf
2026-05-05 11:31   ` Miroslav Benes
2026-05-01  4:08 ` [PATCH v2 38/53] objtool: Add is_cold_func() helper Josh Poimboeuf
2026-05-01 10:43   ` Song Liu
2026-05-05 11:26   ` Miroslav Benes
2026-05-01  4:08 ` Josh Poimboeuf [this message]
2026-05-05 11:43   ` [PATCH v2 39/53] objtool/klp: Extricate checksum calculation from validate_branch() Miroslav Benes
2026-05-01  4:08 ` [PATCH v2 40/53] objtool: Consolidate file decoding into decode_file() Josh Poimboeuf
2026-05-05 11:43   ` Miroslav Benes
2026-05-01  4:08 ` [PATCH v2 41/53] objtool/klp: Add "objtool klp checksum" subcommand Josh Poimboeuf
2026-05-05 11:43   ` Miroslav Benes
2026-05-01  4:08 ` [PATCH v2 42/53] klp-build: Use " Josh Poimboeuf
2026-05-05 11:58   ` Miroslav Benes
2026-05-01  4:08 ` [PATCH v2 43/53] objtool/klp: Remove "objtool --checksum" Josh Poimboeuf
2026-05-05 11:59   ` Miroslav Benes
2026-05-01  4:08 ` [PATCH v2 44/53] klp-build: Validate short-circuit prerequisites Josh Poimboeuf
2026-05-01 10:49   ` Song Liu
2026-05-05 12:00   ` Miroslav Benes
2026-05-01  4:08 ` [PATCH v2 45/53] objtool/klp: Calculate object checksums Josh Poimboeuf
2026-05-01 10:53   ` Song Liu
2026-05-05 12:07   ` Miroslav Benes
2026-05-01  4:08 ` [PATCH v2 46/53] objtool/klp: Rewrite symbol correlation algorithm Josh Poimboeuf
2026-05-01 12:07   ` Song Liu
2026-05-05 13:07   ` Miroslav Benes
2026-05-01  4:08 ` [PATCH v2 47/53] objtool/klp: Add correlation debugging output Josh Poimboeuf
2026-05-05 13:28   ` Miroslav Benes
2026-05-01  4:08 ` [PATCH v2 48/53] objtool: Add insn_sym() helper Josh Poimboeuf
2026-05-01 12:11   ` Song Liu
2026-05-01  4:08 ` [PATCH v2 49/53] objtool/klp: Fix position-dependent checksums for non-relocated jumps/calls Josh Poimboeuf
2026-05-01 12:16   ` Song Liu
2026-05-01  4:08 ` [PATCH v2 50/53] objtool: Grow __cfi_* prefix symbols for all CFI+CALL_PADDING Josh Poimboeuf
2026-05-01  4:08 ` [PATCH v2 51/53] objtool/klp: Fix kCFI prefix finding/cloning Josh Poimboeuf
2026-05-01 12:17   ` Song Liu
2026-05-01  4:08 ` [PATCH v2 52/53] objtool: Improve and simplify prefix symbol detection Josh Poimboeuf
2026-05-01  4:08 ` [PATCH v2 53/53] objtool/klp: Cache dont_correlate() result Josh Poimboeuf
2026-05-05 13:40   ` Miroslav Benes
2026-05-01 18:47 ` [PATCH v2 00/53] objtool/klp: Some klp-build fixes and improvements Josh Poimboeuf

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=a455b47ef57dcc3506cd97e3c2027ac744941cf1.1777575752.git.jpoimboe@kernel.org \
    --to=jpoimboe@kernel.org \
    --cc=joe.lawrence@redhat.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=live-patching@vger.kernel.org \
    --cc=mbenes@suse.cz \
    --cc=peterz@infradead.org \
    --cc=pmladek@suse.com \
    --cc=song@kernel.org \
    --cc=x86@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox