Live Patching
 help / color / mirror / Atom feed
From: Joe Lawrence <joe.lawrence@redhat.com>
To: Puranjay Mohan <puranjay@kernel.org>
Cc: live-patching@vger.kernel.org,
	Josh Poimboeuf <jpoimboe@kernel.org>,
	Peter Zijlstra <peterz@infradead.org>, Song Liu <song@kernel.org>,
	Miroslav Benes <mbenes@suse.cz>
Subject: Re: [PATCH 1/3] objtool/klp: Build test fixtures with ftrace
Date: Thu, 22 Oct 2026 10:46:30 -0400	[thread overview]
Message-ID: <atohxvOb9MAxkhsg@redhat.com> (raw)
In-Reply-To: <20261022122544.125305-2-puranjay@kernel.org>

On Thu, Oct 22, 2026 at 05:25:36AM -0700, Puranjay Mohan wrote:
> Livepatch depends on ftrace, so the kernel klp-build operates on always
> has __mcount_loc, but the test fixtures are built without it.
> 
> On x86, build them with -pg -mfentry and generate __mcount_loc like the
> kernel does: with -mrecord-mcount -mnop-mcount if the compiler supports
> it (FTRACE_MCOUNT_USE_CC), otherwise with objtool --mcount --mnop
> (FTRACE_MCOUNT_USE_OBJTOOL).
> 
> test-checksum-alt ran objtool --mcount only to get insn->alts, which
> "klp checksum" builds by itself, and that now warns about the existing
> __mcount_loc.  Remove it.
> 
> test-special-sections can now check the real __mcount_loc instead of a
> hand-written one.
> 
> Signed-off-by: Puranjay Mohan <puranjay@kernel.org>
> ---
>  .../objtool/Documentation/klp-write-tests.txt |  9 ++--
>  .../tests/generic/test-thinlto-ambiguity.sh   |  3 +-
>  .../tests/generic/test-thinlto-local.sh       |  5 ++-
>  tools/objtool/tests/lib.sh                    | 42 +++++++++++++++++--
>  tools/objtool/tests/x86/test-checksum-alt.sh  |  4 --
>  .../tests/x86/test-special-sections.sh        | 23 ++++++----
>  6 files changed, 64 insertions(+), 22 deletions(-)
> 
> diff --git a/tools/objtool/Documentation/klp-write-tests.txt b/tools/objtool/Documentation/klp-write-tests.txt
> index eb2cacaf57207..7cc2148083cc2 100644
> --- a/tools/objtool/Documentation/klp-write-tests.txt
> +++ b/tools/objtool/Documentation/klp-write-tests.txt
> @@ -116,9 +116,12 @@ Traps that have bitten before
>    section entsize or annotations".  Their targets need real (global) symbols,
>    or it reports "failed to convert reloc sym".
>  * **Prefer letting objtool generate what objtool generates.**
> -  ``.static_call_sites``, ``.mcount_loc``, ``.ibt_endbr_seal`` and ORC come
> -  from its check pass.  Call ``run_objtool_check --mcount`` and let it build
> -  them; a hand-written copy tests your reading of the format, not the format.
> +  ``.static_call_sites``, ``.ibt_endbr_seal`` and ORC come from its check
> +  pass.  Call ``run_objtool_check`` with the option for what you need and let
> +  it build them; a hand-written copy tests your reading of the format, not the
> +  format.
> +* **Fixtures are built with ftrace.**  Objects not built with ``build_one``
> +  need ``$FTRACE_CFLAGS`` and ``record_mcount`` too.
>  
>    Write one by hand only when the test needs a shape objtool will not produce,
>    and say so in the fixture.  generic/fixtures/static_call.c does: objtool
> diff --git a/tools/objtool/tests/generic/test-thinlto-ambiguity.sh b/tools/objtool/tests/generic/test-thinlto-ambiguity.sh
> index 34f4f3a58e201..73740c804d54f 100755
> --- a/tools/objtool/tests/generic/test-thinlto-ambiguity.sh
> +++ b/tools/objtool/tests/generic/test-thinlto-ambiguity.sh
> @@ -38,12 +38,13 @@ build_thinlto()		# $1 output object, $2 extra flags
>  {
>  	local t
>  	for t in "" -DTU_B -DTU_C; do
> -		$THIN_CC -flto=thin -O2 -ffunction-sections -fdata-sections \
> +		$THIN_CC -flto=thin -O2 -ffunction-sections -fdata-sections $FTRACE_CFLAGS \
>  			$2 $t -c "$FIXTURES_DIR/thinlto_ambiguity.c" \
>  			-o "$workdir/tu$t.o" 2>/dev/null || return 1
>  	done
>  	"$THIN_LD" -r "$workdir/tu.o" "$workdir/tu-DTU_B.o" "$workdir/tu-DTU_C.o" \
>  		-o "$1" 2>/dev/null || return 1
> +	record_mcount "$1"
>  }
>  
>  build_thinlto "$workdir/orig.o" "" ||
> diff --git a/tools/objtool/tests/generic/test-thinlto-local.sh b/tools/objtool/tests/generic/test-thinlto-local.sh
> index a266263676ed5..090c6df75ad64 100755
> --- a/tools/objtool/tests/generic/test-thinlto-local.sh
> +++ b/tools/objtool/tests/generic/test-thinlto-local.sh
> @@ -15,11 +15,12 @@ find_thinlto_toolchain ||
>  
>  build_thinlto()		# $1 output object, $2 extra flags
>  {
> -	$THIN_CC -flto=thin -O2 -ffunction-sections -fdata-sections $2 \
> +	$THIN_CC -flto=thin -O2 -ffunction-sections -fdata-sections $FTRACE_CFLAGS $2 \
>  		-c "$FIXTURES_DIR/thinlto_local.c" -o "$workdir/tu_a.o" 2>/dev/null || return 1
> -	$THIN_CC -flto=thin -O2 -ffunction-sections -fdata-sections $2 -DTU_B \
> +	$THIN_CC -flto=thin -O2 -ffunction-sections -fdata-sections $FTRACE_CFLAGS $2 -DTU_B \
>  		-c "$FIXTURES_DIR/thinlto_local.c" -o "$workdir/tu_b.o" 2>/dev/null || return 1
>  	"$THIN_LD" -r "$workdir/tu_a.o" "$workdir/tu_b.o" -o "$1" 2>/dev/null || return 1
> +	record_mcount "$1"
>  }
>  
>  build_thinlto "$workdir/orig.o" "" ||
> diff --git a/tools/objtool/tests/lib.sh b/tools/objtool/tests/lib.sh
> index 4da168d0ddca3..d07eb07d15611 100644
> --- a/tools/objtool/tests/lib.sh
> +++ b/tools/objtool/tests/lib.sh
> @@ -41,7 +41,7 @@ OBJTOOL="${OBJTOOL:-$TESTS_DIR/../objtool}"
>  #
>  klp_preflight()
>  {
> -	local tmp tool cc_version arch host cc_arch
> +	local tmp tool cc_version arch host cc_arch mcount=
>  
>  	bail() { echo "Bail out! $*" >&2; exit 1; }
>  
> @@ -99,6 +99,16 @@ klp_preflight()
>  	*AArch64*)		cc_arch=arm64 ;;
>  	*)			cc_arch= ;;
>  	esac
> +
> +	# Same test as FTRACE_MCOUNT_USE_CC.
> +	if [ "$cc_arch" = x86 ]; then
> +		if $CC -pg -mfentry -mrecord-mcount -mnop-mcount -c \
> +			-o "$tmp/probe.o" "$tmp/probe.c" 2>/dev/null; then
> +			mcount=cc
> +		else
> +			mcount=objtool
> +		fi
> +	fi
>  	rm -rf "$tmp"
>  
>  	# Normalize to the kernel's SRCARCH.
> @@ -119,8 +129,9 @@ klp_preflight()
>  		     "the $arch tests would run against the wrong architecture"
>  
>  	KLP_TEST_ARCH="$arch"
> +	KLP_TEST_MCOUNT="$mcount"
>  	KLP_TEST_PREFLIGHT=done
> -	export OBJTOOL CC KLP_TEST_ARCH KLP_TEST_PREFLIGHT
> +	export OBJTOOL CC KLP_TEST_ARCH KLP_TEST_MCOUNT KLP_TEST_PREFLIGHT
>  
>  	cc_version="$($CC --version 2>/dev/null | head -1)"
>  	cat <<EOF
> @@ -128,6 +139,7 @@ klp_preflight()
>  #   objtool   $OBJTOOL (klp: yes)
>  #   compiler  $cc_version
>  #   arch      $KLP_TEST_ARCH$([ "$arch" = "$host" ] || echo "  (host $host, cross)")
> +#   mcount    ${KLP_TEST_MCOUNT:-n/a}
>  #   tmpdir    ${TMPDIR:-/tmp}  (each test builds in a fresh directory here)
>  EOF
>  }
> @@ -153,6 +165,16 @@ EOF
>  FIXTURE_CFLAGS="-O2 -ffunction-sections -fdata-sections -fno-common \
>  		-fno-asynchronous-unwind-tables"
>  
> +# Build with ftrace, which livepatch depends on.  Objects not built with
> +# build_one() need FTRACE_CFLAGS and record_mcount() too.
> +FTRACE_CFLAGS=
> +if [ "$KLP_TEST_ARCH" = x86 ]; then
> +	FTRACE_CFLAGS="-pg -mfentry"
> +	[ "$KLP_TEST_MCOUNT" = cc ] &&
> +		FTRACE_CFLAGS="$FTRACE_CFLAGS -mrecord-mcount -mnop-mcount"
> +fi
> +FIXTURE_CFLAGS="$FIXTURE_CFLAGS $FTRACE_CFLAGS"
> +
>  test_name="$(basename "$0" .sh)"
>  workdir=
>  
> @@ -343,6 +365,20 @@ build_one()
>  
>  	$CC -c $FIXTURE_CFLAGS "$@" -o "$out" "$fixture" 2>"$workdir/cc.log" ||
>  		fail "$(basename "$fixture") does not build: $(tail -1 "$workdir/cc.log")"
> +
> +	record_mcount "$out"
> +}
> +
> +# record_mcount <object>
> +#
> +# FTRACE_MCOUNT_USE_OBJTOOL.  CONFIG_KLP_BUILD always runs objtool with --link.
> +record_mcount()
> +{
> +	[ "$KLP_TEST_MCOUNT" = objtool ] || return 0
> +
> +	"$OBJTOOL" --mcount --mnop --link "$1" 2>"$workdir/objtool.log" ||
> +		fail "objtool --mcount failed on $(basename "$1"):" \
> +		     "$(tail -1 "$workdir/objtool.log")"
>  }
>  
>  # build_pair <fixture.c> [cflags...]
> @@ -365,7 +401,7 @@ build_pair()
>  # Run objtool's ordinary check pass over the pair, as the kernel build does.
>  #
>  # Some of what klp diff consumes is produced by this pass rather than by the
> -# compiler: .static_call_sites, .mcount_loc, .ibt_endbr_seal, ORC.
> +# compiler: .static_call_sites, .ibt_endbr_seal, ORC.
>  #
>  # Only module objects see it before klp-build -- with CONFIG_KLP_BUILD the
>  # per-object pass is deferred, so built-in objects reach klp diff exactly as
> diff --git a/tools/objtool/tests/x86/test-checksum-alt.sh b/tools/objtool/tests/x86/test-checksum-alt.sh
> index 74ebfca2b3ff3..eb9864c4bf825 100755
> --- a/tools/objtool/tests/x86/test-checksum-alt.sh
> +++ b/tools/objtool/tests/x86/test-checksum-alt.sh
> @@ -16,9 +16,6 @@
>  # the feature bit, so the failure looks like a machine-specific bug rather than
>  # a missing patch.
>  #
> -# insn->alts exists only after objtool's check pass, so the pair goes through
> -# that first -- the compiler emits none of this structure itself.
> -#
>  # Covers the same ground as corpus/x86_64/checksum-alt-group,
>  # checksum-alt-no-group and checksum-alt-recursion-guard in Joe Lawrence's
>  # klp-build unit test corpus.
> @@ -31,7 +28,6 @@ check()
>  {
>  	build_pair checksum_alt.c "-D$1"
>  	assert_input_section .altinstructions
> -	run_objtool_check --mcount
>  	run_checksum
>  
>  	assert_checksum_differs target
> diff --git a/tools/objtool/tests/x86/test-special-sections.sh b/tools/objtool/tests/x86/test-special-sections.sh
> index 8dfaa4fc9a360..b05d43cdc8aa4 100755
> --- a/tools/objtool/tests/x86/test-special-sections.sh
> +++ b/tools/objtool/tests/x86/test-special-sections.sh
> @@ -15,26 +15,31 @@
>  
>  
>  # section, entry size, relocations per entry
> -for spec in "__bug_table 12 1" "__ex_table 12 2" "__mcount_loc 8 1"; do
> +for spec in "__bug_table 12 1" "__ex_table 12 2"; do
>  	set -- $spec
> -	sec=$1
>  
>  	# A fresh workdir per section: run_diff caches its checksums.
>  	setup
>  	build_pair special_sections.c \
>  		-DSPECIAL_SEC="\"$1\"" -DSPECIAL_ENTSIZE="$2" -DSPECIAL_RELOCS="$3"
>  
> -	assert_input_section "$sec"
> +	# __mcount_loc comes from FTRACE_CFLAGS, not from the fixture.
> +	for sec in "$1" __mcount_loc; do
> +		assert_input_section "$sec"
> +	done
>  	run_diff
>  
> -	# Extracted, and pointing at the function that was patched.
> -	assert_section "$sec"
> -	assert_reloc_sym "$sec" target
>  	assert_patched target
> -
> -	# Nothing belonging to the function that was not.
>  	assert_not_patched other
> -	assert_no_reloc_sym "$sec" other
> +
> +	for sec in "$1" __mcount_loc; do
> +		# Extracted, and pointing at the function that was patched.
> +		assert_section "$sec"
> +		assert_reloc_sym "$sec" target
> +
> +		# Nothing belonging to the function that was not.
> +		assert_no_reloc_sym "$sec" other
> +	done

Nitpick: it looks a little odd that the __mcount_loc special case was
pushed inside the greater section loop (bug-tables, ex-table) so it runs
twice AFAICT.  Would it be clearer to just pull this out as its own
block?

--
Joe


  reply	other threads:[~2026-10-22 14:46 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-10-22 12:25 [PATCH 0/3] objtool/klp: Reject changed functions without an ftrace call site Puranjay Mohan
2026-10-22 12:25 ` [PATCH 1/3] objtool/klp: Build test fixtures with ftrace Puranjay Mohan
2026-10-22 14:46   ` Joe Lawrence [this message]
2026-10-22 16:43     ` Puranjay Mohan
2026-10-22 12:25 ` [PATCH 2/3] objtool/klp: Reject changed functions without an ftrace call site Puranjay Mohan
2026-10-22 15:55   ` Joe Lawrence
2026-10-22 12:25 ` [PATCH 3/3] objtool/klp: Add test for " Puranjay Mohan
2026-10-22 16:02   ` Joe Lawrence

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=atohxvOb9MAxkhsg@redhat.com \
    --to=joe.lawrence@redhat.com \
    --cc=jpoimboe@kernel.org \
    --cc=live-patching@vger.kernel.org \
    --cc=mbenes@suse.cz \
    --cc=peterz@infradead.org \
    --cc=puranjay@kernel.org \
    --cc=song@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