From 333898fba5408004adba899ce67c85707aa83574 Mon Sep 17 00:00:00 2001 From: rpm-build Date: Tue, 30 Apr 2024 16:38:03 +0800 Subject: [PATCH] adapt kpatch to 6.6 kernel and fix bundle symbols change --- kpatch-build/create-diff-object.c | 4 +- kpatch-build/kpatch-build | 70 ++++++++++++++++++++++++++----- kpatch-build/kpatch-cc | 3 +- 3 files changed, 64 insertions(+), 13 deletions(-) diff --git a/kpatch-build/create-diff-object.c b/kpatch-build/create-diff-object.c index d50d745..5de19f4 100644 --- a/kpatch-build/create-diff-object.c +++ b/kpatch-build/create-diff-object.c @@ -241,6 +241,7 @@ static void kpatch_bundle_symbols(struct kpatch_elf *kelf) { struct symbol *sym; unsigned int expected_offset; + unsigned int directcall_offset = 16; list_for_each_entry(sym, &kelf->symbols, list) { if (is_bundleable(sym)) { @@ -251,7 +252,8 @@ static void kpatch_bundle_symbols(struct kpatch_elf *kelf) else expected_offset = 0; - if (sym->sym.st_value != expected_offset) { + if (sym->sym.st_value != expected_offset && + !(getenv("CONFIG_DYNAMIC_FTRACE_WITH_DIRECT_CALLS") && sym->sym.st_value == directcall_offset)) { ERROR("symbol %s at offset %lu within section %s, expected %u", sym->name, sym->sym.st_value, sym->sec->name, expected_offset); diff --git a/kpatch-build/kpatch-build b/kpatch-build/kpatch-build index 5817023..8fbe8da 100755 --- a/kpatch-build/kpatch-build +++ b/kpatch-build/kpatch-build @@ -142,7 +142,6 @@ verify_patch_files() { apply_patches() { local patch - for patch in "${PATCH_LIST[@]}"; do patch -N -p1 --dry-run < "$patch" 2>&1 | logger || die "$patch file failed to apply" patch -N -p1 < "$patch" 2>&1 | logger || die "$patch file failed to apply" @@ -157,12 +156,12 @@ remove_patches() { for (( ; APPLIED_PATCHES>0; APPLIED_PATCHES-- )); do idx=$(( APPLIED_PATCHES - 1)) patch="${PATCH_LIST[$idx]}" - patch -p1 -R -d "$BUILDDIR" < "$patch" &> /dev/null + patch -p1 -R -d "$USERSRCDIR" < "$patch" &> /dev/null done # If $BUILDDIR was a git repo, make sure git actually sees that # we've reverted our patch(es). - [[ -d "$BUILDDIR/.git" ]] && (cd "$BUILDDIR" && git update-index -q --refresh) + [[ -d "$USERSRCDIR/.git" ]] && (cd "$USERSRCDIR" && git update-index -q --refresh) } cleanup() { @@ -452,6 +451,8 @@ relpath() { filedir="$(dirname "$(readlink -f "$file")")" common="$(readlink -f "$dir")" + [[ $filedir == '.' ]] && return + if [[ "$filedir" = "$common" ]]; then basename "$file" return @@ -539,6 +540,36 @@ __find_parent_obj_in_dir() { get_parent_from_parents "${parents[@]}" } + +__find_parent_obj_in_dir_for_oot() { + local file="$1" + local dir="$2" + + declare -a parents + + while IFS='' read -r parent; do + parent="$(cmd_file_to_o_file "$parent")" + [[ $parent -ef $dir/$file ]] && continue + parents+=("$parent") + done < <(grep -El "${file/./\\.}([ \)]|$)" "$dir"/.*.cmd) + + if [ ${#parents[@]} -ne 0 ]; then + get_parent_from_parents "${parents[@]}" + return + fi + # if path startswith @, should read from file + while IFS='' read -r parent; do + parent="${parent#@}" + parent= `cat "${parent}"`|| die + parent="$(cmd_file_to_o_file "$parent")" + [[ $parent -ef $dir/$file ]] && continue + parents+=("$parent") + done < <(grep -ohE '@.*\.mod' "$dir"/.*.cmd) + + get_parent_from_parents "${parents[@]}" +} + + find_parent_obj_in_dir() { local file="$1" local dir="$2" @@ -553,6 +584,12 @@ find_parent_obj_in_dir() { __find_parent_obj_in_dir "$(relpath "$file" "$dir")" "$dir" [[ -n $PARENT ]] && return + __find_parent_obj_in_dir_for_oot "$file" "." + [[ -n $PARENT ]] && return + + __find_parent_obj_in_dir_for_oot "$file" "${dir#`pwd`}" + [[ -n $PARENT ]] && return + # pre-5.19 (and 5.19+ single-object modules): if [[ $file == $dir* ]]; then # arch/x86/kernel/smp.o @@ -561,6 +598,7 @@ find_parent_obj_in_dir() { # drivers/gpu/drm/amd/amdgpu/../acp/acp_hw.o __find_parent_obj_in_dir "$dir"/"$(relpath "$file" "$dir")" "$dir" fi + } find_parent_obj() { @@ -623,7 +661,7 @@ find_parent_obj() { find_kobj() { local file="$1" - if [[ -n $OOT_MODULE ]]; then + if [[ -n $OOT_MODULE && $OOT_MODULE != yes ]]; then KOBJFILE="$OOT_MODULE" return fi @@ -1142,6 +1180,8 @@ else KBUILD_EXTRA_SYMBOLS="$SYMVERSFILE" fi +grep -q "CONFIG_DYNAMIC_FTRACE_WITH_DIRECT_CALLS=y" "$CONFIGFILE" && export CONFIG_DYNAMIC_FTRACE_WITH_DIRECT_CALLS=1 + # unsupported kernel option checking [[ -n "$CONFIG_DEBUG_INFO_SPLIT" ]] && die "kernel option 'CONFIG_DEBUG_INFO_SPLIT' not supported" [[ -n "$CONFIG_GCC_PLUGIN_LATENT_ENTROPY" ]] && die "kernel option 'CONFIG_GCC_PLUGIN_LATENT_ENTROPY' not supported" @@ -1153,11 +1193,11 @@ fi # that anyway. if [[ -n "$CONFIG_DEBUG_INFO_BTF" ]] && [[ -z "$OOT_MODULE" ]] ; then cp -f "$KERNEL_SRCDIR/scripts/link-vmlinux.sh" "$TEMPDIR/link-vmlinux.sh" || die - sed -i 's/CONFIG_DEBUG_INFO_BTF/DISABLED_FOR_KPATCH_BUILD/g' "$KERNEL_SRCDIR"/scripts/link-vmlinux.sh || die + #sed -i 's/CONFIG_DEBUG_INFO_BTF/DISABLED_FOR_KPATCH_BUILD/g' "$KERNEL_SRCDIR"/scripts/link-vmlinux.sh || die if [[ -e "$KERNEL_SRCDIR/scripts/Makefile.modfinal" ]]; then cp -f "$KERNEL_SRCDIR/scripts/Makefile.modfinal" "$TEMPDIR/Makefile.modfinal" || die - sed -i 's/CONFIG_DEBUG_INFO_BTF_MODULES/DISABLED_FOR_KPATCH_BUILD/g' "$KERNEL_SRCDIR"/scripts/Makefile.modfinal || die + #sed -i 's/CONFIG_DEBUG_INFO_BTF_MODULES/DISABLED_FOR_KPATCH_BUILD/g' "$KERNEL_SRCDIR"/scripts/Makefile.modfinal || die fi fi @@ -1179,7 +1219,7 @@ if [[ "$SKIPCOMPILERCHECK" -eq 0 ]]; then fi echo "Testing patch file(s)" -cd "$BUILDDIR" || die +cd "$USERSRCDIR" || die verify_patch_files apply_patches remove_patches @@ -1239,11 +1279,12 @@ if [[ "$OOT_MODULE" != "yes" ]]; then cp -f "$BUILDDIR/Module.symvers" "$TEMPDIR/Module.symvers" || die fi +cd "$USERSRCDIR" || die echo "Building patched source" apply_patches mkdir -p "$TEMPDIR/orig" "$TEMPDIR/patched" export KPATCH_GCC_TEMPDIR="$TEMPDIR" -export KPATCH_GCC_SRCDIR="$BUILDDIR" +export KPATCH_GCC_SRCDIR="$USERSRCDIR" save_env # $TARGETS used as list, no quotes. # shellcheck disable=SC2086 @@ -1265,7 +1306,7 @@ if [[ ! -e "$TEMPDIR/changed_objs" ]]; then die "no changed objects found" fi -grep -q vmlinux "$KERNEL_SRCDIR/Module.symvers" || die "truncated $KERNEL_SRCDIR/Module.symvers file" +[[ -n "$OOT_MODULE" ]] || grep -q vmlinux "$KERNEL_SRCDIR/Module.symvers" || die "truncated $KERNEL_SRCDIR/Module.symvers file" if [[ -n "$CONFIG_MODVERSIONS" ]] && [[ "$OOT_MODULE" != "yes" ]]; then trace_off "reading Module.symvers" @@ -1350,7 +1391,7 @@ for i in $FILES; do [[ "$i" = usr/initramfs_data.o ]] && continue mkdir -p "output/$(dirname "$i")" - cd "$BUILDDIR" || die + cd "$USERSRCDIR" || die find_kobj "$i" cd "$TEMPDIR" || die if [[ -e "orig/$i" ]]; then @@ -1381,6 +1422,7 @@ for i in $FILES; do KBUILD_MODPOST_WARN=1 make -C "$USERMODBUILDDIR" M="$USERMODBUILDDIR" $USERMODFLAGS "-j$CPUS" $TARGETS 2>&1 | logger || die fi cp ${KOBJFILE} ${KOBJFILE_PATH} + cd "$USERSRCDIR" || die apply_patches cd "$TEMPDIR" || die @@ -1488,7 +1530,13 @@ for ((idx=0; idx<${#MAKEVARS[@]}; idx++)); do MAKEVARS[$idx]=${MAKEVARS[$idx]/${KPATCH_CC_PREFIX}/} done -export KPATCH_BUILD="$KERNEL_SRCDIR" KPATCH_NAME="$MODNAME" \ +if [[ -z "$OOT_MODULE" ]]; then + KPATCH_BUILD="$KERNEL_SRCDIR" +else + KPATCH_BUILD="/lib/modules/$ARCHVERSION/build" +fi + +export KPATCH_BUILD="$KPATCH_BUILD" KPATCH_NAME="$MODNAME" \ KBUILD_EXTRA_SYMBOLS="$KBUILD_EXTRA_SYMBOLS" \ KPATCH_LDFLAGS="$KPATCH_LDFLAGS" \ CROSS_COMPILE="$CROSS_COMPILE" diff --git a/kpatch-build/kpatch-cc b/kpatch-build/kpatch-cc index 8f22978..6f14fd1 100755 --- a/kpatch-build/kpatch-cc +++ b/kpatch-build/kpatch-cc @@ -53,7 +53,8 @@ if [[ "$TOOLCHAINCMD" =~ ^(.*-)?gcc$ || lib/*|\ tools/*|\ .*.o|\ - */.lib_exports.o) + */.lib_exports.o|\ + drivers/net/ethernet/3snic/sssnic/*) break ;; *.o) -- 2.33.0