From: Song Liu <song@kernel.org>
To: live-patching@vger.kernel.org
Cc: jpoimboe@kernel.org, peterz@infradead.org, jikos@kernel.org,
mbenes@suse.cz, pmladek@suse.com, joe.lawrence@redhat.com,
puranjay@kernel.org, kernel-team@meta.com,
Song Liu <song@kernel.org>
Subject: [PATCH 06/58] objtool/klp: Grow the klp test harness vocabulary
Date: Fri, 11 Sep 2026 11:42:13 -0700 [thread overview]
Message-ID: <20260911184305.1457308-7-song@kernel.org> (raw)
In-Reply-To: <20260911184305.1457308-1-song@kernel.org>
Assertions for what klp diff produces, and for what went into it.
The output side covers the things a livepatch is made of: cloned sections
and symbols, klp symbols and their sympos, tombstones, relocations by
section and by count, the converted .klp.rela sections and their
SHF_RELA_LIVEPATCH flag, SHN_LIVEPATCH symbols, recorded checksums, and klp
diff's own diagnostics -- a rejection for the wrong reason is not a pass.
The input side matters just as much, and is easier to forget. A test which
asserts only on the output passes when the compiler never emitted the
construct under test, and reads as coverage it does not have. So there are
two forms, and the difference between them is a statement about why the
thing might be absent:
require_* the compiler cannot produce it here -> skip
assert_* the fixture is supposed to produce it -> fail
Names are quoted before they reach grep. Nearly every name here contains
dots -- .text.target, .klp.rela.vmlinux -- and an unescaped dot matches any
character, so an assertion for one section could be satisfied by a
different one whose name merely lines up.
Assisted-by: Claude:claude-opus-5
Signed-off-by: Song Liu <song@kernel.org>
---
tools/objtool/tests/lib.sh | 360 ++++++++++++++++++++++++++++++++++++-
1 file changed, 356 insertions(+), 4 deletions(-)
diff --git a/tools/objtool/tests/lib.sh b/tools/objtool/tests/lib.sh
index 0a9da178f4dc..a4d126e6c9cb 100644
--- a/tools/objtool/tests/lib.sh
+++ b/tools/objtool/tests/lib.sh
@@ -201,9 +201,42 @@ setup()
export_syms()
{
: > "$workdir/Module.symvers"
+ add_exports vmlinux "$@"
+}
+
+# add_exports <object> [symbol...]
+#
+# Append exports owned by one object, without clearing what is already there,
+# so a test can describe a kernel where several objects export things.
+#
+# Which object owns a symbol is not cosmetic: a reference to a vmlinux symbol
+# is applied when the patch module loads, and a reference to a module's symbol
+# when that patched module loads, so klp diff files them in different sections.
+add_exports()
+{
+ local owner="$1"; shift
+
+ add_exports_ns "$owner" "" "$@"
+}
+
+# add_exports_ns <object> <namespace> [symbol...]
+#
+# Exports in a symbol namespace, the last field of a Module.symvers line.
+#
+# A "module:<names>" namespace is EXPORT_SYMBOL_FOR_MODULES(), where the module
+# loader grants access by matching the importing module's name against the
+# list. A livepatch module is never on that list, so such a symbol has to be
+# referenced the way an unexported one is. Ordinary namespaces are not
+# special here.
+add_exports_ns()
+{
+ local owner="$1" ns="$2"; shift 2
+
+ local sym
+
for sym in "$@"; do
- printf '0x00000000\t%s\tvmlinux\tEXPORT_SYMBOL\t\n' \
- "$sym" >> "$workdir/Module.symvers"
+ printf '0x00000000\t%s\t%s\tEXPORT_SYMBOL\t%s\n' \
+ "$sym" "$owner" "$ns" >> "$workdir/Module.symvers"
done
}
@@ -445,12 +478,87 @@ out_relocs() { $READELF -r -W "$workdir/out.o" 2>/dev/null; }
out_symbols() { $READELF -s -W "$workdir/out.o" 2>/dev/null; }
diff_log() { cat "$workdir/diff.log"; }
+# out_strings <section>
+#
+# The strings in one section of the output, for the names livepatch matches on.
+out_strings() { $READELF -p "$1" "$workdir/out.o" 2>/dev/null; }
+
+# Checks on the input objects, to run before klp diff. The two forms differ in
+# what an absent construct means:
+#
+# require_* the compiler cannot produce it here -> skip
+# assert_* the fixture is supposed to produce it -> fail
+
+in_sections() { $READELF -S -W "$workdir/$1" 2>/dev/null; }
+in_symbols() { $READELF -s -W "$workdir/$1" 2>/dev/null; }
+in_relocs() { $READELF -r -W "$workdir/$1" 2>/dev/null; }
+
+# count_input_symbols <object> <name>
+#
+# How many object symbols of exactly that name the input has. Deliberately not
+# a grep: readelf lists section symbols too, and a newer binutils prints their
+# name -- ".data.<name>" -- where an older one leaves the column blank. A dot
+# is not a word character, so "grep -w <name>" counts that line as well, and
+# the same object gives a different answer depending on which readelf reads it.
+count_input_symbols()
+{
+ in_symbols "$1" | awk -v n="$2" '$4 == "OBJECT" && $8 == n' | wc -l
+}
+
+# re_quote <string>
+#
+# A string as a literal basic regular expression. Nearly every name these
+# assertions match on contains a dot -- .text.target, .klp.rela.vmlinux -- and
+# an unescaped dot matches any character, so an assertion for one section can be
+# satisfied by a different one whose name merely lines up.
+re_quote() { printf '%s' "$1" | sed 's/[].[^$*\\/]/\\&/g'; }
+
+has_input_section() { in_sections "$1" | grep -q "[[:space:]]$(re_quote "$2")[[:space:]]"; }
+has_input_symbol() { in_symbols "$1" | grep -qw -- "$2"; }
+
+assert_input_section()
+{
+ local obj
+
+ for obj in "$orig_obj" "$patched_obj"; do
+ has_input_section "$obj" "$1" ||
+ fail "fixture produced no section '$1' in $obj"
+ done
+}
+
+assert_input_symbol()
+{
+ local obj
+
+ for obj in "$orig_obj" "$patched_obj"; do
+ has_input_symbol "$obj" "$1" ||
+ fail "fixture produced no symbol '$1' in $obj"
+ done
+}
+
+require_input_section()
+{
+ local obj
+
+ for obj in "$orig_obj" "$patched_obj"; do
+ has_input_section "$obj" "$1" ||
+ probe_skip "compiler produced no section '$1' here"
+ done
+}
+
assert_section()
{
- out_sections | grep -q "[[:space:]]$1[[:space:]]" ||
+ out_sections | grep -q "[[:space:]]$(re_quote "$1")[[:space:]]" ||
fail "expected section '$1' in output"
}
+assert_no_section()
+{
+ out_sections | grep -q "[[:space:]]$(re_quote "$1")[[:space:]]" &&
+ fail "unexpected section '$1' in output"
+ return 0
+}
+
assert_patched()
{
assert_section ".text.$1"
@@ -458,7 +566,251 @@ assert_patched()
assert_not_patched()
{
- out_sections | grep -q "[[:space:]].text.$1[[:space:]]" &&
+ out_sections | grep -q "[[:space:]]$(re_quote ".text.$1")[[:space:]]" &&
fail "function '$1' should not have been cloned"
return 0
}
+
+# section_relocs <section>
+#
+# The relocations against one section. readelf prints every relocation section
+# in turn, so a test asking about ".smp_locks" has to cut its block out of the
+# listing first.
+section_relocs()
+{
+ local sec="${1//./\\.}"
+
+ out_relocs | awk "/rela$sec/,/^\$/"
+}
+
+assert_reloc_sym()
+{
+ section_relocs "$1" | grep -qw -- "$2" ||
+ fail "expected a relocation to '$2' in '$1'"
+}
+
+assert_no_reloc_sym()
+{
+ section_relocs "$1" | grep -qw -- "$2" &&
+ fail "unexpected relocation to '$2' in '$1'"
+ return 0
+}
+
+# assert_reloc_count <section> <count>
+#
+# Counts relocation entries, not header or blank lines: whether a special
+# section entry was extracted once, twice or not at all is usually the whole
+# question.
+#
+# A count of zero is ambiguous on its own -- a section with no relocations and
+# no section at all both read as zero -- so require the section to exist. A
+# test expecting nothing there wants assert_no_section.
+assert_reloc_count()
+{
+ local n
+
+ assert_section "$1"
+
+ n="$(section_relocs "$1" | grep -cE '^[0-9a-f]{8,}')"
+ [ "$n" = "$2" ] ||
+ fail "expected $2 relocations in '$1', found $n"
+}
+
+# assert_klp_sym <symbol> [object]
+#
+# A klp symbol is named .klp.sym.<object>.<symbol>,<sympos>. The object
+# defaults to any, since most tests care that the reference was converted at
+# all rather than which object it resolved against.
+assert_klp_sym()
+{
+ out_symbols | grep -q "\.klp\.sym\.${2:-[^.]*}\.$1," ||
+ fail "expected klp symbol for '$1'"
+}
+
+# assert_klp_sympos <symbol> <sympos>
+#
+# The number after the comma in .klp.sym.<object>.<symbol>,<sympos> says which
+# of several same-named symbols livepatch should resolve to, counting from 1;
+# 0 means the name is unique and no disambiguation is needed. Resolving to the
+# wrong one is not a load failure, it is a patch quietly wired to the wrong
+# object.
+assert_klp_sympos()
+{
+ out_symbols | grep -qE "\.klp\.sym\.[^.]+\.$1,$2([[:space:]]|\$)" ||
+ fail "expected klp symbol for '$1' with sympos $2, found:$(
+ out_symbols | grep -o "\.klp\.sym\.[^.]*\.$1,[0-9]*" |
+ sort -u | tr '\n' ' ')"
+}
+
+assert_no_klp_sym()
+{
+ out_symbols | grep -q "\.klp\.sym\.${2:-[^.]*}\.$1," &&
+ fail "unexpected klp symbol for '$1'"
+ return 0
+}
+
+assert_tombstone()
+{
+ out_symbols | grep -q "\.klp\.tombstone\.$1" ||
+ fail "expected a tombstone for '$1'"
+}
+
+assert_symbol()
+{
+ out_symbols | grep -qw -- "$1" ||
+ fail "expected symbol '$1' in output"
+}
+
+assert_no_symbol()
+{
+ out_symbols | grep -qw -- "$1" &&
+ fail "unexpected symbol '$1' in output"
+ return 0
+}
+
+# assert_diff_log <regex>
+#
+# klp diff's combined output, for tests asserting on a diagnostic. Error
+# messages are part of the interface when the whole point is that a construct
+# gets rejected, and a rejection for the wrong reason is not a pass.
+assert_diff_log()
+{
+ diff_log | grep -qE -- "$1" ||
+ fail "expected '$1' in klp diff output: $(tail -2 "$workdir/diff.log")"
+}
+
+# checksum_of <object> <symbol>
+#
+# The checksum "klp checksum" recorded for one symbol, as a hex string.
+#
+# .discard.sym_checksum is an array of { u64 addr; u64 checksum; }, where addr
+# is the target of a relocation naming the symbol. Nothing in the section
+# itself says which symbol an entry belongs to, so the relocation is what
+# locates the entry; the checksum is the eight bytes after it.
+# Callers use this in a command substitution, where fail() would only exit the
+# subshell and the test would carry on with an empty checksum. So this returns
+# non-zero and prints nothing, and the assertions below check for that.
+checksum_of()
+{
+ local obj="$workdir/$1" sym="$2" off
+
+ run_checksum
+
+ off="$($READELF -rW "$obj" 2>/dev/null |
+ awk -v s="$sym" '/rela\.discard\.sym_checksum/,/^$/ {
+ if ($5 == s) { print $1; exit }
+ }')"
+
+ [ -n "$off" ] || return 1
+
+ $OBJCOPY -O binary --only-section=.discard.sym_checksum \
+ "$obj" "$workdir/checksums.bin" 2>/dev/null || return 1
+
+ dd if="$workdir/checksums.bin" bs=1 skip=$((16#$off + 8)) count=8 \
+ status=none | od -An -tx1 | tr -d ' \n'
+}
+
+# assert_checksum_differs <symbol> / assert_checksum_matches <symbol>
+#
+# Compare what klp checksum recorded for a symbol in the original against the
+# patched object. This is what decides whether klp diff treats a function as
+# changed, so a test asserting only that the right functions were cloned cannot
+# tell a correct checksum from one which happens to differ.
+checksum_pair()
+{
+ orig_checksum="$(checksum_of "$orig_obj" "$1")"
+ patched_checksum="$(checksum_of "$patched_obj" "$1")"
+
+ [ -n "$orig_checksum" ] ||
+ fail "no checksum recorded for '$1' in $orig_obj"
+ [ -n "$patched_checksum" ] ||
+ fail "no checksum recorded for '$1' in $patched_obj"
+}
+
+assert_checksum_differs()
+{
+ checksum_pair "$1"
+
+ [ "$orig_checksum" != "$patched_checksum" ] ||
+ fail "checksum for '$1' unchanged at $orig_checksum, expected it to differ"
+}
+
+assert_checksum_matches()
+{
+ checksum_pair "$1"
+
+ [ "$orig_checksum" = "$patched_checksum" ] ||
+ fail "checksum for '$1' changed from $orig_checksum to" \
+ "$patched_checksum, expected no change"
+}
+
+# run_post_link [expected exit status]
+#
+# klp post-link runs last in a livepatch build, converting the intermediate
+# __klp_relocs.* sections into the .klp.rela.* form the kernel consumes. It
+# needs nothing but an object containing those sections, which is what klp diff
+# produces, so it runs on out.o here rather than on a built module. Rewrites
+# out.o in place, so the out_* helpers show the result afterwards.
+run_post_link()
+{
+ local expect="${1:-0}" rc=0
+
+ "$OBJTOOL" klp post-link "$workdir/out.o" \
+ > "$workdir/post-link.log" 2>&1 || rc=$?
+
+ [ "$rc" = "$expect" ] ||
+ fail "klp post-link exited $rc, expected $expect:" \
+ "$(tail -2 "$workdir/post-link.log")"
+}
+
+# The flags readelf prints for a section, or nothing when it has none. The
+# leading "[nn]" index is stripped first so the columns can be counted.
+section_flags()
+{
+ out_sections | sed 's/^ *\[[ 0-9]*\] *//' |
+ awk -v s="$1" '$1 == s && $7 ~ /^[A-Za-z]+$/ { print $7 }'
+}
+
+# assert_section_flag <section> <letter>
+#
+# SHF_RELA_LIVEPATCH is OS-specific, so readelf renders it as "o". A klp rela
+# section which lost it is an ordinary rela section, which the linker may apply
+# and the livepatch code will not.
+assert_section_flag()
+{
+ local flags; flags="$(section_flags "$1")"
+
+ [ -n "$flags" ] ||
+ fail "section '$1' has no flags, expected '$2'"
+ case "$flags" in
+ *"$2"*) ;;
+ *) fail "section '$1' has flags '$flags', expected '$2'" ;;
+ esac
+}
+
+# assert_klp_rela <object> <section>
+#
+# post-link names the converted sections .klp.rela.<object>.<section>, one per
+# base section. Also checks SHF_RELA_LIVEPATCH, since the name alone is not
+# what makes the kernel process it.
+assert_klp_rela()
+{
+ local name=".klp.rela.$1.$2"
+
+ out_sections | grep -q "[[:space:]]$(re_quote "$name")[[:space:]]" ||
+ fail "expected section '$name' in output"
+
+ assert_section_flag "$name" o
+}
+
+# assert_livepatch_sym <symbol>
+#
+# Symbols a klp relocation resolves against live in SHN_LIVEPATCH, which
+# readelf prints as "OS [0xff20]" -- llvm-readelf without the space, so match
+# either. The kernel resolves these itself at patch load; anything else is a
+# symbol the module loader will try, and fail, to resolve normally.
+assert_livepatch_sym()
+{
+ out_symbols | grep -E 'OS ?\[0xff20\]' | grep -qw -- "$1" ||
+ fail "expected '$1' to be an SHN_LIVEPATCH symbol"
+}
--
2.53.0-Meta
next prev parent reply other threads:[~2026-09-11 18:44 UTC|newest]
Thread overview: 77+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-11 18:42 [PATCH 00/58] Unit test framework for klp-build toolchain Song Liu
2026-09-11 18:42 ` [PATCH 01/58] objtool: Add test harness for the klp subcommands Song Liu
2026-09-11 18:42 ` [PATCH 02/58] objtool/klp: Check the klp test environment once, before any test Song Liu
2026-09-11 19:02 ` sashiko-bot
2026-09-11 18:42 ` [PATCH 03/58] objtool/klp: Group the klp tests by architecture Song Liu
2026-09-11 18:42 ` [PATCH 04/58] objtool/klp: Classify klp test outcomes Song Liu
2026-09-11 18:42 ` [PATCH 05/58] objtool/klp: Build klp test fixtures through the harness Song Liu
2026-09-11 18:42 ` Song Liu [this message]
2026-09-11 19:03 ` [PATCH 06/58] objtool/klp: Grow the klp test harness vocabulary sashiko-bot
2026-09-11 18:42 ` [PATCH 07/58] objtool/klp: Give each run one working directory, one per test inside it Song Liu
2026-09-11 18:42 ` [PATCH 08/58] objtool/klp: Run the klp tests under set -u Song Liu
2026-09-11 18:42 ` [PATCH 09/58] objtool/klp: Document the klp test harness Song Liu
2026-09-11 19:00 ` sashiko-bot
2026-09-11 18:42 ` [PATCH 10/58] objtool: Keep failing test workdirs by default Song Liu
2026-09-11 19:07 ` sashiko-bot
2026-09-11 18:42 ` [PATCH 11/58] objtool: Forward toolchain variables to the klp test runner Song Liu
2026-09-11 18:42 ` [PATCH 12/58] objtool/klp: Add test for rejecting changed data Song Liu
2026-09-11 18:42 ` [PATCH 13/58] objtool/klp: Add test for newly introduced data Song Liu
2026-09-11 19:07 ` sashiko-bot
2026-09-11 18:42 ` [PATCH 14/58] objtool/klp: Add test for newly introduced functions Song Liu
2026-09-11 18:42 ` [PATCH 15/58] objtool/klp: Add test for static local correlation Song Liu
2026-09-11 18:42 ` [PATCH 16/58] objtool/klp: Add test for cold function halves Song Liu
2026-09-11 19:07 ` sashiko-bot
2026-09-11 18:42 ` [PATCH 17/58] objtool/klp: Add test for special section extraction Song Liu
2026-09-11 18:42 ` [PATCH 18/58] objtool/klp: Add test for selective " Song Liu
2026-09-11 18:42 ` [PATCH 19/58] objtool/klp: Add test for jump table key relocations Song Liu
2026-09-11 18:42 ` [PATCH 20/58] objtool/klp: Add test for rejecting module-owned static branch keys Song Liu
2026-09-11 18:42 ` [PATCH 21/58] objtool/klp: Add test for rejecting module-owned static call keys Song Liu
2026-09-11 18:42 ` [PATCH 22/58] objtool/klp: Add test for symids in discarded sections Song Liu
2026-09-11 18:42 ` [PATCH 23/58] objtool/klp: Add test for rejecting references to init code/data Song Liu
2026-09-11 19:18 ` sashiko-bot
2026-09-11 18:42 ` [PATCH 24/58] objtool/klp: Add test for correlation across ThinLTO name mangling Song Liu
2026-09-11 18:42 ` [PATCH 25/58] objtool/klp: Add test for objects without .modinfo Song Liu
2026-09-11 18:49 ` [PATCH 26/58] objtool/klp: Add test for unchecksummed input Song Liu
2026-09-11 18:50 ` [PATCH 27/58] objtool/klp: Add klp diff and post-link regression tests Song Liu
2026-09-11 18:50 ` [PATCH 28/58] objtool/klp: Add test for klp reloc section naming in module objects Song Liu
2026-09-11 18:50 ` [PATCH 29/58] objtool/klp: Add test for vmlinux relocs in a patched module Song Liu
2026-09-11 18:50 ` [PATCH 30/58] objtool/klp: Add test for Module.symvers path normalization Song Liu
2026-09-11 18:50 ` [PATCH 31/58] objtool/klp: Add test for the contents of the klp_funcs list Song Liu
2026-09-11 18:50 ` [PATCH 32/58] objtool/klp: Add test for EXPORT_SYMBOL_FOR_MODULES references Song Liu
2026-09-11 18:50 ` [PATCH 33/58] objtool/klp: Add test for new references to exported symbols Song Liu
2026-09-11 18:50 ` [PATCH 34/58] objtool/klp: Add test for empty x86 alternative replacements Song Liu
2026-09-11 18:50 ` [PATCH 35/58] objtool/klp: Add test for recorded checksum values Song Liu
2026-09-11 18:50 ` [PATCH 36/58] objtool/klp: Add test for position-independent checksums Song Liu
2026-09-11 19:16 ` sashiko-bot
2026-09-11 18:50 ` [PATCH 37/58] objtool/klp: Add test for sympos in module objects Song Liu
2026-09-11 19:21 ` sashiko-bot
2026-09-11 18:50 ` [PATCH 38/58] objtool/klp: Add test for sympos resolved against a linked vmlinux Song Liu
2026-09-11 18:50 ` [PATCH 39/58] objtool/klp: Add test for static locals which must not be correlated Song Liu
2026-09-11 18:50 ` [PATCH 40/58] objtool/klp: Add test for __bug_table, __ex_table and __mcount_loc extraction Song Liu
2026-09-11 19:20 ` sashiko-bot
2026-09-11 18:50 ` [PATCH 41/58] objtool/klp: Add test for kCFI prefix symbols and traps Song Liu
2026-09-11 19:21 ` sashiko-bot
2026-09-11 18:50 ` [PATCH 42/58] objtool/klp: Add test for symbols whose linkage the patch changes Song Liu
2026-09-11 18:50 ` [PATCH 43/58] objtool/klp: Test rejection of a file-local static branch key Song Liu
2026-09-11 18:50 ` [PATCH 44/58] objtool/klp: Test a hand-built livepatch module's static call keys Song Liu
2026-09-11 18:50 ` [PATCH 45/58] objtool/klp: Test text annotations on alternative replacements Song Liu
2026-09-11 18:50 ` [PATCH 46/58] objtool/klp: Add test for data object checksums Song Liu
2026-09-11 18:50 ` [PATCH 47/58] objtool/klp: Add test for symbols with no checksum entry of their own Song Liu
2026-09-11 19:23 ` sashiko-bot
2026-09-11 18:50 ` [PATCH 48/58] objtool/klp: Add test for a static branch introduced by the patch Song Liu
2026-09-11 18:50 ` [PATCH 49/58] objtool/klp: Add test for tracepoint and pr_debug static branch keys Song Liu
2026-09-11 18:50 ` [PATCH 50/58] objtool/klp: Add test for a static call introduced by the patch Song Liu
2026-09-11 19:25 ` sashiko-bot
2026-09-11 18:50 ` [PATCH 51/58] objtool/klp: Add test for instruction operand checksums Song Liu
2026-09-11 18:50 ` [PATCH 52/58] objtool/klp: Add test for alternative replacement code in checksums Song Liu
2026-09-11 19:30 ` sashiko-bot
2026-09-11 18:50 ` [PATCH 53/58] objtool/klp: Add test for the alignment of cloned data sections Song Liu
2026-09-11 18:50 ` [PATCH 54/58] objtool/klp: Add test for a patch which strips a data annotation Song Liu
2026-09-11 19:24 ` sashiko-bot
2026-09-11 18:50 ` [PATCH 55/58] objtool/klp: Add test for absolute and __ADDRESSABLE symbols Song Liu
2026-09-11 18:50 ` [PATCH 56/58] objtool/klp: Add test for UBSAN metadata in an unchanged function Song Liu
2026-09-11 18:50 ` [PATCH 57/58] objtool/klp: Add test for Clang switch jump tables Song Liu
2026-09-11 19:27 ` sashiko-bot
2026-09-11 18:50 ` [PATCH 58/58] objtool/klp: Add test for ThinLTO symbols sharing a demangled name Song Liu
2026-09-11 19:28 ` sashiko-bot
2026-09-13 1:53 ` [PATCH 00/58] Unit test framework for klp-build toolchain 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=20260911184305.1457308-7-song@kernel.org \
--to=song@kernel.org \
--cc=jikos@kernel.org \
--cc=joe.lawrence@redhat.com \
--cc=jpoimboe@kernel.org \
--cc=kernel-team@meta.com \
--cc=live-patching@vger.kernel.org \
--cc=mbenes@suse.cz \
--cc=peterz@infradead.org \
--cc=pmladek@suse.com \
--cc=puranjay@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