diff --git a/0001-Add-__addressable_-to-maybe_discarded_sym.patch b/0001-Add-__addressable_-to-maybe_discarded_sym.patch deleted file mode 100644 index 8e9d4633abcf18b9f88daf1750d9bfccb8822eed..0000000000000000000000000000000000000000 --- a/0001-Add-__addressable_-to-maybe_discarded_sym.patch +++ /dev/null @@ -1,35 +0,0 @@ -From 722d27f6bdd4fa012e08db784bf9bb93bb75be2c Mon Sep 17 00:00:00 2001 -From: Artem Savkov -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 ---- - 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 - diff --git a/9017-support-compile-kpatch-on-aarch64.patch b/0001-support-compile-kpatch-on-aarch64.patch similarity index 56% rename from 9017-support-compile-kpatch-on-aarch64.patch rename to 0001-support-compile-kpatch-on-aarch64.patch index fd80a2f6c5e4dee87f8e05aff1776a04556e5d7b..603b86c97a3e24631d478ca804cd52f8d85ca644 100644 --- a/9017-support-compile-kpatch-on-aarch64.patch +++ b/0001-support-compile-kpatch-on-aarch64.patch @@ -1,15 +1,15 @@ -From 50782f658313574a530f80d2f4b78fe23488c6c2 Mon Sep 17 00:00:00 2001 +From 33c4d7a2a31ca10ce943d7ab0603bd814f4ac530 Mon Sep 17 00:00:00 2001 From: Zhipeng Xie Date: Thu, 20 Dec 2018 04:55:38 +0000 -Subject: [PATCH] support compile kpatch on aarch64 +Subject: [PATCH 01/17] support compile kpatch on aarch64 delete __x86_64__ to support compile kpatch on aarch64. Signed-off-by: Zhipeng Xie --- kpatch-build/Makefile | 3 +++ - kpatch-build/create-diff-object.c | 16 +--------------- - 2 files changed, 4 insertions(+), 15 deletions(-) + kpatch-build/create-diff-object.c | 14 +------------- + 2 files changed, 4 insertions(+), 13 deletions(-) diff --git a/kpatch-build/Makefile b/kpatch-build/Makefile index 232b336..974e0f2 100644 @@ -26,10 +26,10 @@ index 232b336..974e0f2 100644 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 +index c9d2cc6..7b1deb0 100644 --- a/kpatch-build/create-diff-object.c +++ b/kpatch-build/create-diff-object.c -@@ -426,7 +426,6 @@ out: +@@ -470,7 +470,6 @@ out: log_debug("section %s has changed\n", sec->name); } @@ -37,7 +37,7 @@ index 97ae0d4..80a76a9 100644 /* * 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) +@@ -581,7 +580,7 @@ static int kpatch_line_macro_change_only(struct section *sec) return 1; } @@ -46,7 +46,7 @@ index 97ae0d4..80a76a9 100644 #define PPC_INSTR_LEN 4 #define PPC_RA_OFFSET 16 -@@ -603,11 +602,6 @@ static int kpatch_line_macro_change_only(struct section *sec) +@@ -647,11 +646,6 @@ static int kpatch_line_macro_change_only(struct section *sec) return 1; } @@ -56,25 +56,25 @@ index 97ae0d4..80a76a9 100644 - 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) + + static void kpatch_compare_sections(struct list_head *seclist) +@@ -1202,7 +1196,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) + static void rela_insn(const struct section *sec, const 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) +@@ -1226,7 +1219,6 @@ static void rela_insn(const struct section *sec, const struct rela *rela, 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) + static bool is_callback_section(struct section *sec) { + +@@ -1771,7 +1763,6 @@ static int jump_table_group_size(struct kpatch_elf *kelf, int offset) return size; } @@ -82,7 +82,7 @@ index 97ae0d4..80a76a9 100644 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) +@@ -1806,7 +1797,6 @@ static int smp_locks_group_size(struct kpatch_elf *kelf, int offset) { return 4; } @@ -90,28 +90,15 @@ index 97ae0d4..80a76a9 100644 #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, +@@ -1901,7 +1891,6 @@ static struct special_section special_sections[] = { + .name = "__jump_table", + .group_size = jump_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__ - { +@@ -1914,7 +1903,6 @@ static struct special_section special_sections[] = { .name = ".altinstructions", .group_size = altinstructions_group_size, }, @@ -120,5 +107,5 @@ index 97ae0d4..80a76a9 100644 { .name = "__ftr_fixup", -- -2.19.1 +2.18.1 diff --git a/0002-kmod-patch-fix-patch-linking-with-4.20.patch b/0002-kmod-patch-fix-patch-linking-with-4.20.patch deleted file mode 100644 index 4fa997e83cf83fa42fdaf5e56b87943b2c8c3c6e..0000000000000000000000000000000000000000 --- a/0002-kmod-patch-fix-patch-linking-with-4.20.patch +++ /dev/null @@ -1,36 +0,0 @@ -From 17a97b48bcf0d486007b746c48321bab6dedb2d8 Mon Sep 17 00:00:00 2001 -From: Artem Savkov -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 ---- - 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 - diff --git a/9010-kmod-kpatch-build-support-cross-compile-hotpatch-for.patch b/0002-kpatch-build-support-build-patch-for-aarch64.patch similarity index 49% rename from 9010-kmod-kpatch-build-support-cross-compile-hotpatch-for.patch rename to 0002-kpatch-build-support-build-patch-for-aarch64.patch index 8c71670ffb52717a11007803504a985363d1c7c3..033602edfe45a05dd70adf3080bfac57a1c3c042 100644 --- a/9010-kmod-kpatch-build-support-cross-compile-hotpatch-for.patch +++ b/0002-kpatch-build-support-build-patch-for-aarch64.patch @@ -1,66 +1,32 @@ -From be8e5ce9541fc230131be230bd0646c473427895 Mon Sep 17 00:00:00 2001 +From 6dd77e9f5bc044a1f80ad89bb9d7f60756b39755 Mon Sep 17 00:00:00 2001 From: Zhipeng Xie -Date: Fri, 2 Nov 2018 17:25:20 +0000 -Subject: [PATCH 1010/1015] kmod/kpatch-build: support cross compile hotpatch - for aarch64 +Date: Wed, 26 Feb 2020 07:09:50 -0500 +Subject: [PATCH 02/17] kpatch-build: support build patch for aarch64 -use R_AARCH64_ABS64 for aarch64, function_ptr_rela and -kpatch_line_macro_change_only are left to implement later. +use R_AARCH64_ABS64 for aarch64 + +exclude line only change for arm64 by compare mov instruction +except immediate part. + +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. + +support cross compile for aarch64 Signed-off-by: Zhipeng Xie --- - 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(-) + kpatch-build/create-diff-object.c | 216 ++++++++++++++++++++++++---- + kpatch-build/create-kpatch-module.c | 24 +++- + kpatch-build/kpatch-build | 116 ++++++++++++++- + kpatch-build/kpatch-gcc | 4 +- + 4 files changed, 319 insertions(+), 41 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 +index 7b1deb0..58789f1 100644 --- a/kpatch-build/create-diff-object.c +++ b/kpatch-build/create-diff-object.c -@@ -70,6 +70,31 @@ char *childobj; +@@ -76,6 +76,31 @@ enum subsection { enum loglevel loglevel = NORMAL; @@ -92,34 +58,158 @@ index ed96758..b8d3bb4 100644 /******************* * 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) +@@ -647,6 +672,67 @@ static int kpatch_line_macro_change_only(struct section *sec) + return 1; + } + #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) + { +@@ -662,7 +748,16 @@ 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; +@@ -722,6 +817,8 @@ static void kpatch_compare_correlated_symbol(struct symbol *sym) + 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 */ 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 +@@ -1289,22 +1386,22 @@ static void kpatch_replace_sections_syms(struct kpatch_elf *kelf) + continue; + } + +-#ifdef __powerpc64__ + add_off = 0; +-#else +- if (rela->type == R_X86_64_PC32 || +- rela->type == R_X86_64_PLT32) { +- 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; +-#endif ++ if (arch == EM_X86_64) { ++ if (rela->type == R_X86_64_PC32 || ++ rela->type == R_X86_64_PLT32) { ++ 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 */ + + /* + * Attempt to replace references to unbundled sections +@@ -2401,7 +2498,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) + \ + rela->offset = index * sizeof(struct kpatch_arch) + \ offsetof(struct kpatch_arch, sec); -@@ -2302,7 +2329,7 @@ static void kpatch_create_kpatch_arch_section(struct kpatch_elf *kelf, char *obj +@@ -2409,7 +2506,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) + \ + rela->offset = index * sizeof(struct kpatch_arch) + \ offsetof(struct kpatch_arch, objname); -@@ -2500,7 +2527,7 @@ static void kpatch_create_patches_sections(struct kpatch_elf *kelf, +@@ -2607,7 +2704,7 @@ static void kpatch_create_patches_sections(struct kpatch_elf *kelf, */ ALLOC_LINK(rela, &relasec->relas); rela->sym = sym; @@ -128,7 +218,7 @@ index ed96758..b8d3bb4 100644 rela->addend = 0; rela->offset = index * sizeof(*funcs); -@@ -2510,7 +2537,7 @@ static void kpatch_create_patches_sections(struct kpatch_elf *kelf, +@@ -2617,7 +2714,7 @@ static void kpatch_create_patches_sections(struct kpatch_elf *kelf, */ ALLOC_LINK(rela, &relasec->relas); rela->sym = strsym; @@ -137,7 +227,7 @@ index ed96758..b8d3bb4 100644 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, +@@ -2628,7 +2725,7 @@ static void kpatch_create_patches_sections(struct kpatch_elf *kelf, */ ALLOC_LINK(rela, &relasec->relas); rela->sym = strsym; @@ -146,7 +236,19 @@ index ed96758..b8d3bb4 100644 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, +@@ -2686,7 +2783,10 @@ 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) +@@ -2940,7 +3040,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; @@ -155,7 +257,7 @@ index ed96758..b8d3bb4 100644 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, +@@ -2948,7 +3048,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; @@ -164,7 +266,7 @@ index ed96758..b8d3bb4 100644 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, +@@ -2969,7 +3069,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); @@ -173,7 +275,7 @@ index ed96758..b8d3bb4 100644 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, +@@ -2977,7 +3077,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; @@ -182,7 +284,7 @@ index ed96758..b8d3bb4 100644 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, +@@ -2985,7 +3085,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; @@ -191,7 +293,7 @@ index ed96758..b8d3bb4 100644 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 * +@@ -3048,7 +3148,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; @@ -200,26 +302,29 @@ index ed96758..b8d3bb4 100644 rela->addend = objname_offset; rela->offset = callbackp->offset; break; -@@ -3000,6 +3027,7 @@ static void kpatch_create_mcount_sections(struct kpatch_elf *kelf) +@@ -3101,6 +3201,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; + rela->offset = index * sizeof(void*); +@@ -3136,6 +3237,40 @@ static void kpatch_create_mcount_sections(struct kpatch_elf *kelf) + + 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); ++ rela->offset = index * sizeof(void*); + + 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; @@ -246,15 +351,16 @@ index ed96758..b8d3bb4 100644 index++; } -@@ -3168,6 +3227,7 @@ int main(int argc, char *argv[]) +@@ -3334,6 +3469,8 @@ 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; + struct sym_compare_type *base_locals, *sym_comp; ++ char *no_profiling_calls = NULL; ++ char *gcc_add_option = NULL, *mlongcall = NULL; arguments.debug = 0; argp_parse (&argp, argc, argv, 0, NULL, &arguments); -@@ -3188,6 +3248,13 @@ int main(int argc, char *argv[]) +@@ -3354,6 +3491,13 @@ int main(int argc, char *argv[]) kelf_base = kpatch_elf_open(orig_obj); kelf_patched = kpatch_elf_open(patched_obj); @@ -266,16 +372,30 @@ index ed96758..b8d3bb4 100644 + 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_compare_elf_headers(kelf_base->elf, kelf_patched->elf); + kpatch_check_program_headers(kelf_base->elf); +@@ -3392,7 +3536,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); + +@@ -3452,7 +3601,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 (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 { @@ -285,7 +405,7 @@ index ed96758..b8d3bb4 100644 /* * 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 +index 43d6809..6f80831 100644 --- a/kpatch-build/create-kpatch-module.c +++ b/kpatch-build/create-kpatch-module.c @@ -31,6 +31,17 @@ @@ -347,10 +467,83 @@ index 67b16b0..9f1c3b9 100644 /* * Sanity checks: diff --git a/kpatch-build/kpatch-build b/kpatch-build/kpatch-build -index 93a0589..017604c 100755 +index ae0733c..17a5e11 100755 --- a/kpatch-build/kpatch-build +++ b/kpatch-build/kpatch-build -@@ -384,6 +384,27 @@ find_kobj() { +@@ -299,12 +299,72 @@ find_special_section_data_ppc64le() { + return + } + ++find_special_section_data_arm64() { ++ ++ [[ "$CONFIG_JUMP_LABEL" -eq 0 ]] && AWK_OPTIONS="$AWK_OPTIONS -vskip_j=1" ++ ++ # 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 = j = c = f = s = i = r = t = 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} ++ j == 0 && /DW_AT_name.* jump_entry[[:space:]]*$/ {j = 1; next} ++ c == 0 && /DW_AT_name.* klp_func[[:space:]]*$/ {c = 1; next} ++ t == 0 && /DW_AT_name.* klp_object[[:space:]]*$/ {t = 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 } ++ j == 1 && !/DW_AT_byte_size/ { j = 0; next } ++ c == 1 && /DW_TAG_structure_type/ { c = 3; next } ++ t == 1 && /DW_TAG_structure_type/ { t = 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} ++ t == 1 && /DW_AT_name.* relocs[[:space:]]*$/ {r = 2; next} ++ t == 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} ++ j == 1 {printf("export JUMP_STRUCT_SIZE=%d\n", $4); j = 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 && (j == 2 || skip_j) && c == 3 && t == 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" ++ [[ -z "$JUMP_STRUCT_SIZE" && "$CONFIG_JUMP_LABEL" -ne 0 ]] && die "can't find special struct jump_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" + [[ "$CONFIG_JUMP_LABEL" -eq 0 ]] && AWK_OPTIONS="$AWK_OPTIONS -vskip_j=1" +@@ -428,6 +488,29 @@ find_kobj() { done } @@ -363,9 +556,11 @@ index 93a0589..017604c 100755 + 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 ++ if grep "\-mlong-calls" /lib/modules/$ARCHVERSION/build//Makefile > /dev/null; then + export GCC_ADD_OPTION="-fno-section-anchors -mlong-calls" + else + export GCC_ADD_OPTION="-fno-section-anchors" @@ -378,7 +573,7 @@ index 93a0589..017604c 100755 # 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 +@@ -786,13 +869,13 @@ apply_patches remove_patches cp -LR "$DATADIR/patch" "$TEMPDIR" || die @@ -388,49 +583,58 @@ index 93a0589..017604c 100755 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}" + export KCFLAGS="-I$DATADIR/patch -ffunction-sections -fdata-sections \ +- $ARCH_KCFLAGS $DEBUG_KCFLAGS" ++ $ARCH_KCFLAGS $DEBUG_KCFLAGS ${GCC_ADD_OPTION}" echo "Reading special section data" find_special_section_data -@@ -752,9 +773,9 @@ unset KPATCH_GCC_TEMPDIR +@@ -806,7 +889,7 @@ echo "Building original source" + 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 +-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 - sleep 1 -@@ -770,11 +791,11 @@ export KPATCH_GCC_TEMPDIR + echo "Building patched source" + apply_patches +@@ -817,7 +900,7 @@ KPATCH_GCC_SRCDIR="$SRCDIR" + export KPATCH_GCC_SRCDIR # $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 +-CROSS_COMPILE="$TOOLSDIR/kpatch-gcc " \ ++CROSS_COMPILE="$TOOLSDIR/kpatch-gcc $ARCH_COMPILE" \ + KBUILD_MODPOST_WARN=1 \ + make "-j$CPUS" $TARGETS 2>&1 | logger || die + +@@ -950,6 +1033,26 @@ if "$KPATCH_MODULE"; then export KCPPFLAGS="-D__KPATCH_MODULE__" fi -+if grep "hulk" $SRCDIR/Makefile > /dev/null; then -+ export KCPPFLAGS="-D__HULK__ $KCPPFLAGS" ++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 -@@ -919,12 +944,12 @@ fi +@@ -962,12 +1065,12 @@ fi cd "$TEMPDIR/output" || die # $KPATCH_LDFLAGS and result of find used as list, no quotes. # shellcheck disable=SC2086,SC2046 @@ -445,8 +649,8 @@ index 93a0589..017604c 100755 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" \ +@@ -984,6 +1087,7 @@ fi + KPATCH_BUILD="$KPATCH_BUILD" KPATCH_NAME="$MODNAME" \ KBUILD_EXTRA_SYMBOLS="$KBUILD_EXTRA_SYMBOLS" \ KPATCH_LDFLAGS="$KPATCH_LDFLAGS" \ +CROSS_COMPILE="$ARCH_COMPILE" \ @@ -454,27 +658,27 @@ index 93a0589..017604c 100755 if ! "$KPATCH_MODULE"; then diff --git a/kpatch-build/kpatch-gcc b/kpatch-build/kpatch-gcc -index 21f7e2e..be18847 100755 +index 9663290..35d7c1c 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 +-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 +@@ -60,7 +60,7 @@ if [[ "$TOOLCHAINCMD" =~ "gcc" ]] ; then fi shift done -elif [[ "$TOOLCHAINCMD" = "ld" ]] ; then -+elif [[ "$TOOLCHAINCMD" = ${ARCH_COMPILE}ld ]] ; then ++elif [[ "$TOOLCHAINCMD" = "${ARCH_COMPILE}ld" ]] ; then while [ "$#" -gt 0 ]; do if [ "$1" = "-o" ]; then obj="$2" -- -1.7.5.4 +2.18.1 diff --git a/9004-create-diff-object-new-static-var-should-be-included.patch b/0003-create-diff-object-new-static-var-should-be-included.patch similarity index 66% rename from 9004-create-diff-object-new-static-var-should-be-included.patch rename to 0003-create-diff-object-new-static-var-should-be-included.patch index 55e5bb07fe872407efbfdeaaca6dd33e1199fa83..5e5078386c088bb95d23489cf01d38322f39e91a 100644 --- a/9004-create-diff-object-new-static-var-should-be-included.patch +++ b/0003-create-diff-object-new-static-var-should-be-included.patch @@ -1,8 +1,7 @@ -From fc6b9c5b1b3eb5d59186fe35cc90d3c06b07c537 Mon Sep 17 00:00:00 2001 +From 3af07fd0f178a4c6e2ae68207c3fedfd10672e65 Mon Sep 17 00:00:00 2001 From: Zhipeng Xie -Date: Fri, 2 Nov 2018 17:24:36 +0000 -Subject: [PATCH 1004/1015] create-diff-object: new static var should be - included +Date: Tue, 25 Feb 2020 22:44:50 -0500 +Subject: [PATCH 03/17] 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 @@ -15,14 +14,14 @@ cause a problem even the new static variables are in unbundled section. Signed-off-by: Zhou Chengming Signed-off-by: Zhipeng Xie --- - kpatch-build/create-diff-object.c | 15 +++++++++++++++ - 1 files changed, 15 insertions(+), 0 deletions(-) + kpatch-build/create-diff-object.c | 15 +++++++++++++++ + 1 file changed, 15 insertions(+) diff --git a/kpatch-build/create-diff-object.c b/kpatch-build/create-diff-object.c -index d242d01..6e23295 100644 +index 58789f1..93570df 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) +@@ -1689,6 +1689,20 @@ static void kpatch_include_force_elements(struct kpatch_elf *kelf) sym->include = 0; } @@ -32,8 +31,8 @@ index d242d01..6e23295 100644 + + 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); + } + @@ -43,14 +42,14 @@ index d242d01..6e23295 100644 static int kpatch_include_new_globals(struct kpatch_elf *kelf) { struct symbol *sym; -@@ -3211,6 +3225,7 @@ int main(int argc, char *argv[]) +@@ -3554,6 +3568,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_include_new_static_var(kelf_patched); + + kpatch_process_special_sections(kelf_patched); - kpatch_print_changes(kelf_patched); - kpatch_dump_kelf(kelf_patched); -- -1.7.5.4 +2.18.1 diff --git a/0003-kmod-patch-more-linking-fixes.patch b/0003-kmod-patch-more-linking-fixes.patch deleted file mode 100644 index ab4b8bc7779f7ec3f512a1a57a8e6779fbd84cbb..0000000000000000000000000000000000000000 --- a/0003-kmod-patch-more-linking-fixes.patch +++ /dev/null @@ -1,42 +0,0 @@ -From b2f40b03ce1778c7e97586e4111d22d3b28b3330 Mon Sep 17 00:00:00 2001 -From: Artem Savkov -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 ---- - 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 - diff --git a/0004-create-diff-object-allow-changing-subsections.patch b/0004-create-diff-object-allow-changing-subsections.patch deleted file mode 100644 index e573d43b54a99b2889b8d16f3c0eb15865084975..0000000000000000000000000000000000000000 --- a/0004-create-diff-object-allow-changing-subsections.patch +++ /dev/null @@ -1,75 +0,0 @@ -From 942cc3ace7edb7c15f40f931dd6f47a934b9fc77 Mon Sep 17 00:00:00 2001 -From: Artem Savkov -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 - -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 - diff --git a/9005-livepatch-fix-use-THIS-modname-as-the-name-of-ddebug.patch b/0004-livepatch-fix-use-THIS-modname-as-the-name-of-ddebug.patch similarity index 65% rename from 9005-livepatch-fix-use-THIS-modname-as-the-name-of-ddebug.patch rename to 0004-livepatch-fix-use-THIS-modname-as-the-name-of-ddebug.patch index ea84d33efcaf07f8f1f0e3f9aeb13c06e55c8cc7..1a5d168caaf02f420a1385519c4b5a0415467a95 100644 --- a/9005-livepatch-fix-use-THIS-modname-as-the-name-of-ddebug.patch +++ b/0004-livepatch-fix-use-THIS-modname-as-the-name-of-ddebug.patch @@ -1,7 +1,7 @@ -From 858cc1f1ef2565d6ffa539550fc13af7e62863e4 Mon Sep 17 00:00:00 2001 +From c03772c4e29473eae68009c12efc182238d103c7 Mon Sep 17 00:00:00 2001 From: Zhipeng Xie Date: Fri, 2 Nov 2018 17:24:42 +0000 -Subject: [PATCH 1005/1015] livepatch, fix: use THIS modname as the name of +Subject: [PATCH 04/17] 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 @@ -12,21 +12,21 @@ Suggested-by: Li Bin Signed-off-by: Zhou Chengming Signed-off-by: Zhipeng Xie --- - kmod/patch/livepatch-patch-hook.c | 1 + - 1 files changed, 1 insertions(+), 0 deletions(-) + kmod/patch/livepatch-patch-hook.c | 1 + + 1 file changed, 1 insertion(+) diff --git a/kmod/patch/livepatch-patch-hook.c b/kmod/patch/livepatch-patch-hook.c -index e59a377..2c0cadd 100644 +index e12fd50..613d037 100644 --- a/kmod/patch/livepatch-patch-hook.c +++ b/kmod/patch/livepatch-patch-hook.c -@@ -452,6 +452,7 @@ out: +@@ -473,6 +473,7 @@ out: static void __exit patch_exit(void) { -+ pr_debug("make THIS modname first\n"); ++ pr_debug("make THIS modname first\n"); + #ifndef HAVE_SIMPLE_ENABLE WARN_ON(klp_unregister_patch(lpatch)); - } - + #endif -- -1.7.5.4 +2.18.1 diff --git a/9006-create-diff-object-fix-correlate-static-local-variab.patch b/0005-create-diff-object-fix-correlate-static-local-variab.patch similarity index 83% rename from 9006-create-diff-object-fix-correlate-static-local-variab.patch rename to 0005-create-diff-object-fix-correlate-static-local-variab.patch index 83526e1fd4390104e2f0fb0d5e2ead7349cfbf2c..1d8c46a38655b1fe8c4f5009ef29739673334b4d 100644 --- a/9006-create-diff-object-fix-correlate-static-local-variab.patch +++ b/0005-create-diff-object-fix-correlate-static-local-variab.patch @@ -1,7 +1,7 @@ -From 2f95a0fa6214a97f60a0d5ba4dc0cda152d5c7d4 Mon Sep 17 00:00:00 2001 +From 5504f36c6de3abae8a4f7ba11f7a2838ddbc5b58 Mon Sep 17 00:00:00 2001 From: Zhipeng Xie Date: Fri, 2 Nov 2018 17:24:51 +0000 -Subject: [PATCH 1006/1015] create-diff-object: fix correlate static local +Subject: [PATCH 05/17] create-diff-object: fix correlate static local variables for __param section kpatch-build correlate fail when no sections reference @@ -27,14 +27,14 @@ copy_module_from_fd.isra.43+0x53/0x150 Signed-off-by: Zhipeng Xie --- - kpatch-build/create-diff-object.c | 4 ++++ - 1 files changed, 4 insertions(+), 0 deletions(-) + kpatch-build/create-diff-object.c | 4 ++++ + 1 file changed, 4 insertions(+) diff --git a/kpatch-build/create-diff-object.c b/kpatch-build/create-diff-object.c -index 6e23295..bd7dd37 100644 +index 93570df..9f1abc0 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) +@@ -1094,6 +1094,10 @@ static int kpatch_is_normal_static_local(struct symbol *sym) if (is_special_static(sym)) return 0; @@ -46,5 +46,5 @@ index 6e23295..bd7dd37 100644 } -- -1.7.5.4 +2.18.1 diff --git a/9007-create-diff-object-don-t-create-dynamic-reloc-for-sy.patch b/0006-create-diff-object-don-t-create-dynamic-reloc-for-sy.patch similarity index 61% rename from 9007-create-diff-object-don-t-create-dynamic-reloc-for-sy.patch rename to 0006-create-diff-object-don-t-create-dynamic-reloc-for-sy.patch index 298afbc06774a49cc4f3fb6c0e093a48f3d780be..6528070a7cf3e62e98d4d6d622aac6f242e498b5 100644 --- a/9007-create-diff-object-don-t-create-dynamic-reloc-for-sy.patch +++ b/0006-create-diff-object-don-t-create-dynamic-reloc-for-sy.patch @@ -1,7 +1,7 @@ -From 0a92ec9f158340501151bf350050597414affece Mon Sep 17 00:00:00 2001 +From 16aa1e59851c29ce63b18f8ef5c570052c6a95af Mon Sep 17 00:00:00 2001 From: Zhipeng Xie Date: Fri, 2 Nov 2018 17:24:58 +0000 -Subject: [PATCH 1007/1015] create-diff-object: don't create dynamic reloc for +Subject: [PATCH 06/17] 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, @@ -9,23 +9,23 @@ use origin reloc to get right symbol version. Signed-off-by: Zhipeng Xie --- - kpatch-build/create-diff-object.c | 3 +++ - 1 files changed, 3 insertions(+), 0 deletions(-) + kpatch-build/create-diff-object.c | 3 +++ + 1 file changed, 3 insertions(+) diff --git a/kpatch-build/create-diff-object.c b/kpatch-build/create-diff-object.c -index bd7dd37..349e483 100644 +index 9f1abc0..18ed1f7 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, +@@ -3039,6 +3039,9 @@ static void kpatch_create_intermediate_sections(struct kpatch_elf *kelf, if (!strcmp(sym_objname, "vmlinux")) continue; -+ if (!strcmp(sym_objname, pmod_name)) ++ if (!strcmp(sym_objname, objname)) + continue; + external = 1; } } -- -1.7.5.4 +2.18.1 diff --git a/9012-create-diff-object-create-dynamic-relocs-for-changed.patch b/0007-create-diff-object-create-dynamic-relocs-for-changed.patch similarity index 82% rename from 9012-create-diff-object-create-dynamic-relocs-for-changed.patch rename to 0007-create-diff-object-create-dynamic-relocs-for-changed.patch index 7b27cd435fcdc9a45d846766fc077bf34b777647..684967a2777e39febdd76dab1f32c05b0ce2bb62 100644 --- a/9012-create-diff-object-create-dynamic-relocs-for-changed.patch +++ b/0007-create-diff-object-create-dynamic-relocs-for-changed.patch @@ -1,8 +1,8 @@ -From 78a13a6091a0d4b1a45fe8f378892a64dece7202 Mon Sep 17 00:00:00 2001 +From a743990bb6d871fb8cd5ffe6f78ffaa8d5ee7c0a Mon Sep 17 00:00:00 2001 From: Zhipeng Xie 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 +Subject: [PATCH 07/17] 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: @@ -22,14 +22,14 @@ Signed-off-by: Zhou Chengming Signed-off-by: Li Bin Signed-off-by: Zhipeng Xie --- - kpatch-build/create-diff-object.c | 20 ++++++++++++++++---- - 1 files changed, 16 insertions(+), 4 deletions(-) + kpatch-build/create-diff-object.c | 20 ++++++++++++++++---- + 1 file 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 +index 18ed1f7..5cdb97b 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, +@@ -2883,6 +2883,14 @@ static void kpatch_create_intermediate_sections(struct kpatch_elf *kelf, */ if (may_need_dynrela(rela)) toc_rela(rela)->need_dynrela = 1; @@ -44,7 +44,7 @@ index b8d3bb4..4fb27da 100644 } } -@@ -2765,10 +2773,14 @@ static void kpatch_create_intermediate_sections(struct kpatch_elf *kelf, +@@ -2965,10 +2973,14 @@ static void kpatch_create_intermediate_sections(struct kpatch_elf *kelf, /* An unchanged local symbol */ ret = lookup_local_symbol(table, rela->sym->name, &result); @@ -64,5 +64,5 @@ index b8d3bb4..4fb27da 100644 else if (vmlinux) { /* -- -1.7.5.4 +2.18.1 diff --git a/9019-fix-rodata.str-problem.patch b/0008-fix-rodata.str-problem.patch similarity index 67% rename from 9019-fix-rodata.str-problem.patch rename to 0008-fix-rodata.str-problem.patch index f356ed3f16ba49b0352b42ec5c425197dd951725..535dc8edf613b6d2ff8aa397a09c6df7f5627f18 100644 --- a/9019-fix-rodata.str-problem.patch +++ b/0008-fix-rodata.str-problem.patch @@ -1,20 +1,20 @@ -From e617351fafaf7504a531fd00a49994653e59a737 Mon Sep 17 00:00:00 2001 +From b356b59eb0f4c21ae927b036a45e573899a59378 Mon Sep 17 00:00:00 2001 From: Zhiyu Hu Date: Fri, 28 Dec 2018 07:06:38 +0000 -Subject: [PATCH] fix rodata.str problem +Subject: [PATCH 08/17] fix rodata.str problem - fix some rodata.str problem +fix some rodata.str problem - Signed-off-by: Zhiyu Hu +Signed-off-by: Zhiyu Hu --- 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 +index 5cdb97b..643ae3e 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) +@@ -1620,7 +1620,7 @@ static void kpatch_include_standard_elements(struct kpatch_elf *kelf) !strcmp(sec->name, ".toc") || !strcmp(sec->name, ".rodata") || (!strncmp(sec->name, ".rodata.", 8) && @@ -24,5 +24,5 @@ index d2e6aee..f075671 100644 } } -- -1.8.3.1 +2.18.1 diff --git a/0009-livepatch-patch-hook-don-t-active-patch-when-insmod.patch b/0009-livepatch-patch-hook-don-t-active-patch-when-insmod.patch new file mode 100644 index 0000000000000000000000000000000000000000..2c76e8a23766d6f625f2da1c84c9fcd88017d3cf --- /dev/null +++ b/0009-livepatch-patch-hook-don-t-active-patch-when-insmod.patch @@ -0,0 +1,52 @@ +From c14444fc4049048abd445462676576cd8b043ea3 Mon Sep 17 00:00:00 2001 +From: Zhipeng Xie +Date: Tue, 25 Feb 2020 23:40:37 -0500 +Subject: [PATCH 09/17] livepatch-patch-hook: don't active patch when insmod + +Don't active patch after loading the patch when +DISABLE_AFTER_LOAD is set. + +Signed-off-by: Zhipeng Xie +--- + kmod/patch/livepatch-patch-hook.c | 2 ++ + kpatch-build/kpatch-build | 4 ++++ + 2 files changed, 6 insertions(+) + +diff --git a/kmod/patch/livepatch-patch-hook.c b/kmod/patch/livepatch-patch-hook.c +index 613d037..163ae1d 100644 +--- a/kmod/patch/livepatch-patch-hook.c ++++ b/kmod/patch/livepatch-patch-hook.c +@@ -455,6 +455,7 @@ static int __init patch_init(void) + } + #endif + ++#if !defined(DISABLE_AFTER_LOAD) + ret = klp_enable_patch(lpatch); + if (ret) { + #ifndef HAVE_SIMPLE_ENABLE +@@ -463,6 +464,7 @@ static int __init patch_init(void) + patch_free_livepatch(lpatch); + return ret; + } ++#endif + + return 0; + out: +diff --git a/kpatch-build/kpatch-build b/kpatch-build/kpatch-build +index 17a5e11..894f0ab 100755 +--- a/kpatch-build/kpatch-build ++++ b/kpatch-build/kpatch-build +@@ -1053,6 +1053,10 @@ if [[ -n "$KLP_SUPPORT_LOADHOOKS" ]];then + export KCPPFLAGS="-DHAVE_LOADHOOKS $KCPPFLAGS" + fi + ++if [[ -n "$DISABLE_AFTER_LOAD" ]];then ++ export KCPPFLAGS="-DDISABLE_AFTER_LOAD $KCPPFLAGS" ++fi ++ + echo "Building patch module: $MODNAME.ko" + + if [[ -z "$USERSRCDIR" ]] && [[ "$DISTRO" = ubuntu ]]; then +-- +2.18.1 + diff --git a/0010-kpatch-build-enhance-for-out-of-tree-module.patch b/0010-kpatch-build-enhance-for-out-of-tree-module.patch new file mode 100644 index 0000000000000000000000000000000000000000..f1ab2a186311c13af29d6fca6a78ad30435ec56c --- /dev/null +++ b/0010-kpatch-build-enhance-for-out-of-tree-module.patch @@ -0,0 +1,133 @@ +From a8cf8f9bd90e0e7fde437a59715aa21622fad7b6 Mon Sep 17 00:00:00 2001 +From: Zhipeng Xie +Date: Wed, 26 Feb 2020 06:44:06 -0500 +Subject: [PATCH 10/17] kpatch-build: enhance for out of tree module + +support set USERMODBUILDDIR to build patch for out +of tree module. + +Signed-off-by: Zhipeng Xie +--- + kpatch-build/kpatch-build | 50 ++++++++++++++++++++++++++++++++------- + 1 file changed, 42 insertions(+), 8 deletions(-) + +diff --git a/kpatch-build/kpatch-build b/kpatch-build/kpatch-build +index 894f0ab..4e38412 100755 +--- a/kpatch-build/kpatch-build ++++ b/kpatch-build/kpatch-build +@@ -419,7 +419,11 @@ filter_parent_obj() + local dir="${1}" + local file="${2}" + +- grep -v "\.mod\.cmd$" | grep -Fv "${dir}/.${file}.cmd" ++ grep -v "\.mod\.cmd$" | grep -Fv "${dir}/.${file}.cmd" | while read input; do ++ if [ "$(readlink -f $input)" != "$(readlink -f ${dir}/.${file}.cmd)" ];then ++ echo $input; ++ fi ++ done + } + + find_parent_obj() { +@@ -441,6 +445,11 @@ find_parent_obj() { + num="$(find . -name ".*.cmd" -print0 | xargs -0 grep -lw "$grepname" | filter_parent_obj "${pdir}" "${file}" | wc -l)" + [[ "$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 -lw "$grepname" "$dir"/.*.cmd | filter_parent_obj "${dir}" "${file}" | head -n1)" + num="$(grep -lw "$grepname" "$dir"/.*.cmd | filter_parent_obj "${dir}" "${file}" | wc -l)" +@@ -646,6 +655,10 @@ if [[ -n "$SRCRPM" ]]; then + ARCHVERSION="${ARCHVERSION#alt-}" + fi + ++if [[ -n "$USERMODBUILDDIR" ]]; then ++ OOT_MODULE="yes" ++fi ++ + if [[ -n "$OOT_MODULE" ]] && [[ -z "$USERSRCDIR" ]]; then + warn "--oot-module requires --sourcedir" + exit 1 +@@ -663,7 +676,7 @@ if [[ -n "$USERSRCDIR" ]]; then + fi + SRCDIR="$USERSRCDIR" + +- if [[ -z "$OOT_MODULE" ]]; then ++ if [[ -z "$OOT_MODULE" || "$OOT_MODULE" == "yes" ]]; then + [[ -z "$VMLINUX" ]] && VMLINUX="$SRCDIR"/vmlinux + [[ ! -e "$VMLINUX" ]] && die "can't find vmlinux" + +@@ -685,7 +698,7 @@ if [[ "$ARCHVERSION" =~ - ]]; then + fi + [[ "$ARCHVERSION" =~ .el7a. ]] && ALT="-alt" + +-[[ -z "$TARGETS" ]] && TARGETS="vmlinux modules" ++[[ -z "$OOT_MODULE" ]] && [[ -z "$TARGETS" ]] && TARGETS="vmlinux modules" + + # Don't check external file. + # shellcheck disable=SC1090 +@@ -889,7 +902,11 @@ echo "Building original source" + unset KPATCH_GCC_TEMPDIR + # $TARGETS used as list, no quotes. + # shellcheck disable=SC2086 +-CROSS_COMPILE="$TOOLSDIR/kpatch-gcc $ARCH_COMPILE" make "-j$CPUS" $TARGETS 2>&1 | logger || die ++if [[ -z "$USERMODBUILDDIR" ]]; then ++ CROSS_COMPILE="$TOOLSDIR/kpatch-gcc $ARCH_COMPILE" make "-j$CPUS" $TARGETS 2>&1 | logger || die ++else ++ CROSS_COMPILE="$TOOLSDIR/kpatch-gcc $ARCH_COMPILE" make -C "$USERMODBUILDDIR" M="$USERMODBUILDDIR" "-j$CPUS" $USERMODFLAGS $TARGETS 2>&1 | logger || die ++fi + + echo "Building patched source" + apply_patches +@@ -900,9 +917,15 @@ KPATCH_GCC_SRCDIR="$SRCDIR" + export KPATCH_GCC_SRCDIR + # $TARGETS used as list, no quotes. + # shellcheck disable=SC2086 +-CROSS_COMPILE="$TOOLSDIR/kpatch-gcc $ARCH_COMPILE" \ +- KBUILD_MODPOST_WARN=1 \ +- make "-j$CPUS" $TARGETS 2>&1 | logger || die ++if [[ -z "$USERMODBUILDDIR" ]]; then ++ 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 $ARCH_COMPILE" \ ++ 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/" \ +@@ -922,7 +945,11 @@ fi + 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 "$USERMODBUILDDIR" ];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" +@@ -987,6 +1014,13 @@ for i in $FILES; do + KOBJFILE_PATH="${TEMPDIR}/module/$KOBJFILE" + SYMTAB="${KOBJFILE_PATH}.symtab" + SYMVERS_FILE="$SRCDIR/Module.symvers" ++ ++ if [ "$OOT_MODULE" == "yes" ];then ++ BUILDDIR="/lib/modules/$ARCHVERSION/build/" ++ SYMVERS_FILE="$TEMPDIR/Module.symvers" ++ [[ -e $SRCDIR/Module.symvers ]] && cp "$SRCDIR/Module.symvers" "$SYMVERS_FILE" ++ awk '{ print $1 "\t" $2 "\t" $3 "\t" $4}' "${BUILDDIR}/Module.symvers" >> "$SYMVERS_FILE" ++ fi + fi + + readelf -s --wide "$KOBJFILE_PATH" > "$SYMTAB" +-- +2.18.1 + diff --git a/0011-support-c-plus-kernel-module.patch b/0011-support-c-plus-kernel-module.patch new file mode 100644 index 0000000000000000000000000000000000000000..7b4106c36e3c6d1d9efe38dbb380ac8862953231 --- /dev/null +++ b/0011-support-c-plus-kernel-module.patch @@ -0,0 +1,193 @@ +From 20de56a8393e6be3b556156124aa4b2139b10733 Mon Sep 17 00:00:00 2001 +From: Zhipeng Xie +Date: Wed, 26 Feb 2020 07:36:59 -0500 +Subject: [PATCH 11/17] support c plus kernel module + +support GNU_UNIQUE type symbols. +support .group section corelation. +ignore compile warning for third party modules. + +Signed-off-by: Zhipeng Xie +--- + kpatch-build/create-diff-object.c | 62 ++++++++++++++++++++----------- + kpatch-build/kpatch-build | 2 +- + kpatch-build/kpatch-elf.c | 8 +++- + kpatch-build/kpatch-gcc | 3 +- + kpatch-build/lookup.c | 5 ++- + 5 files changed, 55 insertions(+), 25 deletions(-) + +diff --git a/kpatch-build/create-diff-object.c b/kpatch-build/create-diff-object.c +index 643ae3e..190753a 100644 +--- a/kpatch-build/create-diff-object.c ++++ b/kpatch-build/create-diff-object.c +@@ -454,7 +454,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 +@@ -470,7 +470,7 @@ static void kpatch_compare_correlated_section(struct section *sec) + sec1->sh.sh_flags != sec2->sh.sh_flags || + sec1->sh.sh_entsize != sec2->sh.sh_entsize || + (sec1->sh.sh_addralign != sec2->sh.sh_addralign && +- !is_text_section(sec1))) ++ !is_text_section(sec1) && strcmp(sec1->name, ".rodata"))) + DIFF_FATAL("%s section header details differ from %s", sec1->name, sec2->name); + + /* Short circuit for mcount sections, we rebuild regardless */ +@@ -907,6 +907,33 @@ static void kpatch_correlate_section(struct section *sec1, struct section *sec2) + kpatch_correlate_symbol(sec1->sym, sec2->sym); + } + ++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; +@@ -924,15 +951,19 @@ 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; + } + +@@ -1507,17 +1538,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) +diff --git a/kpatch-build/kpatch-build b/kpatch-build/kpatch-build +index 4e38412..4896136 100755 +--- a/kpatch-build/kpatch-build ++++ b/kpatch-build/kpatch-build +@@ -1157,7 +1157,7 @@ fi + # column containing lines unique to first file. + UNDEFINED=$(comm -23 <(sort -u "${TEMPDIR}"/undefined_references) \ + <(sort -u "${TEMPDIR}"/new_symbols) | tr '\n' ' ') +-[[ -n "$UNDEFINED" ]] && die "Undefined symbols: $UNDEFINED" ++[[ -z "$USERMODBUILDDIR" ]] && [[ -n "$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 1c0e099..debf028 100644 +--- a/kpatch-build/kpatch-elf.c ++++ b/kpatch-build/kpatch-elf.c +@@ -708,8 +708,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 35d7c1c..6ad6ebc 100755 +--- a/kpatch-build/kpatch-gcc ++++ b/kpatch-build/kpatch-gcc +@@ -13,7 +13,8 @@ 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 8387e8b..4e2fcb9 100644 +--- a/kpatch-build/lookup.c ++++ b/kpatch-build/lookup.c +@@ -255,6 +255,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, "UNIQUE")) { ++ table->obj_syms[i].bind = STB_GNU_UNIQUE; + } else { + ERROR("unknown symbol bind %s", bind); + } +@@ -431,7 +433,8 @@ int lookup_global_symbol(struct lookup_table *table, char *name, + + memset(result, 0, sizeof(*result)); + for_each_obj_symbol(i, sym, table) { +- if ((sym->bind == STB_GLOBAL || sym->bind == STB_WEAK) && ++ 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; +-- +2.18.1 + diff --git a/9013-kmod-kpatch-build-fix-duplicate-symbol-relocation-fo.patch b/0012-symbol-lookup-enhancement.patch similarity index 37% rename from 9013-kmod-kpatch-build-fix-duplicate-symbol-relocation-fo.patch rename to 0012-symbol-lookup-enhancement.patch index 4e2f5b22ca956545443e9313a8921d1d3438fe34..c8aa13eba3e6a335a548e220fca0daff0c6a53d1 100644 --- a/9013-kmod-kpatch-build-fix-duplicate-symbol-relocation-fo.patch +++ b/0012-symbol-lookup-enhancement.patch @@ -1,26 +1,28 @@ -From 1eaabfe01cfae870abd45bfa470caa144f34e74c Mon Sep 17 00:00:00 2001 +From 56ec8b76667fb6c7fbc018a8fe7a77f144232f3f Mon Sep 17 00:00:00 2001 From: Zhipeng Xie -Date: Fri, 2 Nov 2018 17:25:45 +0000 -Subject: [PATCH 1013/1015] kmod/kpatch-build: fix duplicate symbol relocation - for hulk kernel +Date: Wed, 26 Feb 2020 22:03:55 -0500 +Subject: [PATCH 12/17] symbol lookup enhancement -hulk kernel fix it by find a uniq symbol(ref_name) and -use ref_offset to find the duplicate symbol +For symbols which have same name in one module or have +length longger than KSYM_NAME_LEN(128 bytes). we add +some work around to lookup another unique symbol and add +relative offset to get the actual symbol. This patch +depend on a kernel patch to deal with new relocation +style. Signed-off-by: Zhipeng Xie --- - 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(-) + kmod/patch/kpatch-patch.h | 4 + + kpatch-build/create-diff-object.c | 46 ++++++++++- + kpatch-build/create-klp-module.c | 25 +++++- + kpatch-build/kpatch-build | 12 +++ + kpatch-build/kpatch-intermediate.h | 2 + + kpatch-build/lookup.c | 123 ++++++++++++++++++++++++++++- + kpatch-build/lookup.h | 13 +++ + 7 files changed, 217 insertions(+), 8 deletions(-) diff --git a/kmod/patch/kpatch-patch.h b/kmod/patch/kpatch-patch.h -index 4d47d30..2eacb37 100644 +index 917ea32..7cd6dae 100644 --- a/kmod/patch/kpatch-patch.h +++ b/kmod/patch/kpatch-patch.h @@ -30,6 +30,8 @@ struct kpatch_patch_func { @@ -41,65 +43,49 @@ index 4d47d30..2eacb37 100644 }; 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 +index 190753a..55db18c 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, +@@ -2734,6 +2734,28 @@ 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_is_duplicate_symbol(table, sym->name, objname, result.pos)) { ++ struct lookup_refsym refsym; ++ long offset; + -+ if (lookup_ref_symbol(table, sym->name, &refsym)) -+ ERROR("unresolvable ambiguity on symbol %s\n", sym->name); ++ 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; ++ 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; ++ /* ++ * 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); ++ 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, +@@ -2753,7 +2775,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); + +@@ -2872,6 +2894,7 @@ static void kpatch_create_intermediate_sections(struct kpatch_elf *kelf, struct lookup_result result; char *sym_objname; int ret, vmlinux, external; @@ -107,7 +93,7 @@ index 4fb27da..e72f6dd 100644 vmlinux = !strcmp(objname, "vmlinux"); -@@ -2860,12 +2884,29 @@ static void kpatch_create_intermediate_sections(struct kpatch_elf *kelf, +@@ -3080,12 +3103,28 @@ 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); @@ -119,13 +105,12 @@ index 4fb27da..e72f6dd 100644 + 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; @@ -138,7 +123,16 @@ index 4fb27da..e72f6dd 100644 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, +@@ -3094,7 +3133,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); + +@@ -3113,6 +3152,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; @@ -146,70 +140,94 @@ index 4fb27da..e72f6dd 100644 /* 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; +diff --git a/kpatch-build/create-klp-module.c b/kpatch-build/create-klp-module.c +index d995525..5073a04 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; +@@ -67,9 +69,14 @@ static struct symbol *find_or_add_ksym_to_symbols(struct kpatch_elf *kelf, + + objname = strings + rela->addend; + +- 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) { +@@ -176,6 +183,7 @@ static void create_klp_relasecs_and_syms(struct kpatch_elf *kelf, struct section 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; + char *objname; + int nr, index, offset, dest_off; ++ char *ref_name; - 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); -+ + nr = krelasec->data->d_size / sizeof(*krelas); +@@ -200,6 +208,15 @@ static void create_klp_relasecs_and_syms(struct kpatch_elf *kelf, struct section + + objname = strings + rela->addend; + ++ /* 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 = strings + rela->addend; + } ++ + /* Get the .kpatch.symbol entry for the rela src */ + rela = find_rela_by_offset(krelasec->rela, + offset + offsetof(struct kpatch_relocation, ksym)); +@@ -207,7 +224,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"); - /* dest */ - ALLOC_LINK(rela, &dynsec->rela->relas); diff --git a/kpatch-build/kpatch-build b/kpatch-build/kpatch-build -index 9c40612..80b9607 100755 +index 4896136..8bef7fb 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" +@@ -1015,6 +1015,18 @@ for i in $FILES; do SYMTAB="${KOBJFILE_PATH}.symtab" + SYMVERS_FILE="$SRCDIR/Module.symvers" + + unset KCFLAGS + remove_patches -+ if [ -z "$USERMODDIR" ];then -+ cd "$SRCDIR" || die ++ cd "$SRCDIR" || die ++ if [ -z "$USERMODBUILDDIR" ];then + 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" ++ + if [ "$OOT_MODULE" == "yes" ];then + BUILDDIR="/lib/modules/$ARCHVERSION/build/" + SYMVERS_FILE="$TEMPDIR/Module.symvers" diff --git a/kpatch-build/kpatch-intermediate.h b/kpatch-build/kpatch-intermediate.h index 3dea775..59deed0 100644 --- a/kpatch-build/kpatch-intermediate.h @@ -224,7 +242,7 @@ index 3dea775..59deed0 100644 struct kpatch_arch { diff --git a/kpatch-build/lookup.c b/kpatch-build/lookup.c -index d08c10b..e4677db 100644 +index 4e2fcb9..190a7d8 100644 --- a/kpatch-build/lookup.c +++ b/kpatch-build/lookup.c @@ -44,6 +44,7 @@ struct object_symbol { @@ -235,34 +253,87 @@ index d08c10b..e4677db 100644 }; struct export_symbol { -@@ -229,6 +230,7 @@ static void symtab_read(struct lookup_table *table, char *path) +@@ -248,6 +249,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].size = strtoul(size, NULL, 0); + 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; +@@ -398,6 +400,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++; ++ } - return NULL; -- } -+} + if (table->local_syms == sym) { + in_file = 1; +@@ -429,16 +440,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) { ++ /* 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++; + -+int lookup_is_duplicate_symbol(struct lookup_table *table, char *name) + 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; + } + } +@@ -485,6 +505,107 @@ char *lookup_exported_symbol_objname(struct lookup_table *table, char *name) + return NULL; + } + ++int lookup_is_duplicate_symbol(struct lookup_table *table, char *name, ++ char *objname, unsigned long pos) +{ -+ struct object_symbol *sym; -+ int i, count = 0; ++ 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)) { ++ count++; ++ if (count > 1) ++ return 1; ++ } + -+ for_each_obj_symbol(i, sym, table) -+ if (!strcmp(sym->name, name)) { -+ count++; -+ if (count > 1) -+ 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; ++ return 0; +} + +struct object_symbol *lookup_find_symbol_by_name(struct lookup_table *table, char *name) @@ -308,38 +379,54 @@ index d08c10b..e4677db 100644 + 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; ++ struct object_symbol *orig_sym, *sym; ++ int i; ++ ++ orig_sym = lookup_find_symbol_by_name(table, name); ++ if (!orig_sym) ++ ERROR("lookup_ref_symbol_offset"); ++ memset(refsym, 0, sizeof(*refsym)); + -+ 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; ++ /*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 || ++ strchr(sym->name, '.')) ++ continue; + -+ if (!lookup_is_duplicate_symbol(table, sym->name)) { -+ refsym->name = sym->name; -+ refsym->value = sym->value; -+ return 0; -+ } -+ } ++ 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; ++ } ++ } + -+ return 1; ++ 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 +index 420d0f0..fed3fe9 100644 --- a/kpatch-build/lookup.h +++ b/kpatch-build/lookup.h -@@ -14,6 +14,11 @@ struct sym_compare_type { +@@ -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 { +@@ -14,6 +17,11 @@ struct sym_compare_type { int type; }; @@ -351,15 +438,17 @@ index 420d0f0..5ad9241 100644 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, +@@ -23,5 +31,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 +2.18.1 diff --git a/0013-Add-running-kernel-symbol-table-to-help-symbol-looku.patch b/0013-Add-running-kernel-symbol-table-to-help-symbol-looku.patch new file mode 100644 index 0000000000000000000000000000000000000000..6a47a34a515e192fd075394b184cbd6d4fc204fa --- /dev/null +++ b/0013-Add-running-kernel-symbol-table-to-help-symbol-looku.patch @@ -0,0 +1,171 @@ +From 05051ffc7abcb953fb1ec51b0826b41f160ce191 Mon Sep 17 00:00:00 2001 +From: Zhipeng Xie +Date: Wed, 26 Feb 2020 20:28:13 -0500 +Subject: [PATCH 13/17] Add running kernel symbol table to help symbol lookup + +For some duplicate symbols whose section have no other +symbols, we need running kernel symbol table to help +symbol lookup. + +Signed-off-by: Zhipeng Xie +--- + kpatch-build/create-diff-object.c | 7 ++- + kpatch-build/lookup.c | 73 ++++++++++++++++++++++++++++++- + kpatch-build/lookup.h | 3 +- + 3 files changed, 80 insertions(+), 3 deletions(-) + +diff --git a/kpatch-build/create-diff-object.c b/kpatch-build/create-diff-object.c +index 55db18c..4589ba4 100644 +--- a/kpatch-build/create-diff-object.c ++++ b/kpatch-build/create-diff-object.c +@@ -3564,6 +3564,7 @@ int main(int argc, char *argv[]) + struct sym_compare_type *base_locals, *sym_comp; + char *no_profiling_calls = NULL; + char *gcc_add_option = NULL, *mlongcall = NULL; ++ char *kallsyms; + + arguments.debug = 0; + argp_parse (&argp, argc, argv, 0, NULL, &arguments); +@@ -3677,8 +3678,12 @@ int main(int argc, char *argv[]) + */ + kpatch_elf_teardown(kelf_patched); + ++ kallsyms = getenv("KALLSYMS"); ++ if (kallsyms) ++ log_debug("kallsyms file:%s\n", kallsyms); ++ + /* create symbol lookup table */ +- lookup = lookup_open(parent_symtab, mod_symvers, hint, base_locals); ++ lookup = lookup_open(parent_symtab, mod_symvers, hint, base_locals, kallsyms); + for (sym_comp = base_locals; sym_comp && sym_comp->name; sym_comp++) { + free(sym_comp->name); + } +diff --git a/kpatch-build/lookup.c b/kpatch-build/lookup.c +index 190a7d8..8f53567 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 { +@@ -284,6 +285,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); ++} ++ + /* + * Symvers file format is the following for kernels v5.3 and newer: + * +@@ -352,7 +403,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; + +@@ -363,6 +415,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; +@@ -603,6 +657,23 @@ int lookup_ref_symbol_offset(struct lookup_table *table, char *name, + } + } + ++ 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 || strchr(sym->name, '.')) ++ 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; ++ } ++ } ++ + return 1; + } + +diff --git a/kpatch-build/lookup.h b/kpatch-build/lookup.h +index fed3fe9..00b6ccc 100644 +--- a/kpatch-build/lookup.h ++++ b/kpatch-build/lookup.h +@@ -23,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); +-- +2.18.1 + diff --git a/9008-livepatch-patch-hook-support-force-enable-disable-fu.patch b/0014-livepatch-patch-hook-support-force-enable-disable.patch similarity index 50% rename from 9008-livepatch-patch-hook-support-force-enable-disable-fu.patch rename to 0014-livepatch-patch-hook-support-force-enable-disable.patch index 33a47a025bad7e4cc9284dc330311260702acfe2..e277e9e0b05e535639521beaf4e29b0aa2cab3c4 100644 --- a/9008-livepatch-patch-hook-support-force-enable-disable-fu.patch +++ b/0014-livepatch-patch-hook-support-force-enable-disable.patch @@ -1,21 +1,21 @@ -From aaaec2d292b7e1d07c35e07ba92917ee05a4a141 Mon Sep 17 00:00:00 2001 +From b63c72375420cb098a81167c48d822d596e770a9 Mon Sep 17 00:00:00 2001 From: Zhipeng Xie -Date: Fri, 2 Nov 2018 17:25:03 +0000 -Subject: [PATCH 1008/1015] livepatch-patch-hook: support force enable/disable - function +Date: Wed, 26 Feb 2020 20:43:34 -0500 +Subject: [PATCH 14/17] livepatch-patch-hook: support force enable/disable -we use immediate to indicate patch which bypass stack check. +we use force to indicate function which bypass stack check Signed-off-by: Zhipeng Xie --- - kmod/patch/livepatch-patch-hook.c | 11 +++++++++++ - 1 files changed, 11 insertions(+), 0 deletions(-) + kmod/patch/livepatch-patch-hook.c | 18 ++++++++++++++++++ + kpatch-build/kpatch-build | 4 ++++ + 2 files changed, 22 insertions(+) diff --git a/kmod/patch/livepatch-patch-hook.c b/kmod/patch/livepatch-patch-hook.c -index 2c0cadd..625ffbd 100644 +index 163ae1d..7e848a7 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 +@@ -238,6 +238,17 @@ 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[]; @@ -29,17 +29,39 @@ index 2c0cadd..625ffbd 100644 + 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) +@@ -403,6 +414,13 @@ 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); ++#if defined(__KLP_SUPPORT_FORCE__) ++#ifdef __ALL_FORCE__ ++ lfunc->force = 1; ++#else ++ lfunc->force = patch_is_func_forced(func->kfunc->new_addr); ++#endif ++#endif #ifdef HAVE_SYMPOS lfunc->old_sympos = func->kfunc->sympos; #else +diff --git a/kpatch-build/kpatch-build b/kpatch-build/kpatch-build +index 8bef7fb..57487b1 100755 +--- a/kpatch-build/kpatch-build ++++ b/kpatch-build/kpatch-build +@@ -1079,6 +1079,10 @@ if "$KPATCH_MODULE"; then + export KCPPFLAGS="-D__KPATCH_MODULE__" + fi + ++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 -- -1.7.5.4 +2.18.1 diff --git a/0015-kpatch-build-ignore-debuginfo-in-patch.patch b/0015-kpatch-build-ignore-debuginfo-in-patch.patch new file mode 100644 index 0000000000000000000000000000000000000000..36caea5848225d50003a31be74b60e72f6b30a18 --- /dev/null +++ b/0015-kpatch-build-ignore-debuginfo-in-patch.patch @@ -0,0 +1,64 @@ +From 720769ca54d446baf9cbc986fd2a8832da45ce71 Mon Sep 17 00:00:00 2001 +From: Zhipeng Xie +Date: Wed, 26 Feb 2020 21:01:02 -0500 +Subject: [PATCH 15/17] kpatch-build: ignore debuginfo in patch + +Just ignore all .debug_* sections + +Signed-off-by: Zhipeng Xie +--- + kpatch-build/create-diff-object.c | 18 ++++++++++++++++++ + kpatch-build/kpatch-build | 1 + + 2 files changed, 19 insertions(+) + +diff --git a/kpatch-build/create-diff-object.c b/kpatch-build/create-diff-object.c +index 4589ba4..c466eb0 100644 +--- a/kpatch-build/create-diff-object.c ++++ b/kpatch-build/create-diff-object.c +@@ -2396,6 +2396,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; +@@ -3645,6 +3662,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); +diff --git a/kpatch-build/kpatch-build b/kpatch-build/kpatch-build +index 57487b1..c109ee3 100755 +--- a/kpatch-build/kpatch-build ++++ b/kpatch-build/kpatch-build +@@ -1143,6 +1143,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 +-- +2.18.1 + diff --git a/9028-add-object-in-kpatch.patch b/0016-add-object-in-kpatch.patch similarity index 64% rename from 9028-add-object-in-kpatch.patch rename to 0016-add-object-in-kpatch.patch index b103ed6be76762eca9322244203d8b8a14fae04c..8af8963fc36196c49750a0e65fd656794c75f44f 100644 --- a/9028-add-object-in-kpatch.patch +++ b/0016-add-object-in-kpatch.patch @@ -1,17 +1,17 @@ -From d6304fcd36edd4e9df48687517f30965d9a790e9 Mon Sep 17 00:00:00 2001 +From dd03a70462783a9e8426ff76e42c41a7eaab644f Mon Sep 17 00:00:00 2001 From: Bin Yang Date: Tue, 16 Jul 2019 14:39:27 +0800 -Subject: [PATCH] add object in kpatch +Subject: [PATCH 16/17] 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 +index c109ee3..de448dc 100755 --- a/kpatch-build/kpatch-build +++ b/kpatch-build/kpatch-build -@@ -1011,6 +1011,8 @@ echo -n "Patched objects:" +@@ -1071,6 +1071,8 @@ echo -n "Patched objects:" for i in $(echo "${objnames[@]}" | tr ' ' '\n' | sort -u | tr '\n' ' ') do echo -n " $i" @@ -20,8 +20,8 @@ index 59af250..f685654 100644 done echo -@@ -1113,6 +1115,7 @@ UNDEFINED=$(comm -23 <(sort -u "${TEMPDIR}"/undefined_references) \ - [[ -z "$USERMODDIR" ]] && [[ ! -z "$UNDEFINED" ]] && die "Undefined symbols: $UNDEFINED" +@@ -1177,6 +1179,7 @@ UNDEFINED=$(comm -23 <(sort -u "${TEMPDIR}"/undefined_references) \ + [[ -z "$USERMODBUILDDIR" ]] && [[ -n "$UNDEFINED" ]] && die "Undefined symbols: $UNDEFINED" cp -f "$TEMPDIR/patch/$MODNAME.ko" "$BASE" || die +cp -f "$TEMPDIR/patch/object" "$BASE" || die @@ -29,5 +29,5 @@ index 59af250..f685654 100644 [[ "$DEBUG" -eq 0 ]] && rm -f "$LOGFILE" -- -2.17.1 +2.18.1 diff --git a/0017-create-diff-object-fix-.orc_unwind_ip-error.patch b/0017-create-diff-object-fix-.orc_unwind_ip-error.patch new file mode 100644 index 0000000000000000000000000000000000000000..ab28f7c33f28a79ac567718979b93b1b0b1ae780 --- /dev/null +++ b/0017-create-diff-object-fix-.orc_unwind_ip-error.patch @@ -0,0 +1,42 @@ +From 96e3ca2fbed32589510c800e9efe31bab2f5e58a Mon Sep 17 00:00:00 2001 +From: Zhipeng Xie +Date: Thu, 27 Feb 2020 15:36:55 -0500 +Subject: [PATCH 17/17] create-diff-object: fix .orc_unwind_ip error + +error: .orc_unwind_ip section header details +differ from .orc_unwind_ip + +Don't correlate .orc_unwind sections and symbols + +Signed-off-by: root +--- + kpatch-build/create-diff-object.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/kpatch-build/create-diff-object.c b/kpatch-build/create-diff-object.c +index c466eb0..320b239 100644 +--- a/kpatch-build/create-diff-object.c ++++ b/kpatch-build/create-diff-object.c +@@ -967,6 +967,9 @@ static void kpatch_correlate_sections(struct list_head *seclist1, struct list_he + continue; + } + ++ if (strstr(sec1->name, ".orc_unwind")) ++ continue; ++ + kpatch_correlate_section(sec1, sec2); + break; + } +@@ -1012,6 +1015,9 @@ static void kpatch_correlate_symbols(struct list_head *symlist1, struct list_hea + sym1->sec->twin != sym2->sec) + continue; + ++ if (strstr(sym1->name, ".orc_unwind")) ++ continue; ++ + kpatch_correlate_symbol(sym1, sym2); + break; + } +-- +2.18.1 + diff --git a/9001-livepatch-patch-hook-don-t-active-patch-when-insmod.patch b/9001-livepatch-patch-hook-don-t-active-patch-when-insmod.patch deleted file mode 100644 index 5eb830e178b66094337831894ce674637cf542c6..0000000000000000000000000000000000000000 --- a/9001-livepatch-patch-hook-don-t-active-patch-when-insmod.patch +++ /dev/null @@ -1,34 +0,0 @@ -From ee167e43252bdb9e84cbefcd8b6fe767c9dc768f Mon Sep 17 00:00:00 2001 -From: Zhipeng Xie -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 ---- - 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 - diff --git a/9002-kpatch-build-support-third-party-module-make-hotpatc.patch b/9002-kpatch-build-support-third-party-module-make-hotpatc.patch deleted file mode 100644 index aca779840640870f3a0fdc59a7d4983af645aac5..0000000000000000000000000000000000000000 --- a/9002-kpatch-build-support-third-party-module-make-hotpatc.patch +++ /dev/null @@ -1,208 +0,0 @@ -From c27f1093cd47c48e2f403c4ffb29bf066ce0bea5 Mon Sep 17 00:00:00 2001 -From: Zhipeng Xie -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 ---- - 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 - diff --git a/9003-kpatch-build-support-makefile-not-in-third-party-mod.patch b/9003-kpatch-build-support-makefile-not-in-third-party-mod.patch deleted file mode 100644 index 544b6d05047d01bf3dfaf2cd51810addc1cffcdb..0000000000000000000000000000000000000000 --- a/9003-kpatch-build-support-makefile-not-in-third-party-mod.patch +++ /dev/null @@ -1,92 +0,0 @@ -From 214de7459555f3f0461cf4127c55f727ccf473d1 Mon Sep 17 00:00:00 2001 -From: Zhipeng Xie -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 ---- - 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 - diff --git a/9009-kmod-kpatch-build-support-build-patch-for-old-kernel.patch b/9009-kmod-kpatch-build-support-build-patch-for-old-kernel.patch deleted file mode 100644 index beecafa5a48d103c54e00109c4ed6a01d112314a..0000000000000000000000000000000000000000 --- a/9009-kmod-kpatch-build-support-build-patch-for-old-kernel.patch +++ /dev/null @@ -1,349 +0,0 @@ -From e91d2d2c6778275b16249f7e9d7439018fed70fe Mon Sep 17 00:00:00 2001 -From: Zhipeng Xie -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 ---- - 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 - diff --git a/9011-kpatch-build-use-.klp.rela-in-euleros-7.5-kernel.patch b/9011-kpatch-build-use-.klp.rela-in-euleros-7.5-kernel.patch deleted file mode 100644 index 58562a443451aa9351920a30c324eb5dcea6d2d1..0000000000000000000000000000000000000000 --- a/9011-kpatch-build-use-.klp.rela-in-euleros-7.5-kernel.patch +++ /dev/null @@ -1,48 +0,0 @@ -From 868a6e4462bebcffa4bf6beea02262823e7dc3a3 Mon Sep 17 00:00:00 2001 -From: Zhipeng Xie -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 ---- - 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 - diff --git a/9014-create-diff-object-add-dynamic-reloction-for-functio.patch b/9014-create-diff-object-add-dynamic-reloction-for-functio.patch deleted file mode 100644 index 692a415b9c5b1fe62a5b1a0b279ddbc1766bfeca..0000000000000000000000000000000000000000 --- a/9014-create-diff-object-add-dynamic-reloction-for-functio.patch +++ /dev/null @@ -1,31 +0,0 @@ -From 83ecafcda5326baceeb68fba90dc13083ff48fe6 Mon Sep 17 00:00:00 2001 -From: Zhipeng Xie -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 ---- - 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 - diff --git a/9015-create-diff-object-exclude-line-only-change-for-arm6.patch b/9015-create-diff-object-exclude-line-only-change-for-arm6.patch deleted file mode 100644 index 6ed7af1b08954b045195dc148fcdd10e4f273ee7..0000000000000000000000000000000000000000 --- a/9015-create-diff-object-exclude-line-only-change-for-arm6.patch +++ /dev/null @@ -1,106 +0,0 @@ -From d1bbff5da464148e5d277b601a31d7872b4e376b Mon Sep 17 00:00:00 2001 -From: Zhipeng Xie -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 ---- - 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 - diff --git a/9016-kpatch-build-include-secsym-in-kpatch_mark_ignored_s.patch b/9016-kpatch-build-include-secsym-in-kpatch_mark_ignored_s.patch deleted file mode 100644 index b64f46dd0b9df3c502486e441aa4adc223fae295..0000000000000000000000000000000000000000 --- a/9016-kpatch-build-include-secsym-in-kpatch_mark_ignored_s.patch +++ /dev/null @@ -1,31 +0,0 @@ -From dc771a1789ea3769777228f792f0902f8b0566ba Mon Sep 17 00:00:00 2001 -From: Zhipeng Xie -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 ---- - 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 - diff --git a/9018-support-c-plus-kernel-module.patch b/9018-support-c-plus-kernel-module.patch deleted file mode 100644 index 209cf4970cce7cacff24844b0ce69a33055a3b23..0000000000000000000000000000000000000000 --- a/9018-support-c-plus-kernel-module.patch +++ /dev/null @@ -1,828 +0,0 @@ -From 9d590b5b9fb59c1cd52221feeef2794eb3333571 Mon Sep 17 00:00:00 2001 -From: Zhipeng Xie -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 ---- - 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 - diff --git a/9023-kpatch-build-adapt-for-ksymtab-in-4.19-kernel.patch b/9023-kpatch-build-adapt-for-ksymtab-in-4.19-kernel.patch deleted file mode 100644 index e655cf5d385bcead01366b090cf871abb81b3621..0000000000000000000000000000000000000000 --- a/9023-kpatch-build-adapt-for-ksymtab-in-4.19-kernel.patch +++ /dev/null @@ -1,28 +0,0 @@ -From f221fbe8ff0c22b61aaf42687f5ece04f10ec403 Mon Sep 17 00:00:00 2001 -From: Zhipeng Xie -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 ---- - 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 - diff --git a/9024-support-force-enable-disable-for-kernel-4.19.patch b/9024-support-force-enable-disable-for-kernel-4.19.patch deleted file mode 100644 index 35727aaded1bc02343446d0046c0cd4889a8ade2..0000000000000000000000000000000000000000 --- a/9024-support-force-enable-disable-for-kernel-4.19.patch +++ /dev/null @@ -1,91 +0,0 @@ -From 6b7ff79bb40a7dbb28e6aba320e4ac075e4c182d Mon Sep 17 00:00:00 2001 -From: Zhipeng Xie -Date: Fri, 18 Jan 2019 00:07:02 +0000 -Subject: [PATCH] support force enable/disable for kernel 4.19 - -Signed-off-by: Zhipeng Xie ---- - 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 - diff --git a/9025-kpatch-build-adapt-for-native-compile_env.patch b/9025-kpatch-build-adapt-for-native-compile_env.patch deleted file mode 100644 index e2f58576e7179ba7b406917bfd1f698d39e7ace4..0000000000000000000000000000000000000000 --- a/9025-kpatch-build-adapt-for-native-compile_env.patch +++ /dev/null @@ -1,118 +0,0 @@ -From 87203483495fec8ad1394def83fa884a96b711ec Mon Sep 17 00:00:00 2001 -From: Zhipeng Xie -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 ---- - 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 - diff --git a/9026-add-find_special_section_data_arm64-for-arm64.patch b/9026-add-find_special_section_data_arm64-for-arm64.patch deleted file mode 100644 index 283cdcaed0decff546b369654c32417afeec97b1..0000000000000000000000000000000000000000 --- a/9026-add-find_special_section_data_arm64-for-arm64.patch +++ /dev/null @@ -1,96 +0,0 @@ -From d53b2d1f87f5e891ba8f6945765134da9ee2d29d Mon Sep 17 00:00:00 2001 -From: Zhipeng Xie -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 ---- - 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 - diff --git a/9027-fix-ref-static-local-symbol-for-longname-symbol.patch b/9027-fix-ref-static-local-symbol-for-longname-symbol.patch deleted file mode 100644 index 88be4416b7bdba112bfa0e7f8af3ac0fe157ddf4..0000000000000000000000000000000000000000 --- a/9027-fix-ref-static-local-symbol-for-longname-symbol.patch +++ /dev/null @@ -1,31 +0,0 @@ -From 1069d212fd848f1f1e2425dffe8e9aea188c6150 Mon Sep 17 00:00:00 2001 -From: Zhipeng Xie -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 ---- - 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 - diff --git a/9030-kmod-core-fix-compilation-with-CONFIG_HAVE_ARCH_PREL.patch b/9030-kmod-core-fix-compilation-with-CONFIG_HAVE_ARCH_PREL.patch deleted file mode 100644 index 58c22788e5f76fd05cb3f175bb71485299a7dce8..0000000000000000000000000000000000000000 --- a/9030-kmod-core-fix-compilation-with-CONFIG_HAVE_ARCH_PREL.patch +++ /dev/null @@ -1,34 +0,0 @@ -From da3eed612df1d26e19b0678763e116f666da13b2 Mon Sep 17 00:00:00 2001 -From: Artem Savkov -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 ---- - 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 - diff --git a/kpatch-0.6.1.tar.gz b/kpatch-0.6.1.tar.gz deleted file mode 100644 index 1be0f4a14e1005da8570ce9ceec88eb43f99ea40..0000000000000000000000000000000000000000 Binary files a/kpatch-0.6.1.tar.gz and /dev/null differ diff --git a/kpatch-0.9.0.tar.gz b/kpatch-0.9.0.tar.gz new file mode 100644 index 0000000000000000000000000000000000000000..343d51866c7f96de8c2bcd9009627d4379046480 Binary files /dev/null and b/kpatch-0.9.0.tar.gz differ diff --git a/kpatch.spec b/kpatch.spec index d988e244837115a6bb1aa680cbaeffe8d87611d1..51f9eb0dcab17e4154cec0eac9e8db9536c98db5 100644 --- a/kpatch.spec +++ b/kpatch.spec @@ -1,8 +1,8 @@ -%global raw_version 0.6.1 +%global raw_version 0.9.0 Name: kpatch Version: 2.0 -Release: 3.1.23 +Release: 3.1.24 Summary: A Linux dynamic kernel patching infrastructure License: GPLv2 @@ -13,36 +13,23 @@ 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 +Patch0001:0001-support-compile-kpatch-on-aarch64.patch +Patch0002:0002-kpatch-build-support-build-patch-for-aarch64.patch +Patch0003:0003-create-diff-object-new-static-var-should-be-included.patch +Patch0004:0004-livepatch-fix-use-THIS-modname-as-the-name-of-ddebug.patch +Patch0005:0005-create-diff-object-fix-correlate-static-local-variab.patch +Patch0006:0006-create-diff-object-don-t-create-dynamic-reloc-for-sy.patch +Patch0007:0007-create-diff-object-create-dynamic-relocs-for-changed.patch +Patch0008:0008-fix-rodata.str-problem.patch +Patch0009:0009-livepatch-patch-hook-don-t-active-patch-when-insmod.patch +Patch0010:0010-kpatch-build-enhance-for-out-of-tree-module.patch +Patch0011:0011-support-c-plus-kernel-module.patch +Patch0012:0012-symbol-lookup-enhancement.patch +Patch0013:0013-Add-running-kernel-symbol-table-to-help-symbol-looku.patch +Patch0014:0014-livepatch-patch-hook-support-force-enable-disable.patch +Patch0015:0015-kpatch-build-ignore-debuginfo-in-patch.patch +Patch0016:0016-add-object-in-kpatch.patch +Patch0017:0017-create-diff-object-fix-.orc_unwind_ip-error.patch BuildRequires: gcc elfutils-libelf-devel uname-build-checks kernel kernel-devel Requires: bc @@ -61,7 +48,7 @@ BuildArch: noarch %description runtime Dynamic kernel patching -%package_help +#%package_help %prep %autosetup -n %{name}-%{raw_version} -p1 @@ -89,9 +76,6 @@ popd %{_datadir}/%{name}/* %{_sysconfdir}/init/* /opt/patch_workspace/* -%ifarch x86_64 -%{_prefix}/lib/kpatch -%endif %files runtime %defattr(-,root,root) @@ -102,6 +86,12 @@ popd %{_mandir}/man1/*.1.gz %changelog +* Wed Feb 26 2020 Zhipeng Xie -2.0-3.1.24 +- Type:enhancement +- ID:NA +- SUG:NA +- DESC:rebase from upstream version v0.9.0 + * Mon Feb 17 2020 openEuler Buildteam -2.0-3.1.23 - Type:enhancement - ID:NA diff --git a/livepatch b/livepatch index e6e1093969aa49d04242c7b4001465c22859680c..a6f362d682c019d5bd89ff84992ee675756f9d45 100644 --- a/livepatch +++ b/livepatch @@ -1,19 +1,8 @@ #!/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 < -q[patch]/--query[=patch] -h/--help -v/--version @@ -28,38 +17,38 @@ input_args=`getopt -a -o l:a:r:d:q:v -l load:,activate:,remove:,deactivate:,quer eval set -- "${input_args}" while true; do - case "$1" in - -l|--load) + 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) + 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 + *) + fn_help + exit 1 + ;; + esac done diff --git a/make_hotpatch b/make_hotpatch index 3057146ade4d770b34bff0ca231027d4e70afb5a..a773944ad4d558328d666600d1c8968457701b60 100644 --- a/make_hotpatch +++ b/make_hotpatch @@ -1,14 +1,18 @@ -#!/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. +#!/usr/bin/bash +#******************************************************************** +# Copyright (C) Huawei Technologies, 2015-11 +# +# #FileName : make_hotpatch +# #Description : make hotpatch +# #Author : +# #Language : shell +# #Environment : Euler compile env +# #Created : 2015-11 +# #History +# 1.Date: +# Author: +# Modification: +#******************************************************************** SHELL_DIR=$(dirname $0) SHELL_DIR=$(cd $SHELL_DIR; pwd) @@ -72,12 +76,12 @@ Options: -p,--patch Specifies the patch file --kallsyms - Specifies module kallsyms in running system(cat /proc/kallsyms|grep mod) + Specifies module kallsyms in running system(cat /proc/kallsyms|grep mod) -h,--help help info EOF - return 0 +return 0 } @@ -94,7 +98,7 @@ function fn_do_clean() unset NO_STACK_CHECK unset KALLSYMS rm -rf $G_TMP_DIR - + } ######################################################### @@ -109,7 +113,7 @@ function fn_check_reg_char() 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 @@ -139,10 +143,10 @@ function fn_check_reg_char() else echo "error: string $l_str can only contain characters included by ('0-9', 'a-z', 'A-Z', '-', '_')." fi - + return 1 fi - + } ######################################################### @@ -159,7 +163,7 @@ function fn_check_id() 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 @@ -197,8 +201,8 @@ function fn_check_jobs() function fn_check_patch(){ local l_patch=$1 if [ ! -f $1 ];then - echo "error:patch file $1 not exit" - return 1 + echo "error:patch file $1 not exist" + return 1 fi G_PATCHFILE=$l_patch } @@ -324,136 +328,136 @@ function fn_verify_input() 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 + -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 + -h|--help) 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) + 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) + ;; + --debug_info) G_DEBUG_INFO="-d" shift 1 - ;; - --kallsyms) - export KALLSYMS=$(readlink -f $2) - if [ $? -eq 0 ]; then + ;; + --kallsyms) + if [ "$2" == "" ];then + echo "error: param --kallsyms need file parameter" + fn_do_clean + fn_usage + exit 1 + fi + export KALLSYMS=$(readlink -f $2) shift 2 - else + ;; + + *) + echo "error: params is invalid,please check it." 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 @@ -474,11 +478,11 @@ function fn_init_module_build() 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" @@ -534,14 +538,15 @@ function fn_makepatch() 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 + 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" + USERMODBUILDDIR=$G_MODULE_SRC fi if [ -n "$G_JOBS" ];then @@ -551,63 +556,61 @@ function fn_makepatch() 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 + #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 + 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) + 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 + export NO_PROFILING_CALLS="yes" + export DISABLE_AFTER_LOAD="yes" + kpatch-build -s $G_PATCH_SRC -c $G_KERNEL_CONFIG -v $G_VMLINUX --skip-gcc-check -n "${G_PREFIX}_${G_HOTPATCH_ID}" $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 + 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}" + 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}" + echo "------------------------------------------------------------------------ " >> "${l_env_file}" fi echo >> "${l_env_file}" @@ -617,41 +620,41 @@ function fn_makepatch() 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}" + 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}" + 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}" + 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}" + 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} + tar -czf $G_HOTPATCH_TAR ${G_PREFIX}_${G_HOTPATCH_ID} mv ${G_HOTPATCH_TAR} ${G_HOTPATCH_DIR} - cd - &>/dev/null + cd - &>/dev/null if [ $? -ne 0 ];then echo "error: move ${G_HOTPATCH} to ${G_KSPLICE_HOTPATCH} failed" return 1 @@ -682,43 +685,43 @@ function fn_main() 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 + 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 + echo "[$0]someone is making, please try again later." + exit 1 fi fn_prepare diff --git a/os_hotpatch b/os_hotpatch index 48b50b7e73c7dc09d0267005ead387a84ef28e0b..d56841a5ff921b92627c06e486eb4b9dfc26782f 100644 --- a/os_hotpatch +++ b/os_hotpatch @@ -1,17 +1,21 @@ #!/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. +#******************************************************************** +# Copyright (C) Huawei Technologies, 2015-11 +# +# #FileName : make_hotpatch +# #Description : make hotpatch +# #Author : +# #Language : shell +# #Environment : Euler compile env +# #Created : 2015-11 +# #History +# 1.Date: +# Author: +# Modification:2015-12-7 +#******************************************************************** SYS_LIVEPATCH=/sys/kernel/livepatch -G_TMP_DIR=/tmp/hotpatch.$$ +G_TMP_DIR=/lib/modules/hotpatch.$$ G_PATCH_FILE= ######################################################### @@ -21,14 +25,14 @@ G_PATCH_FILE= ######################################################### OS_HP_HELP() { - echo "usage: os_hotpatch" - echo "-w|--check : check hotpatch" - echo "-l|--load : load hotpatch" - echo "-a|--active : active hotpatch" - echo "-r|--rollback : rollback/deactive hotpatch" - echo "-d|--delete : delete/unload hotpatch" - echo "-q|--query /all : query hotpatch" - echo "-h|--help : show this help information" + echo "usage: os_hotpatch" + echo "-w|--check : check hotpatch" + echo "-l|--load : load hotpatch" + echo "-a|--active : active hotpatch" + echo "-r|--rollback : rollback/deactive hotpatch" + echo "-d|--delete : delete/unload hotpatch" + echo "-q|--query /all : query hotpatch" + echo "-h|--help : show this help information" } ######################################################### @@ -39,20 +43,20 @@ OS_HP_HELP() ######################################################### 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" + 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 - exit 1; - fi - CLEAN_UP - echo "The file $path is valid" - exit 0 + echo "The file $path is valid" + exit 0 } ######################################################### @@ -63,30 +67,30 @@ OS_HP_CHECK() ######################################################### OS_HP_ACTIVE() { - file=$1 - patch_name=`echo ${file%.tar.gz}|tr '-' '_'` - patch_install=`lsmod | grep -w $patch_name` + 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 + 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 + 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 + 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 } ######################################################### @@ -97,30 +101,30 @@ OS_HP_ACTIVE() ######################################################### OS_HP_DEACTIVE() { - file=$1 - patch_name=`echo ${file%.tar.gz}|tr '-' '_'` - patch_install=`lsmod | grep -w $patch_name` + 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 + 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 + is_active=`cat ${SYS_LIVEPATCH}/${patch_name}/enabled` + if [ ${is_active} == 0 ]; then + echo "patch $file already deactive" + exit 0 else - echo "deactive patch $file fail" - exit 1 - fi - fi + 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 } ######################################################### @@ -131,31 +135,31 @@ OS_HP_DEACTIVE() ######################################################### OS_HP_REMOVE() { - file=$1 - patch_name=`echo ${file%.tar.gz}|tr '-' '_'` - patch_install=`lsmod | grep -w $patch_name` + 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 - 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 + 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 + 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 } ######################################################### @@ -166,61 +170,61 @@ OS_HP_REMOVE() ######################################################### OS_HP_INQUIRY() { - file=$1 - lret=0 - if [ "all" == $file ];then - cd ${SYS_LIVEPATCH} - if [ -z "`ls -d */ 2>/dev/null`" ];then + 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 - 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 "-----------------------------------------------------------" + 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 + exit $lret } ######################################################### # Description: extract hotpatch tar to tmp dir @@ -230,11 +234,12 @@ OS_HP_INQUIRY() ######################################################### EXTRACT_HP() { - mkdir $G_TMP_DIR + rm -rf $G_TMP_DIR + mkdir -p $G_TMP_DIR tar xzf $1 -C $G_TMP_DIR l_ret=$? if [ $l_ret -eq 0 ];then - #find the hotpatch module + #find the hotpatch module G_PATCH_FILE=$(find $G_TMP_DIR|grep -w "klp.*\.ko") return 0 else @@ -248,7 +253,7 @@ EXTRACT_HP() ######################################################### CLEAN_UP() { - rm -rf $G_TMP_DIR + rm -rf $G_TMP_DIR } ######################################################### # Description: install a hotpatch @@ -258,80 +263,80 @@ CLEAN_UP() ######################################################### OS_HP_INSTALL() { - path=$1 + 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!" + 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 - 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 + return 0 } #----------------------------main-------------------------# if [ ! -d ${SYS_LIVEPATCH} ];then - echo "this OS does not support kernel livepatch" - exit 1 + 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 + 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