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 3/3] objtool/klp: Add test for changed functions without an ftrace call site
Date: Thu, 22 Oct 2026 12:02:42 -0400 [thread overview]
Message-ID: <atozok6_aRetCLq2@redhat.com> (raw)
In-Reply-To: <20261022122544.125305-4-puranjay@kernel.org>
On Thu, Oct 22, 2026 at 05:25:38AM -0700, Puranjay Mohan wrote:
> Test that klp diff rejects a changed function without an ftrace call
> site, both a notrace one and an inline one emitted out of line, and
> reports each of them. Also test that a fully inlined function and an
> ordinary function can still be patched.
>
> Signed-off-by: Puranjay Mohan <puranjay@kernel.org>
> ---
> .../tests/x86/fixtures/notrace_target.c | 71 ++++++++++++++++++
> .../objtool/tests/x86/test-notrace-target.sh | 74 +++++++++++++++++++
> 2 files changed, 145 insertions(+)
> create mode 100644 tools/objtool/tests/x86/fixtures/notrace_target.c
> create mode 100755 tools/objtool/tests/x86/test-notrace-target.sh
>
> diff --git a/tools/objtool/tests/x86/fixtures/notrace_target.c b/tools/objtool/tests/x86/fixtures/notrace_target.c
> new file mode 100644
> index 0000000000000..64da58c872b8a
> --- /dev/null
> +++ b/tools/objtool/tests/x86/fixtures/notrace_target.c
> @@ -0,0 +1,71 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/* PATCH_<name> changes <name> in the patched build. */
> +#define notrace __attribute__((__no_instrument_function__))
> +
> +static const char __modinfo[]
> + __attribute__((section(".modinfo"), used, aligned(1))) = "\0name=vmlinux";
> +
> +#ifndef PATCHED
> +#undef PATCH_OUTLINED
> +#undef PATCH_NOTRACE
> +#undef PATCH_INLINED
> +#undef PATCH_TRACED
> +#endif
> +
> +#ifdef PATCH_OUTLINED
> +#define OUTLINED_K 2
> +#else
> +#define OUTLINED_K 1
> +#endif
> +
> +#ifdef PATCH_NOTRACE
> +#define NOTRACE_K 2
> +#else
> +#define NOTRACE_K 1
> +#endif
> +
> +#ifdef PATCH_INLINED
> +#define INLINED_K 2
> +#else
> +#define INLINED_K 1
> +#endif
> +
> +#ifdef PATCH_TRACED
> +#define TRACED_K 2
> +#else
> +#define TRACED_K 1
> +#endif
> +
> +int sink;
> +
> +/* Address taken, so emitted out of line. */
> +static inline notrace int outlined(int x)
> +{
> + int i;
> +
> + for (i = 0; i < x; i++)
> + sink += i * OUTLINED_K;
> + return sink;
> +}
> +
> +int (*outlined_ptr)(int) = outlined;
> +
> +notrace int notrace_fn(int x)
> +{
> + return x * 3 + NOTRACE_K;
> +}
> +
> +static inline int inlined(int x)
> +{
> + return x + INLINED_K;
> +}
> +
> +int inlined_user(int x)
> +{
> + return inlined(x) * 5;
> +}
> +
> +int traced(int x)
> +{
> + return x * 7 + TRACED_K;
> +}
> diff --git a/tools/objtool/tests/x86/test-notrace-target.sh b/tools/objtool/tests/x86/test-notrace-target.sh
> new file mode 100755
> index 0000000000000..09414ae65fc2c
> --- /dev/null
> +++ b/tools/objtool/tests/x86/test-notrace-target.sh
> @@ -0,0 +1,74 @@
> +#!/bin/bash
> +# SPDX-License-Identifier: GPL-2.0
> +#
> +# A changed function without an ftrace call site can't be livepatched:
> +# klp_enable_patch() fails with "failed to find location for function".
> +# klp diff must reject it instead.
> +
> +. "$(dirname "$0")/../lib.sh"
> +
> +# mcount_entry <function>: orig.o has an __mcount_loc entry for it.
> +mcount_entry()
> +{
> + in_relocs "$orig_obj" | awk '/rela__mcount_loc/,/^$/' |
> + awk -v f="$1" '$5 == f || $5 == ".text." f' | grep -q .
> +}
> +
> +# check <expected exit status> <-DPATCH_... flags>
> +check()
> +{
> + local expect="$1"; shift
> +
> + setup
> + build_pair notrace_target.c "$@"
> +
> + assert_input_symbol outlined
> + assert_input_symbol notrace_fn
> + has_input_symbol "$orig_obj" inlined &&
> + fail "inlined() was emitted out of line; the fixture tests nothing"
> + mcount_entry traced ||
> + fail "no __mcount_loc entry for traced(); the fixture tests nothing"
> + mcount_entry inlined_user ||
> + fail "no __mcount_loc entry for inlined_user(); the fixture tests nothing"
> + mcount_entry outlined &&
> + fail "outlined() has a __mcount_loc entry; it should be notrace"
> + mcount_entry notrace_fn &&
> + fail "notrace_fn() has a __mcount_loc entry; it should be notrace"
> +
> + run_diff "$expect"
> +}
> +
> +rejected()
> +{
> + local n
> +
> + n="$(diff_log | grep -c "error: objtool: $1: no ftrace call site, can't patch")"
> + [ "$n" = 1 ] ||
> + fail "expected '$1' rejected once, found $n: $(diff_log | tail -2)"
> +}
> +
> +check 255 -DPATCH_OUTLINED
> +rejected outlined
> +cleanup
> +
> +check 255 -DPATCH_NOTRACE
> +rejected notrace_fn
> +cleanup
> +
> +check 255 -DPATCH_OUTLINED -DPATCH_NOTRACE
> +rejected outlined
> +rejected notrace_fn
> +cleanup
> +
> +# Fully inlined: the traceable caller gets patched.
> +check 0 -DPATCH_INLINED
> +assert_patched inlined_user
> +assert_not_patched traced
> +cleanup
> +
> +check 0 -DPATCH_TRACED
> +assert_patched traced
> +assert_not_patched inlined_user
> +cleanup
> +
> +pass "changed function without an ftrace call site rejected"
> --
> 2.53.0-Meta
>
>
Thanks for finding and fixing this bug! By coincidence, I was debugging
this very problem yesterday (wondering why I couldn't load a patch that
modified an un-patchable function).
Acked-by: Joe Lawrence <joe.lawrence@redhat.com>
--
Joe
prev parent reply other threads:[~2026-10-22 16:02 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
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 [this message]
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=atozok6_aRetCLq2@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