From 9846d6873612fdb0639d5e386b6830295f0f6ed6 Mon Sep 17 00:00:00 2001 From: Bin Hu Date: Sat, 30 Oct 2021 15:39:08 +0800 Subject: [PATCH] backport upstream patch to enhance livepatch-patch-hook.c readability Signed-off-by: hubin --- 0035-livepatch-patch-hook-add-comments.patch | 232 +++++++++++++++++++ kpatch.spec | 9 +- 2 files changed, 240 insertions(+), 1 deletion(-) create mode 100644 0035-livepatch-patch-hook-add-comments.patch diff --git a/0035-livepatch-patch-hook-add-comments.patch b/0035-livepatch-patch-hook-add-comments.patch new file mode 100644 index 0000000..6b0ce7e --- /dev/null +++ b/0035-livepatch-patch-hook-add-comments.patch @@ -0,0 +1,232 @@ +From 005bd5ac6878b48ade7402156b2224c1b8c8ff5e Mon Sep 17 00:00:00 2001 +From: Joe Lawrence +Date: Fri, 24 Jul 2020 15:33:28 -0400 +Subject: [PATCH] livepatch-patch-hook: add comments + +Add some commentary to the livepatch-patch-hook file to explain what +it's doing. + +Signed-off-by: Joe Lawrence +--- + kmod/patch/livepatch-patch-hook.c | 106 ++++++++++++++++++++++++++++++ + 1 file changed, 106 insertions(+) + +diff --git a/kmod/patch/livepatch-patch-hook.c b/kmod/patch/livepatch-patch-hook.c +index d3fb1db..17b40b9 100644 +--- a/kmod/patch/livepatch-patch-hook.c ++++ b/kmod/patch/livepatch-patch-hook.c +@@ -92,10 +92,28 @@ + * done, the scaffold structs are no longer needed. + */ + ++/* ++ * lpatch is the kernel data structure that will be created on patch ++ * init, registered with the livepatch API on init, and finally ++ * unregistered when the patch exits. Its struct klp_object *objs ++ * member must be dynamically allocated according to the number of ++ * target objects it will be patching. ++ */ + static struct klp_patch *lpatch; + + static LIST_HEAD(patch_objects); + static int patch_objects_nr; ++ ++/** ++ * struct patch_object - scaffolding structure tracking patch target objects ++ * @list: list of patch_object (threaded onto patch_objects) ++ * @funcs: list of patch_func associated with this object ++ * @relocs: list of patch_reloc associated with this object ++ * @callbacks: kernel struct of object callbacks ++ * @name: patch target object name (NULL for vmlinux) ++ * @funcs_nr: count of kpatch_patch_func added to @funcs ++ * @relocs_nr: count of patch_reloc added to @relocs ++ */ + struct patch_object { + struct list_head list; + struct list_head funcs; +@@ -107,16 +125,36 @@ struct patch_object { + int funcs_nr, relocs_nr; + }; + ++/** ++ * struct patch_func - scaffolding structure for kpatch_patch_func ++ * @list: list of patch_func (threaded onto patch_object.funcs) ++ * @kfunc: array of kpatch_patch_func ++ */ + struct patch_func { + struct list_head list; + struct kpatch_patch_func *kfunc; + }; + ++/** ++ * struct patch_reloc - scaffolding structure for kpatch_patch_dynrela ++ * @list: list of patch_reloc (threaded onto patch_object.relocs) ++ * @kdynrela: array of kpatch_patch_dynrela ++ */ + struct patch_reloc { + struct list_head list; + struct kpatch_patch_dynrela *kdynrela; + }; + ++/** ++ * patch_alloc_new_object() - creates and initializes a new patch_object ++ * @name: target object name ++ * ++ * Return: pointer to new patch_object, NULL on failure. ++ * ++ * Does not check for previously created patch_objects with the same ++ * name. Updates patch_objects_nr and threads new data structure onto ++ * the patch_objects list. ++ */ + static struct patch_object *patch_alloc_new_object(const char *name) + { + struct patch_object *object; +@@ -135,6 +173,16 @@ static struct patch_object *patch_alloc_new_object(const char *name) + return object; + } + ++/** ++ * patch_find_object_by_name() - find or create a patch_object with a ++ * given name ++ * @name: target object name ++ * ++ * Return: pointer to patch_object, NULL on failure. ++ * ++ * Searches the patch_objects list for an already created instance with ++ * @name, otherwise tries to create it via patch_alloc_new_object() ++ */ + static struct patch_object *patch_find_object_by_name(const char *name) + { + struct patch_object *object; +@@ -146,6 +194,17 @@ static struct patch_object *patch_find_object_by_name(const char *name) + return patch_alloc_new_object(name); + } + ++/** ++ * patch_add_func_to_object() - create scaffolding from kpatch_patch_func data ++ * ++ * @kfunc: Individual kpatch_patch_func pointer ++ * ++ * Return: 0 on success, -ENOMEM on failure. ++ * ++ * Builds scaffolding data structures from .kpatch.funcs section's array ++ * of kpatch_patch_func structures. Updates the associated ++ * patch_object's funcs_nr count. ++ */ + static int patch_add_func_to_object(struct kpatch_patch_func *kfunc) + { + struct patch_func *func; +@@ -168,6 +227,17 @@ static int patch_add_func_to_object(struct kpatch_patch_func *kfunc) + } + + #ifndef HAVE_ELF_RELOCS ++/** ++ * patch_add_reloc_to_object() - create scaffolding from kpatch_patch_dynrela data ++ * ++ * @kdynrela: Individual kpatch_patch_dynrela pointer ++ * ++ * Return: 0 on success, -ENOMEM on failure. ++ * ++ * Builds scaffolding data structures from .kpatch.dynrelas section's array ++ * of kpatch_patch_dynrela structures. Updates the associated ++ * patch_object's relocs_nr count. ++ */ + static int patch_add_reloc_to_object(struct kpatch_patch_dynrela *kdynrela) + { + struct patch_reloc *reloc; +@@ -190,6 +260,9 @@ static int patch_add_reloc_to_object(struct kpatch_patch_dynrela *kdynrela) + } + #endif + ++/** ++ * patch_free_scaffold() - tear down the temporary kpatch scaffolding ++ */ + static void patch_free_scaffold(void) { + struct patch_func *func, *safefunc; + struct patch_object *object, *safeobject; +@@ -215,6 +288,9 @@ static void patch_free_scaffold(void) { + } + } + ++/** ++ * patch_free_livepatch() - release the klp_patch and friends ++ */ + static void patch_free_livepatch(struct klp_patch *patch) + { + struct klp_object *object; +@@ -234,6 +310,7 @@ static void patch_free_livepatch(struct klp_patch *patch) + } + } + ++/* Defined by kpatch.lds.S */ + extern struct kpatch_pre_patch_callback __kpatch_callbacks_pre_patch[], __kpatch_callbacks_pre_patch_end[]; + 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[]; +@@ -267,6 +344,14 @@ static int add_kpatch_objects(void) + + + #ifdef HAVE_CALLBACKS ++/** ++ * add_callbacks_to_patch_objects() - create patch_objects that have callbacks ++ * ++ * Return: 0 on success, -ENOMEM or -EINVAL on failure ++ * ++ * Iterates through all kpatch pre/post-(un)patch callback data ++ * structures and creates scaffolding patch_objects for them. ++ */ + static int add_callbacks_to_patch_objects(void) + { + struct kpatch_pre_patch_callback *p_pre_patch_callback; +@@ -356,6 +441,7 @@ static inline int add_callbacks_to_patch_objects(void) + } + #endif /* HAVE_CALLBACKS */ + ++/* Defined by kpatch.lds.S */ + extern struct kpatch_patch_func __kpatch_funcs[], __kpatch_funcs_end[]; + #ifndef HAVE_ELF_RELOCS + extern struct kpatch_patch_dynrela __kpatch_dynrelas[], __kpatch_dynrelas_end[]; +@@ -375,6 +461,12 @@ static int __init patch_init(void) + struct klp_reloc *lrelocs, *lreloc; + #endif + ++ ++ /* ++ * Step 1 - read from output.o, create temporary scaffolding ++ * data-structures ++ */ ++ + /* organize functions and relocs by object in scaffold */ + for (kfunc = __kpatch_funcs; + kfunc != __kpatch_funcs_end; +@@ -404,6 +496,16 @@ static int __init patch_init(void) + /* past this point, only possible return code is -ENOMEM */ + ret = -ENOMEM; + ++ /* ++ * Step 2 - create livepatch klp_patch and friends ++ * ++ * There are two dynamically allocated parts: ++ * ++ * klp_patch ++ * klp_object objs [patch_objects_nr] <= i ++ * klp_func funcs [object->funcs_nr] <= j ++ */ ++ + /* allocate and fill livepatch structures */ + lpatch = kzalloc(sizeof(*lpatch), GFP_KERNEL); + if (!lpatch) +@@ -478,6 +580,10 @@ static int __init patch_init(void) + i++; + } + ++ /* ++ * Step 3 - throw away scaffolding ++ */ ++ + /* + * Once the patch structure that the live patching API expects + * has been built, we can release the scaffold structure. +-- +2.27.0 + + diff --git a/kpatch.spec b/kpatch.spec index 064e6df..6756368 100644 --- a/kpatch.spec +++ b/kpatch.spec @@ -1,7 +1,7 @@ Name: kpatch Epoch: 1 Version: 0.9.1 -Release: 20 +Release: 21 Summary: A Linux dynamic kernel patching infrastructure License: GPLv2 @@ -46,6 +46,7 @@ Patch0031:0031-create-diff-object-fix-segment-fault-when-sec2-rela-.patch Patch0032:0032-create-diff-object-Fix-out-of-range-relocation-error.patch Patch0033:0033-create-diff-object-Fix-out-of-range-relocation-check.patch Patch0034:0034-add-openEuler-build-support.patch +Patch0035:0035-livepatch-patch-hook-add-comments.patch BuildRequires: gcc elfutils-libelf-devel kernel-devel git Requires: bc make gcc patch bison flex openssl-devel @@ -106,6 +107,12 @@ popd %{_mandir}/man1/*.1.gz %changelog +* Sat Oct 30 2021 Bin Hu -1:0.9.1-21 +- Type:enhancement +- ID:NA +- SUG:NA +- DESC:backport upstream patch + * Tue Oct 26 2021 Zhipeng Xie -1:0.9.1-20 - Type:enhancement - ID:NA -- Gitee