|
|
96f5c7 |
From 17dcebf077d694d594ad073828687c2ef7b4c08e Mon Sep 17 00:00:00 2001
|
|
|
96f5c7 |
From: Song Liu <song@kernel.org>
|
|
|
96f5c7 |
Date: Fri, 14 May 2021 17:32:41 -0700
|
|
|
96f5c7 |
Subject: [PATCH 1/4] kpatch-build: enable klp with replace option by default
|
|
|
96f5c7 |
|
|
|
96f5c7 |
Since 5.1 kernel, klp_patch supports a "replace" option, which does atomic
|
|
|
96f5c7 |
replace of cumulative patches. Enable building such patch by default. If
|
|
|
96f5c7 |
replace behavior is not desired, the user can use -R|--non-replace option
|
|
|
96f5c7 |
to disable it.
|
|
|
96f5c7 |
|
|
|
96f5c7 |
Signed-off-by: Song Liu <song@kernel.org>
|
|
|
96f5c7 |
---
|
|
|
96f5c7 |
kmod/patch/livepatch-patch-hook.c | 15 +++++++++++++++
|
|
|
96f5c7 |
kpatch-build/kpatch-build | 25 ++++++++++++++++++++++++-
|
|
|
96f5c7 |
2 files changed, 39 insertions(+), 1 deletion(-)
|
|
|
96f5c7 |
|
|
|
96f5c7 |
diff --git a/kmod/patch/livepatch-patch-hook.c b/kmod/patch/livepatch-patch-hook.c
|
|
|
96f5c7 |
index e12fd505..120c637a 100644
|
|
|
96f5c7 |
--- a/kmod/patch/livepatch-patch-hook.c
|
|
|
96f5c7 |
+++ b/kmod/patch/livepatch-patch-hook.c
|
|
|
96f5c7 |
@@ -74,6 +74,18 @@
|
|
|
96f5c7 |
# define HAVE_SIMPLE_ENABLE
|
|
|
96f5c7 |
#endif
|
|
|
96f5c7 |
|
|
|
96f5c7 |
+#ifdef RHEL_RELEASE_CODE
|
|
|
96f5c7 |
+# if RHEL_RELEASE_CODE >= RHEL_RELEASE_VERSION(8, 2)
|
|
|
96f5c7 |
+# define HAVE_KLP_REPLACE
|
|
|
96f5c7 |
+# endif
|
|
|
96f5c7 |
+#elif LINUX_VERSION_CODE >= KERNEL_VERSION(5, 1, 0)
|
|
|
96f5c7 |
+# define HAVE_KLP_REPLACE
|
|
|
96f5c7 |
+#endif
|
|
|
96f5c7 |
+
|
|
|
96f5c7 |
+#ifndef KLP_REPLACE_ENABLE
|
|
|
96f5c7 |
+#define KLP_REPLACE_ENABLE true
|
|
|
96f5c7 |
+#endif
|
|
|
96f5c7 |
+
|
|
|
96f5c7 |
/*
|
|
|
96f5c7 |
* There are quite a few similar structures at play in this file:
|
|
|
96f5c7 |
* - livepatch.h structs prefixed with klp_*
|
|
|
96f5c7 |
@@ -385,6 +397,9 @@ static int __init patch_init(void)
|
|
|
96f5c7 |
goto out;
|
|
|
96f5c7 |
lpatch->mod = THIS_MODULE;
|
|
|
96f5c7 |
lpatch->objs = lobjects;
|
|
|
96f5c7 |
+#ifdef HAVE_KLP_REPLACE
|
|
|
96f5c7 |
+ lpatch->replace = KLP_REPLACE_ENABLE;
|
|
|
96f5c7 |
+#endif
|
|
|
96f5c7 |
#if defined(__powerpc64__) && defined(HAVE_IMMEDIATE)
|
|
|
96f5c7 |
lpatch->immediate = true;
|
|
|
96f5c7 |
#endif
|
|
|
96f5c7 |
diff --git a/kpatch-build/kpatch-build b/kpatch-build/kpatch-build
|
|
|
96f5c7 |
index 617f8578..e40f79b2 100755
|
|
|
96f5c7 |
--- a/kpatch-build/kpatch-build
|
|
|
96f5c7 |
+++ b/kpatch-build/kpatch-build
|
|
|
96f5c7 |
@@ -55,6 +55,7 @@ DEBUG_KCFLAGS=""
|
|
|
96f5c7 |
declare -a PATCH_LIST
|
|
|
96f5c7 |
APPLIED_PATCHES=0
|
|
|
96f5c7 |
OOT_MODULE=
|
|
|
96f5c7 |
+KLP_REPLACE=1
|
|
|
96f5c7 |
|
|
|
96f5c7 |
warn() {
|
|
|
96f5c7 |
echo "ERROR: $1" >&2
|
|
|
96f5c7 |
@@ -218,6 +219,15 @@ use_klp_arch()
|
|
|
96f5c7 |
fi
|
|
|
96f5c7 |
}
|
|
|
96f5c7 |
|
|
|
96f5c7 |
+support_klp_replace()
|
|
|
96f5c7 |
+{
|
|
|
96f5c7 |
+ if kernel_is_rhel; then
|
|
|
96f5c7 |
+ rhel_kernel_version_gte 4.18.0-193.el8
|
|
|
96f5c7 |
+ else
|
|
|
96f5c7 |
+ kernel_version_gte 5.1.0
|
|
|
96f5c7 |
+ fi
|
|
|
96f5c7 |
+}
|
|
|
96f5c7 |
+
|
|
|
96f5c7 |
find_dirs() {
|
|
|
96f5c7 |
if [[ -e "$SCRIPTDIR/create-diff-object" ]]; then
|
|
|
96f5c7 |
# git repo
|
|
|
96f5c7 |
@@ -514,12 +524,13 @@ usage() {
|
|
|
96f5c7 |
echo " (can be specified multiple times)" >&2
|
|
|
96f5c7 |
echo " -e, --oot-module Enable patching out-of-tree module," >&2
|
|
|
96f5c7 |
echo " specify current version of module" >&2
|
|
|
96f5c7 |
+ echo " -R, --non-replace Disable replace patch (replace is on by default)" >&2
|
|
|
96f5c7 |
echo " --skip-cleanup Skip post-build cleanup" >&2
|
|
|
96f5c7 |
echo " --skip-compiler-check Skip compiler version matching check" >&2
|
|
|
96f5c7 |
echo " (not recommended)" >&2
|
|
|
96f5c7 |
}
|
|
|
96f5c7 |
|
|
|
96f5c7 |
-options="$(getopt -o ha:r:s:c:v:j:t:n:o:de: -l "help,archversion:,sourcerpm:,sourcedir:,config:,vmlinux:,jobs:,target:,name:,output:,oot-module:,debug,skip-gcc-check,skip-compiler-check,skip-cleanup" -- "$@")" || die "getopt failed"
|
|
|
96f5c7 |
+options="$(getopt -o ha:r:s:c:v:j:t:n:o:de:R -l "help,archversion:,sourcerpm:,sourcedir:,config:,vmlinux:,jobs:,target:,name:,output:,oot-module:,debug,skip-gcc-check,skip-compiler-check,skip-cleanup,non-replace" -- "$@")" || die "getopt failed"
|
|
|
96f5c7 |
|
|
|
96f5c7 |
eval set -- "$options"
|
|
|
96f5c7 |
|
|
|
96f5c7 |
@@ -582,6 +593,9 @@ while [[ $# -gt 0 ]]; do
|
|
|
96f5c7 |
OOT_MODULE="$(readlink -f "$2")"
|
|
|
96f5c7 |
shift
|
|
|
96f5c7 |
;;
|
|
|
96f5c7 |
+ -R|--non-replace)
|
|
|
96f5c7 |
+ KLP_REPLACE=0
|
|
|
96f5c7 |
+ ;;
|
|
|
96f5c7 |
--skip-cleanup)
|
|
|
96f5c7 |
echo "Skipping cleanup"
|
|
|
96f5c7 |
SKIPCLEANUP=1
|
|
|
96f5c7 |
@@ -821,6 +835,12 @@ if grep -q "CONFIG_LIVEPATCH=y" "$CONFIGFILE" && (kernel_is_rhel || kernel_versi
|
|
|
96f5c7 |
KPATCH_LDFLAGS="--unique=.parainstructions --unique=.altinstructions"
|
|
|
96f5c7 |
CDO_FLAGS="--klp-arch"
|
|
|
96f5c7 |
fi
|
|
|
96f5c7 |
+
|
|
|
96f5c7 |
+ if [[ "$KLP_REPLACE" -eq 1 ]] ; then
|
|
|
96f5c7 |
+ support_klp_replace || die "The kernel doesn't support klp replace"
|
|
|
96f5c7 |
+ else
|
|
|
96f5c7 |
+ export KBUILD_CFLAGS_MODULE="$KBUILD_CFLAGS_MODULE -DKLP_REPLACE_ENABLE=false"
|
|
|
96f5c7 |
+ fi
|
|
|
96f5c7 |
else
|
|
|
96f5c7 |
# No support for livepatch in the kernel. Kpatch core module is needed.
|
|
|
96f5c7 |
|
|
|
96f5c7 |
@@ -828,6 +848,9 @@ else
|
|
|
96f5c7 |
# sections. Use with caution!
|
|
|
96f5c7 |
echo "WARNING: Use of kpatch core module (kpatch.ko) is deprecated! There may be bugs!" >&2
|
|
|
96f5c7 |
|
|
|
96f5c7 |
+ if [[ "$KLP_REPLACE" -eq 1 ]] ; then
|
|
|
96f5c7 |
+ die "kpatch core module (kpatch.ko) does not support replace, please add -R|--non-replace"
|
|
|
96f5c7 |
+ fi
|
|
|
96f5c7 |
find_core_symvers || die "unable to find Module.symvers for kpatch core module"
|
|
|
96f5c7 |
KBUILD_EXTRA_SYMBOLS="$SYMVERSFILE"
|
|
|
96f5c7 |
fi
|
|
|
96f5c7 |
|
|
|
96f5c7 |
From 69e69d59e83a98ca3272c5028fa89f7e9196770d Mon Sep 17 00:00:00 2001
|
|
|
96f5c7 |
From: Song Liu <song@kernel.org>
|
|
|
96f5c7 |
Date: Wed, 19 May 2021 15:18:27 -0700
|
|
|
96f5c7 |
Subject: [PATCH 2/4] doc: kpatch-build uses "replace" flag by default
|
|
|
96f5c7 |
|
|
|
96f5c7 |
Add documentation about kpatch-build enables livepatch "replace" flag by
|
|
|
96f5c7 |
default, and provides -R|--non-replace option to disable the flag.
|
|
|
96f5c7 |
|
|
|
96f5c7 |
Signed-off-by: Song Liu <song@kernel.org>
|
|
|
96f5c7 |
---
|
|
|
96f5c7 |
doc/patch-author-guide.md | 7 +++++++
|
|
|
96f5c7 |
1 file changed, 7 insertions(+)
|
|
|
96f5c7 |
|
|
|
96f5c7 |
diff --git a/doc/patch-author-guide.md b/doc/patch-author-guide.md
|
|
|
96f5c7 |
index 33c1b277..f3dcf736 100644
|
|
|
96f5c7 |
--- a/doc/patch-author-guide.md
|
|
|
96f5c7 |
+++ b/doc/patch-author-guide.md
|
|
|
96f5c7 |
@@ -39,6 +39,13 @@ recommended that when patching a system which has already been patched, the
|
|
|
96f5c7 |
second patch should be a cumulative upgrade which is a superset of the first
|
|
|
96f5c7 |
patch.
|
|
|
96f5c7 |
|
|
|
96f5c7 |
+Since upstream kernel 5.1, livepatch supports a "replace" flag to help the
|
|
|
96f5c7 |
+management of cumulative patches. With the flag set, the kernel will load
|
|
|
96f5c7 |
+the cumulative patch and unload all existing patches in one transition.
|
|
|
96f5c7 |
+kpatch-build enables the replace flag by default. If replace behavior is
|
|
|
96f5c7 |
+not desired, the user can disable it with -R|--non-replace.
|
|
|
96f5c7 |
+
|
|
|
96f5c7 |
+
|
|
|
96f5c7 |
Data structure changes
|
|
|
96f5c7 |
----------------------
|
|
|
96f5c7 |
|
|
|
96f5c7 |
|
|
|
96f5c7 |
From 8487a0ca0a5201ca53b33b3a2de5b65320b947c9 Mon Sep 17 00:00:00 2001
|
|
|
96f5c7 |
From: Song Liu <song@kernel.org>
|
|
|
96f5c7 |
Date: Tue, 25 May 2021 15:20:59 -0700
|
|
|
96f5c7 |
Subject: [PATCH 3/4] manpages: update kpatch-build with -R | --non-replace
|
|
|
96f5c7 |
option
|
|
|
96f5c7 |
|
|
|
96f5c7 |
Signed-off-by: Song Liu <song@kernel.org>
|
|
|
96f5c7 |
---
|
|
|
96f5c7 |
man/kpatch-build.1 | 4 ++++
|
|
|
96f5c7 |
1 file changed, 4 insertions(+)
|
|
|
96f5c7 |
|
|
|
96f5c7 |
diff --git a/man/kpatch-build.1 b/man/kpatch-build.1
|
|
|
96f5c7 |
index dfd61acf..4483a4a3 100644
|
|
|
96f5c7 |
--- a/man/kpatch-build.1
|
|
|
96f5c7 |
+++ b/man/kpatch-build.1
|
|
|
96f5c7 |
@@ -51,6 +51,10 @@ effect.
|
|
|
96f5c7 |
Enable patching out-of-tree module,
|
|
|
96f5c7 |
specify current version of module
|
|
|
96f5c7 |
|
|
|
96f5c7 |
+-R|--non-replace
|
|
|
96f5c7 |
+ Disable replace flag of KLP
|
|
|
96f5c7 |
+ (replace is on by default)
|
|
|
96f5c7 |
+
|
|
|
96f5c7 |
--skip-cleanup
|
|
|
96f5c7 |
Skip post-build cleanup
|
|
|
96f5c7 |
|
|
|
96f5c7 |
|
|
|
96f5c7 |
From 4b68be868f40244ff9850bf35f8d273afa12cf12 Mon Sep 17 00:00:00 2001
|
|
|
96f5c7 |
From: Song Liu <song@kernel.org>
|
|
|
96f5c7 |
Date: Mon, 24 May 2021 17:34:24 -0700
|
|
|
96f5c7 |
Subject: [PATCH 4/4] kpatch-test: disable replace flag when the kernel doesn't
|
|
|
96f5c7 |
support it
|
|
|
96f5c7 |
|
|
|
96f5c7 |
For redhat kernel < 4.18.0-193.el8 or non-redhat kernel version < 5.1,
|
|
|
96f5c7 |
add -R to $KPATCHBUILD_OPTS.
|
|
|
96f5c7 |
|
|
|
96f5c7 |
Signed-off-by: Song Liu <song@kernel.org>
|
|
|
96f5c7 |
---
|
|
|
96f5c7 |
test/integration/kpatch-test | 27 +++++++++++++++++++++++++++
|
|
|
96f5c7 |
1 file changed, 27 insertions(+)
|
|
|
96f5c7 |
|
|
|
96f5c7 |
diff --git a/test/integration/kpatch-test b/test/integration/kpatch-test
|
|
|
96f5c7 |
index 4359b463..ca5e7835 100755
|
|
|
96f5c7 |
--- a/test/integration/kpatch-test
|
|
|
96f5c7 |
+++ b/test/integration/kpatch-test
|
|
|
96f5c7 |
@@ -50,6 +50,7 @@ ERROR=0
|
|
|
96f5c7 |
LOG=test.log
|
|
|
96f5c7 |
DYNDEBUG_CONTROL=/sys/kernel/debug/dynamic_debug/control
|
|
|
96f5c7 |
DYNDEBUG_ENABLED=1
|
|
|
96f5c7 |
+ARCHVERSION="$(uname -r)"
|
|
|
96f5c7 |
rm -f ./*.log
|
|
|
96f5c7 |
|
|
|
96f5c7 |
PATCHDIR="${PATCHDIR:-$PWD}"
|
|
|
96f5c7 |
@@ -308,6 +309,27 @@ new_dmesg() {
|
|
|
96f5c7 |
fi
|
|
|
96f5c7 |
}
|
|
|
96f5c7 |
|
|
|
96f5c7 |
+kernel_version_gte() {
|
|
|
96f5c7 |
+ [ "${ARCHVERSION//-*/}" = "$(echo -e "${ARCHVERSION//-*}\\n$1" | sort -rV | head -n1)" ]
|
|
|
96f5c7 |
+}
|
|
|
96f5c7 |
+
|
|
|
96f5c7 |
+support_klp_replace()
|
|
|
96f5c7 |
+{
|
|
|
96f5c7 |
+ if kernel_is_rhel; then
|
|
|
96f5c7 |
+ rhel_kernel_version_gte 4.18.0-193.el8
|
|
|
96f5c7 |
+ else
|
|
|
96f5c7 |
+ kernel_version_gte 5.1.0
|
|
|
96f5c7 |
+ fi
|
|
|
96f5c7 |
+}
|
|
|
96f5c7 |
+
|
|
|
96f5c7 |
+kernel_is_rhel() {
|
|
|
96f5c7 |
+ [[ "$ARCHVERSION" =~ \.el[789] ]]
|
|
|
96f5c7 |
+}
|
|
|
96f5c7 |
+
|
|
|
96f5c7 |
+rhel_kernel_version_gte() {
|
|
|
96f5c7 |
+ [ "${ARCHVERSION}" = "$(echo -e "${ARCHVERSION}\\n$1" | sort -rV | head -n1)" ]
|
|
|
96f5c7 |
+}
|
|
|
96f5c7 |
+
|
|
|
96f5c7 |
# shellcheck disable=SC1091
|
|
|
96f5c7 |
source /etc/os-release
|
|
|
96f5c7 |
if [[ "${ID}" == "rhel" && "${VERSION_ID%%.*}" == "7" && "${VERSION_ID##*.}" -le "6" ]]; then
|
|
|
96f5c7 |
@@ -315,6 +337,11 @@ if [[ "${ID}" == "rhel" && "${VERSION_ID%%.*}" == "7" && "${VERSION_ID##*.}" -le
|
|
|
96f5c7 |
echo "Dynamic debug is not supported on '${PRETTY_NAME}', disabling."
|
|
|
96f5c7 |
fi
|
|
|
96f5c7 |
|
|
|
96f5c7 |
+if ! support_klp_replace ; then
|
|
|
96f5c7 |
+ KPATCHBUILD_OPTS="$KPATCHBUILD_OPTS -R"
|
|
|
96f5c7 |
+ echo "KLP replace is not supported on '${PRETTY_NAME}', disabling."
|
|
|
96f5c7 |
+fi
|
|
|
96f5c7 |
+
|
|
|
96f5c7 |
for file in "${PATCH_LIST[@]}"; do
|
|
|
96f5c7 |
if [[ $QUICK != 1 || "$file" =~ -FAIL ]]; then
|
|
|
96f5c7 |
build_module "$file"
|