sync code to openeuler
sync latest code to openeuler Signed-off-by: Zhipeng Xie <xiezhipeng1@huawei.com>
This commit is contained in:
parent
873089dd88
commit
428b311440
35
0001-Add-__addressable_-to-maybe_discarded_sym.patch
Normal file
35
0001-Add-__addressable_-to-maybe_discarded_sym.patch
Normal file
@ -0,0 +1,35 @@
|
||||
From 722d27f6bdd4fa012e08db784bf9bb93bb75be2c Mon Sep 17 00:00:00 2001
|
||||
From: Artem Savkov <asavkov@redhat.com>
|
||||
Date: Tue, 16 Oct 2018 16:05:01 +0200
|
||||
Subject: [PATCH] Add "__addressable_" to maybe_discarded_sym().
|
||||
|
||||
Starting with 1b1eeca7e4c1 "init: allow initcall tables to be emitted using
|
||||
relative references" [1] __init functions are generating an "__addressable_"
|
||||
symbol in a ".discarded.addressable" section so it does not show up in final
|
||||
vmlinux triggering find_local_syms failures. Add "_addressable_" to the list
|
||||
in maybe_discarded_sym().
|
||||
|
||||
[1] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=1b1eeca7e4c19fa76d409d4c7b338dba21f2df45
|
||||
|
||||
Signed-off-by: Artem Savkov <asavkov@redhat.com>
|
||||
---
|
||||
kpatch-build/lookup.c | 3 ++-
|
||||
1 file changed, 2 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/kpatch-build/lookup.c b/kpatch-build/lookup.c
|
||||
index b88dc59..7c8e635 100644
|
||||
--- a/kpatch-build/lookup.c
|
||||
+++ b/kpatch-build/lookup.c
|
||||
@@ -80,7 +80,8 @@ static int maybe_discarded_sym(const char *name)
|
||||
*/
|
||||
if (!strncmp(name, "__exitcall_", 11) ||
|
||||
!strncmp(name, "__brk_reservation_fn_", 21) ||
|
||||
- !strncmp(name, "__func_stack_frame_non_standard_", 32))
|
||||
+ !strncmp(name, "__func_stack_frame_non_standard_", 32) ||
|
||||
+ !strncmp(name, "__addressable_", 14))
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
--
|
||||
1.7.12.4
|
||||
|
||||
36
0002-kmod-patch-fix-patch-linking-with-4.20.patch
Normal file
36
0002-kmod-patch-fix-patch-linking-with-4.20.patch
Normal file
@ -0,0 +1,36 @@
|
||||
From 17a97b48bcf0d486007b746c48321bab6dedb2d8 Mon Sep 17 00:00:00 2001
|
||||
From: Artem Savkov <asavkov@redhat.com>
|
||||
Date: Wed, 14 Nov 2018 15:09:34 +0100
|
||||
Subject: [PATCH] kmod/patch: fix patch linking with 4.20
|
||||
|
||||
4.20 includes commit 69ea912fda74 "kbuild: remove unneeded link_multi_deps"
|
||||
which changes kbuild so that only '.o' files are given to ld as targets
|
||||
for linking, leaving out our linker script. Even before this commit we
|
||||
were still doing this wrong and were succeeding just because ld is smart
|
||||
enough to detect the script, it even throws a warning:
|
||||
|
||||
ld: warning: kpatch.lds contains output sections; did you forget -T?
|
||||
|
||||
The right thing to do is to add the script to ldflags either through
|
||||
kbuilds 'ldflags-y' or by adding it to LDFLAGS/KPATCH_LDFLAGS directly.
|
||||
|
||||
Signed-off-by: Artem Savkov <asavkov@redhat.com>
|
||||
---
|
||||
kmod/patch/Makefile | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
diff --git a/kmod/patch/Makefile b/kmod/patch/Makefile
|
||||
index 96d1fca..7ba0820 100644
|
||||
--- a/kmod/patch/Makefile
|
||||
+++ b/kmod/patch/Makefile
|
||||
@@ -11,6 +11,7 @@ KBUILD_CFLAGS_MODULE += -mcmodel=large
|
||||
endif
|
||||
|
||||
obj-m += $(KPATCH_NAME).o
|
||||
+ldflags-y += -T $(src)/kpatch.lds
|
||||
|
||||
$(KPATCH_NAME)-objs += patch-hook.o kpatch.lds output.o
|
||||
|
||||
--
|
||||
1.7.12.4
|
||||
|
||||
42
0003-kmod-patch-more-linking-fixes.patch
Normal file
42
0003-kmod-patch-more-linking-fixes.patch
Normal file
@ -0,0 +1,42 @@
|
||||
From b2f40b03ce1778c7e97586e4111d22d3b28b3330 Mon Sep 17 00:00:00 2001
|
||||
From: Artem Savkov <asavkov@redhat.com>
|
||||
Date: Fri, 7 Dec 2018 16:46:08 +0100
|
||||
Subject: [PATCH] kmod/patch: more linking fixes
|
||||
|
||||
While adding proper linker script option my previous patch left the
|
||||
linker script in the list of source files (on pre-4.20 kernels) for
|
||||
ld somehow breaking kpatch callback sections. For this to work
|
||||
properly kpatch.lds needs to be added to 'extra-y' instead of objs. And
|
||||
for kbuild to process this option properly we need to call make without
|
||||
the .ko target, i.e. let kbuild decide what to build.
|
||||
|
||||
Fixes: 17a97b4 ("kmod/patch: fix patch linking with 4.20")
|
||||
Signed-off-by: Artem Savkov <asavkov@redhat.com>
|
||||
---
|
||||
kmod/patch/Makefile | 5 +++--
|
||||
1 file changed, 3 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/kmod/patch/Makefile b/kmod/patch/Makefile
|
||||
index 7ba0820..e017b17 100644
|
||||
--- a/kmod/patch/Makefile
|
||||
+++ b/kmod/patch/Makefile
|
||||
@@ -12,13 +12,14 @@ endif
|
||||
|
||||
obj-m += $(KPATCH_NAME).o
|
||||
ldflags-y += -T $(src)/kpatch.lds
|
||||
+extra-y := kpatch.lds
|
||||
|
||||
-$(KPATCH_NAME)-objs += patch-hook.o kpatch.lds output.o
|
||||
+$(KPATCH_NAME)-objs += patch-hook.o output.o
|
||||
|
||||
all: $(KPATCH_NAME).ko
|
||||
|
||||
$(KPATCH_NAME).ko:
|
||||
- $(KPATCH_MAKE) $(KPATCH_NAME).ko
|
||||
+ $(KPATCH_MAKE)
|
||||
|
||||
patch-hook.o: patch-hook.c kpatch-patch-hook.c livepatch-patch-hook.c
|
||||
$(KPATCH_MAKE) patch-hook.o
|
||||
--
|
||||
1.7.12.4
|
||||
|
||||
75
0004-create-diff-object-allow-changing-subsections.patch
Normal file
75
0004-create-diff-object-allow-changing-subsections.patch
Normal file
@ -0,0 +1,75 @@
|
||||
From 942cc3ace7edb7c15f40f931dd6f47a934b9fc77 Mon Sep 17 00:00:00 2001
|
||||
From: Artem Savkov <asavkov@redhat.com>
|
||||
Date: Tue, 12 Jun 2018 17:33:17 +0200
|
||||
Subject: [PATCH] create-diff-object: allow changing subsections
|
||||
|
||||
gcc8 can place functions to .text.unlikely and .text.hot subsections
|
||||
during optimizations. Allow symbols to change subsections instead of
|
||||
failing.
|
||||
|
||||
Signed-off-by: Artem Savkov <asavkov@redhat.com>
|
||||
|
||||
backport from:
|
||||
https://github.com/jpoimboe/kpatch/commit/35cc6ff0162fc8008c4c639fdfcabd61b38a982f
|
||||
---
|
||||
kpatch-build/create-diff-object.c | 28 ++++++++++++++++++++++++++--
|
||||
1 file changed, 26 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/kpatch-build/create-diff-object.c b/kpatch-build/create-diff-object.c
|
||||
index 2ddd00d..61ce74f 100644
|
||||
--- a/kpatch-build/create-diff-object.c
|
||||
+++ b/kpatch-build/create-diff-object.c
|
||||
@@ -68,6 +68,12 @@
|
||||
|
||||
char *childobj;
|
||||
|
||||
+enum subsection {
|
||||
+ SUBSECTION_NORMAL,
|
||||
+ SUBSECTION_HOT,
|
||||
+ SUBSECTION_UNLIKELY
|
||||
+};
|
||||
+
|
||||
enum loglevel loglevel = NORMAL;
|
||||
|
||||
#ifndef EM_X86_64
|
||||
@@ -708,6 +714,22 @@ static void kpatch_compare_sections(struct list_head *seclist)
|
||||
}
|
||||
}
|
||||
|
||||
+static enum subsection kpatch_subsection_type(struct section *sec)
|
||||
+{
|
||||
+ if (!strncmp(sec->name, ".text.unlikely.", 15))
|
||||
+ return SUBSECTION_UNLIKELY;
|
||||
+
|
||||
+ if (!strncmp(sec->name, ".text.hot.", 10))
|
||||
+ return SUBSECTION_HOT;
|
||||
+
|
||||
+ return SUBSECTION_NORMAL;
|
||||
+}
|
||||
+
|
||||
+static int kpatch_subsection_changed(struct section *sec1, struct section *sec2)
|
||||
+{
|
||||
+ return kpatch_subsection_type(sec1) != kpatch_subsection_type(sec2);
|
||||
+}
|
||||
+
|
||||
static void kpatch_compare_correlated_symbol(struct symbol *sym)
|
||||
{
|
||||
struct symbol *sym1 = sym, *sym2 = sym->twin;
|
||||
@@ -720,10 +742,12 @@ static void kpatch_compare_correlated_symbol(struct symbol *sym)
|
||||
/*
|
||||
* If two symbols are correlated but their sections are not, then the
|
||||
* symbol has changed sections. This is only allowed if the symbol is
|
||||
- * moving out of an ignored section.
|
||||
++ * moving out of an ignored section, or moving between normal/hot/unlikely
|
||||
++ * subsections.
|
||||
*/
|
||||
if (sym1->sec && sym2->sec && sym1->sec->twin != sym2->sec) {
|
||||
- if (sym2->sec->twin && sym2->sec->twin->ignore)
|
||||
+ if ((sym2->sec->twin && sym2->sec->twin->ignore) ||
|
||||
+ kpatch_subsection_changed(sym1->sec, sym2->sec))
|
||||
sym->status = CHANGED;
|
||||
else if (sym1->name[0] == '$') /* reserved symbols in aarch64 */
|
||||
log_debug("maping symbols: %s", sym1->name); /* do nothing just ignogre */
|
||||
--
|
||||
2.19.1
|
||||
|
||||
@ -0,0 +1,34 @@
|
||||
From ee167e43252bdb9e84cbefcd8b6fe767c9dc768f Mon Sep 17 00:00:00 2001
|
||||
From: Zhipeng Xie <xiezhipeng1@huawei.com>
|
||||
Date: Fri, 2 Nov 2018 17:24:15 +0000
|
||||
Subject: [PATCH 1001/1015] livepatch-patch-hook: don't active patch when
|
||||
insmod
|
||||
|
||||
we want to active patch after loading the patch.
|
||||
|
||||
Signed-off-by: Zhipeng Xie <xiezhipeng1@huawei.com>
|
||||
---
|
||||
kmod/patch/livepatch-patch-hook.c | 7 -------
|
||||
1 files changed, 0 insertions(+), 7 deletions(-)
|
||||
|
||||
diff --git a/kmod/patch/livepatch-patch-hook.c b/kmod/patch/livepatch-patch-hook.c
|
||||
index 7a587a3..e59a377 100644
|
||||
--- a/kmod/patch/livepatch-patch-hook.c
|
||||
+++ b/kmod/patch/livepatch-patch-hook.c
|
||||
@@ -443,13 +443,6 @@ static int __init patch_init(void)
|
||||
return ret;
|
||||
}
|
||||
|
||||
- ret = klp_enable_patch(lpatch);
|
||||
- if (ret) {
|
||||
- WARN_ON(klp_unregister_patch(lpatch));
|
||||
- patch_free_livepatch(lpatch);
|
||||
- return ret;
|
||||
- }
|
||||
-
|
||||
return 0;
|
||||
out:
|
||||
patch_free_livepatch(lpatch);
|
||||
--
|
||||
1.7.5.4
|
||||
|
||||
208
9002-kpatch-build-support-third-party-module-make-hotpatc.patch
Normal file
208
9002-kpatch-build-support-third-party-module-make-hotpatc.patch
Normal file
@ -0,0 +1,208 @@
|
||||
From c27f1093cd47c48e2f403c4ffb29bf066ce0bea5 Mon Sep 17 00:00:00 2001
|
||||
From: Zhipeng Xie <xiezhipeng1@huawei.com>
|
||||
Date: Fri, 2 Nov 2018 17:24:24 +0000
|
||||
Subject: [PATCH 1002/1015] kpatch-build: support third party module make
|
||||
hotpatch
|
||||
|
||||
support out of tree module to make hotpatch.
|
||||
|
||||
Signed-off-by: Zhipeng Xie <xiezhipeng1@huawei.com>
|
||||
---
|
||||
kpatch-build/kpatch-build | 76 ++++++++++++++++++++++++++++++++++++---------
|
||||
kpatch-build/kpatch-gcc | 5 +++
|
||||
2 files changed, 66 insertions(+), 15 deletions(-)
|
||||
|
||||
diff --git a/kpatch-build/kpatch-build b/kpatch-build/kpatch-build
|
||||
index a76913f..ccef86d 100755
|
||||
--- a/kpatch-build/kpatch-build
|
||||
+++ b/kpatch-build/kpatch-build
|
||||
@@ -102,7 +102,11 @@ remove_patches() {
|
||||
for (( ; APPLIED_PATCHES>0; APPLIED_PATCHES-- )); do
|
||||
idx=$(( APPLIED_PATCHES - 1))
|
||||
patch="${PATCH_LIST[$idx]}"
|
||||
- patch -p1 -R -d "$SRCDIR" < "$patch" &> /dev/null
|
||||
+ if [ -n "$USERMODDIR" ];then
|
||||
+ patch -p1 -R -d "$USERMODDIR" < "$patch" &> /dev/null
|
||||
+ else
|
||||
+ patch -p1 -R -d "$SRCDIR" < "$patch" &> /dev/null
|
||||
+ fi
|
||||
done
|
||||
|
||||
# If $SRCDIR was a git repo, make sure git actually sees that
|
||||
@@ -318,8 +322,8 @@ find_parent_obj() {
|
||||
num="$(grep -l "$grepname" "$last_deep_find"/.*.cmd | grep -Fvc "$pdir/.${file}.cmd")"
|
||||
fi
|
||||
if [[ "$num" -eq 0 ]]; then
|
||||
- parent="$(find ./* -name ".*.cmd" -print0 | xargs -0 grep -l "$grepname" | grep -Fv "$pdir/.${file}.cmd" | cut -c3- | head -n1)"
|
||||
- num="$(find ./* -name ".*.cmd" -print0 | xargs -0 grep -l "$grepname" | grep -Fvc "$pdir/.${file}.cmd")"
|
||||
+ parent="$(find . -name ".*.cmd" -print0 | xargs -0 grep -l "$grepname" | grep -Fv "$pdir/.${file}.cmd" | cut -c3- | head -n1)"
|
||||
+ num="$(find . -name ".*.cmd" -print0 | xargs -0 grep -l "$grepname" | grep -Fvc "$pdir/.${file}.cmd")"
|
||||
[[ "$num" -eq 1 ]] && last_deep_find="$(dirname "$parent")"
|
||||
fi
|
||||
else
|
||||
@@ -335,6 +339,9 @@ find_parent_obj() {
|
||||
PARENT="${PARENT#.}"
|
||||
PARENT="${PARENT%.cmd}"
|
||||
PARENT="$dir/$PARENT"
|
||||
+ if [ -n "$USERMODDIR" ];then
|
||||
+ PARENT="$(readlink -f "$PARENT")"
|
||||
+ fi
|
||||
[[ ! -e "$PARENT" ]] && die "ERROR: can't find parent $PARENT for $1"
|
||||
}
|
||||
|
||||
@@ -397,7 +404,7 @@ usage() {
|
||||
echo " (not recommended)" >&2
|
||||
}
|
||||
|
||||
-options="$(getopt -o ha:r:s:c:v:j:t:n:o:d -l "help,archversion:,sourcerpm:,sourcedir:,config:,vmlinux:,jobs:,target:,name:,output:,debug,skip-gcc-check,skip-cleanup" -- "$@")" || die "getopt failed"
|
||||
+options="$(getopt -o ha:r:s:c:v:j:t:n:o:dm:b: -l "help,archversion:,sourcerpm:,sourcedir:,config:,vmlinux:,jobs:,target:,name:,output:,debug,skip-gcc-check,skip-cleanup,moduledir,builddir" -- "$@")" || die "getopt failed"
|
||||
|
||||
eval set -- "$options"
|
||||
|
||||
@@ -463,6 +470,16 @@ while [[ $# -gt 0 ]]; do
|
||||
echo "WARNING: Skipping gcc version matching check (not recommended)"
|
||||
SKIPGCCCHECK=1
|
||||
;;
|
||||
+ -m|--moduledir)
|
||||
+ USERMODDIR=$(readlink -f "$2")
|
||||
+ shift
|
||||
+ [[ ! -d "$USERMODDIR" ]] && die "module dir $USERMODDIR not found"
|
||||
+ ;;
|
||||
+ -b|--builddir)
|
||||
+ BUILDDIR=$(readlink -f "$2")
|
||||
+ shift
|
||||
+ [[ ! -d "$BUILDDIR" ]] && die "kernel develop dir $BUILDDIR not found"
|
||||
+ ;;
|
||||
*)
|
||||
[[ "$1" = "--" ]] && shift && continue
|
||||
[[ ! -f "$1" ]] && die "patch file '$1' not found"
|
||||
@@ -528,7 +545,7 @@ if [[ "$ARCHVERSION" =~ - ]]; then
|
||||
fi
|
||||
[[ "$ARCHVERSION" =~ .el7a. ]] && ALT="-alt"
|
||||
|
||||
-[[ -z "$TARGETS" ]] && TARGETS="vmlinux modules"
|
||||
+[[ -z "$USERMODDIR" ]] && [[ -z "$TARGETS" ]] && TARGETS="vmlinux modules"
|
||||
|
||||
# Don't check external file.
|
||||
# shellcheck disable=SC1091
|
||||
@@ -691,7 +708,11 @@ fi
|
||||
grep -q "CONFIG_DEBUG_INFO_SPLIT=y" "$CONFIGFILE" && die "kernel option 'CONFIG_DEBUG_INFO_SPLIT' not supported"
|
||||
|
||||
echo "Testing patch file(s)"
|
||||
-cd "$SRCDIR" || die
|
||||
+if [ -z "$USERMODDIR" ];then
|
||||
+ cd "$SRCDIR" || die
|
||||
+else
|
||||
+ cd $USERMODDIR || die
|
||||
+fi
|
||||
apply_patches
|
||||
remove_patches
|
||||
|
||||
@@ -709,15 +730,23 @@ find_special_section_data
|
||||
if [[ $DEBUG -ge 4 ]]; then
|
||||
export KPATCH_GCC_DEBUG=1
|
||||
fi
|
||||
-
|
||||
-echo "Building original kernel"
|
||||
-./scripts/setlocalversion --save-scmversion || die
|
||||
+if [ -z "$USERMODDIR" ];then
|
||||
+ echo "Building original kernel"
|
||||
+ ./scripts/setlocalversion --save-scmversion || die
|
||||
+else
|
||||
+ echo "Building original module"
|
||||
+fi
|
||||
unset KPATCH_GCC_TEMPDIR
|
||||
# $TARGETS used as list, no quotes.
|
||||
# shellcheck disable=SC2086
|
||||
CROSS_COMPILE="$TOOLSDIR/kpatch-gcc " make "-j$CPUS" $TARGETS 2>&1 | logger || die
|
||||
|
||||
-echo "Building patched kernel"
|
||||
+sleep 1
|
||||
+if [ -z "$USERMODDIR" ];then
|
||||
+ echo "Building patched kernel"
|
||||
+else
|
||||
+ echo "Building patched module"
|
||||
+fi
|
||||
apply_patches
|
||||
mkdir -p "$TEMPDIR/orig" "$TEMPDIR/patched"
|
||||
KPATCH_GCC_TEMPDIR="$TEMPDIR"
|
||||
@@ -739,14 +768,22 @@ if [[ ! -e "$TEMPDIR/changed_objs" ]]; then
|
||||
die "no changed objects found"
|
||||
fi
|
||||
|
||||
-grep -q vmlinux "$SRCDIR/Module.symvers" || die "truncated $SRCDIR/Module.symvers file"
|
||||
+SYMVERS="$SRCDIR/Module.symvers"
|
||||
+if [ ! -f "$SYMVERS" -a -n "$BUILDDIR" ];then
|
||||
+ SYMVERS="$BUILDDIR/Module.symvers"
|
||||
+fi
|
||||
+grep -q vmlinux "$SYMVERS" || die "truncated $SYMVERS file"
|
||||
|
||||
# Read as words, no quotes.
|
||||
# shellcheck disable=SC2013
|
||||
for i in $(cat "$TEMPDIR/changed_objs")
|
||||
do
|
||||
mkdir -p "$TEMPDIR/patched/$(dirname "$i")" || die
|
||||
- cp -f "$SRCDIR/$i" "$TEMPDIR/patched/$i" || die
|
||||
+ if [ -z "$USERMODDIR" ];then
|
||||
+ cp -f "$SRCDIR/$i" "$TEMPDIR/patched/$i" || die
|
||||
+ else
|
||||
+ cp -f "$i" "$TEMPDIR/patched/$i" || die
|
||||
+ fi
|
||||
done
|
||||
|
||||
echo "Extracting new and modified ELF sections"
|
||||
@@ -788,7 +825,11 @@ for i in $FILES; do
|
||||
[[ "$i" = usr/initramfs_data.o ]] && continue
|
||||
|
||||
mkdir -p "output/$(dirname "$i")"
|
||||
- cd "$SRCDIR" || die
|
||||
+ if [ -z "$USERMODDIR" ];then
|
||||
+ cd "$SRCDIR" || die
|
||||
+ else
|
||||
+ cd $USERMODDIR || die
|
||||
+ fi
|
||||
find_kobj "$i"
|
||||
cd "$TEMPDIR" || die
|
||||
if [[ -e "orig/$i" ]]; then
|
||||
@@ -808,7 +849,7 @@ for i in $FILES; do
|
||||
# create-diff-object orig.o patched.o parent-name parent-symtab
|
||||
# Module.symvers patch-mod-name output.o
|
||||
"$TOOLSDIR"/create-diff-object "orig/$i" "patched/$i" "$KOBJFILE_NAME" \
|
||||
- "$SYMTAB" "$SRCDIR/Module.symvers" "${MODNAME//-/_}" \
|
||||
+ "$SYMTAB" "$SYMVERS" "${MODNAME//-/_}" \
|
||||
"output/$i" 2>&1 | logger 1
|
||||
check_pipe_status create-diff-object
|
||||
# create-diff-object returns 3 if no functional change is found
|
||||
@@ -871,7 +912,12 @@ fi
|
||||
|
||||
cd "$TEMPDIR/patch" || die
|
||||
|
||||
-KPATCH_BUILD="$SRCDIR" KPATCH_NAME="$MODNAME" \
|
||||
+if [ -z "$BUILDDIR" ];then
|
||||
+ KPATCH_BUILDIR="$SRCDIR"
|
||||
+else
|
||||
+ KPATCH_BUILDIR="$BUILDDIR"
|
||||
+fi
|
||||
+KPATCH_BUILD="$KPATCH_BUILDIR" KPATCH_NAME="$MODNAME" \
|
||||
KBUILD_EXTRA_SYMBOLS="$KBUILD_EXTRA_SYMBOLS" \
|
||||
KPATCH_LDFLAGS="$KPATCH_LDFLAGS" \
|
||||
make 2>&1 | logger || die
|
||||
diff --git a/kpatch-build/kpatch-gcc b/kpatch-build/kpatch-gcc
|
||||
index 2d56da1..21f7e2e 100755
|
||||
--- a/kpatch-build/kpatch-gcc
|
||||
+++ b/kpatch-build/kpatch-gcc
|
||||
@@ -23,6 +23,11 @@ if [[ "$TOOLCHAINCMD" = "gcc" ]] ; then
|
||||
[[ "$obj" = */.tmp_mc_*.o ]] && break;
|
||||
|
||||
[[ "$obj" = */.tmp_*.o ]] && obj="${obj/.tmp_/}"
|
||||
+
|
||||
+ if [[ $obj =~ \/\.[0-9]+\.o ]]; then
|
||||
+ break;
|
||||
+ fi
|
||||
+
|
||||
case "$obj" in
|
||||
*.mod.o|\
|
||||
*built-in.o|\
|
||||
--
|
||||
1.7.5.4
|
||||
|
||||
@ -0,0 +1,92 @@
|
||||
From 214de7459555f3f0461cf4127c55f727ccf473d1 Mon Sep 17 00:00:00 2001
|
||||
From: Zhipeng Xie <xiezhipeng1@huawei.com>
|
||||
Date: Fri, 2 Nov 2018 17:24:30 +0000
|
||||
Subject: [PATCH 1003/1015] kpatch-build: support makefile not in third party
|
||||
module source directory
|
||||
|
||||
support makefile not in third party module source directory.
|
||||
for example:
|
||||
testmod/build/Makefile
|
||||
testmod/src/test.c
|
||||
|
||||
Signed-off-by: Zhipeng Xie <xiezhipeng1@huawei.com>
|
||||
---
|
||||
kpatch-build/kpatch-build | 32 +++++++++++++++++++++++++++-----
|
||||
1 files changed, 27 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/kpatch-build/kpatch-build b/kpatch-build/kpatch-build
|
||||
index ccef86d..93a0589 100755
|
||||
--- a/kpatch-build/kpatch-build
|
||||
+++ b/kpatch-build/kpatch-build
|
||||
@@ -311,7 +311,10 @@ find_parent_obj() {
|
||||
dir="$(dirname "$1")"
|
||||
absdir="$(readlink -f "$dir")"
|
||||
pwddir="$(readlink -f .)"
|
||||
- pdir="${absdir#$pwddir/}"
|
||||
+ pdir="."
|
||||
+ if [ "$absdir" != "$pwddir" ];then
|
||||
+ pdir="${absdir#$pwddir/}"
|
||||
+ fi
|
||||
file="$(basename "$1")"
|
||||
grepname="${1%.o}"
|
||||
grepname="$grepname\\.o"
|
||||
@@ -326,6 +329,11 @@ find_parent_obj() {
|
||||
num="$(find . -name ".*.cmd" -print0 | xargs -0 grep -l "$grepname" | grep -Fvc "$pdir/.${file}.cmd")"
|
||||
[[ "$num" -eq 1 ]] && last_deep_find="$(dirname "$parent")"
|
||||
fi
|
||||
+ if [[ "$num" -eq 0 ]]; then
|
||||
+ parent="$(find $USERMODBUILDDIR -name ".*.cmd" -print0 | xargs -0 grep -l "$grepname" | grep -Fv "$pdir/.${file}.cmd" | head -n1)"
|
||||
+ num="$(find $USERMODBUILDDIR -name ".*.cmd" -print0 | xargs -0 grep -l "$grepname" | grep -Fvc "$pdir/.${file}.cmd")"
|
||||
+ [[ "$num" -eq 1 ]] && last_deep_find="$(dirname "$parent")"
|
||||
+ fi
|
||||
else
|
||||
parent="$(grep -l "$grepname" "$dir"/.*.cmd | grep -Fv "$dir/.${file}.cmd" | head -n1)"
|
||||
num="$(grep -l "$grepname" "$dir"/.*.cmd | grep -Fvc "$dir/.${file}.cmd")"
|
||||
@@ -730,16 +738,24 @@ find_special_section_data
|
||||
if [[ $DEBUG -ge 4 ]]; then
|
||||
export KPATCH_GCC_DEBUG=1
|
||||
fi
|
||||
+if [ -z "$USERMODBUILDDIR" ];then
|
||||
+ USERMODBUILDDIR=$USERMODDIR;
|
||||
+fi
|
||||
if [ -z "$USERMODDIR" ];then
|
||||
echo "Building original kernel"
|
||||
./scripts/setlocalversion --save-scmversion || die
|
||||
else
|
||||
echo "Building original module"
|
||||
+ [[ -e $USERMODDIR/Module.symvers ]] && cp -f $USERMODDIR/Module.symvers $TEMPDIR/patch/
|
||||
fi
|
||||
unset KPATCH_GCC_TEMPDIR
|
||||
# $TARGETS used as list, no quotes.
|
||||
# shellcheck disable=SC2086
|
||||
-CROSS_COMPILE="$TOOLSDIR/kpatch-gcc " make "-j$CPUS" $TARGETS 2>&1 | logger || die
|
||||
+if [ -z "$USERMODDIR" ];then
|
||||
+ CROSS_COMPILE="$TOOLSDIR/kpatch-gcc " make "-j$CPUS" $TARGETS 2>&1 | logger || die
|
||||
+else
|
||||
+ CROSS_COMPILE="$TOOLSDIR/kpatch-gcc " make -C "$USERMODBUILDDIR" M="$USERMODBUILDDIR" "-j$CPUS" $USERMODFLAGS $TARGETS 2>&1 | logger || die
|
||||
+fi
|
||||
|
||||
sleep 1
|
||||
if [ -z "$USERMODDIR" ];then
|
||||
@@ -753,9 +769,15 @@ KPATCH_GCC_TEMPDIR="$TEMPDIR"
|
||||
export KPATCH_GCC_TEMPDIR
|
||||
# $TARGETS used as list, no quotes.
|
||||
# shellcheck disable=SC2086
|
||||
-CROSS_COMPILE="$TOOLSDIR/kpatch-gcc " \
|
||||
- KBUILD_MODPOST_WARN=1 \
|
||||
- make "-j$CPUS" $TARGETS 2>&1 | logger || die
|
||||
+if [ -z "$USERMODDIR" ];then
|
||||
+ CROSS_COMPILE="$TOOLSDIR/kpatch-gcc " \
|
||||
+ KBUILD_MODPOST_WARN=1 \
|
||||
+ make "-j$CPUS" $TARGETS 2>&1 | logger || die
|
||||
+else
|
||||
+ CROSS_COMPILE="$TOOLSDIR/kpatch-gcc " \
|
||||
+ KBUILD_MODPOST_WARN=1 \
|
||||
+ make -C "$USERMODBUILDDIR" M="$USERMODBUILDDIR" "-j$CPUS" $USERMODFLAGS $TARGETS 2>&1 | logger || die
|
||||
+fi
|
||||
|
||||
# source.c:(.section+0xFF): undefined reference to `symbol'
|
||||
grep "undefined reference" "$LOGFILE" | sed -r "s/^.*\`(.*)'$/\\1/" \
|
||||
--
|
||||
1.7.5.4
|
||||
|
||||
@ -0,0 +1,56 @@
|
||||
From fc6b9c5b1b3eb5d59186fe35cc90d3c06b07c537 Mon Sep 17 00:00:00 2001
|
||||
From: Zhipeng Xie <xiezhipeng1@huawei.com>
|
||||
Date: Fri, 2 Nov 2018 17:24:36 +0000
|
||||
Subject: [PATCH 1004/1015] create-diff-object: new static var should be
|
||||
included
|
||||
|
||||
Before this patch, only global variables(no referenced) will be
|
||||
included by kpatch-build. But some macros put some static varibles
|
||||
in the object file, and no function references it, so they won't
|
||||
be included by kpatch-build. Because they are changed, the kpatch
|
||||
will report an error.
|
||||
This patch includes all new static variables, and this method won't
|
||||
cause a problem even the new static variables are in unbundled section.
|
||||
|
||||
Signed-off-by: Zhou Chengming <zhouchengming1@huawei.com>
|
||||
Signed-off-by: Zhipeng Xie <xiezhipeng1@huawei.com>
|
||||
---
|
||||
kpatch-build/create-diff-object.c | 15 +++++++++++++++
|
||||
1 files changed, 15 insertions(+), 0 deletions(-)
|
||||
|
||||
diff --git a/kpatch-build/create-diff-object.c b/kpatch-build/create-diff-object.c
|
||||
index d242d01..6e23295 100644
|
||||
--- a/kpatch-build/create-diff-object.c
|
||||
+++ b/kpatch-build/create-diff-object.c
|
||||
@@ -1536,6 +1536,20 @@ static void kpatch_include_force_elements(struct kpatch_elf *kelf)
|
||||
sym->include = 0;
|
||||
}
|
||||
|
||||
+int kpatch_include_new_static_var(struct kpatch_elf *kelf)
|
||||
+{
|
||||
+ struct symbol *sym;
|
||||
+
|
||||
+ list_for_each_entry(sym, &kelf->symbols, list) {
|
||||
+ if (sym->status == NEW &&
|
||||
+ sym->type == STT_OBJECT &&
|
||||
+ sym->bind == STB_LOCAL)
|
||||
+ kpatch_include_symbol(sym);
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
static int kpatch_include_new_globals(struct kpatch_elf *kelf)
|
||||
{
|
||||
struct symbol *sym;
|
||||
@@ -3211,6 +3225,7 @@ int main(int argc, char *argv[])
|
||||
callbacks_exist = kpatch_include_callback_elements(kelf_patched);
|
||||
kpatch_include_force_elements(kelf_patched);
|
||||
new_globals_exist = kpatch_include_new_globals(kelf_patched);
|
||||
+ kpatch_include_new_static_var(kelf_patched);
|
||||
|
||||
kpatch_print_changes(kelf_patched);
|
||||
kpatch_dump_kelf(kelf_patched);
|
||||
--
|
||||
1.7.5.4
|
||||
|
||||
@ -0,0 +1,32 @@
|
||||
From 858cc1f1ef2565d6ffa539550fc13af7e62863e4 Mon Sep 17 00:00:00 2001
|
||||
From: Zhipeng Xie <xiezhipeng1@huawei.com>
|
||||
Date: Fri, 2 Nov 2018 17:24:42 +0000
|
||||
Subject: [PATCH 1005/1015] livepatch, fix: use THIS modname as the name of
|
||||
ddebug_table
|
||||
|
||||
We just want a unique name for every module, so put a _ddebug in
|
||||
this file as the first of _ddebug array. Then remove path will work
|
||||
correctly, use the mod->name.
|
||||
|
||||
Suggested-by: Li Bin <huawei.libin@huawei.com>
|
||||
Signed-off-by: Zhou Chengming <zhouchengming1@huawei.com>
|
||||
Signed-off-by: Zhipeng Xie <xiezhipeng1@huawei.com>
|
||||
---
|
||||
kmod/patch/livepatch-patch-hook.c | 1 +
|
||||
1 files changed, 1 insertions(+), 0 deletions(-)
|
||||
|
||||
diff --git a/kmod/patch/livepatch-patch-hook.c b/kmod/patch/livepatch-patch-hook.c
|
||||
index e59a377..2c0cadd 100644
|
||||
--- a/kmod/patch/livepatch-patch-hook.c
|
||||
+++ b/kmod/patch/livepatch-patch-hook.c
|
||||
@@ -452,6 +452,7 @@ out:
|
||||
|
||||
static void __exit patch_exit(void)
|
||||
{
|
||||
+ pr_debug("make THIS modname first\n");
|
||||
WARN_ON(klp_unregister_patch(lpatch));
|
||||
}
|
||||
|
||||
--
|
||||
1.7.5.4
|
||||
|
||||
@ -0,0 +1,50 @@
|
||||
From 2f95a0fa6214a97f60a0d5ba4dc0cda152d5c7d4 Mon Sep 17 00:00:00 2001
|
||||
From: Zhipeng Xie <xiezhipeng1@huawei.com>
|
||||
Date: Fri, 2 Nov 2018 17:24:51 +0000
|
||||
Subject: [PATCH 1006/1015] create-diff-object: fix correlate static local
|
||||
variables for __param section
|
||||
|
||||
kpatch-build correlate fail when no sections reference
|
||||
static local variables in __param section, so the static
|
||||
local variables are incorrectly recognized as a new symbol
|
||||
and include a incomplete __param section into the patch.
|
||||
The kernel oops when meet the incomplete __param section.
|
||||
[ 625.961330] Call Trace:
|
||||
[ 625.963279] [<ffffffff9b2a0c27>] ? kernfs_name_hash+0x17/0xd0
|
||||
[ 625.965213] [<ffffffff9b2a219f>] kernfs_add_one+0x8f/0x150
|
||||
[ 625.967120] [<ffffffff9b2a3a1e>] __kernfs_create_file+0x7e/0xa0
|
||||
[ 625.969038] [<ffffffff9b2a44db>] sysfs_add_file_mode_ns+0x9b/0x160
|
||||
[ 625.970912] [<ffffffff9b2a5231>] internal_create_group+0xd1/0x250
|
||||
[ 625.972755] [<ffffffff9b0b8629>] ? add_sysfs_param.isra.3+0x89/0x280
|
||||
[ 625.975274] [<ffffffff9b2a53c3>] sysfs_create_group+0x13/0x20
|
||||
[ 625.977108] [<ffffffff9b0b8f24>] module_param_sysfs_setup+0x94/0xd0
|
||||
[ 625.978899] [<ffffffff9b10f4e2>] load_module+0x2392/0x2bc0
|
||||
[ 625.980693] [<ffffffff9b376a70>] ? ddebug_proc_write+0xf0/0xf0
|
||||
[ 625.982448] [<ffffffff9b10b4b3>] ?
|
||||
copy_module_from_fd.isra.43+0x53/0x150
|
||||
[ 625.984187] [<ffffffff9b10fec6>] SyS_finit_module+0xa6/0xd0
|
||||
[ 625.985926] [<ffffffff9b71f7d5>] system_call_fastpath+0x1c/0x21
|
||||
|
||||
Signed-off-by: Zhipeng Xie <xiezhipeng1@huawei.com>
|
||||
---
|
||||
kpatch-build/create-diff-object.c | 4 ++++
|
||||
1 files changed, 4 insertions(+), 0 deletions(-)
|
||||
|
||||
diff --git a/kpatch-build/create-diff-object.c b/kpatch-build/create-diff-object.c
|
||||
index 6e23295..bd7dd37 100644
|
||||
--- a/kpatch-build/create-diff-object.c
|
||||
+++ b/kpatch-build/create-diff-object.c
|
||||
@@ -925,6 +925,10 @@ static int kpatch_is_normal_static_local(struct symbol *sym)
|
||||
if (is_special_static(sym))
|
||||
return 0;
|
||||
|
||||
+ if (!strncmp(sym->name, "__param_", strlen("__param_")) &&
|
||||
+ !strncmp(sym->sec->name, "__param", strlen("__param")))
|
||||
+ return 0;
|
||||
+
|
||||
return 1;
|
||||
}
|
||||
|
||||
--
|
||||
1.7.5.4
|
||||
|
||||
@ -0,0 +1,31 @@
|
||||
From 0a92ec9f158340501151bf350050597414affece Mon Sep 17 00:00:00 2001
|
||||
From: Zhipeng Xie <xiezhipeng1@huawei.com>
|
||||
Date: Fri, 2 Nov 2018 17:24:58 +0000
|
||||
Subject: [PATCH 1007/1015] create-diff-object: don't create dynamic reloc for
|
||||
symbol exported by patch itself
|
||||
|
||||
when a patch export a new function, ___kcrctab+xxx has a reloc,
|
||||
use origin reloc to get right symbol version.
|
||||
|
||||
Signed-off-by: Zhipeng Xie <xiezhipeng1@huawei.com>
|
||||
---
|
||||
kpatch-build/create-diff-object.c | 3 +++
|
||||
1 files changed, 3 insertions(+), 0 deletions(-)
|
||||
|
||||
diff --git a/kpatch-build/create-diff-object.c b/kpatch-build/create-diff-object.c
|
||||
index bd7dd37..349e483 100644
|
||||
--- a/kpatch-build/create-diff-object.c
|
||||
+++ b/kpatch-build/create-diff-object.c
|
||||
@@ -2808,6 +2808,9 @@ static void kpatch_create_intermediate_sections(struct kpatch_elf *kelf,
|
||||
if (!strcmp(sym_objname, "vmlinux"))
|
||||
continue;
|
||||
|
||||
+ if (!strcmp(sym_objname, pmod_name))
|
||||
+ continue;
|
||||
+
|
||||
external = 1;
|
||||
}
|
||||
}
|
||||
--
|
||||
1.7.5.4
|
||||
|
||||
@ -0,0 +1,45 @@
|
||||
From aaaec2d292b7e1d07c35e07ba92917ee05a4a141 Mon Sep 17 00:00:00 2001
|
||||
From: Zhipeng Xie <xiezhipeng1@huawei.com>
|
||||
Date: Fri, 2 Nov 2018 17:25:03 +0000
|
||||
Subject: [PATCH 1008/1015] livepatch-patch-hook: support force enable/disable
|
||||
function
|
||||
|
||||
we use immediate to indicate patch which bypass stack check.
|
||||
|
||||
Signed-off-by: Zhipeng Xie <xiezhipeng1@huawei.com>
|
||||
---
|
||||
kmod/patch/livepatch-patch-hook.c | 11 +++++++++++
|
||||
1 files changed, 11 insertions(+), 0 deletions(-)
|
||||
|
||||
diff --git a/kmod/patch/livepatch-patch-hook.c b/kmod/patch/livepatch-patch-hook.c
|
||||
index 2c0cadd..625ffbd 100644
|
||||
--- a/kmod/patch/livepatch-patch-hook.c
|
||||
+++ b/kmod/patch/livepatch-patch-hook.c
|
||||
@@ -228,6 +228,16 @@ extern struct kpatch_pre_patch_callback __kpatch_callbacks_pre_patch[], __kpatch
|
||||
extern struct kpatch_post_patch_callback __kpatch_callbacks_post_patch[], __kpatch_callbacks_post_patch_end[];
|
||||
extern struct kpatch_pre_unpatch_callback __kpatch_callbacks_pre_unpatch[], __kpatch_callbacks_pre_unpatch_end[];
|
||||
extern struct kpatch_post_unpatch_callback __kpatch_callbacks_post_unpatch[], __kpatch_callbacks_post_unpatch_end[];
|
||||
+extern unsigned long __kpatch_force_funcs[], __kpatch_force_funcs_end[];
|
||||
+
|
||||
+static int patch_is_func_forced(unsigned long addr)
|
||||
+{
|
||||
+ unsigned long *a;
|
||||
+ for (a = __kpatch_force_funcs; a < __kpatch_force_funcs_end; a++)
|
||||
+ if (*a == addr)
|
||||
+ return 1;
|
||||
+ return 0;
|
||||
+}
|
||||
|
||||
#ifdef HAVE_CALLBACKS
|
||||
static int add_callbacks_to_patch_objects(void)
|
||||
@@ -393,6 +403,7 @@ static int __init patch_init(void)
|
||||
lfunc = &lfuncs[j];
|
||||
lfunc->old_name = func->kfunc->name;
|
||||
lfunc->new_func = (void *)func->kfunc->new_addr;
|
||||
+ lfunc->immediate = patch_is_func_forced(lfunc->new_func);
|
||||
#ifdef HAVE_SYMPOS
|
||||
lfunc->old_sympos = func->kfunc->sympos;
|
||||
#else
|
||||
--
|
||||
1.7.5.4
|
||||
|
||||
349
9009-kmod-kpatch-build-support-build-patch-for-old-kernel.patch
Normal file
349
9009-kmod-kpatch-build-support-build-patch-for-old-kernel.patch
Normal file
@ -0,0 +1,349 @@
|
||||
From e91d2d2c6778275b16249f7e9d7439018fed70fe Mon Sep 17 00:00:00 2001
|
||||
From: Zhipeng Xie <xiezhipeng1@huawei.com>
|
||||
Date: Fri, 2 Nov 2018 17:25:08 +0000
|
||||
Subject: [PATCH 1009/1015] kmod/kpatch-build: support build patch for
|
||||
old kernels
|
||||
|
||||
Forward compatible for old kernels
|
||||
|
||||
Signed-off-by: Zhipeng Xie <xiezhipeng1@huawei.com>
|
||||
---
|
||||
kmod/patch/kpatch-macros.h | 48 ++++++++++++++
|
||||
kmod/patch/kpatch-patch.h | 4 +
|
||||
kmod/patch/kpatch.lds.S | 12 ++++
|
||||
kmod/patch/livepatch-patch-hook.c | 124 +++++++++++++++++++++++++++++++++++++
|
||||
kpatch-build/create-diff-object.c | 8 +++
|
||||
5 files changed, 196 insertions(+), 0 deletions(-)
|
||||
|
||||
diff --git a/kmod/patch/kpatch-macros.h b/kmod/patch/kpatch-macros.h
|
||||
index a60a267..569a18d 100644
|
||||
--- a/kmod/patch/kpatch-macros.h
|
||||
+++ b/kmod/patch/kpatch-macros.h
|
||||
@@ -133,4 +133,52 @@ struct kpatch_post_unpatch_callback {
|
||||
printk(_fmt, ## __VA_ARGS__); \
|
||||
})
|
||||
|
||||
+typedef void (*kpatch_loadcall_t)(void);
|
||||
+typedef void (*kpatch_unloadcall_t)(void);
|
||||
+
|
||||
+struct kpatch_load {
|
||||
+ kpatch_loadcall_t fn;
|
||||
+ char *objname; /* filled in by create-diff-object */
|
||||
+};
|
||||
+
|
||||
+struct kpatch_unload {
|
||||
+ kpatch_unloadcall_t fn;
|
||||
+ char *objname; /* filled in by create-diff-object */
|
||||
+};
|
||||
+
|
||||
+/*
|
||||
+ * KPATCH_LOAD_HOOK macro
|
||||
+ *
|
||||
+ * The first line only ensures that the hook being registered has the required
|
||||
+ * function signature. If not, there is compile error on this line.
|
||||
+ *
|
||||
+ * The section line declares a struct kpatch_load to be allocated in a new
|
||||
+ * .kpatch.hook.load section. This kpatch_load_data symbol is later stripped
|
||||
+ * by create-diff-object so that it can be declared in multiple objects that
|
||||
+ * are later linked together, avoiding global symbol collision. Since multiple
|
||||
+ * hooks can be registered, the .kpatch.hook.load section is a table of struct
|
||||
+ * kpatch_load elements that will be executed in series by the kpatch core
|
||||
+ * module at load time, assuming the kernel object (module) is currently
|
||||
+ * loaded; otherwise, the hook is called when module to be patched is loaded
|
||||
+ * via the module load notifier.
|
||||
+ */
|
||||
+#define KPATCH_LOAD_HOOK(_fn) \
|
||||
+ static inline kpatch_loadcall_t __loadtest(void) { return _fn; } \
|
||||
+ struct kpatch_load kpatch_load_data __section(.kpatch.hooks.load) = { \
|
||||
+ .fn = _fn, \
|
||||
+ .objname = NULL \
|
||||
+ };
|
||||
+
|
||||
+/*
|
||||
+ * KPATCH_UNLOAD_HOOK macro
|
||||
+ *
|
||||
+ * Same as LOAD hook with s/load/unload/
|
||||
+ */
|
||||
+#define KPATCH_UNLOAD_HOOK(_fn) \
|
||||
+ static inline kpatch_unloadcall_t __unloadtest(void) { return _fn; } \
|
||||
+ struct kpatch_unload kpatch_unload_data __section(.kpatch.hooks.unload) = { \
|
||||
+ .fn = _fn, \
|
||||
+ .objname = NULL \
|
||||
+ };
|
||||
+
|
||||
#endif /* __KPATCH_MACROS_H_ */
|
||||
diff --git a/kmod/patch/kpatch-patch.h b/kmod/patch/kpatch-patch.h
|
||||
index 917ea32..4d47d30 100644
|
||||
--- a/kmod/patch/kpatch-patch.h
|
||||
+++ b/kmod/patch/kpatch-patch.h
|
||||
@@ -59,5 +59,9 @@ struct kpatch_post_unpatch_callback {
|
||||
void (*callback)(void *obj);
|
||||
char *objname;
|
||||
};
|
||||
+struct kpatch_patch_hook {
|
||||
+ void (*hook)(void);
|
||||
+ char *objname;
|
||||
+};
|
||||
|
||||
#endif /* _KPATCH_PATCH_H_ */
|
||||
diff --git a/kmod/patch/kpatch.lds.S b/kmod/patch/kpatch.lds.S
|
||||
index bc5de82..e3c4e97 100644
|
||||
--- a/kmod/patch/kpatch.lds.S
|
||||
+++ b/kmod/patch/kpatch.lds.S
|
||||
@@ -47,4 +47,16 @@ SECTIONS
|
||||
__kpatch_force_funcs_end = . ;
|
||||
QUAD(0);
|
||||
}
|
||||
+ .kpatch.hooks.load : {
|
||||
+ __kpatch_hooks_load = . ;
|
||||
+ *(.kpatch.hooks.load)
|
||||
+ __kpatch_hooks_load_end = . ;
|
||||
+ QUAD(0);
|
||||
+ }
|
||||
+ .kpatch.hooks.unload : {
|
||||
+ __kpatch_hooks_unload = . ;
|
||||
+ *(.kpatch.hooks.unload)
|
||||
+ __kpatch_hooks_unload_end = . ;
|
||||
+ QUAD(0);
|
||||
+ }
|
||||
}
|
||||
diff --git a/kmod/patch/livepatch-patch-hook.c b/kmod/patch/livepatch-patch-hook.c
|
||||
index 625ffbd..8f7d044 100644
|
||||
--- a/kmod/patch/livepatch-patch-hook.c
|
||||
+++ b/kmod/patch/livepatch-patch-hook.c
|
||||
@@ -64,6 +64,15 @@
|
||||
# define HAVE_CALLBACKS
|
||||
#endif
|
||||
|
||||
+#ifdef EULER_RELEASE_CODE
|
||||
+# if EULER_RELEASE_CODE <= EULER_RELEASE_VERSION(2, 3)
|
||||
+# undef HAVE_SYMPOS
|
||||
+# undef HAVE_IMMEDIATE
|
||||
+# undef HAVE_ELF_RELOCS
|
||||
+# define HAVE_LOADHOOKS
|
||||
+# endif
|
||||
+#endif
|
||||
+
|
||||
/*
|
||||
* There are quite a few similar structures at play in this file:
|
||||
* - livepatch.h structs prefixed with klp_*
|
||||
@@ -95,6 +104,11 @@ struct patch_object {
|
||||
#endif
|
||||
const char *name;
|
||||
int funcs_nr, relocs_nr;
|
||||
+#ifdef HAVE_LOADHOOKS
|
||||
+ struct list_head hooks_load;
|
||||
+ struct list_head hooks_unload;
|
||||
+ int hooks_load_nr, hooks_unload_nr;
|
||||
+#endif
|
||||
};
|
||||
|
||||
struct patch_func {
|
||||
@@ -107,6 +121,13 @@ struct patch_reloc {
|
||||
struct kpatch_patch_dynrela *kdynrela;
|
||||
};
|
||||
|
||||
+#ifdef HAVE_LOADHOOKS
|
||||
+struct patch_hook {
|
||||
+ struct list_head list;
|
||||
+ struct kpatch_patch_hook *khook;
|
||||
+};
|
||||
+#endif
|
||||
+
|
||||
static struct patch_object *patch_alloc_new_object(const char *name)
|
||||
{
|
||||
struct patch_object *object;
|
||||
@@ -118,6 +139,10 @@ static struct patch_object *patch_alloc_new_object(const char *name)
|
||||
#ifndef HAVE_ELF_RELOCS
|
||||
INIT_LIST_HEAD(&object->relocs);
|
||||
#endif
|
||||
+#ifdef HAVE_LOADHOOKS
|
||||
+ INIT_LIST_HEAD(&object->hooks_load);
|
||||
+ INIT_LIST_HEAD(&object->hooks_unload);
|
||||
+#endif
|
||||
if (strcmp(name, "vmlinux"))
|
||||
object->name = name;
|
||||
list_add(&object->list, &patch_objects);
|
||||
@@ -180,6 +205,37 @@ static int patch_add_reloc_to_object(struct kpatch_patch_dynrela *kdynrela)
|
||||
}
|
||||
#endif
|
||||
|
||||
+#ifdef HAVE_LOADHOOKS
|
||||
+static int patch_add_hook_to_object(struct kpatch_patch_hook *khook, bool load)
|
||||
+{
|
||||
+ struct patch_hook *hook;
|
||||
+ struct patch_object *object;
|
||||
+
|
||||
+ hook = kzalloc(sizeof(*hook), GFP_KERNEL);
|
||||
+ if (!hook)
|
||||
+ return -ENOMEM;
|
||||
+ INIT_LIST_HEAD(&hook->list);
|
||||
+ hook->khook = khook;
|
||||
+
|
||||
+ object = patch_find_object_by_name(khook->objname);
|
||||
+ if (!object) {
|
||||
+ kfree(hook);
|
||||
+ return -ENOMEM;
|
||||
+ }
|
||||
+
|
||||
+ if (load) {
|
||||
+ list_add(&hook->list, &object->hooks_load);
|
||||
+ object->hooks_load_nr++;
|
||||
+ }
|
||||
+ else {
|
||||
+ list_add(&hook->list, &object->hooks_unload);
|
||||
+ object->hooks_unload_nr++;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+#endif
|
||||
+
|
||||
static void patch_free_scaffold(void) {
|
||||
struct patch_func *func, *safefunc;
|
||||
struct patch_object *object, *safeobject;
|
||||
@@ -217,6 +273,12 @@ static void patch_free_livepatch(struct klp_patch *patch)
|
||||
if (object->relocs)
|
||||
kfree(object->relocs);
|
||||
#endif
|
||||
+#ifdef HAVE_LOADHOOKS
|
||||
+ if (object->hooks_load)
|
||||
+ kfree(object->hooks_load);
|
||||
+ if (object->hooks_unload)
|
||||
+ kfree(object->hooks_unload);
|
||||
+#endif
|
||||
}
|
||||
if (patch->objs)
|
||||
kfree(patch->objs);
|
||||
@@ -228,6 +290,10 @@ extern struct kpatch_pre_patch_callback __kpatch_callbacks_pre_patch[], __kpatch
|
||||
extern struct kpatch_post_patch_callback __kpatch_callbacks_post_patch[], __kpatch_callbacks_post_patch_end[];
|
||||
extern struct kpatch_pre_unpatch_callback __kpatch_callbacks_pre_unpatch[], __kpatch_callbacks_pre_unpatch_end[];
|
||||
extern struct kpatch_post_unpatch_callback __kpatch_callbacks_post_unpatch[], __kpatch_callbacks_post_unpatch_end[];
|
||||
+#ifdef HAVE_LOADHOOKS
|
||||
+extern struct kpatch_patch_hook __kpatch_hooks_load[], __kpatch_hooks_load_end[];
|
||||
+extern struct kpatch_patch_hook __kpatch_hooks_unload[], __kpatch_hooks_unload_end[];
|
||||
+#endif
|
||||
extern unsigned long __kpatch_force_funcs[], __kpatch_force_funcs_end[];
|
||||
|
||||
static int patch_is_func_forced(unsigned long addr)
|
||||
@@ -347,6 +413,11 @@ static int __init patch_init(void)
|
||||
struct patch_reloc *reloc;
|
||||
struct klp_reloc *lrelocs, *lreloc;
|
||||
#endif
|
||||
+#ifdef HAVE_LOADHOOKS
|
||||
+ struct patch_hook *hook;
|
||||
+ struct kpatch_patch_hook *khook_load, *khook_unload;
|
||||
+ struct klp_hook *lhooks_load, *lhooks_unload, *lhook;
|
||||
+#endif
|
||||
|
||||
/* organize functions and relocs by object in scaffold */
|
||||
for (kfunc = __kpatch_funcs;
|
||||
@@ -371,6 +442,24 @@ static int __init patch_init(void)
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
+#ifdef HAVE_LOADHOOKS
|
||||
+ for (khook_load = __kpatch_hooks_load;
|
||||
+ khook_load != __kpatch_hooks_load_end;
|
||||
+ khook_load++) {
|
||||
+ ret = patch_add_hook_to_object(khook_load, true);
|
||||
+ if (ret)
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
+ for (khook_unload = __kpatch_hooks_unload;
|
||||
+ khook_unload != __kpatch_hooks_unload_end;
|
||||
+ khook_unload++) {
|
||||
+ ret = patch_add_hook_to_object(khook_unload, false);
|
||||
+ if (ret)
|
||||
+ goto out;
|
||||
+ }
|
||||
+#endif
|
||||
+
|
||||
/* past this point, only possible return code is -ENOMEM */
|
||||
ret = -ENOMEM;
|
||||
|
||||
@@ -403,12 +492,21 @@ static int __init patch_init(void)
|
||||
lfunc = &lfuncs[j];
|
||||
lfunc->old_name = func->kfunc->name;
|
||||
lfunc->new_func = (void *)func->kfunc->new_addr;
|
||||
+#if defined(HAVE_IMMEDIATE)
|
||||
lfunc->immediate = patch_is_func_forced(lfunc->new_func);
|
||||
+#endif
|
||||
#ifdef HAVE_SYMPOS
|
||||
lfunc->old_sympos = func->kfunc->sympos;
|
||||
#else
|
||||
lfunc->old_addr = func->kfunc->old_addr;
|
||||
#endif
|
||||
+#ifdef EULER_RELEASE_CODE
|
||||
+# if EULER_RELEASE_CODE <= EULER_RELEASE_VERSION(2, 3)
|
||||
+ lfunc->old_size = func->kfunc->old_size;
|
||||
+ lfunc->new_size = func->kfunc->new_size;
|
||||
+ lfunc->force = patch_is_func_forced(func->kfunc->new_addr);
|
||||
+# endif
|
||||
+#endif
|
||||
j++;
|
||||
}
|
||||
|
||||
@@ -439,6 +537,32 @@ static int __init patch_init(void)
|
||||
lobject->callbacks = object->callbacks;
|
||||
#endif
|
||||
|
||||
+#ifdef HAVE_LOADHOOKS
|
||||
+ lhooks_load = kzalloc(sizeof(struct klp_hook) *
|
||||
+ (object->hooks_load_nr+1), GFP_KERNEL);
|
||||
+ if (!lhooks_load)
|
||||
+ goto out;
|
||||
+ lobject->hooks_load = lhooks_load;
|
||||
+ j = 0;
|
||||
+ list_for_each_entry(hook, &object->hooks_load, list) {
|
||||
+ lhook = &lhooks_load[j];
|
||||
+ lhook->hook = hook->khook->hook;
|
||||
+ j++;
|
||||
+ }
|
||||
+
|
||||
+ lhooks_unload = kzalloc(sizeof(struct klp_hook) *
|
||||
+ (object->hooks_unload_nr+1), GFP_KERNEL);
|
||||
+ if (!lhooks_unload)
|
||||
+ goto out;
|
||||
+ lobject->hooks_unload = lhooks_unload;
|
||||
+ j = 0;
|
||||
+ list_for_each_entry(hook, &object->hooks_unload, list) {
|
||||
+ lhook = &lhooks_unload[j];
|
||||
+ lhook->hook = hook->khook->hook;
|
||||
+ j++;
|
||||
+ }
|
||||
+#endif
|
||||
+
|
||||
i++;
|
||||
}
|
||||
|
||||
diff --git a/kpatch-build/create-diff-object.c b/kpatch-build/create-diff-object.c
|
||||
index 349e483..ed96758 100644
|
||||
--- a/kpatch-build/create-diff-object.c
|
||||
+++ b/kpatch-build/create-diff-object.c
|
||||
@@ -1463,6 +1463,10 @@ static int kpatch_include_callback_elements(struct kpatch_elf *kelf)
|
||||
".rela.kpatch.callbacks.post_patch",
|
||||
".rela.kpatch.callbacks.pre_unpatch",
|
||||
".rela.kpatch.callbacks.post_unpatch",
|
||||
+ ".kpatch.hooks.load",
|
||||
+ ".kpatch.hooks.unload",
|
||||
+ ".rela.kpatch.hooks.load",
|
||||
+ ".rela.kpatch.hooks.unload",
|
||||
NULL,
|
||||
};
|
||||
char **callback_section;
|
||||
@@ -2921,6 +2925,10 @@ static void kpatch_create_callbacks_objname_rela(struct kpatch_elf *kelf, char *
|
||||
.offset = offsetof(struct kpatch_pre_unpatch_callback, objname) },
|
||||
{ .name = ".rela.kpatch.callbacks.post_unpatch",
|
||||
.offset = offsetof(struct kpatch_post_patch_callback, objname) },
|
||||
+ { .name = ".rela.kpatch.hooks.load",
|
||||
+ .offset = offsetof(struct kpatch_patch_hook, objname) },
|
||||
+ { .name = ".rela.kpatch.hooks.unload",
|
||||
+ .offset = offsetof(struct kpatch_patch_hook, objname) },
|
||||
{ .name = NULL, .offset = 0 },
|
||||
};
|
||||
struct callback *callbackp;
|
||||
--
|
||||
1.7.5.4
|
||||
|
||||
480
9010-kmod-kpatch-build-support-cross-compile-hotpatch-for.patch
Normal file
480
9010-kmod-kpatch-build-support-cross-compile-hotpatch-for.patch
Normal file
@ -0,0 +1,480 @@
|
||||
From be8e5ce9541fc230131be230bd0646c473427895 Mon Sep 17 00:00:00 2001
|
||||
From: Zhipeng Xie <xiezhipeng1@huawei.com>
|
||||
Date: Fri, 2 Nov 2018 17:25:20 +0000
|
||||
Subject: [PATCH 1010/1015] kmod/kpatch-build: support cross compile hotpatch
|
||||
for aarch64
|
||||
|
||||
use R_AARCH64_ABS64 for aarch64, function_ptr_rela and
|
||||
kpatch_line_macro_change_only are left to implement later.
|
||||
|
||||
Signed-off-by: Zhipeng Xie <xiezhipeng1@huawei.com>
|
||||
---
|
||||
kmod/patch/livepatch-patch-hook.c | 16 +++---
|
||||
kpatch-build/create-diff-object.c | 98 ++++++++++++++++++++++++++++++----
|
||||
kpatch-build/create-kpatch-module.c | 24 ++++++++-
|
||||
kpatch-build/kpatch-build | 42 ++++++++++++---
|
||||
kpatch-build/kpatch-gcc | 4 +-
|
||||
5 files changed, 152 insertions(+), 32 deletions(-)
|
||||
|
||||
diff --git a/kmod/patch/livepatch-patch-hook.c b/kmod/patch/livepatch-patch-hook.c
|
||||
index 8f7d044..ee3b2b9 100644
|
||||
--- a/kmod/patch/livepatch-patch-hook.c
|
||||
+++ b/kmod/patch/livepatch-patch-hook.c
|
||||
@@ -66,13 +66,17 @@
|
||||
|
||||
#ifdef EULER_RELEASE_CODE
|
||||
# if EULER_RELEASE_CODE <= EULER_RELEASE_VERSION(2, 3)
|
||||
-# undef HAVE_SYMPOS
|
||||
-# undef HAVE_IMMEDIATE
|
||||
-# undef HAVE_ELF_RELOCS
|
||||
-# define HAVE_LOADHOOKS
|
||||
+# define __HULK__
|
||||
# endif
|
||||
#endif
|
||||
|
||||
+#ifdef __HULK__
|
||||
+# undef HAVE_SYMPOS
|
||||
+# undef HAVE_IMMEDIATE
|
||||
+# undef HAVE_ELF_RELOCS
|
||||
+# define HAVE_LOADHOOKS
|
||||
+#endif
|
||||
+
|
||||
/*
|
||||
* There are quite a few similar structures at play in this file:
|
||||
* - livepatch.h structs prefixed with klp_*
|
||||
@@ -500,12 +504,10 @@ static int __init patch_init(void)
|
||||
#else
|
||||
lfunc->old_addr = func->kfunc->old_addr;
|
||||
#endif
|
||||
-#ifdef EULER_RELEASE_CODE
|
||||
-# if EULER_RELEASE_CODE <= EULER_RELEASE_VERSION(2, 3)
|
||||
+#ifdef __HULK__
|
||||
lfunc->old_size = func->kfunc->old_size;
|
||||
lfunc->new_size = func->kfunc->new_size;
|
||||
lfunc->force = patch_is_func_forced(func->kfunc->new_addr);
|
||||
-# endif
|
||||
#endif
|
||||
j++;
|
||||
}
|
||||
diff --git a/kpatch-build/create-diff-object.c b/kpatch-build/create-diff-object.c
|
||||
index ed96758..b8d3bb4 100644
|
||||
--- a/kpatch-build/create-diff-object.c
|
||||
+++ b/kpatch-build/create-diff-object.c
|
||||
@@ -70,6 +70,31 @@ char *childobj;
|
||||
|
||||
enum loglevel loglevel = NORMAL;
|
||||
|
||||
+#ifndef EM_X86_64
|
||||
+#define EM_X86_64 62
|
||||
+#endif
|
||||
+
|
||||
+#ifndef EM_AARCH64
|
||||
+#define EM_AARCH64 183
|
||||
+#endif
|
||||
+
|
||||
+#ifndef R_AARCH64_ABS64
|
||||
+#define R_AARCH64_NONE 0
|
||||
+#define R_AARCH64_ABS64 257
|
||||
+#define R_AARCH64_CALL26 283
|
||||
+#endif
|
||||
+
|
||||
+static unsigned int arch;
|
||||
+static unsigned int absolute_rela_type;
|
||||
+
|
||||
+static unsigned int arch_of_elf(Elf *elf)
|
||||
+{
|
||||
+ GElf_Ehdr eh;
|
||||
+ if (!gelf_getehdr(elf, &eh))
|
||||
+ ERROR("gelf_getehdr");
|
||||
+ return eh.e_machine;
|
||||
+}
|
||||
+
|
||||
/*******************
|
||||
* Data structures
|
||||
* ****************/
|
||||
@@ -635,6 +660,8 @@ static void kpatch_compare_correlated_symbol(struct symbol *sym)
|
||||
if (sym1->sec && sym2->sec && sym1->sec->twin != sym2->sec) {
|
||||
if (sym2->sec->twin && sym2->sec->twin->ignore)
|
||||
sym->status = CHANGED;
|
||||
+ else if (sym1->name[0] == '$') /* reserved symbols in aarch64 */
|
||||
+ log_debug("maping symbols: %s", sym1->name); /* do nothing just ignogre */
|
||||
else
|
||||
DIFF_FATAL("symbol changed sections: %s", sym1->name);
|
||||
}
|
||||
@@ -2294,7 +2321,7 @@ static void kpatch_create_kpatch_arch_section(struct kpatch_elf *kelf, char *obj
|
||||
/* entries[index].sec */
|
||||
ALLOC_LINK(rela, &karch_sec->rela->relas);
|
||||
rela->sym = sec->secsym;
|
||||
- rela->type = ABSOLUTE_RELA_TYPE;
|
||||
+ rela->type = absolute_rela_type;
|
||||
rela->addend = 0;
|
||||
rela->offset = index * sizeof(*entries) + \
|
||||
offsetof(struct kpatch_arch, sec);
|
||||
@@ -2302,7 +2329,7 @@ static void kpatch_create_kpatch_arch_section(struct kpatch_elf *kelf, char *obj
|
||||
/* entries[index].objname */
|
||||
ALLOC_LINK(rela, &karch_sec->rela->relas);
|
||||
rela->sym = strsym;
|
||||
- rela->type = ABSOLUTE_RELA_TYPE;
|
||||
+ rela->type = absolute_rela_type;
|
||||
rela->addend = offset_of_string(&kelf->strings, objname);
|
||||
rela->offset = index * sizeof(*entries) + \
|
||||
offsetof(struct kpatch_arch, objname);
|
||||
@@ -2500,7 +2527,7 @@ static void kpatch_create_patches_sections(struct kpatch_elf *kelf,
|
||||
*/
|
||||
ALLOC_LINK(rela, &relasec->relas);
|
||||
rela->sym = sym;
|
||||
- rela->type = ABSOLUTE_RELA_TYPE;
|
||||
+ rela->type = absolute_rela_type;
|
||||
rela->addend = 0;
|
||||
rela->offset = index * sizeof(*funcs);
|
||||
|
||||
@@ -2510,7 +2537,7 @@ static void kpatch_create_patches_sections(struct kpatch_elf *kelf,
|
||||
*/
|
||||
ALLOC_LINK(rela, &relasec->relas);
|
||||
rela->sym = strsym;
|
||||
- rela->type = ABSOLUTE_RELA_TYPE;
|
||||
+ rela->type = absolute_rela_type;
|
||||
rela->addend = offset_of_string(&kelf->strings, sym->name);
|
||||
rela->offset = index * sizeof(*funcs) +
|
||||
offsetof(struct kpatch_patch_func, name);
|
||||
@@ -2521,7 +2548,7 @@ static void kpatch_create_patches_sections(struct kpatch_elf *kelf,
|
||||
*/
|
||||
ALLOC_LINK(rela, &relasec->relas);
|
||||
rela->sym = strsym;
|
||||
- rela->type = ABSOLUTE_RELA_TYPE;
|
||||
+ rela->type = absolute_rela_type;
|
||||
rela->addend = objname_offset;
|
||||
rela->offset = index * sizeof(*funcs) +
|
||||
offsetof(struct kpatch_patch_func,objname);
|
||||
@@ -2834,7 +2861,7 @@ static void kpatch_create_intermediate_sections(struct kpatch_elf *kelf,
|
||||
/* add rela to fill in ksyms[index].name field */
|
||||
ALLOC_LINK(rela2, &ksym_sec->rela->relas);
|
||||
rela2->sym = strsym;
|
||||
- rela2->type = ABSOLUTE_RELA_TYPE;
|
||||
+ rela2->type = absolute_rela_type;
|
||||
rela2->addend = offset_of_string(&kelf->strings, rela->sym->name);
|
||||
rela2->offset = index * sizeof(*ksyms) + \
|
||||
offsetof(struct kpatch_symbol, name);
|
||||
@@ -2842,7 +2869,7 @@ static void kpatch_create_intermediate_sections(struct kpatch_elf *kelf,
|
||||
/* add rela to fill in ksyms[index].objname field */
|
||||
ALLOC_LINK(rela2, &ksym_sec->rela->relas);
|
||||
rela2->sym = strsym;
|
||||
- rela2->type = ABSOLUTE_RELA_TYPE;
|
||||
+ rela2->type = absolute_rela_type;
|
||||
rela2->addend = offset_of_string(&kelf->strings, sym_objname);
|
||||
rela2->offset = index * sizeof(*ksyms) + \
|
||||
offsetof(struct kpatch_symbol, objname);
|
||||
@@ -2863,7 +2890,7 @@ static void kpatch_create_intermediate_sections(struct kpatch_elf *kelf,
|
||||
ERROR("can't create dynrela for section %s (symbol %s): no bundled or section symbol",
|
||||
sec->name, rela->sym->name);
|
||||
|
||||
- rela2->type = ABSOLUTE_RELA_TYPE;
|
||||
+ rela2->type = absolute_rela_type;
|
||||
rela2->addend = rela->offset;
|
||||
rela2->offset = index * sizeof(*krelas) + \
|
||||
offsetof(struct kpatch_relocation, dest);
|
||||
@@ -2871,7 +2898,7 @@ static void kpatch_create_intermediate_sections(struct kpatch_elf *kelf,
|
||||
/* add rela to fill in krelas[index].objname field */
|
||||
ALLOC_LINK(rela2, &krela_sec->rela->relas);
|
||||
rela2->sym = strsym;
|
||||
- rela2->type = ABSOLUTE_RELA_TYPE;
|
||||
+ rela2->type = absolute_rela_type;
|
||||
rela2->addend = offset_of_string(&kelf->strings, objname);
|
||||
rela2->offset = index * sizeof(*krelas) + \
|
||||
offsetof(struct kpatch_relocation, objname);
|
||||
@@ -2879,7 +2906,7 @@ static void kpatch_create_intermediate_sections(struct kpatch_elf *kelf,
|
||||
/* add rela to fill in krelas[index].ksym field */
|
||||
ALLOC_LINK(rela2, &krela_sec->rela->relas);
|
||||
rela2->sym = ksym_sec_sym;
|
||||
- rela2->type = ABSOLUTE_RELA_TYPE;
|
||||
+ rela2->type = absolute_rela_type;
|
||||
rela2->addend = index * sizeof(*ksyms);
|
||||
rela2->offset = index * sizeof(*krelas) + \
|
||||
offsetof(struct kpatch_relocation, ksym);
|
||||
@@ -2946,7 +2973,7 @@ static void kpatch_create_callbacks_objname_rela(struct kpatch_elf *kelf, char *
|
||||
if (!strcmp(callbackp->name, sec->name)) {
|
||||
ALLOC_LINK(rela, &sec->relas);
|
||||
rela->sym = strsym;
|
||||
- rela->type = ABSOLUTE_RELA_TYPE;
|
||||
+ rela->type = absolute_rela_type;
|
||||
rela->addend = objname_offset;
|
||||
rela->offset = callbackp->offset;
|
||||
break;
|
||||
@@ -3000,6 +3027,7 @@ static void kpatch_create_mcount_sections(struct kpatch_elf *kelf)
|
||||
/* add rela in .rela__mcount_loc to fill in function pointer */
|
||||
ALLOC_LINK(rela, &relasec->relas);
|
||||
rela->sym = sym;
|
||||
+ if (arch == EM_X86_64) {
|
||||
rela->type = R_X86_64_64;
|
||||
rela->addend = 0;
|
||||
rela->offset = index * sizeof(*funcs);
|
||||
@@ -3024,6 +3052,37 @@ static void kpatch_create_mcount_sections(struct kpatch_elf *kelf)
|
||||
rela = list_first_entry(&sym->sec->rela->relas, struct rela,
|
||||
list);
|
||||
rela->type = R_X86_64_PC32;
|
||||
+ } else if (arch == EM_AARCH64) {
|
||||
+ unsigned int *insnp;
|
||||
+ rela->type = R_AARCH64_ABS64;
|
||||
+ /* bl <__fentry__> is the second insn */
|
||||
+ rela->addend = 4;
|
||||
+ rela->offset = index * sizeof(*funcs);
|
||||
+
|
||||
+ newdata = malloc(sym->sec->data->d_size);
|
||||
+ memcpy(newdata, sym->sec->data->d_buf, sym->sec->data->d_size);
|
||||
+ sym->sec->data->d_buf = newdata;
|
||||
+ insnp = newdata;
|
||||
+
|
||||
+ /*
|
||||
+ * mov x9, x30
|
||||
+ * nop //function in .text.<func>, so it be replaced with nop by recordmcount
|
||||
+ * mov x30, x9
|
||||
+ */
|
||||
+ if (insnp[0] != 0xaa1e03e9 || insnp[1] != 0xd503201f || insnp[2] != 0xaa0903fe)
|
||||
+ ERROR("%s: unexpected instruction at the start of the function",
|
||||
+ sym->name);
|
||||
+
|
||||
+ /* change the nop to bl __fentry__ */
|
||||
+ insnp[1] = 0x94000000;
|
||||
+ rela = list_first_entry(&sym->sec->rela->relas, struct rela,
|
||||
+ list);
|
||||
+ rela->type = R_AARCH64_CALL26;
|
||||
+ rela->offset = 4;
|
||||
+
|
||||
+ } else {
|
||||
+ ERROR("unsupport arch %d\n", arch);
|
||||
+ }
|
||||
|
||||
index++;
|
||||
}
|
||||
@@ -3168,6 +3227,7 @@ int main(int argc, char *argv[])
|
||||
char *hint = NULL, *orig_obj, *patched_obj, *parent_name;
|
||||
char *parent_symtab, *mod_symvers, *patch_name, *output_obj;
|
||||
struct sym_compare_type *base_locals;
|
||||
+ char *gcc_add_option, *mlongcall;
|
||||
|
||||
arguments.debug = 0;
|
||||
argp_parse (&argp, argc, argv, 0, NULL, &arguments);
|
||||
@@ -3188,6 +3248,13 @@ int main(int argc, char *argv[])
|
||||
|
||||
kelf_base = kpatch_elf_open(orig_obj);
|
||||
kelf_patched = kpatch_elf_open(patched_obj);
|
||||
+ arch = arch_of_elf(kelf_base->elf);
|
||||
+ if (arch == EM_X86_64)
|
||||
+ absolute_rela_type = R_X86_64_64;
|
||||
+ else if (arch == EM_AARCH64)
|
||||
+ absolute_rela_type = R_AARCH64_ABS64;
|
||||
+ else
|
||||
+ ERROR("only arch x86_64 and arm64 be supported\n");
|
||||
|
||||
kpatch_bundle_symbols(kelf_base);
|
||||
kpatch_bundle_symbols(kelf_patched);
|
||||
@@ -3276,7 +3343,14 @@ int main(int argc, char *argv[])
|
||||
kpatch_create_callbacks_objname_rela(kelf_out, parent_name);
|
||||
kpatch_build_strings_section_data(kelf_out);
|
||||
|
||||
- kpatch_create_mcount_sections(kelf_out);
|
||||
+ gcc_add_option = getenv("GCC_ADD_OPTION");
|
||||
+ printf("gcc add option :%s\n", gcc_add_option);
|
||||
+ mlongcall = strstr(gcc_add_option, "-mlong-calls");
|
||||
+ if (arch == EM_AARCH64 && mlongcall) {
|
||||
+ printf("-mlong-calls found, no need to create mcount section\n");
|
||||
+ } else {
|
||||
+ kpatch_create_mcount_sections(kelf_out);
|
||||
+ }
|
||||
|
||||
/*
|
||||
* At this point, the set of output sections and symbols is
|
||||
diff --git a/kpatch-build/create-kpatch-module.c b/kpatch-build/create-kpatch-module.c
|
||||
index 67b16b0..9f1c3b9 100644
|
||||
--- a/kpatch-build/create-kpatch-module.c
|
||||
+++ b/kpatch-build/create-kpatch-module.c
|
||||
@@ -31,6 +31,17 @@
|
||||
char *childobj;
|
||||
enum loglevel loglevel = NORMAL;
|
||||
|
||||
+static unsigned int arch;
|
||||
+static unsigned int absolute_rela_type;
|
||||
+
|
||||
+static unsigned int arch_of_elf(Elf *elf)
|
||||
+{
|
||||
+ GElf_Ehdr eh;
|
||||
+ if (!gelf_getehdr(elf, &eh))
|
||||
+ ERROR("gelf_getehdr");
|
||||
+ return eh.e_machine;
|
||||
+}
|
||||
+
|
||||
/*
|
||||
* Create .kpatch.dynrelas from .kpatch.relocations and .kpatch.symbols sections
|
||||
*
|
||||
@@ -102,14 +113,14 @@ static void create_dynamic_rela_sections(struct kpatch_elf *kelf, struct section
|
||||
/* dest */
|
||||
ALLOC_LINK(rela, &dynsec->rela->relas);
|
||||
rela->sym = sym;
|
||||
- rela->type = R_X86_64_64;
|
||||
+ rela->type = absolute_rela_type;
|
||||
rela->addend = dest_offset;
|
||||
rela->offset = index * sizeof(*dynrelas);
|
||||
|
||||
/* name */
|
||||
ALLOC_LINK(rela, &dynsec->rela->relas);
|
||||
rela->sym = strsec->secsym;
|
||||
- rela->type = R_X86_64_64;
|
||||
+ rela->type = absolute_rela_type;
|
||||
rela->addend = name_offset;
|
||||
rela->offset = index * sizeof(*dynrelas) + \
|
||||
offsetof(struct kpatch_patch_dynrela, name);
|
||||
@@ -117,7 +128,7 @@ static void create_dynamic_rela_sections(struct kpatch_elf *kelf, struct section
|
||||
/* objname */
|
||||
ALLOC_LINK(rela, &dynsec->rela->relas);
|
||||
rela->sym = strsec->secsym;
|
||||
- rela->type = R_X86_64_64;
|
||||
+ rela->type = absolute_rela_type;
|
||||
rela->addend = objname_offset;
|
||||
rela->offset = index * sizeof(*dynrelas) + \
|
||||
offsetof(struct kpatch_patch_dynrela, objname);
|
||||
@@ -200,6 +211,13 @@ int main(int argc, char *argv[])
|
||||
childobj = basename(arguments.args[0]);
|
||||
|
||||
kelf = kpatch_elf_open(arguments.args[0]);
|
||||
+ arch = arch_of_elf(kelf->elf);
|
||||
+ if (arch == EM_X86_64)
|
||||
+ absolute_rela_type = R_X86_64_64;
|
||||
+ else if (arch == EM_AARCH64)
|
||||
+ absolute_rela_type = R_AARCH64_ABS64;
|
||||
+ else
|
||||
+ ERROR("only arch x86_64 and arm64 be supported\n");
|
||||
|
||||
/*
|
||||
* Sanity checks:
|
||||
diff --git a/kpatch-build/kpatch-build b/kpatch-build/kpatch-build
|
||||
index 93a0589..017604c 100755
|
||||
--- a/kpatch-build/kpatch-build
|
||||
+++ b/kpatch-build/kpatch-build
|
||||
@@ -384,6 +384,27 @@ find_kobj() {
|
||||
done
|
||||
}
|
||||
|
||||
+arch_export() {
|
||||
+ E_MACHINE=$(od -An -j18 -N2 -d $VMLINUX)
|
||||
+ if [[ $E_MACHINE -eq 62 ]]; then
|
||||
+ export ARCH=x86_64
|
||||
+ export ARCH_COMPILE=
|
||||
+ export ENDIAN=little
|
||||
+ export GCC_ADD_OPTION=
|
||||
+ elif [[ $E_MACHINE -eq 183 ]]; then
|
||||
+ export ARCH=arm64
|
||||
+ export ARCH_COMPILE=aarch64-linux-gnu-
|
||||
+ export ENDIAN=little
|
||||
+ if grep "\-mlong-calls" $SRCDIR/Makefile > /dev/null; then
|
||||
+ export GCC_ADD_OPTION="-fno-section-anchors -mlong-calls"
|
||||
+ else
|
||||
+ export GCC_ADD_OPTION="-fno-section-anchors"
|
||||
+ fi
|
||||
+ else
|
||||
+ die "only support arm64 or x86_64 architecture"
|
||||
+ fi
|
||||
+}
|
||||
+
|
||||
# Only allow alphanumerics and '_' and '-' in the module name. Everything else
|
||||
# is replaced with '-'. Also truncate to 48 chars so the full name fits in the
|
||||
# kernel's 56-byte module name array.
|
||||
@@ -725,12 +746,12 @@ apply_patches
|
||||
remove_patches
|
||||
|
||||
cp -LR "$DATADIR/patch" "$TEMPDIR" || die
|
||||
-
|
||||
+arch_export
|
||||
if [[ "$ARCH" = "ppc64le" ]]; then
|
||||
ARCH_KCFLAGS="-mcmodel=large -fplugin=$PLUGINDIR/ppc64le-plugin.so"
|
||||
fi
|
||||
|
||||
-export KCFLAGS="-I$DATADIR/patch -ffunction-sections -fdata-sections $ARCH_KCFLAGS"
|
||||
+export KCFLAGS="-I$DATADIR/patch -ffunction-sections -fdata-sections $ARCH_KCFLAGS ${GCC_ADD_OPTION}"
|
||||
|
||||
echo "Reading special section data"
|
||||
find_special_section_data
|
||||
@@ -752,9 +773,9 @@ unset KPATCH_GCC_TEMPDIR
|
||||
# $TARGETS used as list, no quotes.
|
||||
# shellcheck disable=SC2086
|
||||
if [ -z "$USERMODDIR" ];then
|
||||
- CROSS_COMPILE="$TOOLSDIR/kpatch-gcc " make "-j$CPUS" $TARGETS 2>&1 | logger || die
|
||||
+ CROSS_COMPILE="$TOOLSDIR/kpatch-gcc $ARCH_COMPILE" make "-j$CPUS" $TARGETS 2>&1 | logger || die
|
||||
else
|
||||
- CROSS_COMPILE="$TOOLSDIR/kpatch-gcc " make -C "$USERMODBUILDDIR" M="$USERMODBUILDDIR" "-j$CPUS" $USERMODFLAGS $TARGETS 2>&1 | logger || die
|
||||
+ CROSS_COMPILE="$TOOLSDIR/kpatch-gcc $ARCH_COMPILE" make -C "$USERMODBUILDDIR" M="$USERMODBUILDDIR" "-j$CPUS" $USERMODFLAGS $TARGETS 2>&1 | logger || die
|
||||
fi
|
||||
|
||||
sleep 1
|
||||
@@ -770,11 +791,11 @@ export KPATCH_GCC_TEMPDIR
|
||||
# $TARGETS used as list, no quotes.
|
||||
# shellcheck disable=SC2086
|
||||
if [ -z "$USERMODDIR" ];then
|
||||
- CROSS_COMPILE="$TOOLSDIR/kpatch-gcc " \
|
||||
+ CROSS_COMPILE="$TOOLSDIR/kpatch-gcc $ARCH_COMPILE" \
|
||||
KBUILD_MODPOST_WARN=1 \
|
||||
make "-j$CPUS" $TARGETS 2>&1 | logger || die
|
||||
else
|
||||
- CROSS_COMPILE="$TOOLSDIR/kpatch-gcc " \
|
||||
+ CROSS_COMPILE="$TOOLSDIR/kpatch-gcc $ARCH_COMPILE" \
|
||||
KBUILD_MODPOST_WARN=1 \
|
||||
make -C "$USERMODBUILDDIR" M="$USERMODBUILDDIR" "-j$CPUS" $USERMODFLAGS $TARGETS 2>&1 | logger || die
|
||||
fi
|
||||
@@ -907,6 +928,10 @@ if "$KPATCH_MODULE"; then
|
||||
export KCPPFLAGS="-D__KPATCH_MODULE__"
|
||||
fi
|
||||
|
||||
+if grep "hulk" $SRCDIR/Makefile > /dev/null; then
|
||||
+ export KCPPFLAGS="-D__HULK__ $KCPPFLAGS"
|
||||
+fi
|
||||
+
|
||||
echo "Building patch module: $MODNAME.ko"
|
||||
|
||||
if [[ -z "$USERSRCDIR" ]] && [[ "$DISTRO" = ubuntu ]]; then
|
||||
@@ -919,12 +944,12 @@ fi
|
||||
cd "$TEMPDIR/output" || die
|
||||
# $KPATCH_LDFLAGS and result of find used as list, no quotes.
|
||||
# shellcheck disable=SC2086,SC2046
|
||||
-ld -r $KPATCH_LDFLAGS -o ../patch/tmp_output.o $(find . -name "*.o") 2>&1 | logger || die
|
||||
+${ARCH_COMPILE}ld -r $KPATCH_LDFLAGS -o ../patch/tmp_output.o $(find . -name "*.o") 2>&1 | logger || die
|
||||
|
||||
if "$KPATCH_MODULE"; then
|
||||
# Add .kpatch.checksum for kpatch script
|
||||
md5sum ../patch/tmp_output.o | awk '{printf "%s\0", $1}' > checksum.tmp || die
|
||||
- objcopy --add-section .kpatch.checksum=checksum.tmp --set-section-flags .kpatch.checksum=alloc,load,contents,readonly ../patch/tmp_output.o || die
|
||||
+ ${ARCH_COMPILE}objcopy --add-section .kpatch.checksum=checksum.tmp --set-section-flags .kpatch.checksum=alloc,load,contents,readonly ../patch/tmp_output.o || die
|
||||
rm -f checksum.tmp
|
||||
"$TOOLSDIR"/create-kpatch-module "$TEMPDIR"/patch/tmp_output.o "$TEMPDIR"/patch/output.o 2>&1 | logger 1
|
||||
check_pipe_status create-kpatch-module
|
||||
@@ -942,6 +967,7 @@ fi
|
||||
KPATCH_BUILD="$KPATCH_BUILDIR" KPATCH_NAME="$MODNAME" \
|
||||
KBUILD_EXTRA_SYMBOLS="$KBUILD_EXTRA_SYMBOLS" \
|
||||
KPATCH_LDFLAGS="$KPATCH_LDFLAGS" \
|
||||
+CROSS_COMPILE="$ARCH_COMPILE" \
|
||||
make 2>&1 | logger || die
|
||||
|
||||
if ! "$KPATCH_MODULE"; then
|
||||
diff --git a/kpatch-build/kpatch-gcc b/kpatch-build/kpatch-gcc
|
||||
index 21f7e2e..be18847 100755
|
||||
--- a/kpatch-build/kpatch-gcc
|
||||
+++ b/kpatch-build/kpatch-gcc
|
||||
@@ -13,7 +13,7 @@ fi
|
||||
|
||||
declare -a args=("$@")
|
||||
|
||||
-if [[ "$TOOLCHAINCMD" = "gcc" ]] ; then
|
||||
+if [[ "$TOOLCHAINCMD" = ${ARCH_COMPILE}gcc ]] ; then
|
||||
while [ "$#" -gt 0 ]; do
|
||||
if [ "$1" = "-o" ]; then
|
||||
obj="$2"
|
||||
@@ -64,7 +64,7 @@ if [[ "$TOOLCHAINCMD" = "gcc" ]] ; then
|
||||
fi
|
||||
shift
|
||||
done
|
||||
-elif [[ "$TOOLCHAINCMD" = "ld" ]] ; then
|
||||
+elif [[ "$TOOLCHAINCMD" = ${ARCH_COMPILE}ld ]] ; then
|
||||
while [ "$#" -gt 0 ]; do
|
||||
if [ "$1" = "-o" ]; then
|
||||
obj="$2"
|
||||
--
|
||||
1.7.5.4
|
||||
|
||||
48
9011-kpatch-build-use-.klp.rela-in-euleros-7.5-kernel.patch
Normal file
48
9011-kpatch-build-use-.klp.rela-in-euleros-7.5-kernel.patch
Normal file
@ -0,0 +1,48 @@
|
||||
From 868a6e4462bebcffa4bf6beea02262823e7dc3a3 Mon Sep 17 00:00:00 2001
|
||||
From: Zhipeng Xie <xiezhipeng1@huawei.com>
|
||||
Date: Fri, 2 Nov 2018 17:25:33 +0000
|
||||
Subject: [PATCH] kpatch-build: use .klp.rela in euleros 7.5 kernel
|
||||
|
||||
use .klp.rela in euleros 7.5 kernel
|
||||
|
||||
Signed-off-by: Zhipeng Xie <xiezhipeng1@huawei.com>
|
||||
---
|
||||
kpatch-build/kpatch-build | 13 +++++++++++--
|
||||
1 files changed, 11 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/kpatch-build/kpatch-build b/kpatch-build/kpatch-build
|
||||
index fb14850..5a70a44 100755
|
||||
--- a/kpatch-build/kpatch-build
|
||||
+++ b/kpatch-build/kpatch-build
|
||||
@@ -157,6 +157,15 @@ is_rhel() {
|
||||
[[ $1 =~ \.el[78]\. ]]
|
||||
}
|
||||
|
||||
+is_euleros_klp() {
|
||||
+ if [[ "$1" =~ ^3.10.0-862 ]] ;then
|
||||
+ if [ $ID == "euleros" ];then
|
||||
+ return 0;
|
||||
+ fi
|
||||
+ fi
|
||||
+ return 1;
|
||||
+}
|
||||
+
|
||||
find_dirs() {
|
||||
if [[ -e "$SCRIPTDIR/create-diff-object" ]]; then
|
||||
# git repo
|
||||
@@ -708,10 +717,10 @@ KPATCH_MODULE=true
|
||||
grep -q "CONFIG_DEBUG_INFO=y" "$CONFIGFILE" || die "kernel doesn't have 'CONFIG_DEBUG_INFO' enabled"
|
||||
if grep -q "CONFIG_LIVEPATCH=y" "$CONFIGFILE"; then
|
||||
# The kernel supports livepatch.
|
||||
- if version_gte "${ARCHVERSION//-*/}" 4.7.0 || is_rhel "$ARCHVERSION"; then
|
||||
+ if version_gte "${ARCHVERSION//-*/}" 4.7.0 || is_rhel "$ARCHVERSION" || is_euleros_klp "$ARCHVERSION"; then
|
||||
# Use new .klp.rela. sections
|
||||
KPATCH_MODULE=false
|
||||
- if version_gte "${ARCHVERSION//-*/}" 4.9.0 || is_rhel "$ARCHVERSION"; then
|
||||
+ if version_gte "${ARCHVERSION//-*/}" 4.9.0 || is_rhel "$ARCHVERSION" || is_euleros_klp "$ARCHVERSION"; then
|
||||
KPATCH_LDFLAGS="--unique=.parainstructions --unique=.altinstructions"
|
||||
fi
|
||||
fi
|
||||
--
|
||||
1.7.5.4
|
||||
|
||||
@ -0,0 +1,68 @@
|
||||
From 78a13a6091a0d4b1a45fe8f378892a64dece7202 Mon Sep 17 00:00:00 2001
|
||||
From: Zhipeng Xie <xiezhipeng1@huawei.com>
|
||||
Date: Fri, 2 Nov 2018 17:25:38 +0000
|
||||
Subject: [PATCH 1012/1015] create-diff-object: create dynamic relocs for
|
||||
changed functions in this object
|
||||
|
||||
Currently, we only create dynamic relocs for changed functions of
|
||||
other objects, but not this object. It will cause a problem like:
|
||||
|
||||
original: funcA and funcB (funcA calls funcB)
|
||||
patch-1: funcA-1 and funcB-1 (funcA-1 calls funcB-1)
|
||||
patch-2: funcB-2 (funcA-1 should call funcB-2)
|
||||
|
||||
But as we don't create dynamic relocs for funcA-1, it will call
|
||||
funcB-1 directly (not by jumping from funcB). So the new funcB-2
|
||||
will not get called. This patch will create dynamic relocs for
|
||||
all the changed functions, including changed ones in this object.
|
||||
|
||||
Reported-by: Xie Zhipeng <xiezhipeng1@huawei.com>
|
||||
Tested-by: Zhou Chengming <zhouchengming1@huawei.com>
|
||||
Signed-off-by: Zhou Chengming <zhouchengming1@huawei.com>
|
||||
Signed-off-by: Li Bin <huawei.libin@huawei.com>
|
||||
Signed-off-by: Zhipeng Xie <xiezhipeng1@huawei.com>
|
||||
---
|
||||
kpatch-build/create-diff-object.c | 20 ++++++++++++++++----
|
||||
1 files changed, 16 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/kpatch-build/create-diff-object.c b/kpatch-build/create-diff-object.c
|
||||
index b8d3bb4..4fb27da 100644
|
||||
--- a/kpatch-build/create-diff-object.c
|
||||
+++ b/kpatch-build/create-diff-object.c
|
||||
@@ -2684,6 +2684,14 @@ static void kpatch_create_intermediate_sections(struct kpatch_elf *kelf,
|
||||
*/
|
||||
if (may_need_dynrela(rela))
|
||||
toc_rela(rela)->need_dynrela = 1;
|
||||
+ if (rela->sym->sec) {
|
||||
+ if (rela->sym->type == STT_FUNC &&
|
||||
+ rela->sym->status == CHANGED &&
|
||||
+ rela->sym->sec != sec->base &&
|
||||
+ sec->base->sym &&
|
||||
+ sec->base->sym->type == STT_FUNC)
|
||||
+ toc_rela(rela)->need_dynrela = 1;
|
||||
+ }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2765,10 +2773,14 @@ static void kpatch_create_intermediate_sections(struct kpatch_elf *kelf,
|
||||
/* An unchanged local symbol */
|
||||
ret = lookup_local_symbol(table,
|
||||
rela->sym->name, &result);
|
||||
- if (ret)
|
||||
- ERROR("lookup_local_symbol %s needed for %s",
|
||||
- rela->sym->name, sec->base->name);
|
||||
-
|
||||
+ if (ret) {
|
||||
+ /* maybe it is a global symbol converted in kpatch_create_patches_sections*/
|
||||
+ ret = lookup_global_symbol(table,
|
||||
+ rela->sym->name, &result);
|
||||
+ if (ret)
|
||||
+ ERROR("lookup_local_symbol %s needed for %s",
|
||||
+ rela->sym->name, sec->base->name);
|
||||
+ }
|
||||
}
|
||||
else if (vmlinux) {
|
||||
/*
|
||||
--
|
||||
1.7.5.4
|
||||
|
||||
365
9013-kmod-kpatch-build-fix-duplicate-symbol-relocation-fo.patch
Normal file
365
9013-kmod-kpatch-build-fix-duplicate-symbol-relocation-fo.patch
Normal file
@ -0,0 +1,365 @@
|
||||
From 1eaabfe01cfae870abd45bfa470caa144f34e74c Mon Sep 17 00:00:00 2001
|
||||
From: Zhipeng Xie <xiezhipeng1@huawei.com>
|
||||
Date: Fri, 2 Nov 2018 17:25:45 +0000
|
||||
Subject: [PATCH 1013/1015] kmod/kpatch-build: fix duplicate symbol relocation
|
||||
for hulk kernel
|
||||
|
||||
hulk kernel fix it by find a uniq symbol(ref_name) and
|
||||
use ref_offset to find the duplicate symbol
|
||||
|
||||
Signed-off-by: Zhipeng Xie <xiezhipeng1@huawei.com>
|
||||
---
|
||||
kmod/patch/kpatch-patch.h | 4 ++
|
||||
kmod/patch/livepatch-patch-hook.c | 6 ++
|
||||
kpatch-build/create-diff-object.c | 44 +++++++++++++++++-
|
||||
kpatch-build/create-kpatch-module.c | 23 +++++++++-
|
||||
kpatch-build/kpatch-build | 12 +++++
|
||||
kpatch-build/kpatch-intermediate.h | 2 +
|
||||
kpatch-build/lookup.c | 87 ++++++++++++++++++++++++++++++++++-
|
||||
kpatch-build/lookup.h | 8 +++
|
||||
8 files changed, 183 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/kmod/patch/kpatch-patch.h b/kmod/patch/kpatch-patch.h
|
||||
index 4d47d30..2eacb37 100644
|
||||
--- a/kmod/patch/kpatch-patch.h
|
||||
+++ b/kmod/patch/kpatch-patch.h
|
||||
@@ -30,6 +30,8 @@ struct kpatch_patch_func {
|
||||
unsigned long sympos;
|
||||
char *name;
|
||||
char *objname;
|
||||
+ char *ref_name;
|
||||
+ long ref_offset;
|
||||
};
|
||||
|
||||
struct kpatch_patch_dynrela {
|
||||
@@ -41,6 +43,8 @@ struct kpatch_patch_dynrela {
|
||||
char *objname;
|
||||
int external;
|
||||
int addend;
|
||||
+ char *ref_name;
|
||||
+ long ref_offset;
|
||||
};
|
||||
|
||||
struct kpatch_pre_patch_callback {
|
||||
diff --git a/kmod/patch/livepatch-patch-hook.c b/kmod/patch/livepatch-patch-hook.c
|
||||
index ee3b2b9..fefc068 100644
|
||||
--- a/kmod/patch/livepatch-patch-hook.c
|
||||
+++ b/kmod/patch/livepatch-patch-hook.c
|
||||
@@ -508,6 +508,8 @@ static int __init patch_init(void)
|
||||
lfunc->old_size = func->kfunc->old_size;
|
||||
lfunc->new_size = func->kfunc->new_size;
|
||||
lfunc->force = patch_is_func_forced(func->kfunc->new_addr);
|
||||
+ lfunc->ref_name= func->kfunc->ref_name;
|
||||
+ lfunc->ref_offset = func->kfunc->ref_offset;
|
||||
#endif
|
||||
j++;
|
||||
}
|
||||
@@ -531,6 +533,10 @@ static int __init patch_init(void)
|
||||
lreloc->name = reloc->kdynrela->name;
|
||||
lreloc->addend = reloc->kdynrela->addend;
|
||||
lreloc->external = reloc->kdynrela->external;
|
||||
+#ifdef __HULK__
|
||||
+ lreloc->ref_name = reloc->kdynrela->ref_name;
|
||||
+ lreloc->ref_offset = reloc->kdynrela->ref_offset;
|
||||
+#endif
|
||||
j++;
|
||||
}
|
||||
#endif /* HAVE_ELF_RELOCS */
|
||||
diff --git a/kpatch-build/create-diff-object.c b/kpatch-build/create-diff-object.c
|
||||
index 4fb27da..e72f6dd 100644
|
||||
--- a/kpatch-build/create-diff-object.c
|
||||
+++ b/kpatch-build/create-diff-object.c
|
||||
@@ -2519,6 +2519,29 @@ static void kpatch_create_patches_sections(struct kpatch_elf *kelf,
|
||||
funcs[index].old_size = result.size;
|
||||
funcs[index].new_size = sym->sym.st_size;
|
||||
funcs[index].sympos = result.pos;
|
||||
+ if (lookup_is_duplicate_symbol(table, sym->name)) {
|
||||
+ struct lookup_refsym refsym;
|
||||
+ long offset;
|
||||
+
|
||||
+ if (lookup_ref_symbol(table, sym->name, &refsym))
|
||||
+ ERROR("unresolvable ambiguity on symbol %s\n", sym->name);
|
||||
+
|
||||
+ offset = (long)result.value - (long)refsym.value;
|
||||
+ funcs[index].ref_offset = offset;
|
||||
+
|
||||
+ /*
|
||||
+ * Add a relocation that will populate
|
||||
+ * the funcs[index].ref_name field.
|
||||
+ */
|
||||
+ ALLOC_LINK(rela, &relasec->relas);
|
||||
+ rela->sym = strsym;
|
||||
+ rela->type = absolute_rela_type;
|
||||
+ rela->addend = offset_of_string(&kelf->strings, refsym.name);
|
||||
+ rela->offset = index * sizeof(*funcs) +
|
||||
+ offsetof(struct kpatch_patch_func, ref_name);
|
||||
+
|
||||
+ }
|
||||
+
|
||||
|
||||
/*
|
||||
* Add a relocation that will populate
|
||||
@@ -2653,6 +2676,7 @@ static void kpatch_create_intermediate_sections(struct kpatch_elf *kelf,
|
||||
struct lookup_result result;
|
||||
char *sym_objname;
|
||||
int ret, vmlinux, external;
|
||||
+ long ref_offset;
|
||||
|
||||
vmlinux = !strcmp(objname, "vmlinux");
|
||||
|
||||
@@ -2860,12 +2884,29 @@ static void kpatch_create_intermediate_sections(struct kpatch_elf *kelf,
|
||||
log_debug("lookup for %s @ 0x%016lx len %lu\n",
|
||||
rela->sym->name, result.value, result.size);
|
||||
|
||||
+ ref_offset = 0;
|
||||
/* Fill in ksyms[index] */
|
||||
if (vmlinux)
|
||||
ksyms[index].src = result.value;
|
||||
- else
|
||||
+ else {
|
||||
/* for modules, src is discovered at runtime */
|
||||
ksyms[index].src = 0;
|
||||
+ if (lookup_is_duplicate_symbol(table, rela->sym->name)) {
|
||||
+ struct lookup_refsym refsym;
|
||||
+
|
||||
+ if (lookup_ref_symbol(table, rela->sym->name, &refsym))
|
||||
+ ERROR("unresolvable ambiguity on symbol %s\n", rela->sym->name);
|
||||
+
|
||||
+ ref_offset = (long)result.value - (long)refsym.value;
|
||||
+ /* add rela to fill in ref_name field */
|
||||
+ ALLOC_LINK(rela2, &krela_sec->rela->relas);
|
||||
+ rela2->sym = strsym;
|
||||
+ rela2->type = absolute_rela_type;
|
||||
+ rela2->addend = offset_of_string(&kelf->strings, refsym.name);
|
||||
+ rela2->offset = index * sizeof(*krelas) +
|
||||
+ offsetof(struct kpatch_relocation, ref_name);
|
||||
+ }
|
||||
+ }
|
||||
ksyms[index].pos = result.pos;
|
||||
ksyms[index].type = rela->sym->type;
|
||||
ksyms[index].bind = rela->sym->bind;
|
||||
@@ -2893,6 +2934,7 @@ static void kpatch_create_intermediate_sections(struct kpatch_elf *kelf,
|
||||
krelas[index].addend = rela->addend;
|
||||
krelas[index].type = rela->type;
|
||||
krelas[index].external = external;
|
||||
+ krelas[index].ref_offset = ref_offset;
|
||||
|
||||
/* add rela to fill in krelas[index].dest field */
|
||||
ALLOC_LINK(rela2, &krela_sec->rela->relas);
|
||||
diff --git a/kpatch-build/create-kpatch-module.c b/kpatch-build/create-kpatch-module.c
|
||||
index 9f1c3b9..8292dc8 100644
|
||||
--- a/kpatch-build/create-kpatch-module.c
|
||||
+++ b/kpatch-build/create-kpatch-module.c
|
||||
@@ -57,7 +57,7 @@ static void create_dynamic_rela_sections(struct kpatch_elf *kelf, struct section
|
||||
struct section *dynsec;
|
||||
struct symbol *sym;
|
||||
struct rela *rela;
|
||||
- int index, nr, offset, dest_offset, objname_offset, name_offset;
|
||||
+ int index, nr, offset, dest_offset, objname_offset, name_offset, ref_name_offset;
|
||||
|
||||
ksyms = ksymsec->data->d_buf;
|
||||
krelas = krelasec->data->d_buf;
|
||||
@@ -109,6 +109,27 @@ static void create_dynamic_rela_sections(struct kpatch_elf *kelf, struct section
|
||||
dynrelas[index].type = krelas[index].type;
|
||||
dynrelas[index].external = krelas[index].external;
|
||||
dynrelas[index].sympos = ksym->pos;
|
||||
+ dynrelas[index].ref_name = krelas[index].ref_name;
|
||||
+ dynrelas[index].ref_offset = krelas[index].ref_offset;
|
||||
+
|
||||
+ if (dynrelas[index].ref_offset)
|
||||
+ {
|
||||
+ /* Get objname offset */
|
||||
+ rela = find_rela_by_offset(krelasec->rela,
|
||||
+ index * sizeof(*krelas) + offsetof(struct kpatch_relocation, ref_name));
|
||||
+ if (!rela) {
|
||||
+ ERROR("find_rela_by_offset");
|
||||
+ }
|
||||
+ ref_name_offset = rela->addend;
|
||||
+ /* ref_name */
|
||||
+ ALLOC_LINK(rela, &dynsec->rela->relas);
|
||||
+ rela->sym = strsec->secsym;
|
||||
+ rela->type = absolute_rela_type;
|
||||
+ rela->addend = ref_name_offset;
|
||||
+ rela->offset = index * sizeof(*dynrelas) + \
|
||||
+ offsetof(struct kpatch_patch_dynrela, ref_name);
|
||||
+
|
||||
+ }
|
||||
|
||||
/* dest */
|
||||
ALLOC_LINK(rela, &dynsec->rela->relas);
|
||||
diff --git a/kpatch-build/kpatch-build b/kpatch-build/kpatch-build
|
||||
index 9c40612..80b9607 100755
|
||||
--- a/kpatch-build/kpatch-build
|
||||
+++ b/kpatch-build/kpatch-build
|
||||
@@ -894,6 +894,18 @@ for i in $FILES; do
|
||||
KOBJFILE_NAME="${KOBJFILE_NAME/-/_}"
|
||||
KOBJFILE_PATH="${TEMPDIR}/module/$KOBJFILE"
|
||||
SYMTAB="${KOBJFILE_PATH}.symtab"
|
||||
+ unset KCFLAGS
|
||||
+ remove_patches
|
||||
+ if [ -z "$USERMODDIR" ];then
|
||||
+ cd "$SRCDIR" || die
|
||||
+ CROSS_COMPILE="$ARCH_COMPILE" make "-j$CPUS" ${KOBJFILE} 2>&1 | logger || die
|
||||
+ else
|
||||
+ cd "$USERMODDIR"
|
||||
+ CROSS_COMPILE="$ARCH_COMPILE" make -C "$USERMODBUILDDIR" M="$USERMODBUILDDIR" "-j$CPUS" $USERMODFLAGS $TARGETS 2>&1 | logger || die
|
||||
+ fi
|
||||
+ cp ${KOBJFILE} ${KOBJFILE_PATH}
|
||||
+ apply_patches
|
||||
+ cd "$TEMPDIR" || die
|
||||
fi
|
||||
|
||||
eu-readelf -s "$KOBJFILE_PATH" > "$SYMTAB"
|
||||
diff --git a/kpatch-build/kpatch-intermediate.h b/kpatch-build/kpatch-intermediate.h
|
||||
index 3dea775..59deed0 100644
|
||||
--- a/kpatch-build/kpatch-intermediate.h
|
||||
+++ b/kpatch-build/kpatch-intermediate.h
|
||||
@@ -39,6 +39,8 @@ struct kpatch_relocation {
|
||||
int external;
|
||||
char *objname; /* object to which this rela applies to */
|
||||
struct kpatch_symbol *ksym;
|
||||
+ char *ref_name;
|
||||
+ long ref_offset;
|
||||
};
|
||||
|
||||
struct kpatch_arch {
|
||||
diff --git a/kpatch-build/lookup.c b/kpatch-build/lookup.c
|
||||
index d08c10b..e4677db 100644
|
||||
--- a/kpatch-build/lookup.c
|
||||
+++ b/kpatch-build/lookup.c
|
||||
@@ -44,6 +44,7 @@ struct object_symbol {
|
||||
unsigned long size;
|
||||
char *name;
|
||||
int type, bind;
|
||||
+ int sec_index;
|
||||
};
|
||||
|
||||
struct export_symbol {
|
||||
@@ -229,6 +230,7 @@ static void symtab_read(struct lookup_table *table, char *path)
|
||||
table->obj_syms[i].value = value;
|
||||
table->obj_syms[i].size = size;
|
||||
table->obj_syms[i].name = strdup(name);
|
||||
+ table->obj_syms[i].sec_index = atoi(ndx);
|
||||
|
||||
if (!strcmp(bind, "LOCAL")) {
|
||||
table->obj_syms[i].bind = STB_LOCAL;
|
||||
@@ -425,7 +427,90 @@ char *lookup_exported_symbol_objname(struct lookup_table *table, char *name)
|
||||
return match->objname;
|
||||
|
||||
return NULL;
|
||||
- }
|
||||
+}
|
||||
+
|
||||
+int lookup_is_duplicate_symbol(struct lookup_table *table, char *name)
|
||||
+{
|
||||
+ struct object_symbol *sym;
|
||||
+ int i, count = 0;
|
||||
+
|
||||
+ for_each_obj_symbol(i, sym, table)
|
||||
+ if (!strcmp(sym->name, name)) {
|
||||
+ count++;
|
||||
+ if (count > 1)
|
||||
+ return 1;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+struct object_symbol *lookup_find_symbol_by_name(struct lookup_table *table, char *name)
|
||||
+{
|
||||
+ struct object_symbol *sym;
|
||||
+ unsigned long pos = 0;
|
||||
+ int i, match = 0, in_file = 0;
|
||||
+
|
||||
+ if (!table->local_syms)
|
||||
+ return NULL;
|
||||
+
|
||||
+ for_each_obj_symbol(i, sym, table) {
|
||||
+ if (sym->bind == STB_LOCAL && !strcmp(sym->name, name))
|
||||
+ pos++;
|
||||
+
|
||||
+ if (table->local_syms == sym) {
|
||||
+ in_file = 1;
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
+ if (!in_file)
|
||||
+ continue;
|
||||
+
|
||||
+ if (sym->type == STT_FILE)
|
||||
+ break;
|
||||
+
|
||||
+ if (sym->bind == STB_LOCAL && !strcmp(sym->name, name)) {
|
||||
+ match = 1;
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if (!match) {
|
||||
+ for_each_obj_symbol(i, sym, table) {
|
||||
+ if ((sym->bind == STB_GLOBAL || sym->bind == STB_WEAK) &&
|
||||
+ !strcmp(sym->name, name)) {
|
||||
+ return sym;
|
||||
+ }
|
||||
+ }
|
||||
+ return NULL;
|
||||
+ }
|
||||
+
|
||||
+ return sym;
|
||||
+}
|
||||
+
|
||||
+int lookup_ref_symbol(struct lookup_table *table, char *name,
|
||||
+ struct lookup_refsym *refsym)
|
||||
+{
|
||||
+ struct object_symbol *orig_sym, *sym;
|
||||
+ int i;
|
||||
+
|
||||
+ orig_sym = lookup_find_symbol_by_name(table, name);
|
||||
+ if (!orig_sym)
|
||||
+ ERROR("lookup_ref_symbol");
|
||||
+ memset(refsym, 0, sizeof(*refsym));
|
||||
+ for_each_obj_symbol(i, sym, table) {
|
||||
+ if (!strcmp(sym->name, name) || sym->type == STT_FILE ||
|
||||
+ sym->sec_index != orig_sym->sec_index)
|
||||
+ continue;
|
||||
+
|
||||
+ if (!lookup_is_duplicate_symbol(table, sym->name)) {
|
||||
+ refsym->name = sym->name;
|
||||
+ refsym->value = sym->value;
|
||||
+ return 0;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return 1;
|
||||
+}
|
||||
|
||||
#if 0 /* for local testing */
|
||||
static void find_this(struct lookup_table *table, char *sym, char *hint)
|
||||
diff --git a/kpatch-build/lookup.h b/kpatch-build/lookup.h
|
||||
index 420d0f0..5ad9241 100644
|
||||
--- a/kpatch-build/lookup.h
|
||||
+++ b/kpatch-build/lookup.h
|
||||
@@ -14,6 +14,11 @@ struct sym_compare_type {
|
||||
int type;
|
||||
};
|
||||
|
||||
+struct lookup_refsym {
|
||||
+ char *name;
|
||||
+ unsigned long value;
|
||||
+};
|
||||
+
|
||||
struct lookup_table *lookup_open(char *symtab_path, char *symvers_path,
|
||||
char *hint, struct sym_compare_type *locals);
|
||||
void lookup_close(struct lookup_table *table);
|
||||
@@ -23,5 +28,8 @@ int lookup_global_symbol(struct lookup_table *table, char *name,
|
||||
struct lookup_result *result);
|
||||
int lookup_is_exported_symbol(struct lookup_table *table, char *name);
|
||||
char *lookup_exported_symbol_objname(struct lookup_table *table, char *name);
|
||||
+int lookup_is_duplicate_symbol(struct lookup_table *table, char *name);
|
||||
+int lookup_ref_symbol(struct lookup_table *table, char *name,
|
||||
+ struct lookup_refsym *refsym);
|
||||
|
||||
#endif /* _LOOKUP_H_ */
|
||||
--
|
||||
1.7.5.4
|
||||
|
||||
@ -0,0 +1,31 @@
|
||||
From 83ecafcda5326baceeb68fba90dc13083ff48fe6 Mon Sep 17 00:00:00 2001
|
||||
From: Zhipeng Xie <xiezhipeng1@huawei.com>
|
||||
Date: Fri, 2 Nov 2018 17:25:50 +0000
|
||||
Subject: [PATCH 1014/1015] create-diff-object: add dynamic reloction for
|
||||
function pointer on aarch64
|
||||
|
||||
implement function_ptr_rela for aarch64.
|
||||
|
||||
Signed-off-by: Zhipeng Xie <xiezhipeng1@huawei.com>
|
||||
---
|
||||
kpatch-build/create-diff-object.c | 4 +++-
|
||||
1 files changed, 3 insertions(+), 1 deletions(-)
|
||||
|
||||
diff --git a/kpatch-build/create-diff-object.c b/kpatch-build/create-diff-object.c
|
||||
index e72f6dd..f8f3e15 100644
|
||||
--- a/kpatch-build/create-diff-object.c
|
||||
+++ b/kpatch-build/create-diff-object.c
|
||||
@@ -2628,7 +2628,9 @@ static int function_ptr_rela(const struct rela *rela)
|
||||
rela_toc->addend == (int)rela_toc->sym->sym.st_value &&
|
||||
(rela->type == R_X86_64_32S ||
|
||||
rela->type == R_PPC64_TOC16_HA ||
|
||||
- rela->type == R_PPC64_TOC16_LO_DS));
|
||||
+ rela->type == R_PPC64_TOC16_LO_DS ||
|
||||
+ rela->type == R_AARCH64_ADR_PREL_PG_HI21 ||
|
||||
+ rela->type == R_AARCH64_ADD_ABS_LO12_NC));
|
||||
}
|
||||
|
||||
static int may_need_dynrela(const struct rela *rela)
|
||||
--
|
||||
1.7.5.4
|
||||
|
||||
106
9015-create-diff-object-exclude-line-only-change-for-arm6.patch
Normal file
106
9015-create-diff-object-exclude-line-only-change-for-arm6.patch
Normal file
@ -0,0 +1,106 @@
|
||||
From d1bbff5da464148e5d277b601a31d7872b4e376b Mon Sep 17 00:00:00 2001
|
||||
From: Zhipeng Xie <xiezhipeng1@huawei.com>
|
||||
Date: Fri, 2 Nov 2018 17:26:00 +0000
|
||||
Subject: [PATCH 1015/1015] create-diff-object: exclude line only change for
|
||||
arm64
|
||||
|
||||
exclude line only change for arm64 by compare mov instruction
|
||||
except immediate part.
|
||||
|
||||
Signed-off-by: Zhipeng Xie <xiezhipeng1@huawei.com>
|
||||
---
|
||||
kpatch-build/create-diff-object.c | 71 ++++++++++++++++++++++++++++++++++++-
|
||||
1 files changed, 70 insertions(+), 1 deletions(-)
|
||||
|
||||
diff --git a/kpatch-build/create-diff-object.c b/kpatch-build/create-diff-object.c
|
||||
index f8f3e15..12d8bd6 100644
|
||||
--- a/kpatch-build/create-diff-object.c
|
||||
+++ b/kpatch-build/create-diff-object.c
|
||||
@@ -609,6 +609,68 @@ static int kpatch_line_macro_change_only(struct section *sec)
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
+#define ARM64_INSTR_LEN 4
|
||||
+static int arm64_kpatch_line_macro_change_only(struct section *sec)
|
||||
+{
|
||||
+ unsigned long start1, start2, size, offset;
|
||||
+ struct rela *rela;
|
||||
+ int lineonly = 0, found;
|
||||
+ unsigned int mov_imm_mask = ((1<<16) - 1)<<5;
|
||||
+
|
||||
+ if (sec->status != CHANGED ||
|
||||
+ is_rela_section(sec) ||
|
||||
+ !is_text_section(sec) ||
|
||||
+ sec->sh.sh_size != sec->twin->sh.sh_size ||
|
||||
+ !sec->rela ||
|
||||
+ sec->rela->status != SAME)
|
||||
+ return 0;
|
||||
+
|
||||
+ start1 = (unsigned long)sec->twin->data->d_buf;
|
||||
+ start2 = (unsigned long)sec->data->d_buf;
|
||||
+ size = sec->sh.sh_size;
|
||||
+ for (offset = 0; offset < size; offset += ARM64_INSTR_LEN) {
|
||||
+ if (!memcmp((void *)start1 + offset, (void *)start2 + offset,
|
||||
+ ARM64_INSTR_LEN))
|
||||
+ continue;
|
||||
+
|
||||
+ /* verify it's a mov immediate to w1 */
|
||||
+ if ((*(int *)(start1 + offset) & ~mov_imm_mask) !=
|
||||
+ (*(int *)(start2 + offset) & ~mov_imm_mask))
|
||||
+ return 0;
|
||||
+
|
||||
+ found = 0;
|
||||
+ list_for_each_entry(rela, &sec->rela->relas, list) {
|
||||
+ if (rela->offset < offset + ARM64_INSTR_LEN)
|
||||
+ continue;
|
||||
+ if (rela->string)
|
||||
+ continue;
|
||||
+ if (!strncmp(rela->sym->name, "__warned.", 9))
|
||||
+ continue;
|
||||
+ if (!strncmp(rela->sym->name, "warn_slowpath_", 14) ||
|
||||
+ (!strcmp(rela->sym->name, "__warn_printk")) ||
|
||||
+ (!strcmp(rela->sym->name, "__might_sleep")) ||
|
||||
+ (!strcmp(rela->sym->name, "___might_sleep")) ||
|
||||
+ (!strcmp(rela->sym->name, "__might_fault")) ||
|
||||
+ (!strcmp(rela->sym->name, "printk")) ||
|
||||
+ (!strcmp(rela->sym->name, "lockdep_rcu_suspicious"))) {
|
||||
+ found = 1;
|
||||
+ break;
|
||||
+ }
|
||||
+ return 0;
|
||||
+ }
|
||||
+ if (!found)
|
||||
+ return 0;
|
||||
+
|
||||
+ lineonly = 1;
|
||||
+ }
|
||||
+
|
||||
+ if (!lineonly)
|
||||
+ ERROR("no instruction changes detected for changed section %s",
|
||||
+ sec->name);
|
||||
+
|
||||
+ return 1;
|
||||
+}
|
||||
+
|
||||
|
||||
static void kpatch_compare_sections(struct list_head *seclist)
|
||||
{
|
||||
@@ -624,7 +686,14 @@ static void kpatch_compare_sections(struct list_head *seclist)
|
||||
|
||||
/* exclude WARN-only, might_sleep changes */
|
||||
list_for_each_entry(sec, seclist, list) {
|
||||
- if (kpatch_line_macro_change_only(sec)) {
|
||||
+ int line_only;
|
||||
+ if (arch == EM_X86_64)
|
||||
+ line_only = kpatch_line_macro_change_only(sec);
|
||||
+ else if (arch == EM_AARCH64)
|
||||
+ line_only = arm64_kpatch_line_macro_change_only(sec);
|
||||
+ else
|
||||
+ line_only = 0;
|
||||
+ if (line_only) {
|
||||
log_debug("reverting macro / line number section %s status to SAME\n",
|
||||
sec->name);
|
||||
sec->status = SAME;
|
||||
--
|
||||
1.7.5.4
|
||||
|
||||
@ -0,0 +1,31 @@
|
||||
From dc771a1789ea3769777228f792f0902f8b0566ba Mon Sep 17 00:00:00 2001
|
||||
From: Zhipeng Xie <xiezhipeng1@huawei.com>
|
||||
Date: Thu, 22 Nov 2018 21:06:32 +0000
|
||||
Subject: [PATCH] kpatch-build: include secsym in kpatch_mark_ignored_sections
|
||||
|
||||
kpatch_mark_ignored_sections include .rodata.str1.1 section but does
|
||||
not include its section symbol, causing its section symbol can not be
|
||||
included any more in kpatch_include_standard_elements. After the
|
||||
section symbol is freed in kpatch_elf_teardown, we got a segmentation
|
||||
fault in kpatch_create_intermediate_sections.
|
||||
|
||||
Signed-off-by: Zhipeng Xie <xiezhipeng1@huawei.com>
|
||||
---
|
||||
kpatch-build/create-diff-object.c | 1 +
|
||||
1 files changed, 1 insertions(+), 0 deletions(-)
|
||||
|
||||
diff --git a/kpatch-build/create-diff-object.c b/kpatch-build/create-diff-object.c
|
||||
index 2e54960..97ae0d4 100644
|
||||
--- a/kpatch-build/create-diff-object.c
|
||||
+++ b/kpatch-build/create-diff-object.c
|
||||
@@ -2285,6 +2285,7 @@ static void kpatch_mark_ignored_sections(struct kpatch_elf *kelf)
|
||||
* from the section data comparison, but this is a simpler way.
|
||||
*/
|
||||
strsec->include = 1;
|
||||
+ strsec->secsym->include = 1;
|
||||
name = strsec->data->d_buf + rela->addend;
|
||||
ignoresec = find_section_by_name(&kelf->sections, name);
|
||||
if (!ignoresec)
|
||||
--
|
||||
1.7.5.4
|
||||
|
||||
124
9017-support-compile-kpatch-on-aarch64.patch
Normal file
124
9017-support-compile-kpatch-on-aarch64.patch
Normal file
@ -0,0 +1,124 @@
|
||||
From 50782f658313574a530f80d2f4b78fe23488c6c2 Mon Sep 17 00:00:00 2001
|
||||
From: Zhipeng Xie <xiezhipeng1@huawei.com>
|
||||
Date: Thu, 20 Dec 2018 04:55:38 +0000
|
||||
Subject: [PATCH] support compile kpatch on aarch64
|
||||
|
||||
delete __x86_64__ to support compile kpatch on aarch64.
|
||||
|
||||
Signed-off-by: Zhipeng Xie <xiezhipeng1@huawei.com>
|
||||
---
|
||||
kpatch-build/Makefile | 3 +++
|
||||
kpatch-build/create-diff-object.c | 16 +---------------
|
||||
2 files changed, 4 insertions(+), 15 deletions(-)
|
||||
|
||||
diff --git a/kpatch-build/Makefile b/kpatch-build/Makefile
|
||||
index 232b336..974e0f2 100644
|
||||
--- a/kpatch-build/Makefile
|
||||
+++ b/kpatch-build/Makefile
|
||||
@@ -12,6 +12,9 @@ SOURCES = create-diff-object.c kpatch-elf.c \
|
||||
ifeq ($(ARCH),x86_64)
|
||||
SOURCES += insn/insn.c insn/inat.c
|
||||
INSN = insn/insn.o insn/inat.o
|
||||
+else ifeq ($(ARCH),aarch64)
|
||||
+SOURCES += insn/insn.c insn/inat.c
|
||||
+INSN = insn/insn.o insn/inat.o
|
||||
else ifeq ($(ARCH),ppc64le)
|
||||
SOURCES += gcc-plugins/ppc64le-plugin.c
|
||||
PLUGIN = gcc-plugins/ppc64le-plugin.so
|
||||
diff --git a/kpatch-build/create-diff-object.c b/kpatch-build/create-diff-object.c
|
||||
index 97ae0d4..80a76a9 100644
|
||||
--- a/kpatch-build/create-diff-object.c
|
||||
+++ b/kpatch-build/create-diff-object.c
|
||||
@@ -426,7 +426,6 @@ out:
|
||||
log_debug("section %s has changed\n", sec->name);
|
||||
}
|
||||
|
||||
-#ifdef __x86_64__
|
||||
/*
|
||||
* Determine if a section has changed only due to a WARN* or might_sleep
|
||||
* macro call's embedding of the line number into an instruction operand.
|
||||
@@ -537,7 +536,7 @@ static int kpatch_line_macro_change_only(struct section *sec)
|
||||
|
||||
return 1;
|
||||
}
|
||||
-#elif __powerpc64__
|
||||
+#if __powerpc64__
|
||||
#define PPC_INSTR_LEN 4
|
||||
#define PPC_RA_OFFSET 16
|
||||
|
||||
@@ -603,11 +602,6 @@ static int kpatch_line_macro_change_only(struct section *sec)
|
||||
|
||||
return 1;
|
||||
}
|
||||
-#else
|
||||
-static int kpatch_line_macro_change_only(struct section *sec)
|
||||
-{
|
||||
- return 0;
|
||||
-}
|
||||
#endif
|
||||
#define ARM64_INSTR_LEN 4
|
||||
static int arm64_kpatch_line_macro_change_only(struct section *sec)
|
||||
@@ -1248,7 +1242,6 @@ static void kpatch_compare_correlated_elements(struct kpatch_elf *kelf)
|
||||
kpatch_compare_symbols(&kelf->symbols);
|
||||
}
|
||||
|
||||
-#ifdef __x86_64__
|
||||
static void rela_insn(struct section *sec, struct rela *rela, struct insn *insn)
|
||||
{
|
||||
unsigned long insn_addr, start, end, rela_addr;
|
||||
@@ -1267,7 +1260,6 @@ static void rela_insn(struct section *sec, struct rela *rela, struct insn *insn)
|
||||
return;
|
||||
}
|
||||
}
|
||||
-#endif
|
||||
|
||||
/*
|
||||
* Mangle the relas a little. The compiler will sometimes use section symbols
|
||||
@@ -1810,7 +1802,6 @@ static int ex_table_group_size(struct kpatch_elf *kelf, int offset)
|
||||
return size;
|
||||
}
|
||||
|
||||
-#ifdef __x86_64__
|
||||
static int parainstructions_group_size(struct kpatch_elf *kelf, int offset)
|
||||
{
|
||||
static int size = 0;
|
||||
@@ -1845,7 +1836,6 @@ static int smp_locks_group_size(struct kpatch_elf *kelf, int offset)
|
||||
{
|
||||
return 4;
|
||||
}
|
||||
-#endif
|
||||
#ifdef __powerpc64__
|
||||
static int fixup_entry_group_size(struct kpatch_elf *kelf, int offset)
|
||||
{
|
||||
@@ -1921,7 +1911,6 @@ static struct special_section special_sections[] = {
|
||||
.name = "__bug_table",
|
||||
.group_size = bug_table_group_size,
|
||||
},
|
||||
-#ifdef __x86_64__
|
||||
{
|
||||
.name = ".smp_locks",
|
||||
.group_size = smp_locks_group_size,
|
||||
@@ -1930,7 +1919,6 @@ static struct special_section special_sections[] = {
|
||||
.name = ".parainstructions",
|
||||
.group_size = parainstructions_group_size,
|
||||
},
|
||||
-#endif
|
||||
{
|
||||
.name = ".fixup",
|
||||
.group_size = fixup_group_size,
|
||||
@@ -1939,12 +1927,10 @@ static struct special_section special_sections[] = {
|
||||
.name = "__ex_table", /* must come after .fixup */
|
||||
.group_size = ex_table_group_size,
|
||||
},
|
||||
-#ifdef __x86_64__
|
||||
{
|
||||
.name = ".altinstructions",
|
||||
.group_size = altinstructions_group_size,
|
||||
},
|
||||
-#endif
|
||||
#ifdef __powerpc64__
|
||||
{
|
||||
.name = "__ftr_fixup",
|
||||
--
|
||||
2.19.1
|
||||
|
||||
828
9018-support-c-plus-kernel-module.patch
Normal file
828
9018-support-c-plus-kernel-module.patch
Normal file
@ -0,0 +1,828 @@
|
||||
From 9d590b5b9fb59c1cd52221feeef2794eb3333571 Mon Sep 17 00:00:00 2001
|
||||
From: Zhipeng Xie <xiezhipeng1@huawei.com>
|
||||
Date: Thu, 8 Nov 2018 15:12:06 +0000
|
||||
Subject: [PATCH] support c plus kernel module
|
||||
|
||||
support GNU_UNIQUE type symbols.
|
||||
support .group section corelation.
|
||||
support symbol name longger than 128 bytes.
|
||||
fix object size changed error for __FUNCTION__.xxx.
|
||||
ignore compile warning for third party modules.
|
||||
support functions have no fentry call.
|
||||
support all function force enable/disable
|
||||
fix sym replacing error for aarch64
|
||||
|
||||
Signed-off-by: Zhipeng Xie <xiezhipeng1@huawei.com>
|
||||
---
|
||||
kmod/patch/livepatch-patch-hook.c | 8 ++
|
||||
kpatch-build/create-diff-object.c | 161 ++++++++++++++++++++++++-----------
|
||||
kpatch-build/create-klp-module.c | 27 +++++-
|
||||
kpatch-build/create-kpatch-module.c | 15 +--
|
||||
kpatch-build/kpatch-build | 7 ++-
|
||||
kpatch-build/kpatch-elf.c | 8 ++-
|
||||
kpatch-build/kpatch-gcc | 2 +-
|
||||
kpatch-build/lookup.c | 125 +++++++++++++++++++++++++--
|
||||
kpatch-build/lookup.h | 14 ++-
|
||||
9 files changed, 287 insertions(+), 80 deletions(-)
|
||||
|
||||
diff --git a/kmod/patch/livepatch-patch-hook.c b/kmod/patch/livepatch-patch-hook.c
|
||||
index fefc068..ce1c955 100644
|
||||
--- a/kmod/patch/livepatch-patch-hook.c
|
||||
+++ b/kmod/patch/livepatch-patch-hook.c
|
||||
@@ -497,8 +497,12 @@ static int __init patch_init(void)
|
||||
lfunc->old_name = func->kfunc->name;
|
||||
lfunc->new_func = (void *)func->kfunc->new_addr;
|
||||
#if defined(HAVE_IMMEDIATE)
|
||||
+#ifdef __ALL_FORCE__
|
||||
+ lfunc->immediate = 1;
|
||||
+#else
|
||||
lfunc->immediate = patch_is_func_forced(lfunc->new_func);
|
||||
#endif
|
||||
+#endif
|
||||
#ifdef HAVE_SYMPOS
|
||||
lfunc->old_sympos = func->kfunc->sympos;
|
||||
#else
|
||||
@@ -507,7 +511,11 @@ static int __init patch_init(void)
|
||||
#ifdef __HULK__
|
||||
lfunc->old_size = func->kfunc->old_size;
|
||||
lfunc->new_size = func->kfunc->new_size;
|
||||
+#ifdef __ALL_FORCE__
|
||||
+ lfunc->force = 1;
|
||||
+#else
|
||||
lfunc->force = patch_is_func_forced(func->kfunc->new_addr);
|
||||
+#endif
|
||||
lfunc->ref_name= func->kfunc->ref_name;
|
||||
lfunc->ref_offset = func->kfunc->ref_offset;
|
||||
#endif
|
||||
diff --git a/kpatch-build/create-diff-object.c b/kpatch-build/create-diff-object.c
|
||||
index 97ae0d4..8bb650d 100644
|
||||
--- a/kpatch-build/create-diff-object.c
|
||||
+++ b/kpatch-build/create-diff-object.c
|
||||
@@ -224,6 +224,7 @@ static int is_special_static(struct symbol *sym)
|
||||
"__func__.",
|
||||
"_rs.",
|
||||
"CSWTCH.",
|
||||
+ "__FUNCTION__.",
|
||||
NULL,
|
||||
};
|
||||
char **prefix;
|
||||
@@ -386,7 +387,7 @@ static void kpatch_compare_correlated_nonrela_section(struct section *sec)
|
||||
{
|
||||
struct section *sec1 = sec, *sec2 = sec->twin;
|
||||
|
||||
- if (sec1->sh.sh_type != SHT_NOBITS &&
|
||||
+ if (sec1->sh.sh_type != SHT_NOBITS && sec1->sh.sh_type != SHT_GROUP &&
|
||||
memcmp(sec1->data->d_buf, sec2->data->d_buf, sec1->data->d_size))
|
||||
sec->status = CHANGED;
|
||||
else
|
||||
@@ -400,8 +401,9 @@ static void kpatch_compare_correlated_section(struct section *sec)
|
||||
/* Compare section headers (must match or fatal) */
|
||||
if (sec1->sh.sh_type != sec2->sh.sh_type ||
|
||||
sec1->sh.sh_flags != sec2->sh.sh_flags ||
|
||||
- sec1->sh.sh_addralign != sec2->sh.sh_addralign ||
|
||||
- sec1->sh.sh_entsize != sec2->sh.sh_entsize)
|
||||
+ sec1->sh.sh_entsize != sec2->sh.sh_entsize ||
|
||||
+ (sec1->sh.sh_addralign != sec2->sh.sh_addralign &&
|
||||
+ strcmp(sec1->name, ".rodata")))
|
||||
DIFF_FATAL("%s section header details differ", sec1->name);
|
||||
|
||||
/* Short circuit for mcount sections, we rebuild regardless */
|
||||
@@ -763,6 +765,33 @@ static void kpatch_compare_symbols(struct list_head *symlist)
|
||||
}
|
||||
}
|
||||
|
||||
+static int kpatch_correlate_group_section(struct list_head *seclist1, struct list_head *seclist2, struct section *sec1, struct section *sec2)
|
||||
+{
|
||||
+ unsigned int *data1, *end1, *data2;
|
||||
+ struct section *isec1, *isec2;
|
||||
+
|
||||
+ if (sec1->data->d_size != sec2->data->d_size)
|
||||
+ return 1;
|
||||
+ data1 = sec1->data->d_buf;
|
||||
+ data2 = sec2->data->d_buf;
|
||||
+ end1 = sec1->data->d_buf + sec1->data->d_size;
|
||||
+ data1++;
|
||||
+ data2++;
|
||||
+ while (data1 < end1) {
|
||||
+ isec1 = find_section_by_index(seclist1, *data1);
|
||||
+ if (!isec1)
|
||||
+ ERROR("group section not found");
|
||||
+ isec2 = find_section_by_index(seclist2, *data2);
|
||||
+ if (!isec2)
|
||||
+ ERROR("group section not found");
|
||||
+ if (strcmp(isec1->name, isec2->name))
|
||||
+ return 1;
|
||||
+ data1++;
|
||||
+ data2++;
|
||||
+ }
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
static void kpatch_correlate_sections(struct list_head *seclist1, struct list_head *seclist2)
|
||||
{
|
||||
struct section *sec1, *sec2;
|
||||
@@ -777,15 +806,18 @@ static void kpatch_correlate_sections(struct list_head *seclist1, struct list_he
|
||||
sec1->secsym))
|
||||
continue;
|
||||
|
||||
- /*
|
||||
- * Group sections must match exactly to be correlated.
|
||||
- * Changed group sections are currently not supported.
|
||||
- */
|
||||
+ /* Group section的格式为:
|
||||
+ * flag
|
||||
+ * section index
|
||||
+ * section index
|
||||
+ * ...
|
||||
+ *
|
||||
+ * 当C++代码发生修改时,section index可能会发生变化
|
||||
+ * 这时候我们就比对一下section index所对应的section的
|
||||
+ * name,如果相同,我们就认为这两个group是SAME
|
||||
+ * */
|
||||
if (sec1->sh.sh_type == SHT_GROUP) {
|
||||
- if (sec1->data->d_size != sec2->data->d_size)
|
||||
- continue;
|
||||
- if (memcmp(sec1->data->d_buf, sec2->data->d_buf,
|
||||
- sec1->data->d_size))
|
||||
+ if(kpatch_correlate_group_section(seclist1, seclist2, sec1, sec2))
|
||||
continue;
|
||||
}
|
||||
sec1->twin = sec2;
|
||||
@@ -1308,17 +1340,21 @@ static void kpatch_replace_sections_syms(struct kpatch_elf *kelf)
|
||||
#ifdef __powerpc64__
|
||||
add_off = 0;
|
||||
#else
|
||||
- if (rela->type == R_X86_64_PC32) {
|
||||
- struct insn insn;
|
||||
- rela_insn(sec, rela, &insn);
|
||||
- add_off = (long)insn.next_byte -
|
||||
- (long)sec->base->data->d_buf -
|
||||
- rela->offset;
|
||||
- } else if (rela->type == R_X86_64_64 ||
|
||||
- rela->type == R_X86_64_32S)
|
||||
- add_off = 0;
|
||||
- else
|
||||
- continue;
|
||||
+ add_off = 0;
|
||||
+ if (arch == EM_X86_64) {
|
||||
+ if (rela->type == R_X86_64_PC32) {
|
||||
+ struct insn insn;
|
||||
+ rela_insn(sec, rela, &insn);
|
||||
+ add_off = (long)insn.next_byte -
|
||||
+ (long)sec->base->data->d_buf -
|
||||
+ rela->offset;
|
||||
+ } else if (rela->type == R_X86_64_64 ||
|
||||
+ rela->type == R_X86_64_32S)
|
||||
+ add_off = 0;
|
||||
+ else
|
||||
+ continue;
|
||||
+ }
|
||||
+ /* add_off is always equal to 0 on arm64 */
|
||||
#endif
|
||||
|
||||
/*
|
||||
@@ -1421,17 +1457,6 @@ static void kpatch_verify_patchability(struct kpatch_elf *kelf)
|
||||
errs++;
|
||||
}
|
||||
|
||||
- if (sec->status != SAME && sec->grouped) {
|
||||
- log_normal("changed section %s is part of a section group\n",
|
||||
- sec->name);
|
||||
- errs++;
|
||||
- }
|
||||
-
|
||||
- if (sec->sh.sh_type == SHT_GROUP && sec->status == NEW) {
|
||||
- log_normal("new/changed group sections are not supported\n");
|
||||
- errs++;
|
||||
- }
|
||||
-
|
||||
/*
|
||||
* ensure we aren't including .data.* or .bss.*
|
||||
* (.data.unlikely and .data.once is ok b/c it only has __warned vars)
|
||||
@@ -1458,6 +1483,7 @@ static void kpatch_include_section(struct section *sec)
|
||||
/* Include the section and its section symbol */
|
||||
if (sec->include)
|
||||
return;
|
||||
+
|
||||
sec->include = 1;
|
||||
if (sec->secsym)
|
||||
sec->secsym->include = 1;
|
||||
@@ -1640,7 +1666,7 @@ static void kpatch_include_force_elements(struct kpatch_elf *kelf)
|
||||
sym->include = 0;
|
||||
}
|
||||
|
||||
-int kpatch_include_new_static_var(struct kpatch_elf *kelf)
|
||||
+static int kpatch_include_new_static_var(struct kpatch_elf *kelf)
|
||||
{
|
||||
struct symbol *sym;
|
||||
|
||||
@@ -2253,6 +2279,23 @@ static void kpatch_include_debug_sections(struct kpatch_elf *kelf)
|
||||
}
|
||||
}
|
||||
|
||||
+static void kpatch_ignore_debug_sections(struct kpatch_elf *kelf)
|
||||
+{
|
||||
+ struct section *sec;
|
||||
+
|
||||
+ /* include all .debug_* sections */
|
||||
+ list_for_each_entry(sec, &kelf->sections, list) {
|
||||
+ if (is_debug_section(sec)) {
|
||||
+ sec->include = 0;
|
||||
+ sec->status = SAME;
|
||||
+ if (!is_rela_section(sec)) {
|
||||
+ sec->secsym->include = 0;
|
||||
+ sec->secsym->status = SAME;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
static void kpatch_mark_ignored_sections(struct kpatch_elf *kelf)
|
||||
{
|
||||
struct section *sec, *strsec, *ignoresec;
|
||||
@@ -2589,14 +2632,13 @@ static void kpatch_create_patches_sections(struct kpatch_elf *kelf,
|
||||
funcs[index].old_size = result.size;
|
||||
funcs[index].new_size = sym->sym.st_size;
|
||||
funcs[index].sympos = result.pos;
|
||||
- if (lookup_is_duplicate_symbol(table, sym->name)) {
|
||||
+ if (lookup_is_duplicate_symbol(table, sym->name, objname, result.pos)) {
|
||||
struct lookup_refsym refsym;
|
||||
long offset;
|
||||
|
||||
- if (lookup_ref_symbol(table, sym->name, &refsym))
|
||||
+ if (lookup_ref_symbol_offset(table, sym->name, &refsym, objname, &offset))
|
||||
ERROR("unresolvable ambiguity on symbol %s\n", sym->name);
|
||||
|
||||
- offset = (long)result.value - (long)refsym.value;
|
||||
funcs[index].ref_offset = offset;
|
||||
|
||||
/*
|
||||
@@ -2631,7 +2673,7 @@ static void kpatch_create_patches_sections(struct kpatch_elf *kelf,
|
||||
ALLOC_LINK(rela, &relasec->relas);
|
||||
rela->sym = strsym;
|
||||
rela->type = absolute_rela_type;
|
||||
- rela->addend = offset_of_string(&kelf->strings, sym->name);
|
||||
+ rela->addend = offset_of_string(&kelf->strings, strndup(sym->name, KSYM_NAME_LEN-1));
|
||||
rela->offset = index * sizeof(*funcs) +
|
||||
offsetof(struct kpatch_patch_func, name);
|
||||
|
||||
@@ -2780,13 +2822,14 @@ static void kpatch_create_intermediate_sections(struct kpatch_elf *kelf,
|
||||
*/
|
||||
if (may_need_dynrela(rela))
|
||||
toc_rela(rela)->need_dynrela = 1;
|
||||
+
|
||||
if (rela->sym->sec) {
|
||||
if (rela->sym->type == STT_FUNC &&
|
||||
- rela->sym->status == CHANGED &&
|
||||
- rela->sym->sec != sec->base &&
|
||||
- sec->base->sym &&
|
||||
- sec->base->sym->type == STT_FUNC)
|
||||
- toc_rela(rela)->need_dynrela = 1;
|
||||
+ rela->sym->status == CHANGED &&
|
||||
+ rela->sym->sec != sec->base &&
|
||||
+ sec->base->sym &&
|
||||
+ sec->base->sym->type == STT_FUNC)
|
||||
+ toc_rela(rela)->need_dynrela = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2820,6 +2863,7 @@ static void kpatch_create_intermediate_sections(struct kpatch_elf *kelf,
|
||||
if (!strcmp(sec->name, ".rela.kpatch.funcs") ||
|
||||
!strcmp(sec->name, ".rela.kpatch.dynrelas"))
|
||||
continue;
|
||||
+
|
||||
list_for_each_entry_safe(rela, safe, &sec->relas, list) {
|
||||
if (!rela->need_dynrela)
|
||||
continue;
|
||||
@@ -2963,13 +3007,12 @@ static void kpatch_create_intermediate_sections(struct kpatch_elf *kelf,
|
||||
else {
|
||||
/* for modules, src is discovered at runtime */
|
||||
ksyms[index].src = 0;
|
||||
- if (lookup_is_duplicate_symbol(table, rela->sym->name)) {
|
||||
+ if (lookup_is_duplicate_symbol(table, rela->sym->name, objname, result.pos)) {
|
||||
struct lookup_refsym refsym;
|
||||
|
||||
- if (lookup_ref_symbol(table, rela->sym->name, &refsym))
|
||||
+ if (lookup_ref_symbol_offset(table, rela->sym->name, &refsym, objname, &ref_offset))
|
||||
ERROR("unresolvable ambiguity on symbol %s\n", rela->sym->name);
|
||||
|
||||
- ref_offset = (long)result.value - (long)refsym.value;
|
||||
/* add rela to fill in ref_name field */
|
||||
ALLOC_LINK(rela2, &krela_sec->rela->relas);
|
||||
rela2->sym = strsym;
|
||||
@@ -2987,7 +3030,7 @@ static void kpatch_create_intermediate_sections(struct kpatch_elf *kelf,
|
||||
ALLOC_LINK(rela2, &ksym_sec->rela->relas);
|
||||
rela2->sym = strsym;
|
||||
rela2->type = absolute_rela_type;
|
||||
- rela2->addend = offset_of_string(&kelf->strings, rela->sym->name);
|
||||
+ rela2->addend = offset_of_string(&kelf->strings, strndup(rela->sym->name, KSYM_NAME_LEN-1));
|
||||
rela2->offset = index * sizeof(*ksyms) + \
|
||||
offsetof(struct kpatch_symbol, name);
|
||||
|
||||
@@ -3163,6 +3206,9 @@ static void kpatch_create_mcount_sections(struct kpatch_elf *kelf)
|
||||
* __fentry__" so that ftrace will be happy.
|
||||
*/
|
||||
newdata = malloc(sym->sec->data->d_size);
|
||||
+ if (!newdata)
|
||||
+ ERROR("malloc");
|
||||
+
|
||||
memcpy(newdata, sym->sec->data->d_buf, sym->sec->data->d_size);
|
||||
sym->sec->data->d_buf = newdata;
|
||||
insn = newdata;
|
||||
@@ -3186,6 +3232,8 @@ static void kpatch_create_mcount_sections(struct kpatch_elf *kelf)
|
||||
rela->offset = index * sizeof(*funcs);
|
||||
|
||||
newdata = malloc(sym->sec->data->d_size);
|
||||
+ if (!newdata)
|
||||
+ ERROR("malloc");
|
||||
memcpy(newdata, sym->sec->data->d_buf, sym->sec->data->d_size);
|
||||
sym->sec->data->d_buf = newdata;
|
||||
insnp = newdata;
|
||||
@@ -3354,6 +3402,8 @@ int main(int argc, char *argv[])
|
||||
char *parent_symtab, *mod_symvers, *patch_name, *output_obj;
|
||||
struct sym_compare_type *base_locals;
|
||||
char *gcc_add_option, *mlongcall;
|
||||
+ char *no_profiling_calls;
|
||||
+ char *kallsyms;
|
||||
|
||||
arguments.debug = 0;
|
||||
argp_parse (&argp, argc, argv, 0, NULL, &arguments);
|
||||
@@ -3400,9 +3450,12 @@ int main(int argc, char *argv[])
|
||||
return EXIT_STATUS_NO_CHANGE;
|
||||
}
|
||||
|
||||
+ kallsyms = getenv("KALLSYMS");
|
||||
+ if (kallsyms)
|
||||
+ log_debug("kallsyms file:%s\n", kallsyms);
|
||||
/* create symbol lookup table */
|
||||
base_locals = kpatch_elf_locals(kelf_base);
|
||||
- lookup = lookup_open(parent_symtab, mod_symvers, hint, base_locals);
|
||||
+ lookup = lookup_open(parent_symtab, mod_symvers, hint, base_locals, kallsyms);
|
||||
free(base_locals);
|
||||
|
||||
kpatch_mark_grouped_sections(kelf_patched);
|
||||
@@ -3420,7 +3473,12 @@ int main(int argc, char *argv[])
|
||||
*/
|
||||
kpatch_mark_ignored_sections(kelf_patched);
|
||||
kpatch_compare_correlated_elements(kelf_patched);
|
||||
- kpatch_check_func_profiling_calls(kelf_patched);
|
||||
+
|
||||
+ no_profiling_calls = getenv("NO_PROFILING_CALLS");
|
||||
+ if (!no_profiling_calls)
|
||||
+ kpatch_check_func_profiling_calls(kelf_patched);
|
||||
+ else
|
||||
+ log_debug("NO_PROFILING_CALLS set\n");
|
||||
kpatch_elf_teardown(kelf_base);
|
||||
kpatch_elf_free(kelf_base);
|
||||
|
||||
@@ -3430,6 +3488,7 @@ int main(int argc, char *argv[])
|
||||
kpatch_include_standard_elements(kelf_patched);
|
||||
num_changed = kpatch_include_changed_functions(kelf_patched);
|
||||
kpatch_include_debug_sections(kelf_patched);
|
||||
+ kpatch_ignore_debug_sections(kelf_patched);
|
||||
callbacks_exist = kpatch_include_callback_elements(kelf_patched);
|
||||
kpatch_include_force_elements(kelf_patched);
|
||||
new_globals_exist = kpatch_include_new_globals(kelf_patched);
|
||||
@@ -3470,10 +3529,10 @@ int main(int argc, char *argv[])
|
||||
kpatch_build_strings_section_data(kelf_out);
|
||||
|
||||
gcc_add_option = getenv("GCC_ADD_OPTION");
|
||||
- printf("gcc add option :%s\n", gcc_add_option);
|
||||
+ log_debug("gcc add option :%s\n", gcc_add_option);
|
||||
mlongcall = strstr(gcc_add_option, "-mlong-calls");
|
||||
if (arch == EM_AARCH64 && mlongcall) {
|
||||
- printf("-mlong-calls found, no need to create mcount section\n");
|
||||
+ log_debug("-mlong-calls found, no need to create mcount section\n");
|
||||
} else {
|
||||
kpatch_create_mcount_sections(kelf_out);
|
||||
}
|
||||
diff --git a/kpatch-build/create-klp-module.c b/kpatch-build/create-klp-module.c
|
||||
index 253704b..7a72afd 100644
|
||||
--- a/kpatch-build/create-klp-module.c
|
||||
+++ b/kpatch-build/create-klp-module.c
|
||||
@@ -38,7 +38,9 @@ enum loglevel loglevel = NORMAL;
|
||||
*/
|
||||
static struct symbol *find_or_add_ksym_to_symbols(struct kpatch_elf *kelf,
|
||||
struct section *ksymsec,
|
||||
- char *strings, int offset)
|
||||
+ char *strings, int offset,
|
||||
+ char *ref_name,
|
||||
+ long ref_offset)
|
||||
{
|
||||
struct kpatch_symbol *ksyms, *ksym;
|
||||
struct symbol *sym;
|
||||
@@ -71,9 +73,14 @@ static struct symbol *find_or_add_ksym_to_symbols(struct kpatch_elf *kelf,
|
||||
if (!objname)
|
||||
ERROR("strdup");
|
||||
|
||||
- snprintf(pos, 32, "%lu", ksym->pos);
|
||||
/* .klp.sym.objname.name,pos */
|
||||
- snprintf(buf, 256, KLP_SYM_PREFIX "%s.%s,%s", objname, name, pos);
|
||||
+ if (!ref_name) {
|
||||
+ snprintf(pos, 32, "%lu", ksym->pos);
|
||||
+ snprintf(buf, 256, KLP_SYM_PREFIX "%s.%s,%s", objname, name, pos);
|
||||
+ } else {
|
||||
+ snprintf(pos, 32, "%ld", ref_offset);
|
||||
+ snprintf(buf, 256, KLP_SYM_PREFIX "%s-%s,%s", objname, ref_name, pos);
|
||||
+ }
|
||||
|
||||
/* Look for an already allocated symbol */
|
||||
list_for_each_entry(sym, &kelf->symbols, list) {
|
||||
@@ -180,6 +187,7 @@ static void create_klp_relasecs_and_syms(struct kpatch_elf *kelf, struct section
|
||||
struct rela *rela;
|
||||
char *objname;
|
||||
int nr, index, offset, dest_off;
|
||||
+ char *ref_name;
|
||||
|
||||
krelas = krelasec->data->d_buf;
|
||||
nr = krelasec->data->d_size / sizeof(*krelas);
|
||||
@@ -206,6 +214,17 @@ static void create_klp_relasecs_and_syms(struct kpatch_elf *kelf, struct section
|
||||
if (!objname)
|
||||
ERROR("strdup");
|
||||
|
||||
+ /* Get the unique ref_name */
|
||||
+ rela = find_rela_by_offset(krelasec->rela,
|
||||
+ offset + offsetof(struct kpatch_relocation, ref_name));
|
||||
+ if (!rela)
|
||||
+ ref_name = NULL;
|
||||
+ else {
|
||||
+ ref_name = strdup(strings + rela->addend);
|
||||
+ if (!ref_name)
|
||||
+ ERROR("strdup");
|
||||
+ }
|
||||
+
|
||||
/* Get the .kpatch.symbol entry for the rela src */
|
||||
rela = find_rela_by_offset(krelasec->rela,
|
||||
offset + offsetof(struct kpatch_relocation, ksym));
|
||||
@@ -213,7 +232,7 @@ static void create_klp_relasecs_and_syms(struct kpatch_elf *kelf, struct section
|
||||
ERROR("find_rela_by_offset");
|
||||
|
||||
/* Create (or find) a klp symbol from the rela src entry */
|
||||
- sym = find_or_add_ksym_to_symbols(kelf, ksymsec, strings, rela->addend);
|
||||
+ sym = find_or_add_ksym_to_symbols(kelf, ksymsec, strings, rela->addend, ref_name, krelas[index].ref_offset);
|
||||
if (!sym)
|
||||
ERROR("error finding or adding ksym to symtab");
|
||||
|
||||
diff --git a/kpatch-build/create-kpatch-module.c b/kpatch-build/create-kpatch-module.c
|
||||
index 8292dc8..3e24b3a 100644
|
||||
--- a/kpatch-build/create-kpatch-module.c
|
||||
+++ b/kpatch-build/create-kpatch-module.c
|
||||
@@ -112,14 +112,10 @@ static void create_dynamic_rela_sections(struct kpatch_elf *kelf, struct section
|
||||
dynrelas[index].ref_name = krelas[index].ref_name;
|
||||
dynrelas[index].ref_offset = krelas[index].ref_offset;
|
||||
|
||||
- if (dynrelas[index].ref_offset)
|
||||
- {
|
||||
- /* Get objname offset */
|
||||
- rela = find_rela_by_offset(krelasec->rela,
|
||||
- index * sizeof(*krelas) + offsetof(struct kpatch_relocation, ref_name));
|
||||
- if (!rela) {
|
||||
- ERROR("find_rela_by_offset");
|
||||
- }
|
||||
+ /* Get ref_name offset */
|
||||
+ rela = find_rela_by_offset(krelasec->rela,
|
||||
+ index * sizeof(*krelas) + offsetof(struct kpatch_relocation, ref_name));
|
||||
+ if (rela) {
|
||||
ref_name_offset = rela->addend;
|
||||
/* ref_name */
|
||||
ALLOC_LINK(rela, &dynsec->rela->relas);
|
||||
@@ -128,9 +124,8 @@ static void create_dynamic_rela_sections(struct kpatch_elf *kelf, struct section
|
||||
rela->addend = ref_name_offset;
|
||||
rela->offset = index * sizeof(*dynrelas) + \
|
||||
offsetof(struct kpatch_patch_dynrela, ref_name);
|
||||
-
|
||||
}
|
||||
-
|
||||
+
|
||||
/* dest */
|
||||
ALLOC_LINK(rela, &dynsec->rela->relas);
|
||||
rela->sym = sym;
|
||||
diff --git a/kpatch-build/kpatch-build b/kpatch-build/kpatch-build
|
||||
index 81a6a44..a860f12 100755
|
||||
--- a/kpatch-build/kpatch-build
|
||||
+++ b/kpatch-build/kpatch-build
|
||||
@@ -953,6 +953,10 @@ if grep "hulk" $SRCDIR/Makefile > /dev/null; then
|
||||
export KCPPFLAGS="-D__HULK__ $KCPPFLAGS"
|
||||
fi
|
||||
|
||||
+if [[ -n "$NO_STACK_CHECK" ]];then
|
||||
+ export KCPPFLAGS="-D__ALL_FORCE__ $KCPPFLAGS"
|
||||
+fi
|
||||
+
|
||||
echo "Building patch module: $MODNAME.ko"
|
||||
|
||||
if [[ -z "$USERSRCDIR" ]] && [[ "$DISTRO" = ubuntu ]]; then
|
||||
@@ -990,6 +994,7 @@ KBUILD_EXTRA_SYMBOLS="$KBUILD_EXTRA_SYMBOLS" \
|
||||
KPATCH_LDFLAGS="$KPATCH_LDFLAGS" \
|
||||
CROSS_COMPILE="$ARCH_COMPILE" \
|
||||
make 2>&1 | logger || die
|
||||
+${ARCH_COMPILE}strip -g "$TEMPDIR/patch/$MODNAME.ko"
|
||||
|
||||
if ! "$KPATCH_MODULE"; then
|
||||
if [[ -z "$KPATCH_LDFLAGS" ]]; then
|
||||
@@ -1019,7 +1024,7 @@ fi
|
||||
# column containing lines unique to first file.
|
||||
UNDEFINED=$(comm -23 <(sort -u "${TEMPDIR}"/undefined_references) \
|
||||
<(sort -u "${TEMPDIR}"/new_symbols) | tr '\n' ' ')
|
||||
-[[ ! -z "$UNDEFINED" ]] && die "Undefined symbols: $UNDEFINED"
|
||||
+[[ -z "$USERMODDIR" ]] && [[ ! -z "$UNDEFINED" ]] && die "Undefined symbols: $UNDEFINED"
|
||||
|
||||
cp -f "$TEMPDIR/patch/$MODNAME.ko" "$BASE" || die
|
||||
|
||||
diff --git a/kpatch-build/kpatch-elf.c b/kpatch-build/kpatch-elf.c
|
||||
index fcb7161..0794031 100644
|
||||
--- a/kpatch-build/kpatch-elf.c
|
||||
+++ b/kpatch-build/kpatch-elf.c
|
||||
@@ -700,8 +700,14 @@ void kpatch_reindex_elements(struct kpatch_elf *kelf)
|
||||
unsigned int index;
|
||||
|
||||
index = 1; /* elf write function handles NULL section 0 */
|
||||
- list_for_each_entry(sec, &kelf->sections, list)
|
||||
+ list_for_each_entry(sec, &kelf->sections, list) {
|
||||
sec->index = index++;
|
||||
+ /*
|
||||
+ * since we exclude .group section, we clear SHF_GROUP
|
||||
+ * for every section in case of link error.
|
||||
+ * */
|
||||
+ sec->sh.sh_flags &= (~SHF_GROUP);
|
||||
+ }
|
||||
|
||||
index = 0;
|
||||
list_for_each_entry(sym, &kelf->symbols, list) {
|
||||
diff --git a/kpatch-build/kpatch-gcc b/kpatch-build/kpatch-gcc
|
||||
index be18847..d36e67b 100755
|
||||
--- a/kpatch-build/kpatch-gcc
|
||||
+++ b/kpatch-build/kpatch-gcc
|
||||
@@ -13,7 +13,7 @@ fi
|
||||
|
||||
declare -a args=("$@")
|
||||
|
||||
-if [[ "$TOOLCHAINCMD" = ${ARCH_COMPILE}gcc ]] ; then
|
||||
+if [[ "$TOOLCHAINCMD" = ${ARCH_COMPILE}gcc || "$TOOLCHAINCMD" = ${ARCH_COMPILE}g++ ]] ; then
|
||||
while [ "$#" -gt 0 ]; do
|
||||
if [ "$1" = "-o" ]; then
|
||||
obj="$2"
|
||||
diff --git a/kpatch-build/lookup.c b/kpatch-build/lookup.c
|
||||
index e4677db..2a728f6 100644
|
||||
--- a/kpatch-build/lookup.c
|
||||
+++ b/kpatch-build/lookup.c
|
||||
@@ -45,6 +45,7 @@ struct object_symbol {
|
||||
char *name;
|
||||
int type, bind;
|
||||
int sec_index;
|
||||
+ unsigned long kaddr;
|
||||
};
|
||||
|
||||
struct export_symbol {
|
||||
@@ -238,6 +239,8 @@ static void symtab_read(struct lookup_table *table, char *path)
|
||||
table->obj_syms[i].bind = STB_GLOBAL;
|
||||
} else if (!strcmp(bind, "WEAK")) {
|
||||
table->obj_syms[i].bind = STB_WEAK;
|
||||
+ } else if (!strcmp(bind, "GNU_UNIQUE")) {
|
||||
+ table->obj_syms[i].bind = STB_GNU_UNIQUE;
|
||||
} else {
|
||||
ERROR("unknown symbol bind %s", bind);
|
||||
}
|
||||
@@ -263,6 +266,56 @@ static void symtab_read(struct lookup_table *table, char *path)
|
||||
fclose(file);
|
||||
}
|
||||
|
||||
+static void ksymtab_read(struct lookup_table *table, char *path)
|
||||
+{
|
||||
+ FILE *file;
|
||||
+ struct object_symbol *sym, *sym1, *sym2;
|
||||
+ unsigned long value;
|
||||
+ int i, j, idx;
|
||||
+ char line[256], name[256], type[256], mod[256];
|
||||
+ idx = 0;
|
||||
+
|
||||
+ if ((file = fopen(path, "r")) == NULL)
|
||||
+ ERROR("fopen");
|
||||
+
|
||||
+ while (fgets(line, 256, file)) {
|
||||
+ if (sscanf(line, "%lx %s %s [%s]\n",
|
||||
+ &value, type, name, mod) != 4)
|
||||
+ continue;
|
||||
+
|
||||
+ if (name[0] == '$')
|
||||
+ continue;
|
||||
+
|
||||
+ i = idx;
|
||||
+ for_each_obj_symbol_continue(i, sym, table) {
|
||||
+ if (!strncmp(sym->name, name, KSYM_NAME_LEN-1)) {
|
||||
+ sym->kaddr = value;
|
||||
+ idx = i + 1;
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ for_each_obj_symbol(i, sym1, table) {
|
||||
+ if (sym1->kaddr == 0)
|
||||
+ continue;
|
||||
+ for_each_obj_symbol(j, sym2, table) {
|
||||
+ if (sym2->kaddr == 0)
|
||||
+ continue;
|
||||
+ if (sym1 == sym2)
|
||||
+ continue;
|
||||
+ if (sym1->sec_index != sym2->sec_index)
|
||||
+ continue;
|
||||
+ if ((long)sym1->value - (long)sym2->value ==
|
||||
+ (long)sym1->kaddr - (long)sym2->kaddr)
|
||||
+ continue;
|
||||
+
|
||||
+ ERROR("base mismatch(symbol offset)");
|
||||
+ }
|
||||
+ }
|
||||
+ fclose(file);
|
||||
+}
|
||||
+
|
||||
static void symvers_read(struct lookup_table *table, char *path)
|
||||
{
|
||||
FILE *file;
|
||||
@@ -306,7 +359,8 @@ static void symvers_read(struct lookup_table *table, char *path)
|
||||
}
|
||||
|
||||
struct lookup_table *lookup_open(char *symtab_path, char *symvers_path,
|
||||
- char *hint, struct sym_compare_type *locals)
|
||||
+ char *hint, struct sym_compare_type *locals,
|
||||
+ char *kallsyms)
|
||||
{
|
||||
struct lookup_table *table;
|
||||
|
||||
@@ -317,6 +371,8 @@ struct lookup_table *lookup_open(char *symtab_path, char *symvers_path,
|
||||
|
||||
symtab_read(table, symtab_path);
|
||||
symvers_read(table, symvers_path);
|
||||
+ if (kallsyms)
|
||||
+ ksymtab_read(table, kallsyms);
|
||||
find_local_syms(table, hint, locals);
|
||||
|
||||
return table;
|
||||
@@ -343,6 +399,15 @@ int lookup_local_symbol(struct lookup_table *table, char *name,
|
||||
for_each_obj_symbol(i, sym, table) {
|
||||
if (sym->bind == STB_LOCAL && !strcmp(sym->name, name))
|
||||
pos++;
|
||||
+ else {
|
||||
+ /* symbol name longer than KSYM_NAME_LEN will be truncated
|
||||
+ * by kernel, so we can not find it using its original
|
||||
+ * name. we need to add pos for symbols which have same
|
||||
+ * KSYM_NAME_LEN-1 long prefix.*/
|
||||
+ if (strlen(name) >= KSYM_NAME_LEN-1 &&
|
||||
+ !strncmp(sym->name, name, KSYM_NAME_LEN-1))
|
||||
+ pos++;
|
||||
+ }
|
||||
|
||||
if (table->local_syms == sym) {
|
||||
in_file = 1;
|
||||
@@ -374,15 +439,25 @@ int lookup_global_symbol(struct lookup_table *table, char *name,
|
||||
struct lookup_result *result)
|
||||
{
|
||||
struct object_symbol *sym;
|
||||
+ unsigned long pos = 0;
|
||||
int i;
|
||||
|
||||
memset(result, 0, sizeof(*result));
|
||||
for_each_obj_symbol(i, sym, table) {
|
||||
- if ((sym->bind == STB_GLOBAL || sym->bind == STB_WEAK) &&
|
||||
+ /* symbol name longer than KSYM_NAME_LEN will be truncated
|
||||
+ * by kernel, so we can not find it using its original
|
||||
+ * name. we need to add pos for symbols which have same
|
||||
+ * KSYM_NAME_LEN-1 long prefix.*/
|
||||
+ if (strlen(name) >= KSYM_NAME_LEN-1 &&
|
||||
+ !strncmp(sym->name, name, KSYM_NAME_LEN-1))
|
||||
+ pos++;
|
||||
+
|
||||
+ if ((sym->bind == STB_GLOBAL || sym->bind == STB_WEAK
|
||||
+ || sym->bind == STB_GNU_UNIQUE) &&
|
||||
!strcmp(sym->name, name)) {
|
||||
result->value = sym->value;
|
||||
result->size = sym->size;
|
||||
- result->pos = 0; /* always 0 for global symbols */
|
||||
+ result->pos = pos;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@@ -429,10 +504,12 @@ char *lookup_exported_symbol_objname(struct lookup_table *table, char *name)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
-int lookup_is_duplicate_symbol(struct lookup_table *table, char *name)
|
||||
+int lookup_is_duplicate_symbol(struct lookup_table *table, char *name,
|
||||
+ char *objname, unsigned long pos)
|
||||
{
|
||||
struct object_symbol *sym;
|
||||
int i, count = 0;
|
||||
+ char posstr[32], buf[256];
|
||||
|
||||
for_each_obj_symbol(i, sym, table)
|
||||
if (!strcmp(sym->name, name)) {
|
||||
@@ -441,6 +518,17 @@ int lookup_is_duplicate_symbol(struct lookup_table *table, char *name)
|
||||
return 1;
|
||||
}
|
||||
|
||||
+ /* symbol name longer than KSYM_NAME_LEN will be truncated
|
||||
+ * by kernel, so we can not find it using its original
|
||||
+ * name. Here, we consider these long name symbol as duplicated
|
||||
+ * symbols. since create_klp_module will create symbol name
|
||||
+ * format like .klp.sym.objname.symbol,pos, so we consider name
|
||||
+ * length longer than KSYM_NAME_LEN-1 bytes as duplicated symbol*/
|
||||
+ snprintf(posstr, 32, "%lu", pos);
|
||||
+ snprintf(buf, 256, KLP_SYM_PREFIX "%s.%s,%s", objname, name, posstr);
|
||||
+ if (strlen(buf) >= KSYM_NAME_LEN-1)
|
||||
+ return 1;
|
||||
+
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -487,24 +575,45 @@ struct object_symbol *lookup_find_symbol_by_name(struct lookup_table *table, cha
|
||||
return sym;
|
||||
}
|
||||
|
||||
-int lookup_ref_symbol(struct lookup_table *table, char *name,
|
||||
- struct lookup_refsym *refsym)
|
||||
+int lookup_ref_symbol_offset(struct lookup_table *table, char *name,
|
||||
+ struct lookup_refsym *refsym,
|
||||
+ char *objname, long *offset)
|
||||
{
|
||||
struct object_symbol *orig_sym, *sym;
|
||||
int i;
|
||||
|
||||
orig_sym = lookup_find_symbol_by_name(table, name);
|
||||
if (!orig_sym)
|
||||
- ERROR("lookup_ref_symbol");
|
||||
+ ERROR("lookup_ref_symbol_offset");
|
||||
memset(refsym, 0, sizeof(*refsym));
|
||||
+
|
||||
+ /*find a unique symbol in the same section first*/
|
||||
for_each_obj_symbol(i, sym, table) {
|
||||
if (!strcmp(sym->name, name) || sym->type == STT_FILE ||
|
||||
sym->sec_index != orig_sym->sec_index)
|
||||
continue;
|
||||
|
||||
- if (!lookup_is_duplicate_symbol(table, sym->name)) {
|
||||
+ if (!lookup_is_duplicate_symbol(table, sym->name, objname, 1)) {
|
||||
refsym->name = sym->name;
|
||||
refsym->value = sym->value;
|
||||
+ *offset = (long)orig_sym->value - (long)sym->value;
|
||||
+ return 0;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if (orig_sym->kaddr == 0)
|
||||
+ return 1;
|
||||
+
|
||||
+ /*find a unique symbol has kaddr*/
|
||||
+ for_each_obj_symbol(i, sym, table) {
|
||||
+ if (!strcmp(sym->name, name) || sym->type == STT_FILE ||
|
||||
+ sym->kaddr == 0)
|
||||
+ continue;
|
||||
+
|
||||
+ if (!lookup_is_duplicate_symbol(table, sym->name, objname, 1)) {
|
||||
+ refsym->name = sym->name;
|
||||
+ refsym->value = 0;
|
||||
+ *offset = (long)orig_sym->kaddr - (long)sym->kaddr;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
diff --git a/kpatch-build/lookup.h b/kpatch-build/lookup.h
|
||||
index 5ad9241..00b6ccc 100644
|
||||
--- a/kpatch-build/lookup.h
|
||||
+++ b/kpatch-build/lookup.h
|
||||
@@ -1,6 +1,9 @@
|
||||
#ifndef _LOOKUP_H_
|
||||
#define _LOOKUP_H_
|
||||
|
||||
+#include "kpatch-elf.h"
|
||||
+#define KSYM_NAME_LEN 128
|
||||
+
|
||||
struct lookup_table;
|
||||
|
||||
struct lookup_result {
|
||||
@@ -20,7 +23,8 @@ struct lookup_refsym {
|
||||
};
|
||||
|
||||
struct lookup_table *lookup_open(char *symtab_path, char *symvers_path,
|
||||
- char *hint, struct sym_compare_type *locals);
|
||||
+ char *hint, struct sym_compare_type *locals,
|
||||
+ char *kallsyms);
|
||||
void lookup_close(struct lookup_table *table);
|
||||
int lookup_local_symbol(struct lookup_table *table, char *name,
|
||||
struct lookup_result *result);
|
||||
@@ -28,8 +32,10 @@ int lookup_global_symbol(struct lookup_table *table, char *name,
|
||||
struct lookup_result *result);
|
||||
int lookup_is_exported_symbol(struct lookup_table *table, char *name);
|
||||
char *lookup_exported_symbol_objname(struct lookup_table *table, char *name);
|
||||
-int lookup_is_duplicate_symbol(struct lookup_table *table, char *name);
|
||||
-int lookup_ref_symbol(struct lookup_table *table, char *name,
|
||||
- struct lookup_refsym *refsym);
|
||||
+int lookup_is_duplicate_symbol(struct lookup_table *table, char *name,
|
||||
+ char *objname, unsigned long pos);
|
||||
+int lookup_ref_symbol_offset(struct lookup_table *table, char *name,
|
||||
+ struct lookup_refsym *refsym, char *objname,
|
||||
+ long *offset);
|
||||
|
||||
#endif /* _LOOKUP_H_ */
|
||||
--
|
||||
1.7.5.4
|
||||
|
||||
28
9019-fix-rodata.str-problem.patch
Normal file
28
9019-fix-rodata.str-problem.patch
Normal file
@ -0,0 +1,28 @@
|
||||
From e617351fafaf7504a531fd00a49994653e59a737 Mon Sep 17 00:00:00 2001
|
||||
From: Zhiyu Hu <huzhiyu1@huawei.com>
|
||||
Date: Fri, 28 Dec 2018 07:06:38 +0000
|
||||
Subject: [PATCH] fix rodata.str problem
|
||||
|
||||
fix some rodata.str problem
|
||||
|
||||
Signed-off-by: Zhiyu Hu <huzhiyu1@huawei.com>
|
||||
---
|
||||
kpatch-build/create-diff-object.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/kpatch-build/create-diff-object.c b/kpatch-build/create-diff-object.c
|
||||
index d2e6aee..f075671 100644
|
||||
--- a/kpatch-build/create-diff-object.c
|
||||
+++ b/kpatch-build/create-diff-object.c
|
||||
@@ -1552,7 +1552,7 @@ static void kpatch_include_standard_elements(struct kpatch_elf *kelf)
|
||||
!strcmp(sec->name, ".toc") ||
|
||||
!strcmp(sec->name, ".rodata") ||
|
||||
(!strncmp(sec->name, ".rodata.", 8) &&
|
||||
- strstr(sec->name, ".str1."))) {
|
||||
+ strstr(sec->name, ".str"))) {
|
||||
kpatch_include_section(sec);
|
||||
}
|
||||
}
|
||||
--
|
||||
1.8.3.1
|
||||
|
||||
28
9023-kpatch-build-adapt-for-ksymtab-in-4.19-kernel.patch
Normal file
28
9023-kpatch-build-adapt-for-ksymtab-in-4.19-kernel.patch
Normal file
@ -0,0 +1,28 @@
|
||||
From f221fbe8ff0c22b61aaf42687f5ece04f10ec403 Mon Sep 17 00:00:00 2001
|
||||
From: Zhipeng Xie <xiezhipeng1@huawei.com>
|
||||
Date: Thu, 17 Jan 2019 20:50:25 +0000
|
||||
Subject: [PATCH] kpatch-build: adapt for ksymtab in 4.19 kernel
|
||||
|
||||
Signed-off-by: Zhipeng Xie <xiezhipeng1@huawei.com>
|
||||
---
|
||||
kpatch-build/create-diff-object.c | 4 ++--
|
||||
1 files changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/kpatch-build/create-diff-object.c b/kpatch-build/create-diff-object.c
|
||||
index f075671..2ddd00d 100644
|
||||
--- a/kpatch-build/create-diff-object.c
|
||||
+++ b/kpatch-build/create-diff-object.c
|
||||
@@ -1664,8 +1664,8 @@ static int kpatch_include_new_static_var(struct kpatch_elf *kelf)
|
||||
|
||||
list_for_each_entry(sym, &kelf->symbols, list) {
|
||||
if (sym->status == NEW &&
|
||||
- sym->type == STT_OBJECT &&
|
||||
- sym->bind == STB_LOCAL)
|
||||
+ sym->bind == STB_LOCAL &&
|
||||
+ (sym->type == STT_OBJECT || (sym->type == STT_NOTYPE && sym->name[0] != '$')))
|
||||
kpatch_include_symbol(sym);
|
||||
}
|
||||
|
||||
--
|
||||
1.7.5.4
|
||||
|
||||
91
9024-support-force-enable-disable-for-kernel-4.19.patch
Normal file
91
9024-support-force-enable-disable-for-kernel-4.19.patch
Normal file
@ -0,0 +1,91 @@
|
||||
From 6b7ff79bb40a7dbb28e6aba320e4ac075e4c182d Mon Sep 17 00:00:00 2001
|
||||
From: Zhipeng Xie <xiezhipeng1@huawei.com>
|
||||
Date: Fri, 18 Jan 2019 00:07:02 +0000
|
||||
Subject: [PATCH] support force enable/disable for kernel 4.19
|
||||
|
||||
Signed-off-by: Zhipeng Xie <xiezhipeng1@huawei.com>
|
||||
---
|
||||
kmod/patch/livepatch-patch-hook.c | 7 +++++--
|
||||
kpatch-build/kpatch-build | 12 ++++++++++--
|
||||
2 files changed, 15 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/kmod/patch/livepatch-patch-hook.c b/kmod/patch/livepatch-patch-hook.c
|
||||
index ce1c955..919dfc7 100644
|
||||
--- a/kmod/patch/livepatch-patch-hook.c
|
||||
+++ b/kmod/patch/livepatch-patch-hook.c
|
||||
@@ -511,14 +511,17 @@ static int __init patch_init(void)
|
||||
#ifdef __HULK__
|
||||
lfunc->old_size = func->kfunc->old_size;
|
||||
lfunc->new_size = func->kfunc->new_size;
|
||||
+ lfunc->ref_name= func->kfunc->ref_name;
|
||||
+ lfunc->ref_offset = func->kfunc->ref_offset;
|
||||
+#endif
|
||||
+#if defined(__HULK__) || defined(__KLP_SUPPORT_FORCE__)
|
||||
#ifdef __ALL_FORCE__
|
||||
lfunc->force = 1;
|
||||
#else
|
||||
lfunc->force = patch_is_func_forced(func->kfunc->new_addr);
|
||||
#endif
|
||||
- lfunc->ref_name= func->kfunc->ref_name;
|
||||
- lfunc->ref_offset = func->kfunc->ref_offset;
|
||||
#endif
|
||||
+
|
||||
j++;
|
||||
}
|
||||
|
||||
diff --git a/kpatch-build/kpatch-build b/kpatch-build/kpatch-build
|
||||
index a860f12..c227b44 100755
|
||||
--- a/kpatch-build/kpatch-build
|
||||
+++ b/kpatch-build/kpatch-build
|
||||
@@ -279,7 +279,7 @@ find_special_section_data() {
|
||||
# shellcheck disable=SC2086
|
||||
SPECIAL_VARS="$(readelf -wi "$VMLINUX" |
|
||||
gawk --non-decimal-data $AWK_OPTIONS '
|
||||
- BEGIN { a = b = p = e = o = 0 }
|
||||
+ BEGIN { a = b = p = e = o = f = 0 }
|
||||
|
||||
# Set state if name matches
|
||||
a == 0 && /DW_AT_name.* alt_instr[[:space:]]*$/ {a = 1; next}
|
||||
@@ -287,6 +287,7 @@ find_special_section_data() {
|
||||
p == 0 && /DW_AT_name.* paravirt_patch_site[[:space:]]*$/ {p = 1; next}
|
||||
e == 0 && /DW_AT_name.* exception_table_entry[[:space:]]*$/ {e = 1; next}
|
||||
o == 0 && /DW_AT_name.* orc_entry[[:space:]]*$/ {o = 1; next}
|
||||
+ f == 0 && /DW_AT_name.* klp_func[[:space:]]*$/ {f = 1; next}
|
||||
|
||||
# Reset state unless this abbrev describes the struct size
|
||||
a == 1 && !/DW_AT_byte_size/ { a = 0; next }
|
||||
@@ -294,6 +295,8 @@ find_special_section_data() {
|
||||
p == 1 && !/DW_AT_byte_size/ { p = 0; next }
|
||||
e == 1 && !/DW_AT_byte_size/ { e = 0; next }
|
||||
o == 1 && !/DW_AT_byte_size/ { o = 0; next }
|
||||
+ f == 1 && /DW_TAG_structure_type/ { f = 3; next }
|
||||
+ f == 1 && /DW_AT_name.* force[[:space:]]*$/ {f = 2; next}
|
||||
|
||||
# Now that we know the size, stop parsing for it
|
||||
a == 1 {printf("export ALT_STRUCT_SIZE=%d\n", $4); a = 2}
|
||||
@@ -301,9 +304,10 @@ find_special_section_data() {
|
||||
p == 1 {printf("export PARA_STRUCT_SIZE=%d\n", $4); p = 2}
|
||||
e == 1 {printf("export EX_STRUCT_SIZE=%d\n", $4); e = 2}
|
||||
o == 1 {printf("export ORC_STRUCT_SIZE=%d\n", $4); o = 2}
|
||||
+ f == 2 {printf("export KLP_SUPPORT_FORCE=y\n"); f = 3}
|
||||
|
||||
# Bail out once we have everything
|
||||
- a == 2 && b == 2 && (p == 2 || skip_p) && e == 2 && (o == 2 || skip_o) {exit}')"
|
||||
+ a == 2 && b == 2 && (p == 2 || skip_p) && e == 2 && (o == 2 || skip_o) && f == 3 {exit}')"
|
||||
|
||||
[[ -n "$SPECIAL_VARS" ]] && eval "$SPECIAL_VARS"
|
||||
|
||||
@@ -957,6 +961,10 @@ if [[ -n "$NO_STACK_CHECK" ]];then
|
||||
export KCPPFLAGS="-D__ALL_FORCE__ $KCPPFLAGS"
|
||||
fi
|
||||
|
||||
+if [[ -n "$KLP_SUPPORT_FORCE" ]];then
|
||||
+ export KCPPFLAGS="-D__KLP_SUPPORT_FORCE__ $KCPPFLAGS"
|
||||
+fi
|
||||
+
|
||||
echo "Building patch module: $MODNAME.ko"
|
||||
|
||||
if [[ -z "$USERSRCDIR" ]] && [[ "$DISTRO" = ubuntu ]]; then
|
||||
--
|
||||
1.7.5.4
|
||||
|
||||
118
9025-kpatch-build-adapt-for-native-compile_env.patch
Normal file
118
9025-kpatch-build-adapt-for-native-compile_env.patch
Normal file
@ -0,0 +1,118 @@
|
||||
From 87203483495fec8ad1394def83fa884a96b711ec Mon Sep 17 00:00:00 2001
|
||||
From: Zhipeng Xie <xiezhipeng1@huawei.com>
|
||||
Date: Thu, 14 Feb 2019 14:21:20 +0000
|
||||
Subject: [PATCH] kpatch-build: adapt for native compile_env
|
||||
|
||||
we check vmlinux to determine if klp_func and klp_object
|
||||
have some members and set flag for livepatch-patch-hook.c.
|
||||
support arm64 native compile enviroment.
|
||||
|
||||
Signed-off-by: Zhipeng Xie <xiezhipeng1@huawei.com>
|
||||
---
|
||||
kpatch-build/kpatch-build | 46 ++++++++++++++++++++++++++++++++++----------
|
||||
1 files changed, 35 insertions(+), 11 deletions(-)
|
||||
|
||||
diff --git a/kpatch-build/kpatch-build b/kpatch-build/kpatch-build
|
||||
index c227b44..18f79d4 100755
|
||||
--- a/kpatch-build/kpatch-build
|
||||
+++ b/kpatch-build/kpatch-build
|
||||
@@ -279,7 +279,7 @@ find_special_section_data() {
|
||||
# shellcheck disable=SC2086
|
||||
SPECIAL_VARS="$(readelf -wi "$VMLINUX" |
|
||||
gawk --non-decimal-data $AWK_OPTIONS '
|
||||
- BEGIN { a = b = p = e = o = f = 0 }
|
||||
+ BEGIN { a = b = p = e = o = c = f = s = i = r = j = h = 0 }
|
||||
|
||||
# Set state if name matches
|
||||
a == 0 && /DW_AT_name.* alt_instr[[:space:]]*$/ {a = 1; next}
|
||||
@@ -287,7 +287,8 @@ find_special_section_data() {
|
||||
p == 0 && /DW_AT_name.* paravirt_patch_site[[:space:]]*$/ {p = 1; next}
|
||||
e == 0 && /DW_AT_name.* exception_table_entry[[:space:]]*$/ {e = 1; next}
|
||||
o == 0 && /DW_AT_name.* orc_entry[[:space:]]*$/ {o = 1; next}
|
||||
- f == 0 && /DW_AT_name.* klp_func[[:space:]]*$/ {f = 1; next}
|
||||
+ c == 0 && /DW_AT_name.* klp_func[[:space:]]*$/ {c = 1; next}
|
||||
+ j == 0 && /DW_AT_name.* klp_object[[:space:]]*$/ {j = 1; next}
|
||||
|
||||
# Reset state unless this abbrev describes the struct size
|
||||
a == 1 && !/DW_AT_byte_size/ { a = 0; next }
|
||||
@@ -295,8 +296,13 @@ find_special_section_data() {
|
||||
p == 1 && !/DW_AT_byte_size/ { p = 0; next }
|
||||
e == 1 && !/DW_AT_byte_size/ { e = 0; next }
|
||||
o == 1 && !/DW_AT_byte_size/ { o = 0; next }
|
||||
- f == 1 && /DW_TAG_structure_type/ { f = 3; next }
|
||||
- f == 1 && /DW_AT_name.* force[[:space:]]*$/ {f = 2; next}
|
||||
+ c == 1 && /DW_TAG_structure_type/ { c = 3; next }
|
||||
+ j == 1 && /DW_TAG_structure_type/ { j = 3; next }
|
||||
+ c == 1 && /DW_AT_name.* force[[:space:]]*$/ {f = 2; next}
|
||||
+ c == 1 && /DW_AT_name.* old_sympos[[:space:]]*$/ {s = 2; next}
|
||||
+ i == 1 && /DW_AT_name.* immediate[[:space:]]*$/ {i = 2; next}
|
||||
+ j == 1 && /DW_AT_name.* relocs[[:space:]]*$/ {r = 2; next}
|
||||
+ j == 1 && /DW_AT_name.* hooks_load[[:space:]]*$/ {h = 2; next}
|
||||
|
||||
# Now that we know the size, stop parsing for it
|
||||
a == 1 {printf("export ALT_STRUCT_SIZE=%d\n", $4); a = 2}
|
||||
@@ -304,10 +310,14 @@ find_special_section_data() {
|
||||
p == 1 {printf("export PARA_STRUCT_SIZE=%d\n", $4); p = 2}
|
||||
e == 1 {printf("export EX_STRUCT_SIZE=%d\n", $4); e = 2}
|
||||
o == 1 {printf("export ORC_STRUCT_SIZE=%d\n", $4); o = 2}
|
||||
- f == 2 {printf("export KLP_SUPPORT_FORCE=y\n"); f = 3}
|
||||
+ f == 2 {printf("export KLP_SUPPORT_FORCE=y\n"); f = 3}
|
||||
+ s == 2 {printf("export KLP_SUPPORT_OLD_SYMPOS=y\n"); s = 3}
|
||||
+ i == 2 {printf("export KLP_SUPPORT_IMMEDIATE=y\n"); i = 3}
|
||||
+ r == 2 {printf("export KLP_SUPPORT_RELOCS=y\n"); r = 3}
|
||||
+ h == 2 {printf("export KLP_SUPPORT_LOADHOOKS=y\n"); h = 3}
|
||||
|
||||
# Bail out once we have everything
|
||||
- a == 2 && b == 2 && (p == 2 || skip_p) && e == 2 && (o == 2 || skip_o) && f == 3 {exit}')"
|
||||
+ a == 2 && b == 2 && (p == 2 || skip_p) && e == 2 && (o == 2 || skip_o) && c == 3 && j == 3 {exit}')"
|
||||
|
||||
[[ -n "$SPECIAL_VARS" ]] && eval "$SPECIAL_VARS"
|
||||
|
||||
@@ -406,7 +416,9 @@ arch_export() {
|
||||
export GCC_ADD_OPTION=
|
||||
elif [[ $E_MACHINE -eq 183 ]]; then
|
||||
export ARCH=arm64
|
||||
- export ARCH_COMPILE=aarch64-linux-gnu-
|
||||
+ if [ $(arch) != "aarch64" ]; then
|
||||
+ export ARCH_COMPILE=aarch64-linux-gnu-
|
||||
+ fi
|
||||
export ENDIAN=little
|
||||
if grep "\-mlong-calls" $SRCDIR/Makefile > /dev/null; then
|
||||
export GCC_ADD_OPTION="-fno-section-anchors -mlong-calls"
|
||||
@@ -953,10 +965,6 @@ if "$KPATCH_MODULE"; then
|
||||
export KCPPFLAGS="-D__KPATCH_MODULE__"
|
||||
fi
|
||||
|
||||
-if grep "hulk" $SRCDIR/Makefile > /dev/null; then
|
||||
- export KCPPFLAGS="-D__HULK__ $KCPPFLAGS"
|
||||
-fi
|
||||
-
|
||||
if [[ -n "$NO_STACK_CHECK" ]];then
|
||||
export KCPPFLAGS="-D__ALL_FORCE__ $KCPPFLAGS"
|
||||
fi
|
||||
@@ -965,6 +973,22 @@ if [[ -n "$KLP_SUPPORT_FORCE" ]];then
|
||||
export KCPPFLAGS="-D__KLP_SUPPORT_FORCE__ $KCPPFLAGS"
|
||||
fi
|
||||
|
||||
+if [[ -n "$KLP_SUPPORT_OLD_SYMPOS" ]];then
|
||||
+ export KCPPFLAGS="-DHAVE_SYMPOS $KCPPFLAGS"
|
||||
+fi
|
||||
+
|
||||
+if [[ -n "$KLP_SUPPORT_IMMEDIATE" ]];then
|
||||
+ export KCPPFLAGS="-DHAVE_IMMEDIATE $KCPPFLAGS"
|
||||
+fi
|
||||
+
|
||||
+if [[ -n "$KLP_SUPPORT_RELOCS" ]];then
|
||||
+ export KCPPFLAGS="-DHAVE_ELF_RELOCS $KCPPFLAGS"
|
||||
+fi
|
||||
+
|
||||
+if [[ -n "$KLP_SUPPORT_LOADHOOKS" ]];then
|
||||
+ export KCPPFLAGS="-DHAVE_LOADHOOKS $KCPPFLAGS"
|
||||
+fi
|
||||
+
|
||||
echo "Building patch module: $MODNAME.ko"
|
||||
|
||||
if [[ -z "$USERSRCDIR" ]] && [[ "$DISTRO" = ubuntu ]]; then
|
||||
--
|
||||
1.7.5.4
|
||||
|
||||
96
9026-add-find_special_section_data_arm64-for-arm64.patch
Normal file
96
9026-add-find_special_section_data_arm64-for-arm64.patch
Normal file
@ -0,0 +1,96 @@
|
||||
From d53b2d1f87f5e891ba8f6945765134da9ee2d29d Mon Sep 17 00:00:00 2001
|
||||
From: Zhipeng Xie <xiezhipeng1@huawei.com>
|
||||
Date: Thu, 7 Mar 2019 14:38:15 +0000
|
||||
Subject: [PATCH] add find_special_section_data_arm64 for arm64
|
||||
|
||||
arm64 kernel have no paravirt_patch_site or orc_entry structure
|
||||
in vmlinux, we don't need to check these two struct for arm64.
|
||||
|
||||
Signed-off-by: Zhipeng Xie <xiezhipeng1@huawei.com>
|
||||
---
|
||||
kpatch-build/kpatch-build | 56 ++++++++++++++++++++++++++++++++++++++-
|
||||
1 file changed, 55 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/kpatch-build/kpatch-build b/kpatch-build/kpatch-build
|
||||
index 18f79d4..59af250 100755
|
||||
--- a/kpatch-build/kpatch-build
|
||||
+++ b/kpatch-build/kpatch-build
|
||||
@@ -266,12 +266,66 @@ find_special_section_data_ppc64le() {
|
||||
return
|
||||
}
|
||||
|
||||
+find_special_section_data_arm64() {
|
||||
+
|
||||
+ # If $AWK_OPTIONS are blank gawk would treat "" as a blank script
|
||||
+ # shellcheck disable=SC2086
|
||||
+ SPECIAL_VARS="$(readelf -wi "$VMLINUX" |
|
||||
+ gawk --non-decimal-data $AWK_OPTIONS '
|
||||
+ BEGIN { a = b = e = c = f = s = i = r = j = h = 0 }
|
||||
+
|
||||
+ # Set state if name matches
|
||||
+ a == 0 && /DW_AT_name.* alt_instr[[:space:]]*$/ {a = 1; next}
|
||||
+ b == 0 && /DW_AT_name.* bug_entry[[:space:]]*$/ {b = 1; next}
|
||||
+ e == 0 && /DW_AT_name.* exception_table_entry[[:space:]]*$/ {e = 1; next}
|
||||
+ c == 0 && /DW_AT_name.* klp_func[[:space:]]*$/ {c = 1; next}
|
||||
+ j == 0 && /DW_AT_name.* klp_object[[:space:]]*$/ {j = 1; next}
|
||||
+
|
||||
+ # Reset state unless this abbrev describes the struct size
|
||||
+ a == 1 && !/DW_AT_byte_size/ { a = 0; next }
|
||||
+ b == 1 && !/DW_AT_byte_size/ { b = 0; next }
|
||||
+ e == 1 && !/DW_AT_byte_size/ { e = 0; next }
|
||||
+ c == 1 && /DW_TAG_structure_type/ { c = 3; next }
|
||||
+ j == 1 && /DW_TAG_structure_type/ { j = 3; next }
|
||||
+ c == 1 && /DW_AT_name.* force[[:space:]]*$/ {f = 2; next}
|
||||
+ c == 1 && /DW_AT_name.* old_sympos[[:space:]]*$/ {s = 2; next}
|
||||
+ i == 1 && /DW_AT_name.* immediate[[:space:]]*$/ {i = 2; next}
|
||||
+ j == 1 && /DW_AT_name.* relocs[[:space:]]*$/ {r = 2; next}
|
||||
+ j == 1 && /DW_AT_name.* hooks_load[[:space:]]*$/ {h = 2; next}
|
||||
+
|
||||
+ # Now that we know the size, stop parsing for it
|
||||
+ a == 1 {printf("export ALT_STRUCT_SIZE=%d\n", $4); a = 2}
|
||||
+ b == 1 {printf("export BUG_STRUCT_SIZE=%d\n", $4); b = 2}
|
||||
+ e == 1 {printf("export EX_STRUCT_SIZE=%d\n", $4); e = 2}
|
||||
+ f == 2 {printf("export KLP_SUPPORT_FORCE=y\n"); f = 3}
|
||||
+ s == 2 {printf("export KLP_SUPPORT_OLD_SYMPOS=y\n"); s = 3}
|
||||
+ i == 2 {printf("export KLP_SUPPORT_IMMEDIATE=y\n"); i = 3}
|
||||
+ r == 2 {printf("export KLP_SUPPORT_RELOCS=y\n"); r = 3}
|
||||
+ h == 2 {printf("export KLP_SUPPORT_LOADHOOKS=y\n"); h = 3}
|
||||
+
|
||||
+ # Bail out once we have everything
|
||||
+ a == 2 && b == 2 && e == 2 && c == 3 && j == 3 {exit}')"
|
||||
+
|
||||
+ [[ -n "$SPECIAL_VARS" ]] && eval "$SPECIAL_VARS"
|
||||
+
|
||||
+ [[ -z "$ALT_STRUCT_SIZE" ]] && die "can't find special struct alt_instr size"
|
||||
+ [[ -z "$BUG_STRUCT_SIZE" ]] && die "can't find special struct bug_entry size"
|
||||
+ [[ -z "$EX_STRUCT_SIZE" ]] && die "can't find special struct exception_table_entry size"
|
||||
+
|
||||
+ return
|
||||
+}
|
||||
+
|
||||
find_special_section_data() {
|
||||
if [[ "$ARCH" = "ppc64le" ]]; then
|
||||
find_special_section_data_ppc64le
|
||||
return
|
||||
fi
|
||||
|
||||
+ if [[ "$ARCH" = "arm64" ]]; then
|
||||
+ find_special_section_data_arm64
|
||||
+ return
|
||||
+ fi
|
||||
+
|
||||
[[ "$CONFIG_PARAVIRT" -eq 0 ]] && AWK_OPTIONS="-vskip_p=1"
|
||||
[[ "$CONFIG_UNWINDER_ORC" -eq 0 ]] && AWK_OPTIONS="$AWK_OPTIONS -vskip_o=1"
|
||||
|
||||
@@ -323,7 +377,7 @@ find_special_section_data() {
|
||||
|
||||
[[ -z "$ALT_STRUCT_SIZE" ]] && die "can't find special struct alt_instr size"
|
||||
[[ -z "$BUG_STRUCT_SIZE" ]] && die "can't find special struct bug_entry size"
|
||||
- [[ -z "$EX_STRUCT_SIZE" ]] && die "can't find special struct paravirt_patch_site size"
|
||||
+ [[ -z "$EX_STRUCT_SIZE" ]] && die "can't find special struct exception_table_entry size"
|
||||
[[ -z "$PARA_STRUCT_SIZE" && "$CONFIG_PARAVIRT" -ne 0 ]] && die "can't find special struct paravirt_patch_site size"
|
||||
[[ -z "$ORC_STRUCT_SIZE" && "$CONFIG_UNWINDER_ORC" -ne 0 ]] && die "can't find special struct orc_entry size"
|
||||
|
||||
--
|
||||
2.19.1
|
||||
|
||||
31
9027-fix-ref-static-local-symbol-for-longname-symbol.patch
Normal file
31
9027-fix-ref-static-local-symbol-for-longname-symbol.patch
Normal file
@ -0,0 +1,31 @@
|
||||
From 1069d212fd848f1f1e2425dffe8e9aea188c6150 Mon Sep 17 00:00:00 2001
|
||||
From: Zhipeng Xie <xiezhipeng1@huawei.com>
|
||||
Date: Tue, 21 Dec 2083 12:18:38 +0800
|
||||
Subject: [PATCH] fix ref static local symbol for longname symbol
|
||||
|
||||
static local symbol have a "." which will confuse
|
||||
the kernel livepatch klp_resolve_symbols. So, pass
|
||||
static local symbols in lookup_ref_symbol_offset.
|
||||
|
||||
Signed-off-by: Zhipeng Xie <xiezhipeng1@huawei.com>
|
||||
---
|
||||
kpatch-build/lookup.c | 3 ++-
|
||||
1 file changed, 2 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/kpatch-build/lookup.c b/kpatch-build/lookup.c
|
||||
index 2e55862..01abc41 100644
|
||||
--- a/kpatch-build/lookup.c
|
||||
+++ b/kpatch-build/lookup.c
|
||||
@@ -591,7 +591,8 @@ int lookup_ref_symbol_offset(struct lookup_table *table, char *name,
|
||||
/*find a unique symbol in the same section first*/
|
||||
for_each_obj_symbol(i, sym, table) {
|
||||
if (!strcmp(sym->name, name) || sym->type == STT_FILE ||
|
||||
- sym->sec_index != orig_sym->sec_index)
|
||||
+ sym->sec_index != orig_sym->sec_index ||
|
||||
+ strchr(sym->name, '.'))
|
||||
continue;
|
||||
|
||||
if (!lookup_is_duplicate_symbol(table, sym->name, objname, 1)) {
|
||||
--
|
||||
2.19.1
|
||||
|
||||
33
9028-add-object-in-kpatch.patch
Normal file
33
9028-add-object-in-kpatch.patch
Normal file
@ -0,0 +1,33 @@
|
||||
From d6304fcd36edd4e9df48687517f30965d9a790e9 Mon Sep 17 00:00:00 2001
|
||||
From: Bin Yang <robin.yb@huawei.com>
|
||||
Date: Tue, 16 Jul 2019 14:39:27 +0800
|
||||
Subject: [PATCH] add object in kpatch
|
||||
|
||||
---
|
||||
kpatch-build/kpatch-build | 3 +++
|
||||
1 file changed, 3 insertions(+)
|
||||
|
||||
diff --git a/kpatch-build/kpatch-build b/kpatch-build/kpatch-build
|
||||
index 59af250..f685654 100644
|
||||
--- a/kpatch-build/kpatch-build
|
||||
+++ b/kpatch-build/kpatch-build
|
||||
@@ -1011,6 +1011,8 @@ echo -n "Patched objects:"
|
||||
for i in $(echo "${objnames[@]}" | tr ' ' '\n' | sort -u | tr '\n' ' ')
|
||||
do
|
||||
echo -n " $i"
|
||||
+ echo -n " $(basename $i)"
|
||||
+ echo -n "$(basename $i)" >> $TEMPDIR/patch/object
|
||||
done
|
||||
echo
|
||||
|
||||
@@ -1113,6 +1115,7 @@ UNDEFINED=$(comm -23 <(sort -u "${TEMPDIR}"/undefined_references) \
|
||||
[[ -z "$USERMODDIR" ]] && [[ ! -z "$UNDEFINED" ]] && die "Undefined symbols: $UNDEFINED"
|
||||
|
||||
cp -f "$TEMPDIR/patch/$MODNAME.ko" "$BASE" || die
|
||||
+cp -f "$TEMPDIR/patch/object" "$BASE" || die
|
||||
|
||||
[[ "$DEBUG" -eq 0 ]] && rm -f "$LOGFILE"
|
||||
|
||||
--
|
||||
2.17.1
|
||||
|
||||
@ -0,0 +1,34 @@
|
||||
From da3eed612df1d26e19b0678763e116f666da13b2 Mon Sep 17 00:00:00 2001
|
||||
From: Artem Savkov <asavkov@redhat.com>
|
||||
Date: Wed, 14 Nov 2018 12:33:13 +0100
|
||||
Subject: [PATCH] kmod/core: fix compilation with
|
||||
CONFIG_HAVE_ARCH_PREL32_RELOCATIONS
|
||||
|
||||
Kernel commit 7290d5809571 "module: use relative references for
|
||||
__ksymtab entries" changed kernel_symbol structure on some
|
||||
architectures. Adjust kmod/core/core.c accordingly.
|
||||
|
||||
Signed-off-by: Artem Savkov <asavkov@redhat.com>
|
||||
---
|
||||
kmod/core/core.c | 4 ++++
|
||||
1 file changed, 4 insertions(+)
|
||||
|
||||
diff --git a/kmod/core/core.c b/kmod/core/core.c
|
||||
index 4a73a47..a91d417 100644
|
||||
--- a/kmod/core/core.c
|
||||
+++ b/kmod/core/core.c
|
||||
@@ -651,7 +651,11 @@ static int kpatch_find_external_symbol(const char *objname, const char *name,
|
||||
sym = find_symbol(name, NULL, NULL, true, true);
|
||||
preempt_enable();
|
||||
if (sym) {
|
||||
+#ifdef CONFIG_HAVE_ARCH_PREL32_RELOCATIONS
|
||||
+ *addr = (unsigned long)offset_to_ptr(&sym->value_offset);
|
||||
+#else
|
||||
*addr = sym->value;
|
||||
+#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
--
|
||||
2.19.1
|
||||
|
||||
39
README.md
39
README.md
@ -1,39 +0,0 @@
|
||||
# kpatch
|
||||
|
||||
#### 介绍
|
||||
{**以下是码云平台说明,您可以替换此简介**
|
||||
码云是 OSCHINA 推出的基于 Git 的代码托管平台(同时支持 SVN)。专为开发者提供稳定、高效、安全的云端软件开发协作平台
|
||||
无论是个人、团队、或是企业,都能够用码云实现代码托管、项目管理、协作开发。企业项目请看 [https://gitee.com/enterprises](https://gitee.com/enterprises)}
|
||||
|
||||
#### 软件架构
|
||||
软件架构说明
|
||||
|
||||
|
||||
#### 安装教程
|
||||
|
||||
1. xxxx
|
||||
2. xxxx
|
||||
3. xxxx
|
||||
|
||||
#### 使用说明
|
||||
|
||||
1. xxxx
|
||||
2. xxxx
|
||||
3. xxxx
|
||||
|
||||
#### 参与贡献
|
||||
|
||||
1. Fork 本仓库
|
||||
2. 新建 Feat_xxx 分支
|
||||
3. 提交代码
|
||||
4. 新建 Pull Request
|
||||
|
||||
|
||||
#### 码云特技
|
||||
|
||||
1. 使用 Readme\_XXX.md 来支持不同的语言,例如 Readme\_en.md, Readme\_zh.md
|
||||
2. 码云官方博客 [blog.gitee.com](https://blog.gitee.com)
|
||||
3. 你可以 [https://gitee.com/explore](https://gitee.com/explore) 这个地址来了解码云上的优秀开源项目
|
||||
4. [GVP](https://gitee.com/gvp) 全称是码云最有价值开源项目,是码云综合评定出的优秀开源项目
|
||||
5. 码云官方提供的使用手册 [https://gitee.com/help](https://gitee.com/help)
|
||||
6. 码云封面人物是一档用来展示码云会员风采的栏目 [https://gitee.com/gitee-stars/](https://gitee.com/gitee-stars/)
|
||||
BIN
kpatch-0.6.1.tar.gz
Normal file
BIN
kpatch-0.6.1.tar.gz
Normal file
Binary file not shown.
249
kpatch.spec
Normal file
249
kpatch.spec
Normal file
@ -0,0 +1,249 @@
|
||||
%global raw_version 0.6.1
|
||||
|
||||
Name: kpatch
|
||||
Version: 2.0
|
||||
Release: 3.1.22
|
||||
Summary: A Linux dynamic kernel patching infrastructure
|
||||
|
||||
License: GPLv2
|
||||
URL: https://github.com/dynup/kpatch
|
||||
Source0: https://github.com/dynup/kpatch/archive/%{name}-%{raw_version}.tar.gz
|
||||
|
||||
Source1: os_hotpatch
|
||||
Source2: livepatch
|
||||
Source3: make_hotpatch
|
||||
|
||||
Patch9001: 9001-livepatch-patch-hook-don-t-active-patch-when-insmod.patch
|
||||
Patch9002: 9002-kpatch-build-support-third-party-module-make-hotpatc.patch
|
||||
Patch9003: 9003-kpatch-build-support-makefile-not-in-third-party-mod.patch
|
||||
Patch9004: 9004-create-diff-object-new-static-var-should-be-included.patch
|
||||
Patch9005: 9005-livepatch-fix-use-THIS-modname-as-the-name-of-ddebug.patch
|
||||
Patch9006: 9006-create-diff-object-fix-correlate-static-local-variab.patch
|
||||
Patch9007: 9007-create-diff-object-don-t-create-dynamic-reloc-for-sy.patch
|
||||
Patch9008: 9008-livepatch-patch-hook-support-force-enable-disable-fu.patch
|
||||
Patch9009: 9009-kmod-kpatch-build-support-build-patch-for-old-kernel.patch
|
||||
Patch9010: 9010-kmod-kpatch-build-support-cross-compile-hotpatch-for.patch
|
||||
Patch9011: 9011-kpatch-build-use-.klp.rela-in-euleros-7.5-kernel.patch
|
||||
Patch9012: 9012-create-diff-object-create-dynamic-relocs-for-changed.patch
|
||||
Patch9013: 9013-kmod-kpatch-build-fix-duplicate-symbol-relocation-fo.patch
|
||||
Patch9014: 9014-create-diff-object-add-dynamic-reloction-for-functio.patch
|
||||
Patch9015: 9015-create-diff-object-exclude-line-only-change-for-arm6.patch
|
||||
Patch9016: 9016-kpatch-build-include-secsym-in-kpatch_mark_ignored_s.patch
|
||||
Patch9017: 9017-support-compile-kpatch-on-aarch64.patch
|
||||
Patch9018: 9018-support-c-plus-kernel-module.patch
|
||||
Patch9019: 9019-fix-rodata.str-problem.patch
|
||||
Patch9020: 0001-Add-__addressable_-to-maybe_discarded_sym.patch
|
||||
Patch9021: 0002-kmod-patch-fix-patch-linking-with-4.20.patch
|
||||
Patch9022: 0003-kmod-patch-more-linking-fixes.patch
|
||||
Patch9023: 9023-kpatch-build-adapt-for-ksymtab-in-4.19-kernel.patch
|
||||
Patch9024: 9024-support-force-enable-disable-for-kernel-4.19.patch
|
||||
Patch9025: 9025-kpatch-build-adapt-for-native-compile_env.patch
|
||||
Patch9026: 9026-add-find_special_section_data_arm64-for-arm64.patch
|
||||
Patch9027: 9027-fix-ref-static-local-symbol-for-longname-symbol.patch
|
||||
Patch9028: 9028-add-object-in-kpatch.patch
|
||||
Patch9029: 0004-create-diff-object-allow-changing-subsections.patch
|
||||
Patch9030: 9030-kmod-core-fix-compilation-with-CONFIG_HAVE_ARCH_PREL.patch
|
||||
|
||||
BuildRequires: gcc elfutils-libelf-devel uname-build-checks kernel kernel-devel
|
||||
Requires: bc tar bash kmod
|
||||
|
||||
Provides: kpatch-runtime
|
||||
Obsoletes: kpatch-runtime
|
||||
|
||||
%description
|
||||
kpatch is a Linux dynamic kernel patching infrastructure which allows you to patch
|
||||
a running kernel without rebooting or restarting any processes. It enables sysadmins
|
||||
to apply critical security patches to the kernel immediately, without having to wait
|
||||
for long-running tasks to complete, for users to log off, or for scheduled reboot
|
||||
windows. It gives more control over uptime without sacrificing security or stability.
|
||||
|
||||
%package_help
|
||||
|
||||
%prep
|
||||
%autosetup -n %{name}-%{raw_version} -p1
|
||||
|
||||
%build
|
||||
export CFLAGS="$RPM_OPT_FLAGS" LDFLAGS="$RPM_LD_FLAGS"
|
||||
%make_build
|
||||
|
||||
%install
|
||||
%make_install PREFIX=%{_prefix}
|
||||
|
||||
install -Dm 0750 -t %{buildroot}/%{_bindir} %{SOURCE1} %{SOURCE2}
|
||||
install -Dm 0500 -t %{buildroot}/opt/patch_workspace/ %{SOURCE3}
|
||||
pushd %{buildroot}/opt/patch_workspace
|
||||
mkdir hotpatch package
|
||||
popd
|
||||
|
||||
%files
|
||||
%defattr(-,root,root)
|
||||
%doc COPYING README.md
|
||||
%{_bindir}/*
|
||||
%{_prefix}/lib/systemd/system/*
|
||||
%{_libexecdir}/kpatch
|
||||
%{_prefix}/sbin/kpatch
|
||||
%{_datadir}/%{name}/*
|
||||
%{_sysconfdir}/init/*
|
||||
%{_bindir}/livepatch
|
||||
%{_bindir}/os_hotpatch
|
||||
/opt/patch_workspace/*
|
||||
%ifarch x86_64
|
||||
%{_prefix}/lib/kpatch
|
||||
%endif
|
||||
|
||||
%files help
|
||||
%{_mandir}/man1/*.1.gz
|
||||
|
||||
%changelog
|
||||
* Mon Dec 30 2019 openEuler Buildteam <buildteam@openeuler.org> -2.0-3.1.22
|
||||
- Type:enhancement
|
||||
- ID:NA
|
||||
- SUG:NA
|
||||
- DESC:change some patch name and delete useless code
|
||||
|
||||
* Mon Dec 23 2019 openEuler Buildteam <buildteam@openeuler.org> -2.0-3.1.21
|
||||
- Type:enhancement
|
||||
- ID:NA
|
||||
- SUG:NA
|
||||
- DESC:modify email adress
|
||||
|
||||
* Thu Dec 19 2019 chengquan<chengquan3@huawei.com> -2.0-3.1.20
|
||||
- Type:enhancement
|
||||
- ID:NA
|
||||
- SUG:NA
|
||||
- DESC:remove useless description
|
||||
|
||||
* Thu Nov 28 2019 Yufa Fang<fangyufa1@huawei.com> - 2.0-3.1.19
|
||||
- Type:bugfix
|
||||
- ID:NA
|
||||
- SUG:restart
|
||||
- DESC:fix compilation with CONFIG_HAVE_ARCH_PREL32_RELOCATIONS
|
||||
|
||||
* Thu Oct 10 2019 Zhipeng Xie<xiezhipeng1@huawei.com> - 2.0-3.1.18
|
||||
- Type:enhancement
|
||||
- ID:NA
|
||||
- SUG:restart
|
||||
- DESC:add security compile flags
|
||||
|
||||
* Tue Sep 27 2019 Zhipeng Xie<xiezhipeng1@huawei.com> - 2.0-3.1.17
|
||||
- Type:enhancement
|
||||
- ID:NA
|
||||
- SUG:restart
|
||||
- DESC:create-diff-object: allow changing subsections
|
||||
|
||||
* Tue Sep 24 2019 shenyangyang<shenyangyang4@huawei.com> -2.0-3.1.16
|
||||
- Type:enhancement
|
||||
- ID:NA
|
||||
- SUG:NA
|
||||
- DESC:revise help package and subpackage
|
||||
|
||||
* Mon Aug 26 2019 openEuler Buildteam<buildteam@openeuler.org> -2.0-3.1.15
|
||||
- Type:enhancement
|
||||
- ID:NA
|
||||
- SUG:NA
|
||||
- DESC:changelog some patch commit message
|
||||
|
||||
* Tue Aug 20 2019 openEuler Builteam <buildteam@openeuler.org> -2.0-3.1.14
|
||||
- Type:NA
|
||||
- ID:NA
|
||||
- SUG:NA
|
||||
- DESC:rewrite spec
|
||||
|
||||
* Fri Jul 16 2019 yangbin<robin.yb@huawei.com> - 2.0-3.1.13
|
||||
- Type:enhancement
|
||||
- ID:NA
|
||||
- SUG:restart
|
||||
- DESC:add object in kpatch
|
||||
|
||||
* Fri Jul 5 2019 Zhipeng Xie<xiezhipeng1@huawei.com> - 2.0-3.1.12
|
||||
- Type:bugfix
|
||||
- ID:NA
|
||||
- SUG:restart
|
||||
- DESC:fix ref static local symbol for longname symbol
|
||||
|
||||
* Mon Jul 1 2019 Enbo Kang<kangenbo@huawei.com> - 2.0-3.1.11
|
||||
- Type:enhancement
|
||||
- ID:NA
|
||||
- SUG:restart
|
||||
- DESC:fix security problem
|
||||
|
||||
* Tue May 7 2019 Zhipeng Xie<xiezhipeng1@huawei.com> - 2.0-3.1.10
|
||||
- Type:enhancement
|
||||
- ID:NA
|
||||
- SUG:restart
|
||||
- DESC:change some patch to backport prefix
|
||||
|
||||
* Sat Apr 13 2019 hezhanyu<hezhanyu@huawei.com> - 2.0-3.1.9
|
||||
- Type:enhancement
|
||||
- ID:NA
|
||||
- SUG:restart
|
||||
- DESC:modify private key in sign-modules
|
||||
|
||||
* Thu Apr 4 2019 Enbo Kang<kangenbo@huawei.com> - 2.0-3.1.8
|
||||
- Type:enhancement
|
||||
- ID:NA
|
||||
- SUG:restart
|
||||
- DESC:delete sensitive information
|
||||
|
||||
* Thu Mar 28 2019 Enbo Kang<kangenbo@huawei.com> - 2.0-3.1.7
|
||||
- Type:enhancement
|
||||
- ID:NA
|
||||
- SUG:restart
|
||||
- DESC:add RELRO and PIE for create-kpatch-module, create-diff-object, create-klp-module
|
||||
|
||||
* Sat Mar 23 2019 Zhipeng Xie<xiezhipeng1@huawei.com> - 2.0-3.1.6
|
||||
- Type:enhancement
|
||||
- ID:NA
|
||||
- SUG:restart
|
||||
- DESC:upgrade to upstream version 0.6.1
|
||||
|
||||
* Thu Mar 7 2019 Zhipeng Xie<xiezhipeng1@huawei.com> - 2.0-3.1.5
|
||||
- Type:bugfix
|
||||
- ID:NA
|
||||
- SUG:restart
|
||||
- DESC:add find_special_section_data_arm64 for arm64
|
||||
|
||||
* Tue Feb 26 2019 Zhipeng Xie<xiezhipeng1@huawei.com> - 2.0-3.1.4
|
||||
- Type:enhancement
|
||||
- ID:NA
|
||||
- SUG:restart
|
||||
- DESC:add packages required by kpatch and kpatch-runtime
|
||||
|
||||
* Mon Feb 25 2019 Zhipeng Xie<xiezhipeng1@huawei.com> - 2.0-3.1.3
|
||||
- Type:enhancement
|
||||
- ID:NA
|
||||
- SUG:restart
|
||||
- DESC:adapt for native compile_env
|
||||
|
||||
* Mon Feb 11 2019 Zhipeng Xie<xiezhipeng1@huawei.com> - 2.0-3.1.2
|
||||
- Type:enhancement
|
||||
- ID:NA
|
||||
- SUG:restart
|
||||
- DESC:support kernel-4.19
|
||||
|
||||
* Thu Dec 20 2018 Zhipeng Xie<xiezhipeng1@huawei.com> - 2.0-3.1.1
|
||||
- Type:enhancement
|
||||
- ID:NA
|
||||
- SUG:restart
|
||||
- DESC:support c++ kernel module
|
||||
|
||||
* Wed Dec 19 2018 Zhipeng Xie<xiezhipeng1@huawei.com> - 2.0-3.1.0
|
||||
- Type:enhancement
|
||||
- ID:NA
|
||||
- SUG:restart
|
||||
- DESC:support compile kpatch on aarch64
|
||||
|
||||
* Fri Nov 23 2018 Zhipeng Xie<xiezhipeng1@huawei.com> - 2.0-2.7.2
|
||||
- Type:enhancement
|
||||
- ID:NA
|
||||
- SUG:restart
|
||||
- DESC:fix some kpatch-build fail cases
|
||||
|
||||
* Sat Nov 3 2018 Zhipeng Xie<xiezhipeng1@huawei.com> - 2.0-2.7.1
|
||||
- Type:enhancement
|
||||
- ID:NA
|
||||
- SUG:restart
|
||||
- DESC:rebase kpatch
|
||||
|
||||
* Thu Nov 16 2017 openEuler Builteam <buildteam@openeuler.org> 0.4.0-3
|
||||
- Package init
|
||||
65
livepatch
Normal file
65
livepatch
Normal file
@ -0,0 +1,65 @@
|
||||
#!/bin/bash
|
||||
# Copyright (C) 2019. Huawei Technologies Co., Ltd. All rights reserved.
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License version 2 and
|
||||
# only version 2 as published by the Free Software Foundation.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
|
||||
exe_tool=`which os_hotpatch`
|
||||
fn_help()
|
||||
{
|
||||
cat <<EOFE
|
||||
Usage: livepatch -l/--load -r/--remove -a/--activate -d/--deactivate <patch>
|
||||
-q[patch]/--query[=patch]
|
||||
-h/--help -v/--version
|
||||
e.g. : livepatch --load <patch archive name>
|
||||
EOFE
|
||||
}
|
||||
if [ "$1" = "-q" -o "$1" = "--query" ];then
|
||||
$exe_tool -q all
|
||||
exit 0
|
||||
fi
|
||||
input_args=`getopt -a -o l:a:r:d:q:v -l load:,activate:,remove:,deactivate:,query:,help,version -- "$@" 2>&1`
|
||||
eval set -- "${input_args}"
|
||||
while true;
|
||||
do
|
||||
case "$1" in
|
||||
-l|--load)
|
||||
$exe_tool -l "$2"
|
||||
exit $?
|
||||
;;
|
||||
-a|--activate)
|
||||
$exe_tool -a "klp_${2#klp_}"
|
||||
exit $?
|
||||
;;
|
||||
-d|--deactivate)
|
||||
$exe_tool -r "klp_${2#klp_}"
|
||||
exit $?
|
||||
;;
|
||||
-r|--remove)
|
||||
$exe_tool -d "klp_${2#klp_}"
|
||||
exit $?
|
||||
;;
|
||||
-q|--query)
|
||||
$exe_tool -q "klp_${2#klp_}"
|
||||
exit $?
|
||||
;;
|
||||
-h|--help)
|
||||
fn_help
|
||||
exit 0
|
||||
;;
|
||||
-v|--version)
|
||||
echo "LKP:livepatch version 2.0-00000"
|
||||
exit 0
|
||||
;;
|
||||
*)
|
||||
fn_help
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
done
|
||||
726
make_hotpatch
Normal file
726
make_hotpatch
Normal file
@ -0,0 +1,726 @@
|
||||
#!/bin/bash
|
||||
# Copyright (C) 2019. Huawei Technologies Co., Ltd. All rights reserved.
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License version 2 and
|
||||
# only version 2 as published by the Free Software Foundation.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
|
||||
SHELL_DIR=$(dirname $0)
|
||||
SHELL_DIR=$(cd $SHELL_DIR; pwd)
|
||||
G_PRIVATE_MODULE=
|
||||
G_HOTPATCH=
|
||||
G_HOTPATCH_ID=
|
||||
G_HOTPATCH_TAR=
|
||||
G_DIFFEXT=
|
||||
G_JOBS="$(getconf _NPROCESSORS_ONLN)"
|
||||
G_PATCH_SRC=
|
||||
G_KERNEL_SRC=/opt/patch_workspace/kernel-source
|
||||
G_KERNEL_CONFIG=/opt/patch_workspace/.config
|
||||
G_HOTPATCH_DIR=/opt/patch_workspace/hotpatch
|
||||
G_VMLINUX=/opt/patch_workspace/vmlinux
|
||||
G_PREFIX=klp
|
||||
G_TMP_DIR=
|
||||
G_PATCHFILE=
|
||||
G_MODULE_SRC=
|
||||
G_MODULE_MAKEFILE=
|
||||
G_KPLICE_PWD_FIELD="KPLICE_PWD"
|
||||
G_PRIVATE_MODULE_SRC_FIELD="PRIVATE_MODULE_SRC"
|
||||
G_KPATCH_FLAGS=/opt/patch_workspace/.flags
|
||||
G_DEBUG_INFO=
|
||||
G_EXT_FLAGS=
|
||||
USERMODBUILDDIR=
|
||||
|
||||
#########################################################
|
||||
# Description: usage
|
||||
# Input:
|
||||
# Return: 0-success
|
||||
#########################################################
|
||||
function fn_usage()
|
||||
{
|
||||
cat << EOF
|
||||
Usage:
|
||||
make_hotpatch [*OPTIONS*] -d patch_diffext -i patch_id -m module_src
|
||||
|
||||
Options:
|
||||
-d,--diffext
|
||||
make hotpatch using the modified source files with
|
||||
names ending in *patch_diffext*. The patch will be determined by
|
||||
comparing all of the files in the build directory tree
|
||||
whose names end with the extra extension *patch_diffext* against the
|
||||
corresponding files without the extra extension.
|
||||
-j,--jobs
|
||||
Specifies the number of jobs to run simultaneously while
|
||||
performing builds.
|
||||
-i,--id
|
||||
Specifies the unique value that will be used as the identifier
|
||||
of the hotpatch.
|
||||
-m,--modulesrc
|
||||
Specifies the module src path for make user module hotpatch.
|
||||
-f,--makefile
|
||||
Specifies the module makefile for make user module hotpatch.
|
||||
--extra_flags
|
||||
Specifies extra flags file for make user module hotpatch.
|
||||
--no_stack_check
|
||||
make hotpatch without stack check when activating or deactivating this patch.
|
||||
--debug_info
|
||||
Save debug info when hotpatch building.Default is closed.
|
||||
-p,--patch
|
||||
Specifies the patch file
|
||||
--kallsyms
|
||||
Specifies module kallsyms in running system(cat /proc/kallsyms|grep mod)
|
||||
-h,--help
|
||||
help info
|
||||
EOF
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
|
||||
#########################################################
|
||||
# Description: fn_do_clean, remove tmp file
|
||||
# Input:
|
||||
# $1: init flag
|
||||
# Return: 0-success
|
||||
#########################################################
|
||||
function fn_do_clean()
|
||||
{
|
||||
local ret=0
|
||||
G_EXT_FLAGS=
|
||||
unset NO_STACK_CHECK
|
||||
unset KALLSYMS
|
||||
rm -rf $G_TMP_DIR
|
||||
|
||||
}
|
||||
|
||||
#########################################################
|
||||
# Description: fn_check_reg_char
|
||||
# Input:
|
||||
# $@: input param
|
||||
# Return: 0-success,1-failed
|
||||
#########################################################
|
||||
function fn_check_reg_char()
|
||||
{
|
||||
local l_str=$1
|
||||
local l_str_maxlen=$2
|
||||
local l_str_ex=$3
|
||||
local len_str=${#l_str}
|
||||
|
||||
if [ -z "$l_str" ];then
|
||||
echo "error: the string is empty, check string failed"
|
||||
return 1
|
||||
fi
|
||||
##字符串长度
|
||||
if [ -n "$l_str_maxlen" ] && [ -z "`echo $l_str_maxlen | sed 's/[0-9]//g'`" ];then
|
||||
if [ $len_str -gt $l_str_maxlen ]; then
|
||||
echo "error: The length of $l_str exceed max length $l_str_maxlen."
|
||||
return 1
|
||||
fi
|
||||
fi
|
||||
#不能包含其他字符
|
||||
if [ -n "$l_str_ex" ] && [ -n "`echo $l_str | grep -E [$l_str_ex] 2>/dev/null`" ];then
|
||||
echo "error: string $l_str included characters $l_str_ex."
|
||||
return 1
|
||||
fi
|
||||
##数字和字母开头
|
||||
if [ -z "`echo $l_str | grep -E '^[a-z0-9A-Z]'`" ];then
|
||||
echo "error: string $l_str must start with a character ('0-9' or 'A-Z' or 'a-z')."
|
||||
return 1
|
||||
fi
|
||||
##只能数字和字母 -_
|
||||
if [ -n "`echo $l_str | grep -E '[^a-z0-9A-Z_-]'`" ];then
|
||||
if [ -n "$l_str_ex" ] ;then
|
||||
##这个日志写不好
|
||||
echo "error: string $l_str can only contain characters included by ('0-9', 'a-z', 'A-Z')"
|
||||
else
|
||||
echo "error: string $l_str can only contain characters included by ('0-9', 'a-z', 'A-Z', '-', '_')."
|
||||
fi
|
||||
|
||||
return 1
|
||||
fi
|
||||
|
||||
}
|
||||
|
||||
#########################################################
|
||||
# Description: fn_check_id
|
||||
# Input:
|
||||
# $1:
|
||||
# Return: 0-success,1-failed
|
||||
#########################################################
|
||||
function fn_check_id()
|
||||
{
|
||||
local l_id=$1
|
||||
fn_check_reg_char "$l_id" "20" "-_"
|
||||
if [ $? -ne 0 ];then
|
||||
echo "error: check hotpatch id failed"
|
||||
return 1
|
||||
fi
|
||||
|
||||
G_HOTPATCH_ID=$l_id
|
||||
G_HOTPATCH=${G_PREFIX}_${G_HOTPATCH_ID}.ko
|
||||
G_HOTPATCH_TAR=${G_PREFIX}_${G_HOTPATCH_ID}.tar.gz
|
||||
if [ -f "$G_HOTPATCH_DIR/$G_HOTPATCH_TAR" ];then
|
||||
echo "error: $G_HOTPATCH_DIR/$G_HOTPATCH_TAR is exist, check hotpatch id failed"
|
||||
return 1
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
|
||||
|
||||
#########################################################
|
||||
# Description: fn_check_jobs
|
||||
# Input:
|
||||
# $1:
|
||||
# Return: 0-success,1-failed
|
||||
#########################################################
|
||||
function fn_check_jobs()
|
||||
{
|
||||
local l_jobs=$1
|
||||
if [ -z "`echo "$l_jobs" | grep ^[1-9]`" ] || [ -n "`echo "$l_jobs" | sed 's/[0-9]//g'`" ];then
|
||||
echo "error: the '-j' option requires a positive integral argument"
|
||||
return 1
|
||||
fi
|
||||
G_JOBS=$l_jobs
|
||||
return 0
|
||||
}
|
||||
|
||||
#########################################################
|
||||
# Description: fn_check_patch
|
||||
# Input:
|
||||
# $1:
|
||||
# Return: 0-success,1-failed
|
||||
#########################################################
|
||||
function fn_check_patch(){
|
||||
local l_patch=$1
|
||||
if [ ! -f $1 ];then
|
||||
echo "error:patch file $1 not exit"
|
||||
return 1
|
||||
fi
|
||||
G_PATCHFILE=$l_patch
|
||||
}
|
||||
#########################################################
|
||||
# Description: fn_check_diffext
|
||||
# Input:
|
||||
# $1:
|
||||
# Return: 0-success,1-failed
|
||||
#########################################################
|
||||
function fn_check_diffext()
|
||||
{
|
||||
local l_diffext=$1
|
||||
|
||||
if [ -z "$l_diffext" ];then
|
||||
echo "error: diffext is empty, check diffext failed"
|
||||
return 1
|
||||
fi
|
||||
G_DIFFEXT=$l_diffext
|
||||
return 0
|
||||
}
|
||||
|
||||
|
||||
#########################################################
|
||||
# Description: fn_check_kernelsrc
|
||||
# Input:
|
||||
# $1:
|
||||
# Return: 0-success,1-failed
|
||||
#########################################################
|
||||
function fn_check_kernelsrc()
|
||||
{
|
||||
local l_kernelsrc=$1
|
||||
|
||||
if [ ! -d "$l_kernelsrc" ];then
|
||||
echo "error: kernel src $l_kernelsrc is not exist, check kernel src failed"
|
||||
return 1
|
||||
fi
|
||||
G_KERNEL_SRC=$l_kernelsrc
|
||||
return 0
|
||||
}
|
||||
|
||||
#########################################################
|
||||
# Description: fn_check_modulesrc
|
||||
# Input:
|
||||
# $1:
|
||||
# Return: 0-success,1-failed
|
||||
#########################################################
|
||||
function fn_check_modulesrc()
|
||||
{
|
||||
local l_modulesrc=$1
|
||||
|
||||
if [ ! -d "$l_modulesrc" ];then
|
||||
echo "error: module src $l_modulesrc is not exist, check module src failed"
|
||||
return 1
|
||||
fi
|
||||
echo "$l_modulesrc" | grep -q ^/
|
||||
if [ $? -ne 0 ];then
|
||||
echo "error: module src $l_modulesrc must be absolute path, check module src failed"
|
||||
return 1
|
||||
fi
|
||||
G_MODULE_SRC="$l_modulesrc"
|
||||
return 0
|
||||
}
|
||||
#########################################################
|
||||
# Description: fn_check_makefile
|
||||
# Input:
|
||||
# $1:
|
||||
# Return: 0-success,1-failed
|
||||
#########################################################
|
||||
function fn_check_makefile()
|
||||
{
|
||||
local l_module_makefile=$1
|
||||
|
||||
if [ ! -f "$l_module_makefile" ] && [ "$(basename $l_module_makefile)" = "Makefile" ];then
|
||||
echo "error: module makefile $l_module_makefile is not exist or makefile name is not Makefile, check module makefile failed"
|
||||
return 1
|
||||
fi
|
||||
echo "$l_module_makefile" | grep -q ^/
|
||||
if [ $? -ne 0 ];then
|
||||
echo "error: module makefile $l_module_makefile must be absolute path, check module src failed"
|
||||
return 1
|
||||
fi
|
||||
G_MODULE_MAKEFILE=$l_module_makefile
|
||||
return 0
|
||||
}
|
||||
#########################################################
|
||||
# Description: fn_check_extra_flags
|
||||
# Input:
|
||||
# $1:
|
||||
# Return: 0-success,1-failed
|
||||
#########################################################
|
||||
function fn_check_extra_flags()
|
||||
{
|
||||
local l_extra_flags=$1
|
||||
|
||||
if [ ! -f "$l_extra_flags" ];then
|
||||
echo "error: extra flags file $l_extra_flags is not exist, check extra flags failed"
|
||||
return 1
|
||||
fi
|
||||
G_EXT_FLAGS="`readlink -f ${l_extra_flags}`"
|
||||
cp -a $l_extra_flags $G_KPATCH_FLAGS
|
||||
if [ $? -ne 0 ];then
|
||||
echo "error: copy $l_extra_flags to $G_KPATCH_FLAGS failed"
|
||||
return 1
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
|
||||
#########################################################
|
||||
# Description: verify input param
|
||||
# Input:
|
||||
# $@: input param
|
||||
# Return: 0-success,1-failed
|
||||
#########################################################
|
||||
function fn_verify_input()
|
||||
{
|
||||
local input_param=$@
|
||||
|
||||
if [ $# -lt 1 ]; then
|
||||
echo "error: missing param,please check it"
|
||||
fn_do_clean
|
||||
fn_usage
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ -z "`echo "$input_param" | grep -w "\-i"`" \
|
||||
-a -z "`echo $input_param | grep -w "\-\-id"`" \
|
||||
-a $# -gt 1 ];then
|
||||
echo "error: missing param -i or --id"
|
||||
fn_do_clean
|
||||
fn_usage
|
||||
exit 1
|
||||
fi
|
||||
if [ -z "`echo "$input_param" | grep -w "\-d"`" \
|
||||
-a -z "`echo $input_param | grep -w "\-\-diffext"`" \
|
||||
-a -z "`echo $input_param | grep -w "\-p"`" \
|
||||
-a -z "`echo $input_param | grep -w "\-\-patch"`" \
|
||||
-a $# -gt 1 ];then
|
||||
echo "error: missing param -d,--diffext or -p,--patch"
|
||||
fn_do_clean
|
||||
fn_usage
|
||||
exit 1
|
||||
fi
|
||||
|
||||
while [ $# -ge 1 ]; do
|
||||
case "$1" in
|
||||
-h|--help)
|
||||
fn_usage
|
||||
fn_do_clean
|
||||
exit 0
|
||||
;;
|
||||
-j|--jobs)
|
||||
fn_check_jobs $2
|
||||
if [ $? -eq 0 ]; then
|
||||
shift 2
|
||||
else
|
||||
fn_do_clean
|
||||
fn_usage
|
||||
exit 1
|
||||
fi
|
||||
;;
|
||||
-i|--id)
|
||||
fn_check_id $2
|
||||
if [ $? -eq 0 ]; then
|
||||
shift 2
|
||||
else
|
||||
fn_do_clean
|
||||
fn_usage
|
||||
exit 1
|
||||
fi
|
||||
;;
|
||||
-d|--diffext)
|
||||
fn_check_diffext $2
|
||||
if [ $? -eq 0 ]; then
|
||||
shift 2
|
||||
else
|
||||
fn_do_clean
|
||||
fn_usage
|
||||
exit 1
|
||||
fi
|
||||
;;
|
||||
-p|--patch)
|
||||
fn_check_patch $2
|
||||
if [ $? -eq 0 ]; then
|
||||
shift 2
|
||||
else
|
||||
fn_do_clean
|
||||
fn_usage
|
||||
exit 1
|
||||
fi
|
||||
;;
|
||||
-k|--kernelsrc)
|
||||
fn_check_kernelsrc $2
|
||||
if [ $? -eq 0 ]; then
|
||||
shift 2
|
||||
else
|
||||
fn_do_clean
|
||||
fn_usage
|
||||
exit 1
|
||||
fi
|
||||
;;
|
||||
-m|--modulesrc)
|
||||
fn_check_modulesrc $2
|
||||
if [ $? -eq 0 ]; then
|
||||
shift 2
|
||||
else
|
||||
fn_do_clean
|
||||
fn_usage
|
||||
exit 1
|
||||
fi
|
||||
;;
|
||||
-f|--makefile)
|
||||
fn_check_makefile $2
|
||||
if [ $? -eq 0 ]; then
|
||||
shift 2
|
||||
else
|
||||
fn_do_clean
|
||||
fn_usage
|
||||
exit 1
|
||||
fi
|
||||
;;
|
||||
--extra_flags)
|
||||
fn_check_extra_flags $2
|
||||
if [ $? -eq 0 ]; then
|
||||
shift 2
|
||||
else
|
||||
fn_do_clean
|
||||
fn_usage
|
||||
exit 1
|
||||
fi
|
||||
;;
|
||||
--no_stack_check)
|
||||
export NO_STACK_CHECK="yes"
|
||||
shift 1
|
||||
;;
|
||||
--debug_info)
|
||||
G_DEBUG_INFO="-d"
|
||||
shift 1
|
||||
;;
|
||||
--kallsyms)
|
||||
export KALLSYMS=$(readlink -f $2)
|
||||
if [ $? -eq 0 ]; then
|
||||
shift 2
|
||||
else
|
||||
fn_do_clean
|
||||
fn_usage
|
||||
exit 1
|
||||
fi
|
||||
;;
|
||||
|
||||
*)
|
||||
echo "error: params is invalid,please check it."
|
||||
fn_do_clean
|
||||
fn_usage
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
|
||||
#########################################################
|
||||
# Description: fn_init_module_build
|
||||
# Input:
|
||||
# Return: 0-success,1-failed
|
||||
#########################################################
|
||||
function fn_init_module_build()
|
||||
{
|
||||
local l_modulesrc=$1
|
||||
local l_module_makefile=$2
|
||||
local module=
|
||||
|
||||
module=`basename $l_modulesrc`
|
||||
|
||||
if [ ! -e $G_PRIVATE_MODULE ];then
|
||||
mkdir -p $G_PRIVATE_MODULE
|
||||
fi
|
||||
|
||||
rm -rf $G_PRIVATE_MODULE/*
|
||||
if [ $? -ne 0 ];then
|
||||
echo "error: remove $G_PRIVATE_MODULE/$module or Makefile failed"
|
||||
return 1
|
||||
fi
|
||||
|
||||
#make a new softlink 或改成链接
|
||||
ln -sf $l_modulesrc $G_PRIVATE_MODULE
|
||||
if [ $? -ne 0 ];then
|
||||
echo "error: copy $l_modulesrc to $G_PRIVATE_MODULE failed"
|
||||
return 1
|
||||
fi
|
||||
if [ -z "$l_module_makefile" ];then
|
||||
l_module_makefile=$l_modulesrc/Makefile
|
||||
fi
|
||||
|
||||
echo "${G_KPLICE_PWD_FIELD}=${l_modulesrc}/" >> $G_KPATCH_FLAGS
|
||||
echo "${G_PRIVATE_MODULE_SRC_FIELD}=$(dirname $l_module_makefile)/" >> $G_KPATCH_FLAGS
|
||||
|
||||
fMake=`find ${G_PRIVATE_MODULE}/${module}/ -name Makefile`
|
||||
#if no Makefile found in module dir
|
||||
if [ -z "$fMake" ] && [ ! -f "$l_module_makefile" ];then
|
||||
echo "[ERROR] no Makefilie found in module dir $l_modulesrc"
|
||||
return 1
|
||||
fi
|
||||
#filter CC in module Makefile
|
||||
if [ -n "$fMake" ];then
|
||||
cat $fMake|grep -v '^#'|grep '^[ ,]CC[ ,:,=,?]'
|
||||
if [ $? -eq 0 ];then
|
||||
echo "[WARN] ${module}'s Makefile defined CC,please make sure \"CC:=\$(G_KSPLICECC) \$(CC)\" "
|
||||
fi
|
||||
fi
|
||||
if [ -f "$l_module_makefile" ];then
|
||||
cat $l_module_makefile|grep -v '^#'|grep '^[ ,]CC[ ,:,=,?]'
|
||||
if [ $? -eq 0 ];then
|
||||
echo "[WARN] ${module}'s Makefile defined CC,please make sure \"CC:=\$(G_KSPLICECC) \$(CC)\" "
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
#########################################################
|
||||
# Description: fn_makepatch
|
||||
# Input:
|
||||
# Return: 0-success,1-failed
|
||||
#########################################################
|
||||
function fn_makepatch()
|
||||
{
|
||||
local l_extra_module=
|
||||
local l_jobs=
|
||||
local l_ret=0
|
||||
local existflag=0
|
||||
|
||||
G_PATCH_SRC=`readlink -f $G_KERNEL_SRC`
|
||||
if [ -d "$G_MODULE_SRC" ];then
|
||||
echo "make out of tree module hotpath"
|
||||
G_PATCH_SRC=$G_MODULE_SRC
|
||||
#fn_init_module_build $G_MODULE_SRC $G_MODULE_MAKEFILE
|
||||
#if [ $? -ne 0 ];then
|
||||
# echo "error: init module build failed"
|
||||
# return 1
|
||||
#fi
|
||||
l_extra_module="-m $G_MODULE_SRC"
|
||||
fi
|
||||
|
||||
if [ -n "$G_JOBS" ];then
|
||||
l_jobs="--jobs=$G_JOBS"
|
||||
fi
|
||||
G_TMP_DIR=/tmp/${G_PREFIX}_${G_HOTPATCH_ID}
|
||||
mkdir -p $G_TMP_DIR
|
||||
|
||||
if [ -z "$G_PATCHFILE" ];then
|
||||
#generate src patch file from G_DIFFEXT
|
||||
G_PATCHFILE=$G_TMP_DIR/$G_HOTPATCH_ID.patch
|
||||
rm -rf $G_PATCHFILE
|
||||
cd $G_PATCH_SRC &>/dev/null
|
||||
l_change_file=($(find -L -name "*$G_DIFFEXT" | xargs readlink -f 2>/dev/null| sort | uniq))
|
||||
echo "detect change files:${l_change_file[@]}"
|
||||
for file in ${l_change_file[@]};
|
||||
do
|
||||
file="./${file#$(readlink -f $G_PATCH_SRC)}"
|
||||
orig_file=${file%$G_DIFFEXT}
|
||||
if [ "${orig_file##*.}" == "h" ]; then
|
||||
existflag=1 && break
|
||||
fi
|
||||
diff -u $orig_file $file >> $G_PATCHFILE
|
||||
done
|
||||
cd - &>/dev/null
|
||||
if [ ${existflag} -eq 1 ]; then
|
||||
echo "error: do not modify the header file"
|
||||
return 1
|
||||
fi
|
||||
if [ -f $G_PATCHFILE ];then
|
||||
echo "make patch $G_PATCHFILE"
|
||||
else
|
||||
echo "no change detected"
|
||||
return 1
|
||||
fi
|
||||
else
|
||||
cp $G_PATCHFILE $G_TMP_DIR/${G_HOTPATCH_ID}.patch
|
||||
G_PATCHFILE=$G_TMP_DIR/${G_HOTPATCH_ID}.patch
|
||||
fi
|
||||
|
||||
|
||||
cd $G_TMP_DIR &>/dev/null
|
||||
if [ -n "$G_MODULE_MAKEFILE" ];then
|
||||
USERMODBUILDDIR=$(dirname $G_MODULE_MAKEFILE)
|
||||
fi
|
||||
export USERMODBUILDDIR
|
||||
export USERMODFLAGS=`cat $G_KPATCH_FLAGS`
|
||||
export NO_PROFILING_CALLS=yes
|
||||
kpatch-build -s $G_KERNEL_SRC $l_extra_module -c $G_KERNEL_CONFIG -v $G_VMLINUX --skip-gcc-check -n "${G_PREFIX}_${G_HOTPATCH_ID}" -b /lib/modules/`uname -r`/build $G_DEBUG_INFO $G_PATCHFILE
|
||||
l_ret=$?
|
||||
cd - &>/dev/null
|
||||
if [ $l_ret -eq 0 ] && [ -f "$G_TMP_DIR/$G_HOTPATCH" ];then
|
||||
if grep -q "CONFIG_MODULE_SIG=y" .config ;then
|
||||
echo "kernel compile with CONFIG_MODULE_SIG=y,please sign the patch module"
|
||||
fi
|
||||
cd /tmp &>/dev/null
|
||||
l_env_file=$G_TMP_DIR/toolenv
|
||||
if [ -n "`which rpm 2>/dev/null`" ]; then
|
||||
echo "------------------------------------------------------------------------ " > "${l_env_file}"
|
||||
echo >> "${l_env_file}"
|
||||
echo "The kpatch tool version info and release date:" >> "${l_env_file}"
|
||||
rpm -qi kpatch >> "${l_env_file}"
|
||||
echo >> "${l_env_file}"
|
||||
echo "------------------------------------------------------------------------ " >> "${l_env_file}"
|
||||
else
|
||||
echo "------------------------------------------------------------------------ " >> "${l_env_file}"
|
||||
fi
|
||||
|
||||
echo >> "${l_env_file}"
|
||||
echo "The hotpatch build time:" >> "${l_env_file}"
|
||||
echo "`date '+%Y-%m-%d %H:%M:%S'`" >> "${l_env_file}"
|
||||
echo >> "${l_env_file}"
|
||||
echo "------------------------------------------------------------------------ " >> "${l_env_file}"
|
||||
|
||||
if [ -f "/etc/EulerLinux.conf" ]; then
|
||||
echo >> "${l_env_file}"
|
||||
echo "The euler compile env version info:" >> "${l_env_file}"
|
||||
cat /etc/EulerLinux.conf >> "${l_env_file}"
|
||||
echo >> "${l_env_file}"
|
||||
echo "------------------------------------------------------------------------ " >> "${l_env_file}"
|
||||
fi
|
||||
|
||||
if [ -n "${G_MODULE_SRC}" ]; then
|
||||
echo >> "${l_env_file}"
|
||||
echo "The module hotpatch compile path info:" >> "${l_env_file}"
|
||||
echo "MODULE_SRC=${G_MODULE_SRC}" >> "${l_env_file}"
|
||||
echo "MODULE_MAKEFILE=${G_MODULE_MAKEFILE}" >> "${l_env_file}"
|
||||
echo >> "${l_env_file}"
|
||||
echo "------------------------------------------------------------------------ " >> "${l_env_file}"
|
||||
fi
|
||||
|
||||
if [ -f "${G_EXT_FLAGS}" ]; then
|
||||
echo >> "${l_env_file}"
|
||||
echo "The module hotpatch compile flags info:" >> "${l_env_file}"
|
||||
cat "${G_EXT_FLAGS}" >> "${l_env_file}"
|
||||
echo >> "${l_env_file}"
|
||||
echo "------------------------------------------------------------------------ " >> "${l_env_file}"
|
||||
fi
|
||||
|
||||
if [ -n "${G_DEBUG_INFO}" ]; then
|
||||
echo >> "${l_env_file}"
|
||||
echo "The debug option info:" >> "${l_env_file}"
|
||||
echo "${G_DEBUG_INFO}" >> "${l_env_file}"
|
||||
echo >> "${l_env_file}"
|
||||
echo "------------------------------------------------------------------------ " >> "${l_env_file}"
|
||||
fi
|
||||
|
||||
tar -czf $G_HOTPATCH_TAR ${G_PREFIX}_${G_HOTPATCH_ID}
|
||||
mv ${G_HOTPATCH_TAR} ${G_HOTPATCH_DIR}
|
||||
cd - &>/dev/null
|
||||
if [ $? -ne 0 ];then
|
||||
echo "error: move ${G_HOTPATCH} to ${G_KSPLICE_HOTPATCH} failed"
|
||||
return 1
|
||||
fi
|
||||
else
|
||||
echo "error: invoke kpatch-build shell script to build patch failed"
|
||||
return 1
|
||||
fi
|
||||
|
||||
}
|
||||
#########################################################
|
||||
# Description: main
|
||||
# Input:
|
||||
# Return: 0-success,1-failed
|
||||
#########################################################
|
||||
function fn_main()
|
||||
{
|
||||
local ret=
|
||||
local pid=
|
||||
fn_verify_input $@
|
||||
if [ $? -ne 0 ]; then
|
||||
fn_do_clean
|
||||
return 1
|
||||
fi
|
||||
|
||||
fn_makepatch
|
||||
if [ $? -ne 0 ]; then
|
||||
fn_do_clean
|
||||
return 1
|
||||
fi
|
||||
|
||||
fn_do_clean
|
||||
|
||||
return 0
|
||||
|
||||
}
|
||||
|
||||
function fn_prepare()
|
||||
{
|
||||
kerver=`uname -r`
|
||||
kerver=${kerver%.x86_64}
|
||||
kerver=${kerver%.aarch64}
|
||||
echo kernel version:$kerver
|
||||
if [ ! -L kernel-source ];then
|
||||
if [ -d /arm/arm_kernel ];then
|
||||
ln -s /arm/arm_kernel/linux-$kerver kernel-source
|
||||
else
|
||||
ln -s /usr/src/kernels/linux-$kerver kernel-source
|
||||
cp /lib/modules/`uname -r`/build/Makefile /usr/src/kernels/linux-$kerver
|
||||
fi
|
||||
fi
|
||||
if [ ! -L .config ];then
|
||||
if [ -d /arm/arm_kernel ];then
|
||||
ln -s /arm/arm_kernel/linux-$kerver/.config .config
|
||||
else
|
||||
ln -s /usr/src/kernels/linux-$kerver/.config .config
|
||||
cp /lib/modules/`uname -r`/build/.config /usr/src/kernels/linux-$kerver
|
||||
fi
|
||||
fi
|
||||
rm -rf $G_KPATCH_FLAGS
|
||||
touch $G_KPATCH_FLAGS
|
||||
}
|
||||
|
||||
G_NUM=`pidof -x make_hotpatch | wc -w`
|
||||
if [ $G_NUM -gt 2 ];then
|
||||
echo "[$0]someone is making, please try again later."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
fn_prepare
|
||||
fn_main $@
|
||||
exit $?
|
||||
337
os_hotpatch
Normal file
337
os_hotpatch
Normal file
@ -0,0 +1,337 @@
|
||||
#!/bin/sh
|
||||
# Copyright (C) 2019. Huawei Technologies Co., Ltd. All rights reserved.
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License version 2 and
|
||||
# only version 2 as published by the Free Software Foundation.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
|
||||
SYS_LIVEPATCH=/sys/kernel/livepatch
|
||||
G_TMP_DIR=/tmp/hotpatch.$$
|
||||
G_PATCH_FILE=
|
||||
|
||||
#########################################################
|
||||
# Description: usage
|
||||
# Input:
|
||||
# Return: 0-success
|
||||
#########################################################
|
||||
OS_HP_HELP()
|
||||
{
|
||||
echo "usage: os_hotpatch"
|
||||
echo "-w|--check <filepath> : check hotpatch"
|
||||
echo "-l|--load <filepath> : load hotpatch"
|
||||
echo "-a|--active <patchname> : active hotpatch"
|
||||
echo "-r|--rollback <patchname> : rollback/deactive hotpatch"
|
||||
echo "-d|--delete <patchname> : delete/unload hotpatch"
|
||||
echo "-q|--query <patchname>/all : query hotpatch"
|
||||
echo "-h|--help : show this help information"
|
||||
}
|
||||
|
||||
#########################################################
|
||||
# Description: check hotpatch file before install
|
||||
# Input:
|
||||
# $1: hotpatch file path
|
||||
# Return: 0-success,1-failed
|
||||
#########################################################
|
||||
OS_HP_CHECK()
|
||||
{
|
||||
path=$1
|
||||
if [ ! -f "$path" ]; then
|
||||
echo "The file $path is not exit"
|
||||
exit 1;
|
||||
fi
|
||||
EXTRACT_HP $path
|
||||
if [ $? -ne 0 -o ! -f "$G_PATCH_FILE" ];then
|
||||
echo "The file $path is invalid"
|
||||
CLEAN_UP
|
||||
exit 1;
|
||||
fi
|
||||
CLEAN_UP
|
||||
echo "The file $path is valid"
|
||||
exit 0
|
||||
}
|
||||
|
||||
#########################################################
|
||||
# Description: active a hotpatch
|
||||
# Input:
|
||||
# $1: hotpatch name(klp-xxx.tar.gz)
|
||||
# Return: 0-success,1-failed
|
||||
#########################################################
|
||||
OS_HP_ACTIVE()
|
||||
{
|
||||
file=$1
|
||||
patch_name=`echo ${file%.tar.gz}|tr '-' '_'`
|
||||
patch_install=`lsmod | grep -w $patch_name`
|
||||
|
||||
if [ "$patch_install" == "" ]; then
|
||||
echo "patch $file not load"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
is_active=`cat ${SYS_LIVEPATCH}/${patch_name}/enabled`
|
||||
if [ ${is_active} == 1 ]; then
|
||||
echo "patch already active"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
echo 1 > ${SYS_LIVEPATCH}/${patch_name}/enabled
|
||||
is_active=`cat ${SYS_LIVEPATCH}/${patch_name}/enabled`
|
||||
if [ ${is_active} == 1 ]; then
|
||||
echo "active patch $file success"
|
||||
exit 0
|
||||
else
|
||||
echo "active patch $file fail"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
#########################################################
|
||||
# Description: deactive a hotpatch
|
||||
# Input:
|
||||
# $1: hotpatch name(klp-xxx.tar.gz)
|
||||
# Return: 0-success,1-failed
|
||||
#########################################################
|
||||
OS_HP_DEACTIVE()
|
||||
{
|
||||
file=$1
|
||||
patch_name=`echo ${file%.tar.gz}|tr '-' '_'`
|
||||
patch_install=`lsmod | grep -w $patch_name`
|
||||
|
||||
if [ "$patch_install" == "" ]; then
|
||||
echo "patch $file not load"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
is_active=`cat ${SYS_LIVEPATCH}/${patch_name}/enabled`
|
||||
if [ ${is_active} == 0 ]; then
|
||||
echo "patch $file already deactive"
|
||||
exit 0
|
||||
else
|
||||
echo 0 > ${SYS_LIVEPATCH}/${patch_name}/enabled
|
||||
is_active=`cat ${SYS_LIVEPATCH}/${patch_name}/enabled`
|
||||
if [ ${is_active} != 1 ]; then
|
||||
echo "deactive patch $file success"
|
||||
exit 0
|
||||
else
|
||||
echo "deactive patch $file fail"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
#########################################################
|
||||
# Description: remove a hotpatch
|
||||
# Input:
|
||||
# $1: hotpatch name(klp-xxx.tar.gz)
|
||||
# Return: 0-success,1-failed
|
||||
#########################################################
|
||||
OS_HP_REMOVE()
|
||||
{
|
||||
file=$1
|
||||
patch_name=`echo ${file%.tar.gz}|tr '-' '_'`
|
||||
patch_install=`lsmod | grep -w $patch_name`
|
||||
|
||||
if [ "$patch_install" == "" ]; then
|
||||
echo "patch $file not load"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
is_active=`cat ${SYS_LIVEPATCH}/${patch_name}/enabled`
|
||||
if [ ${is_active} == 0 ]; then
|
||||
rmmod ${patch_name}
|
||||
else
|
||||
echo 0 > ${SYS_LIVEPATCH}/${patch_name}/enabled
|
||||
rmmod ${patch_name}
|
||||
fi
|
||||
|
||||
patch_install=`lsmod | grep -w $patch_name`
|
||||
if [ "$patch_install" == "" ]; then
|
||||
echo "remove patch $file success"
|
||||
exit 0
|
||||
else
|
||||
echo "remove patch $file failed"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
#########################################################
|
||||
# Description: query a hotpatch
|
||||
# Input:
|
||||
# $1: hotpatch name(klp-xxx.tar.gz) or all
|
||||
# Return: 0-success,1-not load,2-deactive,3-active,4-fault
|
||||
#########################################################
|
||||
OS_HP_INQUIRY()
|
||||
{
|
||||
file=$1
|
||||
lret=0
|
||||
if [ "all" == $file ];then
|
||||
cd ${SYS_LIVEPATCH}
|
||||
if [ -z "`ls -d */ 2>/dev/null`" ];then
|
||||
exit 0
|
||||
fi
|
||||
for patch in `ls -d */ 2>/dev/null`
|
||||
do
|
||||
patch_id=${patch%/}
|
||||
patch_id=${patch_id#klp_}
|
||||
echo "Patch Name: ${patch_id}"
|
||||
lstate=`cat /${SYS_LIVEPATCH}/${patch}/enabled 2>/dev/null`
|
||||
if [ -z "$lstate" ];then
|
||||
echo "Patch State: Removing"
|
||||
echo "-----------------------------------------------------------"
|
||||
continue
|
||||
fi
|
||||
if [ $lstate -eq 1 ];then
|
||||
echo "Patch State: Active"
|
||||
else
|
||||
echo "Patch State: Deactive"
|
||||
fi
|
||||
cd ${SYS_LIVEPATCH}/${patch} 2>/dev/null
|
||||
depends=`ls -d */ 2>/dev/null`
|
||||
echo "Changes:"
|
||||
ls -l ${SYS_LIVEPATCH}/${patch}/*/ 2>/dev/null|grep '^d'|awk -F ' ' '{print "\t"$9}'
|
||||
echo "Denpendency: ${depends%/}"
|
||||
echo "-----------------------------------------------------------"
|
||||
done
|
||||
exit 0
|
||||
fi
|
||||
patch=`echo ${file%.tar.gz}|tr '-' '_'`
|
||||
patch_install=`lsmod | grep -w $patch`
|
||||
if [ "$patch_install" == "" ]; then
|
||||
exit 1
|
||||
fi
|
||||
patch_id=${patch%/}
|
||||
patch_id=${patch_id#klp_}
|
||||
echo "Patch Name: ${patch_id}"
|
||||
if [ `cat /${SYS_LIVEPATCH}/${patch}/enabled` -eq 1 ];then
|
||||
echo "Patch State: Active"
|
||||
lret=3
|
||||
else
|
||||
echo "Patch State: Deactive"
|
||||
lret=2
|
||||
fi
|
||||
cd ${SYS_LIVEPATCH}/${patch}
|
||||
depends=`ls -d */ 2>/dev/null`
|
||||
echo "Changes:"
|
||||
ls -l ${SYS_LIVEPATCH}/${patch}/*/ 2>/dev/null|grep '^d'|awk -F ' ' '{print "\t"$9}'
|
||||
echo "Denpendency: ${depends%/}"
|
||||
echo "-----------------------------------------------------------"
|
||||
|
||||
exit $lret
|
||||
}
|
||||
#########################################################
|
||||
# Description: extract hotpatch tar to tmp dir
|
||||
# Input:
|
||||
# $1: hotpatch file path
|
||||
# Return: 0-success,1-failed
|
||||
#########################################################
|
||||
EXTRACT_HP()
|
||||
{
|
||||
mkdir $G_TMP_DIR
|
||||
tar xzf $1 -C $G_TMP_DIR
|
||||
l_ret=$?
|
||||
if [ $l_ret -eq 0 ];then
|
||||
#find the hotpatch module
|
||||
G_PATCH_FILE=$(find $G_TMP_DIR|grep -w "klp.*\.ko")
|
||||
return 0
|
||||
else
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
#########################################################
|
||||
# Description: clean up the tmp dir
|
||||
# Input:
|
||||
# Return: none
|
||||
#########################################################
|
||||
CLEAN_UP()
|
||||
{
|
||||
rm -rf $G_TMP_DIR
|
||||
}
|
||||
#########################################################
|
||||
# Description: install a hotpatch
|
||||
# Input:
|
||||
# $1: hotpatch file path
|
||||
# Return: 0-success,1-failed
|
||||
#########################################################
|
||||
OS_HP_INSTALL()
|
||||
{
|
||||
path=$1
|
||||
|
||||
if [ ! -f "$path" ]; then
|
||||
echo "The file $path is not exit"
|
||||
exit 1;
|
||||
fi
|
||||
EXTRACT_HP $path
|
||||
if [ $? -ne 0 -o ! -f "$G_PATCH_FILE" ];then
|
||||
echo "The file $path is invalid!"
|
||||
CLEAN_UP
|
||||
exit 1;
|
||||
fi
|
||||
patch_name=`echo ${G_PATCH_FILE%.ko}|tr '-' '_'`
|
||||
patch_name=${patch_name##*/}
|
||||
patch_install=`lsmod | grep -w $patch_name`
|
||||
if [ "$patch_install" == "" ]; then
|
||||
echo "insmod $G_PATCH_FILE"
|
||||
insmod $G_PATCH_FILE
|
||||
L_RET=$?
|
||||
if [ 0 -ne ${L_RET} ]; then
|
||||
echo "install patch $path fail"
|
||||
CLEAN_UP
|
||||
return 1
|
||||
else
|
||||
echo "install patch $path success"
|
||||
fi
|
||||
else
|
||||
echo "patch $path already install"
|
||||
fi
|
||||
CLEAN_UP
|
||||
return 0
|
||||
}
|
||||
|
||||
#----------------------------main-------------------------#
|
||||
if [ ! -d ${SYS_LIVEPATCH} ];then
|
||||
echo "this OS does not support kernel livepatch"
|
||||
exit 1
|
||||
fi
|
||||
input_args=`getopt -a -o l:a:r:d:w:q: -l load:,active:,delete:,check:,rollback:,query:,help, -- "$@" 2>&1`
|
||||
eval set -- "${input_args}"
|
||||
while true;
|
||||
do
|
||||
case "$1" in
|
||||
-w|--check)
|
||||
OS_HP_CHECK "$2"
|
||||
exit $?
|
||||
;;
|
||||
-l|--load)
|
||||
OS_HP_INSTALL "$2"
|
||||
exit $?
|
||||
;;
|
||||
-a|--active)
|
||||
OS_HP_ACTIVE "$2"
|
||||
exit $?
|
||||
;;
|
||||
-r|--rollback)
|
||||
OS_HP_DEACTIVE "$2"
|
||||
exit $?
|
||||
;;
|
||||
-d|--delete)
|
||||
OS_HP_REMOVE "$2"
|
||||
exit $?
|
||||
;;
|
||||
-q|--query)
|
||||
OS_HP_INQUIRY "$2"
|
||||
exit $?
|
||||
;;
|
||||
-h|--help)
|
||||
OS_HP_HELP
|
||||
exit 0
|
||||
;;
|
||||
*)
|
||||
OS_HP_HELP
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
done
|
||||
Loading…
x
Reference in New Issue
Block a user