diff --git a/0001-kpatch-add-aarch64-support.patch b/0001-kpatch-add-aarch64-support.patch new file mode 100644 index 0000000000000000000000000000000000000000..711a65225906ed80209c61a7a890fd342c030284 --- /dev/null +++ b/0001-kpatch-add-aarch64-support.patch @@ -0,0 +1,172 @@ +From 821e6cb24778bd063d1e8ad097d4bd4c81973091 Mon Sep 17 00:00:00 2001 +From: Zhipeng Xie +Date: Thu, 20 Dec 2018 04:55:38 +0000 +Subject: [PATCH 01/24] kpatch: add aarch64 support + +1.use R_AARCH64_ABS64 for aarch64 +2.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/Makefile | 4 +++ + kpatch-build/create-diff-object.c | 14 ++++++---- + kpatch-build/kpatch-build | 46 +++++++++++++++++++++++++++++++ + kpatch-build/kpatch-elf.c | 2 +- + 4 files changed, 60 insertions(+), 6 deletions(-) + +diff --git a/kpatch-build/Makefile b/kpatch-build/Makefile +index 50899b6..423c32a 100644 +--- a/kpatch-build/Makefile ++++ b/kpatch-build/Makefile +@@ -14,6 +14,10 @@ ifeq ($(ARCH),x86_64) + SOURCES += insn/insn.c insn/inat.c + INSN = insn/insn.o insn/inat.o + insn/%.o: CFLAGS := $(filter-out -Wconversion, $(CFLAGS)) ++else ifeq ($(ARCH),aarch64) ++SOURCES += insn/insn.c insn/inat.c ++INSN = insn/insn.o insn/inat.o ++insn/%.o: CFLAGS := $(filter-out -Wconversion, $(CFLAGS)) + else ifeq ($(ARCH),ppc64le) + SOURCES += gcc-plugins/ppc64le-plugin.c + PLUGIN = gcc-plugins/ppc64le-plugin.so +diff --git a/kpatch-build/create-diff-object.c b/kpatch-build/create-diff-object.c +index 6a4848a..ca55180 100644 +--- a/kpatch-build/create-diff-object.c ++++ b/kpatch-build/create-diff-object.c +@@ -62,6 +62,8 @@ + + #ifdef __powerpc64__ + #define ABSOLUTE_RELA_TYPE R_PPC64_ADDR64 ++#elif __aarch64__ ++#define ABSOLUTE_RELA_TYPE R_AARCH64_ABS64 + #else + #define ABSOLUTE_RELA_TYPE R_X86_64_64 + #endif +@@ -1536,7 +1538,7 @@ static void kpatch_replace_sections_syms(struct kpatch_elf *kelf) + continue; + } + +-#ifdef __powerpc64__ ++#if defined(__powerpc64__) || defined(__aarch64__) + add_off = 0; + #else + if (rela->type == R_X86_64_PC32 || +@@ -2028,7 +2030,7 @@ static int printk_index_group_size(struct kpatch_elf *kelf, int offset) + return size; + } + +-#ifdef __x86_64__ ++#if defined(__x86_64__) || defined(__aarch64__) + static int parainstructions_group_size(struct kpatch_elf *kelf, int offset) + { + static int size = 0; +@@ -2177,7 +2179,7 @@ static struct special_section special_sections[] = { + .name = ".printk_index", + .group_size = printk_index_group_size, + }, +-#ifdef __x86_64__ ++#if defined(__x86_64__) || defined(__aarch64__) + { + .name = ".smp_locks", + .group_size = smp_locks_group_size, +@@ -2990,7 +2992,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 bool need_dynrela(struct lookup_table *table, struct section *sec, const struct rela *rela) +@@ -3479,7 +3483,7 @@ static void kpatch_create_mcount_sections(struct kpatch_elf *kelf) + rela->type = R_X86_64_PC32; + } + +-#else /* __powerpc64__ */ ++#else /* __powerpc64__ || __aarch64__ */ + { + bool found = false; + +diff --git a/kpatch-build/kpatch-build b/kpatch-build/kpatch-build +index eedf383..ad3a079 100755 +--- a/kpatch-build/kpatch-build ++++ b/kpatch-build/kpatch-build +@@ -375,12 +375,58 @@ find_special_section_data_ppc64le() { + return + } + ++find_special_section_data_aarch64() { ++ ++ [[ "$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 = 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} ++ ++ # 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 } ++ ++ # 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} ++ ++ # Bail out once we have everything ++ a == 2 && b == 2 && e == 2 && (j == 2 || skip_j) {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" = "aarch64" ]]; then ++ find_special_section_data_aarch64 ++ 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" +diff --git a/kpatch-build/kpatch-elf.c b/kpatch-build/kpatch-elf.c +index 7e272e2..68d5c86 100644 +--- a/kpatch-build/kpatch-elf.c ++++ b/kpatch-build/kpatch-elf.c +@@ -325,7 +325,7 @@ static void kpatch_find_func_profiling_calls(struct kpatch_elf *kelf) + list_for_each_entry(sym, &kelf->symbols, list) { + if (sym->type != STT_FUNC || !sym->sec || !sym->sec->rela) + continue; +-#ifdef __powerpc64__ ++#if defined(__powerpc64__) || defined(__aarch64__) + list_for_each_entry(rela, &sym->sec->rela->relas, list) { + if (!strcmp(rela->sym->name, "_mcount")) { + sym->has_func_profiling = 1; +-- +2.23.0 + diff --git a/0001-support-compile-kpatch-on-aarch64.patch b/0001-support-compile-kpatch-on-aarch64.patch deleted file mode 100644 index 2df9a326d7386506c122404ceb699ec2a311ec79..0000000000000000000000000000000000000000 --- a/0001-support-compile-kpatch-on-aarch64.patch +++ /dev/null @@ -1,112 +0,0 @@ -From 0de9a5da0cc278973caabfb9929dc58514c73639 Mon Sep 17 00:00:00 2001 -From: Zhipeng Xie -Date: Thu, 20 Dec 2018 04:55:38 +0000 -Subject: [PATCH 01/23] support compile kpatch on aarch64 - -delete __x86_64__ to support compile kpatch on aarch64. - -Signed-off-by: Zhipeng Xie ---- - kpatch-build/Makefile | 4 ++++ - kpatch-build/create-diff-object.c | 14 +------------- - 2 files changed, 5 insertions(+), 13 deletions(-) - -diff --git a/kpatch-build/Makefile b/kpatch-build/Makefile -index 7505e07..8efae94 100644 ---- a/kpatch-build/Makefile -+++ b/kpatch-build/Makefile -@@ -14,6 +14,10 @@ ifeq ($(ARCH),x86_64) - SOURCES += insn/insn.c insn/inat.c - INSN = insn/insn.o insn/inat.o - insn/%.o: CFLAGS := $(filter-out -Wconversion, $(CFLAGS)) -+else ifeq ($(ARCH),aarch64) -+SOURCES += insn/insn.c insn/inat.c -+INSN = insn/insn.o insn/inat.o -+insn/%.o: CFLAGS := $(filter-out -Wconversion, $(CFLAGS)) - else ifeq ($(ARCH),ppc64le) - SOURCES += gcc-plugins/ppc64le-plugin.c - PLUGIN = gcc-plugins/ppc64le-plugin.so -diff --git a/kpatch-build/create-diff-object.c b/kpatch-build/create-diff-object.c -index aedd07d..2707cdb 100644 ---- a/kpatch-build/create-diff-object.c -+++ b/kpatch-build/create-diff-object.c -@@ -475,7 +475,6 @@ out: - log_debug("section %s has changed\n", sec->name); - } - --#ifdef __x86_64__ - /* - * Determine if a section has changed only due to a WARN* or might_sleep - * macro call's embedding of the line number into an instruction operand. -@@ -586,7 +585,7 @@ static int kpatch_line_macro_change_only(struct section *sec) - - return 1; - } --#elif __powerpc64__ -+#if __powerpc64__ - #define PPC_INSTR_LEN 4 - #define PPC_RA_OFFSET 16 - -@@ -652,11 +651,6 @@ static int kpatch_line_macro_change_only(struct section *sec) - - return 1; - } --#else --static int kpatch_line_macro_change_only(struct section *sec) --{ -- return 0; --} - #endif - - static void kpatch_compare_sections(struct list_head *seclist) -@@ -1215,7 +1209,6 @@ static void kpatch_compare_correlated_elements(struct kpatch_elf *kelf) - kpatch_compare_symbols(&kelf->symbols); - } - --#ifdef __x86_64__ - static void rela_insn(const struct section *sec, const struct rela *rela, - struct insn *insn) - { -@@ -1239,7 +1232,6 @@ static void rela_insn(const struct section *sec, const struct rela *rela, - return; - } - } --#endif - - static bool is_callback_section(struct section *sec) { - -@@ -1785,7 +1777,6 @@ static int jump_table_group_size(struct kpatch_elf *kelf, int offset) - return size; - } - --#ifdef __x86_64__ - static int parainstructions_group_size(struct kpatch_elf *kelf, int offset) - { - static int size = 0; -@@ -1820,7 +1811,6 @@ static int smp_locks_group_size(struct kpatch_elf *kelf, int offset) - { - return 4; - } --#endif - #ifdef __powerpc64__ - static int fixup_entry_group_size(struct kpatch_elf *kelf, int offset) - { -@@ -1915,7 +1905,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, -@@ -1928,7 +1917,6 @@ static struct special_section special_sections[] = { - .name = ".altinstructions", - .group_size = altinstructions_group_size, - }, --#endif - #ifdef __powerpc64__ - { - .name = "__ftr_fixup", --- -2.18.1 - diff --git a/0002-create-diff-object-fix-symbol-changed-sections-error.patch b/0002-create-diff-object-fix-symbol-changed-sections-error.patch new file mode 100644 index 0000000000000000000000000000000000000000..eefb711b7aca4d961969443c2a609f567620d396 --- /dev/null +++ b/0002-create-diff-object-fix-symbol-changed-sections-error.patch @@ -0,0 +1,31 @@ +From 72d28d667f8f6baa88882abfc1590cce3e9e2b1f Mon Sep 17 00:00:00 2001 +From: Zhipeng Xie +Date: Sun, 14 Nov 2021 15:57:55 +0800 +Subject: [PATCH 02/24] create-diff-object: fix symbol changed sections error + on aarch64 + +$d is reserved symbols in aarch64, we met following error when +building patch on aarch64. just ignore it. +ERROR: cmdline.o: symbol changed sections: $d + +Signed-off-by: Zhipeng Xie +--- + kpatch-build/create-diff-object.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/kpatch-build/create-diff-object.c b/kpatch-build/create-diff-object.c +index ca55180..6c28280 100644 +--- a/kpatch-build/create-diff-object.c ++++ b/kpatch-build/create-diff-object.c +@@ -865,6 +865,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); + } +-- +2.23.0 + diff --git a/0002-kpatch-build-support-build-patch-for-aarch64.patch b/0002-kpatch-build-support-build-patch-for-aarch64.patch deleted file mode 100644 index 9e9d0ed05f301d699e1359c10e53442a133e20c7..0000000000000000000000000000000000000000 --- a/0002-kpatch-build-support-build-patch-for-aarch64.patch +++ /dev/null @@ -1,744 +0,0 @@ -From d3665b019100715e41b75493d31d51d602ca056a Mon Sep 17 00:00:00 2001 -From: Zhipeng Xie -Date: Wed, 26 Feb 2020 07:09:50 -0500 -Subject: [PATCH 02/23] kpatch-build: support build patch for aarch64 - -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 ---- - kpatch-build/create-diff-object.c | 276 ++++++++++++++++++++++------ - kpatch-build/create-kpatch-module.c | 25 ++- - kpatch-build/kpatch-build | 116 +++++++++++- - kpatch-build/kpatch-gcc | 4 +- - 4 files changed, 352 insertions(+), 69 deletions(-) - -diff --git a/kpatch-build/create-diff-object.c b/kpatch-build/create-diff-object.c -index 2707cdb..b161fee 100644 ---- a/kpatch-build/create-diff-object.c -+++ b/kpatch-build/create-diff-object.c -@@ -76,6 +76,32 @@ enum subsection { - - enum loglevel loglevel = NORMAL; - -+#ifndef EM_X86_64 -+#define EM_X86_64 62 -+#endif -+ -+#ifndef EM_AARCH64 -+#define EM_AARCH64 183 -+#endif -+ -+#ifndef R_AARCH64_ABS64 -+#define R_AARCH64_NONE 0 -+#define R_AARCH64_ABS64 257 -+#define R_AARCH64_CALL26 283 -+#endif -+ -+static unsigned int arch; -+static unsigned int absolute_rela_type; -+ -+static unsigned int arch_of_elf(Elf *elf) -+{ -+ GElf_Ehdr eh; -+ -+ if (!gelf_getehdr(elf, &eh)) -+ ERROR("gelf_getehdr"); -+ return eh.e_machine; -+} -+ - /******************* - * Data structures - * ****************/ -@@ -652,6 +678,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) - { -@@ -667,7 +754,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; -@@ -727,6 +823,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); - } -@@ -1302,22 +1400,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 = (unsigned int)((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 = (unsigned int)((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; -+ } - - /* - * Attempt to replace references to unbundled sections -@@ -2415,7 +2513,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 = (unsigned int)(index * sizeof(struct kpatch_arch) + \ - offsetof(struct kpatch_arch, sec)); -@@ -2423,7 +2521,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 = (unsigned int)(index * sizeof(struct kpatch_arch) + \ - offsetof(struct kpatch_arch, objname)); -@@ -2622,7 +2720,7 @@ static void kpatch_create_patches_sections(struct kpatch_elf *kelf, - */ - ALLOC_LINK(rela, &relasec->relas); - rela->sym = sym; -- rela->type = ABSOLUTE_RELA_TYPE; -+ rela->type = absolute_rela_type; - rela->addend = 0; - rela->offset = (unsigned int)(index * sizeof(*funcs)); - -@@ -2632,7 +2730,7 @@ static void kpatch_create_patches_sections(struct kpatch_elf *kelf, - */ - ALLOC_LINK(rela, &relasec->relas); - rela->sym = strsym; -- rela->type = ABSOLUTE_RELA_TYPE; -+ rela->type = absolute_rela_type; - rela->addend = offset_of_string(&kelf->strings, sym->name); - rela->offset = (unsigned int)(index * sizeof(*funcs) + - offsetof(struct kpatch_patch_func, name)); -@@ -2643,7 +2741,7 @@ static void kpatch_create_patches_sections(struct kpatch_elf *kelf, - */ - ALLOC_LINK(rela, &relasec->relas); - rela->sym = strsym; -- rela->type = ABSOLUTE_RELA_TYPE; -+ rela->type = absolute_rela_type; - rela->addend = objname_offset; - rela->offset = (unsigned int)(index * sizeof(*funcs) + - offsetof(struct kpatch_patch_func,objname)); -@@ -2701,7 +2799,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) -@@ -2955,7 +3056,7 @@ static void kpatch_create_intermediate_sections(struct kpatch_elf *kelf, - /* add rela to fill in ksyms[index].name field */ - ALLOC_LINK(rela2, &ksym_sec->rela->relas); - rela2->sym = strsym; -- rela2->type = ABSOLUTE_RELA_TYPE; -+ rela2->type = absolute_rela_type; - rela2->addend = offset_of_string(&kelf->strings, rela->sym->name); - rela2->offset = (unsigned int)(index * sizeof(*ksyms) + \ - offsetof(struct kpatch_symbol, name)); -@@ -2963,7 +3064,7 @@ static void kpatch_create_intermediate_sections(struct kpatch_elf *kelf, - /* add rela to fill in ksyms[index].objname field */ - ALLOC_LINK(rela2, &ksym_sec->rela->relas); - rela2->sym = strsym; -- rela2->type = ABSOLUTE_RELA_TYPE; -+ rela2->type = absolute_rela_type; - rela2->addend = offset_of_string(&kelf->strings, sym_objname); - rela2->offset = (unsigned int)(index * sizeof(*ksyms) + \ - offsetof(struct kpatch_symbol, objname)); -@@ -2984,7 +3085,7 @@ static void kpatch_create_intermediate_sections(struct kpatch_elf *kelf, - ERROR("can't create dynrela for section %s (symbol %s): no bundled or section symbol", - sec->name, rela->sym->name); - -- rela2->type = ABSOLUTE_RELA_TYPE; -+ rela2->type = absolute_rela_type; - rela2->addend = rela->offset; - rela2->offset = (unsigned int)(index * sizeof(*krelas) + \ - offsetof(struct kpatch_relocation, dest)); -@@ -2992,7 +3093,7 @@ static void kpatch_create_intermediate_sections(struct kpatch_elf *kelf, - /* add rela to fill in krelas[index].objname field */ - ALLOC_LINK(rela2, &krela_sec->rela->relas); - rela2->sym = strsym; -- rela2->type = ABSOLUTE_RELA_TYPE; -+ rela2->type = absolute_rela_type; - rela2->addend = offset_of_string(&kelf->strings, objname); - rela2->offset = (unsigned int)(index * sizeof(*krelas) + \ - offsetof(struct kpatch_relocation, objname)); -@@ -3000,7 +3101,7 @@ static void kpatch_create_intermediate_sections(struct kpatch_elf *kelf, - /* add rela to fill in krelas[index].ksym field */ - ALLOC_LINK(rela2, &krela_sec->rela->relas); - rela2->sym = ksym_sec_sym; -- rela2->type = ABSOLUTE_RELA_TYPE; -+ rela2->type = absolute_rela_type; - rela2->addend = (unsigned int)(index * sizeof(*ksyms)); - rela2->offset = (unsigned int)(index * sizeof(*krelas) + \ - offsetof(struct kpatch_relocation, ksym)); -@@ -3063,7 +3164,7 @@ static void kpatch_create_callbacks_objname_rela(struct kpatch_elf *kelf, char * - if (!strcmp(callbackp->name, sec->name)) { - ALLOC_LINK(rela, &sec->relas); - rela->sym = strsym; -- rela->type = ABSOLUTE_RELA_TYPE; -+ rela->type = absolute_rela_type; - rela->addend = objname_offset; - rela->offset = callbackp->offset; - break; -@@ -3116,40 +3215,79 @@ 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; -- rela->type = R_X86_64_64; -- rela->addend = 0; -- rela->offset = (unsigned int)(index * sizeof(void*)); -+ if (arch == EM_X86_64) { -+ rela->type = R_X86_64_64; -+ rela->addend = 0; -+ rela->offset = (unsigned int)(index * sizeof(void *)); - -- /* -- * Modify the first instruction of the function to "callq -- * __fentry__" so that ftrace will be happy. -- */ -- newdata = malloc(sym->sec->data->d_size); -- if (!newdata) -- ERROR("malloc"); -+ /* -+ * Modify the first instruction of the function to "callq -+ * __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; -+ memcpy(newdata, sym->sec->data->d_buf, sym->sec->data->d_size); -+ sym->sec->data->d_buf = newdata; -+ insn = newdata; - -- rela = list_first_entry(&sym->sec->rela->relas, struct rela, -+ rela = list_first_entry(&sym->sec->rela->relas, struct rela, - list); - -- /* -- * R_X86_64_NONE is only generated by older versions of kernel/gcc -- * which use the mcount script. -- */ -- if (rela->type == R_X86_64_NONE) { -- if (insn[0] != 0xf) -+ /* -+ * R_X86_64_NONE is only generated by older versions of kernel/gcc -+ * which use the mcount script. -+ */ -+ if (rela->type == R_X86_64_NONE) { -+ if (insn[0] != 0xf) -+ ERROR("%s: unexpected instruction at the start of the function", -+ sym->name); -+ insn[0] = 0xe8; -+ insn[1] = 0; -+ insn[2] = 0; -+ insn[3] = 0; -+ insn[4] = 0; -+ -+ 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 = (unsigned int)(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; -+ -+ /* -+ * mov x9, x30 -+ * nop //function in .text., so it be replaced with nop by -+ * recordmcount -+ * -+ * mov x30, x9 -+ */ -+ if (insnp[0] != 0xaa1e03e9 || insnp[1] != 0xd503201f -+ || insnp[2] != 0xaa0903fe) - ERROR("%s: unexpected instruction at the start of the function", -- sym->name); -- insn[0] = 0xe8; -- insn[1] = 0; -- insn[2] = 0; -- insn[3] = 0; -- insn[4] = 0; -- -- rela->type = R_X86_64_PC32; -+ sym->name); -+ -+ /* change the nop to bl __fentry__ */ -+ insnp[1] = 0x94000000; -+ rela = list_first_entry(&sym->sec->rela->relas, struct rela, -+ list); -+ rela->type = R_AARCH64_CALL26; -+ rela->offset = 4; -+ -+ } else { -+ ERROR("unsupport arch %d\n", arch); - } - - index++; -@@ -3349,6 +3489,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, *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); -@@ -3369,6 +3511,13 @@ int main(int argc, char *argv[]) - - kelf_base = kpatch_elf_open(orig_obj); - kelf_patched = kpatch_elf_open(patched_obj); -+ arch = arch_of_elf(kelf_base->elf); -+ if (arch == EM_X86_64) -+ absolute_rela_type = R_X86_64_64; -+ else if (arch == EM_AARCH64) -+ absolute_rela_type = R_AARCH64_ABS64; -+ else -+ ERROR("only arch x86_64 and arm64 be supported\n"); - - kpatch_compare_elf_headers(kelf_base->elf, kelf_patched->elf); - kpatch_check_program_headers(kelf_base->elf); -@@ -3407,7 +3556,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); - -@@ -3467,7 +3621,13 @@ 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"); -+ 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 -+ kpatch_create_mcount_sections(kelf_out); - - /* - * At this point, the set of output sections and symbols is -diff --git a/kpatch-build/create-kpatch-module.c b/kpatch-build/create-kpatch-module.c -index 3d197a7..e8a235d 100644 ---- a/kpatch-build/create-kpatch-module.c -+++ b/kpatch-build/create-kpatch-module.c -@@ -31,6 +31,18 @@ - char *childobj; - enum loglevel loglevel = NORMAL; - -+static unsigned int arch; -+static unsigned int absolute_rela_type; -+ -+static unsigned int arch_of_elf(Elf *elf) -+{ -+ GElf_Ehdr eh; -+ -+ if (!gelf_getehdr(elf, &eh)) -+ ERROR("gelf_getehdr"); -+ return eh.e_machine; -+} -+ - /* - * Create .kpatch.dynrelas from .kpatch.relocations and .kpatch.symbols sections - * -@@ -102,14 +114,14 @@ static void create_dynamic_rela_sections(struct kpatch_elf *kelf, struct section - /* dest */ - ALLOC_LINK(rela, &dynsec->rela->relas); - rela->sym = sym; -- rela->type = R_X86_64_64; -+ rela->type = absolute_rela_type; - rela->addend = dest_offset; - rela->offset = (unsigned int)(index * sizeof(*dynrelas)); - - /* name */ - ALLOC_LINK(rela, &dynsec->rela->relas); - rela->sym = strsec->secsym; -- rela->type = R_X86_64_64; -+ rela->type = absolute_rela_type; - rela->addend = name_offset; - rela->offset = (unsigned int)(index * sizeof(*dynrelas) + \ - offsetof(struct kpatch_patch_dynrela, name)); -@@ -117,7 +129,7 @@ static void create_dynamic_rela_sections(struct kpatch_elf *kelf, struct section - /* objname */ - ALLOC_LINK(rela, &dynsec->rela->relas); - rela->sym = strsec->secsym; -- rela->type = R_X86_64_64; -+ rela->type = absolute_rela_type; - rela->addend = objname_offset; - rela->offset = (unsigned int)(index * sizeof(*dynrelas) + \ - offsetof(struct kpatch_patch_dynrela, objname)); -@@ -200,6 +212,13 @@ int main(int argc, char *argv[]) - childobj = basename(arguments.args[0]); - - kelf = kpatch_elf_open(arguments.args[0]); -+ arch = arch_of_elf(kelf->elf); -+ if (arch == EM_X86_64) -+ absolute_rela_type = R_X86_64_64; -+ else if (arch == EM_AARCH64) -+ absolute_rela_type = R_AARCH64_ABS64; -+ else -+ ERROR("only arch x86_64 and arm64 be supported\n"); - - /* - * Sanity checks: -diff --git a/kpatch-build/kpatch-build b/kpatch-build/kpatch-build -index ae0733c..17a5e11 100755 ---- a/kpatch-build/kpatch-build -+++ b/kpatch-build/kpatch-build -@@ -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 - } - -+arch_export() { -+ E_MACHINE=$(od -An -j18 -N2 -d $VMLINUX) -+ if [[ $E_MACHINE -eq 62 ]]; then -+ export ARCH=x86_64 -+ export ARCH_COMPILE= -+ export ENDIAN=little -+ export GCC_ADD_OPTION= -+ elif [[ $E_MACHINE -eq 183 ]]; then -+ export ARCH=arm64 -+ if [ $(arch) != "aarch64" ]; then -+ export ARCH_COMPILE=aarch64-linux-gnu- -+ fi -+ export ENDIAN=little -+ 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" -+ fi -+ else -+ die "only support arm64 or x86_64 architecture" -+ fi -+} -+ - # Only allow alphanumerics and '_' and '-' in the module name. Everything else - # is replaced with '-'. Also truncate to 48 chars so the full name fits in the - # kernel's 56-byte module name array. -@@ -786,13 +869,13 @@ apply_patches - remove_patches - - cp -LR "$DATADIR/patch" "$TEMPDIR" || die -- -+arch_export - if [[ "$ARCH" = "ppc64le" ]]; then - ARCH_KCFLAGS="-mcmodel=large -fplugin=$PLUGINDIR/ppc64le-plugin.so" - fi - - export KCFLAGS="-I$DATADIR/patch -ffunction-sections -fdata-sections \ -- $ARCH_KCFLAGS $DEBUG_KCFLAGS" -+ $ARCH_KCFLAGS $DEBUG_KCFLAGS ${GCC_ADD_OPTION}" - - echo "Reading special section data" - find_special_section_data -@@ -806,7 +889,7 @@ echo "Building original source" - 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 -+CROSS_COMPILE="$TOOLSDIR/kpatch-gcc $ARCH_COMPILE" make "-j$CPUS" $TARGETS 2>&1 | logger || die - - 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 --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 [[ -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 -@@ -962,12 +1065,12 @@ fi - cd "$TEMPDIR/output" || die - # $KPATCH_LDFLAGS and result of find used as list, no quotes. - # shellcheck disable=SC2086,SC2046 --ld -r $KPATCH_LDFLAGS -o ../patch/tmp_output.o $(find . -name "*.o") 2>&1 | logger || die -+${ARCH_COMPILE}ld -r $KPATCH_LDFLAGS -o ../patch/tmp_output.o $(find . -name "*.o") 2>&1 | logger || die - - if "$KPATCH_MODULE"; then - # Add .kpatch.checksum for kpatch script - md5sum ../patch/tmp_output.o | awk '{printf "%s\0", $1}' > checksum.tmp || die -- objcopy --add-section .kpatch.checksum=checksum.tmp --set-section-flags .kpatch.checksum=alloc,load,contents,readonly ../patch/tmp_output.o || die -+ ${ARCH_COMPILE}objcopy --add-section .kpatch.checksum=checksum.tmp --set-section-flags .kpatch.checksum=alloc,load,contents,readonly ../patch/tmp_output.o || die - rm -f checksum.tmp - "$TOOLSDIR"/create-kpatch-module "$TEMPDIR"/patch/tmp_output.o "$TEMPDIR"/patch/output.o 2>&1 | logger 1 - check_pipe_status create-kpatch-module -@@ -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" \ - make 2>&1 | logger || die - - if ! "$KPATCH_MODULE"; then -diff --git a/kpatch-build/kpatch-gcc b/kpatch-build/kpatch-gcc -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 - while [ "$#" -gt 0 ]; do - if [ "$1" = "-o" ]; then - obj="$2" -@@ -60,7 +60,7 @@ if [[ "$TOOLCHAINCMD" =~ "gcc" ]] ; then - fi - shift - done --elif [[ "$TOOLCHAINCMD" = "ld" ]] ; then -+elif [[ "$TOOLCHAINCMD" = "${ARCH_COMPILE}ld" ]] ; then - while [ "$#" -gt 0 ]; do - if [ "$1" = "-o" ]; then - obj="$2" --- -2.18.1 - diff --git a/0003-create-diff-object-support-kpatch_line_macro_change_.patch b/0003-create-diff-object-support-kpatch_line_macro_change_.patch new file mode 100644 index 0000000000000000000000000000000000000000..bc0d92f759c2b8b26e14091ced4ce010d5943003 --- /dev/null +++ b/0003-create-diff-object-support-kpatch_line_macro_change_.patch @@ -0,0 +1,90 @@ +From b71b6e5f46fdc3f1b709b58777cb0da7ec9fc008 Mon Sep 17 00:00:00 2001 +From: Zhipeng Xie +Date: Sun, 14 Nov 2021 17:26:59 +0800 +Subject: [PATCH 03/24] create-diff-object:support + kpatch_line_macro_change_only on aarch64 + +implement kpatch_line_macro_change_only on aarch64 + +Signed-off-by: Zhipeng Xie +--- + kpatch-build/create-diff-object.c | 63 +++++++++++++++++++++++++++++++ + 1 file changed, 63 insertions(+) + +diff --git a/kpatch-build/create-diff-object.c b/kpatch-build/create-diff-object.c +index 6c28280..c20f75e 100644 +--- a/kpatch-build/create-diff-object.c ++++ b/kpatch-build/create-diff-object.c +@@ -757,6 +757,69 @@ static bool kpatch_line_macro_change_only(struct section *sec) + + return true; + } ++#elif __aarch64__ ++#define ARM64_INSTR_LEN 4 ++ ++static bool 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; ++} + #else + static bool kpatch_line_macro_change_only(struct section *sec) + { +-- +2.23.0 + diff --git a/0004-create-diff-object-support-skip-check-func-profiling.patch b/0004-create-diff-object-support-skip-check-func-profiling.patch new file mode 100644 index 0000000000000000000000000000000000000000..3b6a25c718d733bb99ee1722bd8833ad134d40cd --- /dev/null +++ b/0004-create-diff-object-support-skip-check-func-profiling.patch @@ -0,0 +1,43 @@ +From f82f5ff61b8087e203a994da3911a1c5f3dee978 Mon Sep 17 00:00:00 2001 +From: Zhipeng Xie +Date: Sun, 14 Nov 2021 19:53:22 +0800 +Subject: [PATCH 04/24] create-diff-object:support skip check func profiling + calls + +when kernel support livepatch without ftrace, we can skip check +func profiling calls. + +Signed-off-by: Zhipeng Xie +--- + kpatch-build/create-diff-object.c | 8 +++++++- + 1 file changed, 7 insertions(+), 1 deletion(-) + +diff --git a/kpatch-build/create-diff-object.c b/kpatch-build/create-diff-object.c +index c20f75e..7247345 100644 +--- a/kpatch-build/create-diff-object.c ++++ b/kpatch-build/create-diff-object.c +@@ -3773,6 +3773,7 @@ int main(int argc, char *argv[]) + struct section *sec, *symtab; + char *orig_obj, *patched_obj, *parent_name; + char *parent_symtab, *mod_symvers, *patch_name, *output_obj; ++ char *no_profiling_calls = NULL; + + memset(&arguments, 0, sizeof(arguments)); + argp_parse (&argp, argc, argv, 0, NULL, &arguments); +@@ -3824,7 +3825,12 @@ int main(int argc, char *argv[]) + kpatch_compare_correlated_elements(kelf_patched); + kpatch_mark_ignored_functions_same(kelf_patched); + kpatch_mark_ignored_sections_same(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_orig); + kpatch_elf_free(kelf_orig); + +-- +2.23.0 + diff --git a/0004-livepatch-fix-use-THIS-modname-as-the-name-of-ddebug.patch b/0004-livepatch-fix-use-THIS-modname-as-the-name-of-ddebug.patch deleted file mode 100644 index 4990de1b5fb39e09f7ecbf2a00f3607a37a75da5..0000000000000000000000000000000000000000 --- a/0004-livepatch-fix-use-THIS-modname-as-the-name-of-ddebug.patch +++ /dev/null @@ -1,32 +0,0 @@ -From 67c3fb57cf0b991c4f70aec78bdf25a47fb590b4 Mon Sep 17 00:00:00 2001 -From: Zhipeng Xie -Date: Fri, 2 Nov 2018 17:24:42 +0000 -Subject: [PATCH 04/23] livepatch, fix: use THIS modname as the name of - ddebug_table - -We just want a unique name for every module, so put a _ddebug in -this file as the first of _ddebug array. Then remove path will work -correctly, use the mod->name. - -Suggested-by: Li Bin -Signed-off-by: Zhou Chengming -Signed-off-by: Zhipeng Xie ---- - 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 e12fd50..6ae40de 100644 ---- a/kmod/patch/livepatch-patch-hook.c -+++ b/kmod/patch/livepatch-patch-hook.c -@@ -473,6 +473,7 @@ out: - - static void __exit patch_exit(void) - { -+ pr_debug("make THIS modname first\n"); - #ifndef HAVE_SIMPLE_ENABLE - WARN_ON(klp_unregister_patch(lpatch)); - #endif --- -2.18.1 - diff --git a/0003-create-diff-object-new-static-var-should-be-included.patch b/0005-create-diff-object-new-static-var-should-be-included.patch similarity index 82% rename from 0003-create-diff-object-new-static-var-should-be-included.patch rename to 0005-create-diff-object-new-static-var-should-be-included.patch index b3a8e5fc55cdd9f182dc2fbd24219b0984bd63be..610bfe1fccc6a25dd70c7620d3bac57effb53c3d 100644 --- a/0003-create-diff-object-new-static-var-should-be-included.patch +++ b/0005-create-diff-object-new-static-var-should-be-included.patch @@ -1,7 +1,7 @@ -From 232f97ae9acb73ad7bb0b974f6a94ae4c4ca03d9 Mon Sep 17 00:00:00 2001 +From fb93c5a8dfbc035ade8fc40b75b85018afaeed2e Mon Sep 17 00:00:00 2001 From: Zhipeng Xie Date: Tue, 25 Feb 2020 22:44:50 -0500 -Subject: [PATCH 03/23] create-diff-object: new static var should be included +Subject: [PATCH 05/24] 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 @@ -18,10 +18,10 @@ Signed-off-by: Zhipeng Xie 1 file changed, 16 insertions(+) diff --git a/kpatch-build/create-diff-object.c b/kpatch-build/create-diff-object.c -index b161fee..b94060e 100644 +index 7247345..1be4fac 100644 --- a/kpatch-build/create-diff-object.c +++ b/kpatch-build/create-diff-object.c -@@ -1704,6 +1704,21 @@ static void kpatch_include_force_elements(struct kpatch_elf *kelf) +@@ -1909,6 +1909,21 @@ static void kpatch_include_force_elements(struct kpatch_elf *kelf) sym->include = 0; } @@ -43,14 +43,14 @@ index b161fee..b94060e 100644 static int kpatch_include_new_globals(struct kpatch_elf *kelf) { struct symbol *sym; -@@ -3573,6 +3588,7 @@ int main(int argc, char *argv[]) +@@ -3839,6 +3854,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_debug_sections(kelf_patched); - kpatch_process_special_sections(kelf_patched); + kpatch_process_special_sections(kelf_patched, lookup); -- -2.18.1 +2.23.0 diff --git a/0006-create-diff-object-don-t-create-dynamic-reloc-for-sy.patch b/0006-create-diff-object-don-t-create-dynamic-reloc-for-sy.patch deleted file mode 100644 index 828da77e4ae42c4953d5e83e7bd3d37409ac5105..0000000000000000000000000000000000000000 --- a/0006-create-diff-object-don-t-create-dynamic-reloc-for-sy.patch +++ /dev/null @@ -1,31 +0,0 @@ -From 30446d9a1a65c8369a54844d471c2aeb4c9139dd Mon Sep 17 00:00:00 2001 -From: Zhipeng Xie -Date: Fri, 2 Nov 2018 17:24:58 +0000 -Subject: [PATCH 06/23] create-diff-object: don't create dynamic reloc for - symbol exported by patch itself - -when a patch export a new function, ___kcrctab+xxx has a reloc, -use origin reloc to get right symbol version. - -Signed-off-by: Zhipeng Xie ---- - 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 3681adb..ba2976b 100644 ---- a/kpatch-build/create-diff-object.c -+++ b/kpatch-build/create-diff-object.c -@@ -3056,6 +3056,9 @@ static void kpatch_create_intermediate_sections(struct kpatch_elf *kelf, - if (!strcmp(sym_objname, "vmlinux")) - continue; - -+ if (!strcmp(sym_objname, objname)) -+ continue; -+ - external = 1; - } - } --- -2.18.1 - diff --git a/0005-create-diff-object-fix-correlate-static-local-variab.patch b/0006-create-diff-object-fix-correlate-static-local-variab.patch similarity index 85% rename from 0005-create-diff-object-fix-correlate-static-local-variab.patch rename to 0006-create-diff-object-fix-correlate-static-local-variab.patch index aceb5befd6256d5de65f369ad2f317cd5246201e..7ced282b65b56fd1c13f6b69a750ae37af40b777 100644 --- a/0005-create-diff-object-fix-correlate-static-local-variab.patch +++ b/0006-create-diff-object-fix-correlate-static-local-variab.patch @@ -1,7 +1,7 @@ -From 24c01beb0ac8cee521ba654ece6c22f6ce9bdafe Mon Sep 17 00:00:00 2001 +From 80b74891e1d609d7881f9c9d29fe4828c49e2d83 Mon Sep 17 00:00:00 2001 From: Zhipeng Xie Date: Fri, 2 Nov 2018 17:24:51 +0000 -Subject: [PATCH 05/23] create-diff-object: fix correlate static local +Subject: [PATCH 06/24] create-diff-object: fix correlate static local variables for __param section kpatch-build correlate fail when no sections reference @@ -31,20 +31,20 @@ Signed-off-by: Zhipeng Xie 1 file changed, 4 insertions(+) diff --git a/kpatch-build/create-diff-object.c b/kpatch-build/create-diff-object.c -index b94060e..3681adb 100644 +index 1be4fac..7efe7b4 100644 --- a/kpatch-build/create-diff-object.c +++ b/kpatch-build/create-diff-object.c -@@ -1108,6 +1108,10 @@ static int kpatch_is_normal_static_local(struct symbol *sym) +@@ -1277,6 +1277,10 @@ static bool kpatch_is_normal_static_local(struct symbol *sym) if (is_special_static(sym)) - return 0; + return false; + if (!strncmp(sym->name, "__param_", strlen("__param_")) && + !strncmp(sym->sec->name, "__param", strlen("__param"))) -+ return 0; ++ return false; + - return 1; + return true; } -- -2.18.1 +2.23.0 diff --git a/0008-fix-rodata.str-problem.patch b/0007-fix-rodata.str-problem.patch similarity index 76% rename from 0008-fix-rodata.str-problem.patch rename to 0007-fix-rodata.str-problem.patch index 803c7399adfef5aa0dfaa2283e152a2a06b919a7..9e8cb419482b87de18954f25d1b8d54b7a2d7068 100644 --- a/0008-fix-rodata.str-problem.patch +++ b/0007-fix-rodata.str-problem.patch @@ -1,7 +1,7 @@ -From 9f30a27617915ee8c59aa43d9165d938129796b3 Mon Sep 17 00:00:00 2001 +From 42cfc6a9add67e23433bf431da74d6babe38be61 Mon Sep 17 00:00:00 2001 From: Zhiyu Hu Date: Fri, 28 Dec 2018 07:06:38 +0000 -Subject: [PATCH 08/23] fix rodata.str problem +Subject: [PATCH 07/24] fix rodata.str problem fix some rodata.str problem @@ -11,10 +11,10 @@ Signed-off-by: Zhiyu Hu 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kpatch-build/create-diff-object.c b/kpatch-build/create-diff-object.c -index 8ce3b59..f37d404 100644 +index 7efe7b4..18aff6d 100644 --- a/kpatch-build/create-diff-object.c +++ b/kpatch-build/create-diff-object.c -@@ -1634,7 +1634,7 @@ static void kpatch_include_standard_elements(struct kpatch_elf *kelf) +@@ -1838,7 +1838,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 8ce3b59..f37d404 100644 } } -- -2.18.1 +2.23.0 diff --git a/0009-livepatch-patch-hook-don-t-active-patch-when-insmod.patch b/0008-livepatch-patch-hook-support-no-active-after-load.patch similarity index 54% rename from 0009-livepatch-patch-hook-don-t-active-patch-when-insmod.patch rename to 0008-livepatch-patch-hook-support-no-active-after-load.patch index 226e691e9ae944c487ade2c02d8790bb11692a77..811d543008ae7a9b7f9953d16da17fdb4b7a93e2 100644 --- a/0009-livepatch-patch-hook-don-t-active-patch-when-insmod.patch +++ b/0008-livepatch-patch-hook-support-no-active-after-load.patch @@ -1,22 +1,22 @@ -From 1bc8c76085839576576fc780336fbd9d7ebd29ef Mon Sep 17 00:00:00 2001 +From 3d3cb8c0b294a60faaeb68e0d7361babdc1b8902 Mon Sep 17 00:00:00 2001 From: Zhipeng Xie Date: Tue, 25 Feb 2020 23:40:37 -0500 -Subject: [PATCH 09/23] livepatch-patch-hook: don't active patch when insmod +Subject: [PATCH 08/24] livepatch-patch-hook: support no active after load -Don't active patch after loading the patch when +suppport 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(+) + kpatch-build/kpatch-build | 5 +++++ + 2 files changed, 7 insertions(+) diff --git a/kmod/patch/livepatch-patch-hook.c b/kmod/patch/livepatch-patch-hook.c -index 6ae40de..fb23a94 100644 +index 3d13ab9..b578ef3 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) +@@ -576,6 +576,7 @@ static int __init patch_init(void) } #endif @@ -24,7 +24,7 @@ index 6ae40de..fb23a94 100644 ret = klp_enable_patch(lpatch); if (ret) { #ifndef HAVE_SIMPLE_ENABLE -@@ -463,6 +464,7 @@ static int __init patch_init(void) +@@ -584,6 +585,7 @@ static int __init patch_init(void) patch_free_livepatch(lpatch); return ret; } @@ -33,20 +33,21 @@ index 6ae40de..fb23a94 100644 return 0; out: diff --git a/kpatch-build/kpatch-build b/kpatch-build/kpatch-build -index 17a5e11..894f0ab 100755 +index ad3a079..c85e05a 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" +@@ -1176,6 +1176,11 @@ export KCFLAGS="-I$DATADIR/patch $ARCH_KCFLAGS" + if [[ "$USE_KLP" -eq 0 ]]; then + export KCPPFLAGS="-D__KPATCH_MODULE__" fi - ++ +if [[ -n "$DISABLE_AFTER_LOAD" ]];then -+ export KCPPFLAGS="-DDISABLE_AFTER_LOAD $KCPPFLAGS" ++ export KCPPFLAGS="-DDISABLE_AFTER_LOAD $KCPPFLAGS" +fi + - echo "Building patch module: $MODNAME.ko" + save_env - if [[ -z "$USERSRCDIR" ]] && [[ "$DISTRO" = ubuntu ]]; then + echo "Building patch module: $MODNAME.ko" -- -2.18.1 +2.23.0 diff --git a/0010-kpatch-build-enhance-for-out-of-tree-module.patch b/0009-kpatch-build-enhance-for-out-of-tree-module.patch similarity index 46% rename from 0010-kpatch-build-enhance-for-out-of-tree-module.patch rename to 0009-kpatch-build-enhance-for-out-of-tree-module.patch index 3c52d528beac2d82d65eafea8d8f052e6919a78a..7b672d516c3e37fd8b070bf256133379b96f80a2 100644 --- a/0010-kpatch-build-enhance-for-out-of-tree-module.patch +++ b/0009-kpatch-build-enhance-for-out-of-tree-module.patch @@ -1,21 +1,22 @@ -From a1303033db88fa0036387f3a86f71d162bd5c037 Mon Sep 17 00:00:00 2001 +From 12530d7f476e8629fc7e50443f34164a43ef18b6 Mon Sep 17 00:00:00 2001 From: Zhipeng Xie Date: Wed, 26 Feb 2020 06:44:06 -0500 -Subject: [PATCH 10/23] kpatch-build: enhance for out of tree module +Subject: [PATCH 09/24] 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(-) + kpatch-build/kpatch-build | 62 +++++++++++++++++++++++++++++++-------- + kpatch-build/kpatch-cc | 4 ++- + 2 files changed, 53 insertions(+), 13 deletions(-) diff --git a/kpatch-build/kpatch-build b/kpatch-build/kpatch-build -index 894f0ab..4e38412 100755 +index c85e05a..3aca1f3 100755 --- a/kpatch-build/kpatch-build +++ b/kpatch-build/kpatch-build -@@ -419,7 +419,11 @@ filter_parent_obj() +@@ -492,7 +492,11 @@ filter_parent_obj() local dir="${1}" local file="${2}" @@ -28,7 +29,7 @@ index 894f0ab..4e38412 100755 } find_parent_obj() { -@@ -441,6 +445,11 @@ find_parent_obj() { +@@ -514,6 +518,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 @@ -40,7 +41,7 @@ index 894f0ab..4e38412 100755 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 +@@ -703,6 +712,10 @@ if [[ -n "$SRCRPM" ]]; then ARCHVERSION="${ARCHVERSION#alt-}" fi @@ -51,7 +52,7 @@ index 894f0ab..4e38412 100755 if [[ -n "$OOT_MODULE" ]] && [[ -z "$USERSRCDIR" ]]; then warn "--oot-module requires --sourcedir" exit 1 -@@ -663,7 +676,7 @@ if [[ -n "$USERSRCDIR" ]]; then +@@ -720,7 +733,7 @@ if [[ -n "$USERSRCDIR" ]]; then fi SRCDIR="$USERSRCDIR" @@ -60,7 +61,7 @@ index 894f0ab..4e38412 100755 [[ -z "$VMLINUX" ]] && VMLINUX="$SRCDIR"/vmlinux [[ ! -e "$VMLINUX" ]] && die "can't find vmlinux" -@@ -685,7 +698,7 @@ if [[ "$ARCHVERSION" =~ - ]]; then +@@ -742,7 +755,7 @@ if [[ "$ARCHVERSION" =~ - ]]; then fi [[ "$ARCHVERSION" =~ .el7a. ]] && ALT="-alt" @@ -69,39 +70,69 @@ index 894f0ab..4e38412 100755 # Don't check external file. # shellcheck disable=SC1090 -@@ -889,7 +902,11 @@ echo "Building original source" - unset KPATCH_GCC_TEMPDIR +@@ -870,7 +883,9 @@ fi + [[ -z "$CONFIGFILE" ]] && CONFIGFILE="$SRCDIR"/.config + [[ ! -e "$CONFIGFILE" ]] && die "can't find config file" + if [[ ! "$CONFIGFILE" -ef "$SRCDIR"/.config ]] ; then +- cp -f "$CONFIGFILE" "$SRCDIR/.config" || die ++ if [[ -z "$OOT_MODULE" ]] ; then ++ cp -f "$CONFIGFILE" "$SRCDIR/.config" || die ++ fi + fi + + # kernel option checking +@@ -947,7 +962,7 @@ if [[ "$CONFIG_CC_IS_CLANG" -eq 1 ]]; then + fi + + if [[ "$SKIPCOMPILERCHECK" -eq 0 ]]; then +- if [[ -n "$OOT_MODULE" ]]; then ++ if [[ -n "$OOT_MODULE" ]] && [[ "$OOT_MODULE" != "yes" ]]; then + target="$OOT_MODULE" + else + target="$VMLINUX" +@@ -1005,10 +1020,16 @@ fi + # $TARGETS used as list, no quotes. # shellcheck disable=SC2086 --CROSS_COMPILE="$TOOLSDIR/kpatch-gcc $ARCH_COMPILE" make "-j$CPUS" $TARGETS 2>&1 | logger || die +-make "${MAKEVARS[@]}" "-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 ++ make "${MAKEVARS[@]}" "-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 ++ make "${MAKEVARS[@]}" -C "$USERMODBUILDDIR" M="$USERMODBUILDDIR" $USERMODFLAGS "-j$CPUS" $TARGETS 2>&1 | logger || die ++fi + + # Save original module symvers +-cp -f "$SRCDIR/Module.symvers" "$TEMPDIR/Module.symvers" || die ++if [[ "$OOT_MODULE" != "yes" ]]; then ++ cp -f "$SRCDIR/Module.symvers" "$TEMPDIR/Module.symvers" || die +fi echo "Building patched source" apply_patches -@@ -900,9 +917,15 @@ KPATCH_GCC_SRCDIR="$SRCDIR" - export KPATCH_GCC_SRCDIR +@@ -1018,7 +1039,12 @@ export KPATCH_GCC_SRCDIR="$SRCDIR" + save_env # $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 +-KBUILD_MODPOST_WARN=1 make "${MAKEVARS[@]}" "-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 ++ KBUILD_MODPOST_WARN=1 make "${MAKEVARS[@]}" "-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 ++ KBUILD_MODPOST_WARN=1 make "${MAKEVARS[@]}" -C "$USERMODBUILDDIR" M="$USERMODBUILDDIR" $USERMODFLAGS "-j$CPUS" $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 +@@ -1033,7 +1059,7 @@ fi + + [[ -n "$OOT_MODULE" ]] || grep -q vmlinux "$SRCDIR/Module.symvers" || die "truncated $SRCDIR/Module.symvers file" + +-if [[ "$CONFIG_MODVERSIONS" -eq 1 ]]; then ++if [[ "$CONFIG_MODVERSIONS" -eq 1 ]] && [[ "$OOT_MODULE" != "yes" ]]; then + while read -ra sym_line; do + if [[ ${#sym_line[@]} -lt 4 ]]; then + die "Malformed ${TEMPDIR}/Module.symvers file" +@@ -1061,7 +1087,11 @@ fi for i in $(cat "$TEMPDIR/changed_objs") do mkdir -p "$TEMPDIR/patched/$(dirname "$i")" || die @@ -114,7 +145,16 @@ index 894f0ab..4e38412 100755 done echo "Extracting new and modified ELF sections" -@@ -987,6 +1014,13 @@ for i in $FILES; do +@@ -1095,7 +1125,7 @@ CHANGED=0 + ERROR=0 + + # Prepare OOT module symvers file +-if [[ -n "$OOT_MODULE" ]]; then ++if [[ -n "$OOT_MODULE" ]] && [[ "$OOT_MODULE" != "yes" ]]; then + BUILDDIR="/lib/modules/$ARCHVERSION/build/" + cp -f "$SRCDIR/Module.symvers" "$TEMPDIR/Module.symvers" || die + awk '{ print $1 "\t" $2 "\t" $3 "\t" $4}' "${BUILDDIR}/Module.symvers" >> "$TEMPDIR/Module.symvers" +@@ -1131,6 +1161,14 @@ for i in $FILES; do KOBJFILE_PATH="${TEMPDIR}/module/$KOBJFILE" SYMTAB="${KOBJFILE_PATH}.symtab" SYMVERS_FILE="$SRCDIR/Module.symvers" @@ -123,11 +163,36 @@ index 894f0ab..4e38412 100755 + BUILDDIR="/lib/modules/$ARCHVERSION/build/" + SYMVERS_FILE="$TEMPDIR/Module.symvers" + [[ -e $SRCDIR/Module.symvers ]] && cp "$SRCDIR/Module.symvers" "$SYMVERS_FILE" ++ [[ -e $USERMODBUILDDIR/Module.symvers ]] && cp "$USERMODBUILDDIR/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" +@@ -1283,7 +1321,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-cc b/kpatch-build/kpatch-cc +index 476436f..7ee1655 100755 +--- a/kpatch-build/kpatch-cc ++++ b/kpatch-build/kpatch-cc +@@ -24,7 +24,9 @@ if [[ "$TOOLCHAINCMD" =~ ^(.*-)?gcc$ || "$TOOLCHAINCMD" =~ ^(.*-)?clang$ ]] ; th + + [[ "$obj" = */.tmp_*.o ]] && obj="${obj/.tmp_/}" + relobj=${obj//$KPATCH_GCC_SRCDIR\//} +- case "$relobj" in ++ tmpobj=$(readlink -f $obj) ++ relobj2=${tmpobj//$KPATCH_GCC_SRCDIR\//} ++ case "$relobj2" in + *.mod.o|\ + *built-in.o|\ + *built-in.a|\ -- -2.18.1 +2.23.0 diff --git a/0011-support-c-plus-kernel-module.patch b/0010-support-c-kernel-module.patch similarity index 52% rename from 0011-support-c-plus-kernel-module.patch rename to 0010-support-c-kernel-module.patch index 5bb0b7e4a3680467422b91b95b1dd9555a07f343..87f173cb66de69699f25702df3877766e259b185 100644 --- a/0011-support-c-plus-kernel-module.patch +++ b/0010-support-c-kernel-module.patch @@ -1,7 +1,7 @@ -From d170861502e78c396f0283f66f444a496efd11de Mon Sep 17 00:00:00 2001 +From 86bae0f77f1e11f6b64eb950c739f7c6b444eb43 Mon Sep 17 00:00:00 2001 From: Zhipeng Xie Date: Wed, 26 Feb 2020 07:36:59 -0500 -Subject: [PATCH 11/23] support c plus kernel module +Subject: [PATCH 10/24] support c++ kernel module support GNU_UNIQUE type symbols. support .group section corelation. @@ -9,18 +9,17 @@ ignore compile warning for third party modules. Signed-off-by: Zhipeng Xie --- - kpatch-build/create-diff-object.c | 60 +++++++++++++++++++++---------- - 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(+), 23 deletions(-) + kpatch-build/create-diff-object.c | 48 ++++++++++++++++++++----------- + kpatch-build/kpatch-cc | 4 ++- + kpatch-build/kpatch-elf.c | 8 +++++- + kpatch-build/lookup.c | 5 +++- + 4 files changed, 45 insertions(+), 20 deletions(-) diff --git a/kpatch-build/create-diff-object.c b/kpatch-build/create-diff-object.c -index f37d404..d139f45 100644 +index 18aff6d..5903803 100644 --- a/kpatch-build/create-diff-object.c +++ b/kpatch-build/create-diff-object.c -@@ -460,7 +460,7 @@ static void kpatch_compare_correlated_nonrela_section(struct section *sec) +@@ -539,7 +539,7 @@ static void kpatch_compare_correlated_nonrela_section(struct section *sec) { struct section *sec1 = sec, *sec2 = sec->twin; @@ -29,7 +28,7 @@ index f37d404..d139f45 100644 memcmp(sec1->data->d_buf, sec2->data->d_buf, sec1->data->d_size)) sec->status = CHANGED; else -@@ -476,7 +476,7 @@ static void kpatch_compare_correlated_section(struct section *sec) +@@ -555,7 +555,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 && @@ -38,12 +37,12 @@ index f37d404..d139f45 100644 DIFF_FATAL("%s section header details differ from %s", sec1->name, sec2->name); /* Short circuit for mcount sections, we rebuild regardless */ -@@ -913,6 +913,34 @@ static void kpatch_correlate_section(struct section *sec1, struct section *sec2) - kpatch_correlate_symbol(sec1->sym, sec2->sym); +@@ -1024,6 +1024,34 @@ static void kpatch_correlate_section(struct section *sec_orig, + kpatch_correlate_symbol(sec_orig->sym, sec_patched->sym); } -+static int kpatch_correlate_group_section(struct list_head *seclist1, -+ struct list_head *seclist2, struct section *sec1, struct section *sec2) ++static int kpatch_correlate_group_section(struct list_head *seclist_orig, ++ struct list_head *seclist_patched, struct section *sec1, struct section *sec2) +{ + unsigned int *data1, *end1, *data2; + struct section *isec1, *isec2; @@ -56,10 +55,10 @@ index f37d404..d139f45 100644 + data1++; + data2++; + while (data1 < end1) { -+ isec1 = find_section_by_index(seclist1, *data1); ++ isec1 = find_section_by_index(seclist_orig, *data1); + if (!isec1) + ERROR("group section not found"); -+ isec2 = find_section_by_index(seclist2, *data2); ++ isec2 = find_section_by_index(seclist_patched, *data2); + if (!isec2) + ERROR("group section not found"); + if (strcmp(isec1->name, isec2->name)) @@ -70,36 +69,22 @@ index f37d404..d139f45 100644 + return 0; +} + - static void kpatch_correlate_sections(struct list_head *seclist1, struct list_head *seclist2) + static void kpatch_correlate_sections(struct list_head *seclist_orig, + struct list_head *seclist_patched) { - struct section *sec1, *sec2; -@@ -931,14 +959,19 @@ static void kpatch_correlate_sections(struct list_head *seclist1, struct list_he - 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 +@@ -1047,10 +1075,7 @@ static void kpatch_correlate_sections(struct list_head *seclist_orig, + * Changed group sections are currently not supported. */ -+ - if (sec1->sh.sh_type == SHT_GROUP) { -- if (sec1->data->d_size != sec2->data->d_size) + if (sec_orig->sh.sh_type == SHT_GROUP) { +- if (sec_orig->data->d_size != sec_patched->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)) +- if (memcmp(sec_orig->data->d_buf, sec_patched->data->d_buf, +- sec_orig->data->d_size)) ++ if (kpatch_correlate_group_section(seclist_orig, seclist_patched, sec_orig, sec_patched)) continue; } -@@ -1521,17 +1554,6 @@ static void kpatch_verify_patchability(struct kpatch_elf *kelf) +@@ -1725,17 +1750,6 @@ static void kpatch_verify_patchability(struct kpatch_elf *kelf) errs++; } @@ -117,24 +102,26 @@ index f37d404..d139f45 100644 /* * 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" +diff --git a/kpatch-build/kpatch-cc b/kpatch-build/kpatch-cc +index 7ee1655..80d310c 100755 +--- a/kpatch-build/kpatch-cc ++++ b/kpatch-build/kpatch-cc +@@ -13,7 +13,9 @@ fi - cp -f "$TEMPDIR/patch/$MODNAME.ko" "$BASE" || die + declare -a args=("$@") +-if [[ "$TOOLCHAINCMD" =~ ^(.*-)?gcc$ || "$TOOLCHAINCMD" =~ ^(.*-)?clang$ ]] ; then ++if [[ "$TOOLCHAINCMD" =~ ^(.*-)?gcc$ || ++ "$TOOLCHAINCMD" =~ ^(.*-)?g\+\+$ || ++ "$TOOLCHAINCMD" =~ ^(.*-)?clang$ ]] ; then + while [ "$#" -gt 0 ]; do + if [ "$1" = "-o" ]; then + obj="$2" diff --git a/kpatch-build/kpatch-elf.c b/kpatch-build/kpatch-elf.c -index c6af59e..f76a9eb 100644 +index 68d5c86..2df9105 100644 --- a/kpatch-build/kpatch-elf.c +++ b/kpatch-build/kpatch-elf.c -@@ -710,8 +710,14 @@ void kpatch_reindex_elements(struct kpatch_elf *kelf) +@@ -712,8 +712,14 @@ void kpatch_reindex_elements(struct kpatch_elf *kelf) unsigned int index; index = 1; /* elf write function handles NULL section 0 */ @@ -150,25 +137,11 @@ index c6af59e..f76a9eb 100644 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 +index 0323c61..e81e934 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) +@@ -304,6 +304,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; @@ -177,16 +150,16 @@ index 8387e8b..4e2fcb9 100644 } else { ERROR("unknown symbol bind %s", bind); } -@@ -431,7 +433,8 @@ int lookup_global_symbol(struct lookup_table *table, char *name, +@@ -528,7 +530,8 @@ static bool 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) && +++ 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; + + if (result->objname) -- -2.18.1 +2.23.0 diff --git a/0012-symbol-lookup-enhancement.patch b/0011-symbol-lookup-enhancement.patch similarity index 59% rename from 0012-symbol-lookup-enhancement.patch rename to 0011-symbol-lookup-enhancement.patch index 1239e300cc000116bebc0b6bf82c11ac6a3aa16e..8c740da2cc043c00047a79678358bde128f7b657 100644 --- a/0012-symbol-lookup-enhancement.patch +++ b/0011-symbol-lookup-enhancement.patch @@ -1,7 +1,7 @@ -From 8dbdf64abc81a8c6f9ec71a4187eb7db9b81d090 Mon Sep 17 00:00:00 2001 +From 34a0c47eb0f786222b3f2e1fe544f71687920943 Mon Sep 17 00:00:00 2001 From: Zhipeng Xie Date: Wed, 26 Feb 2020 22:03:55 -0500 -Subject: [PATCH 12/23] symbol lookup enhancement +Subject: [PATCH 11/24] symbol lookup enhancement For symbols which have same name in one module or have length longger than KSYM_NAME_LEN(128 bytes). we add @@ -13,13 +13,13 @@ style. Signed-off-by: Zhipeng Xie --- kmod/patch/kpatch-patch.h | 4 + - kpatch-build/create-diff-object.c | 53 +++++++++++- - kpatch-build/create-klp-module.c | 25 +++++- + kpatch-build/create-diff-object.c | 40 +++++++- + kpatch-build/create-klp-module.c | 25 ++++- kpatch-build/kpatch-build | 12 +++ kpatch-build/kpatch-intermediate.h | 2 + - kpatch-build/lookup.c | 129 ++++++++++++++++++++++++++++- - kpatch-build/lookup.h | 13 +++ - 7 files changed, 230 insertions(+), 8 deletions(-) + kpatch-build/lookup.c | 159 ++++++++++++++++++++++++++++- + kpatch-build/lookup.h | 15 +++ + 7 files changed, 247 insertions(+), 10 deletions(-) diff --git a/kmod/patch/kpatch-patch.h b/kmod/patch/kpatch-patch.h index da4f6a0..9df7818 100644 @@ -44,111 +44,98 @@ index da4f6a0..9df7818 100644 struct kpatch_pre_patch_callback { diff --git a/kpatch-build/create-diff-object.c b/kpatch-build/create-diff-object.c -index d139f45..73c557b 100644 +index 5903803..ea1e01b 100644 --- a/kpatch-build/create-diff-object.c +++ b/kpatch-build/create-diff-object.c -@@ -2753,6 +2753,29 @@ static void kpatch_create_patches_sections(struct kpatch_elf *kelf, - funcs[index].old_size = result.size; - funcs[index].new_size = sym->sym.st_size; - funcs[index].sympos = result.pos; -+ if (lookup_is_duplicate_symbol(table, sym->name, objname, result.pos)) { -+ struct lookup_refsym refsym; -+ long offset; -+ -+ if (lookup_ref_symbol_offset(table, sym->name, &refsym, -+ objname, &offset)) -+ ERROR("unresolvable ambiguity on symbol %s\n", sym->name); -+ -+ funcs[index].ref_offset = offset; -+ -+ /* -+ * Add a relocation that will populate -+ * the funcs[index].ref_name field. -+ */ -+ ALLOC_LINK(rela, &relasec->relas); -+ rela->sym = strsym; -+ rela->type = absolute_rela_type; -+ rela->addend = offset_of_string(&kelf->strings, refsym.name); -+ rela->offset = (unsigned int)(index * sizeof(*funcs) + -+ offsetof(struct kpatch_patch_func, ref_name)); -+ +@@ -3032,6 +3032,14 @@ static void kpatch_create_patches_sections(struct kpatch_elf *kelf, + funcs[index].old_size = symbol.size; + funcs[index].new_size = sym->sym.st_size; + funcs[index].sympos = symbol.sympos; ++ if (lookup_is_duplicate_symbol(table, sym->name, objname, symbol.sympos)) { ++ if (!strcmp(objname, "vmlinux")) { ++ symbol.sympos = get_vmlinux_duplicate_symbol_pos(table, sym->name, symbol.addr); ++ log_debug("update %s sympos from %ld to %ld\n", ++ sym->name, funcs[index].sympos, symbol.sympos); ++ funcs[index].sympos = symbol.sympos; + } -+ ++ } - /* - * Add a relocation that will populate -@@ -2772,7 +2795,8 @@ 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, + /* + * Add a relocation that will populate the +@@ -3050,7 +3058,8 @@ 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 = (unsigned int)(index * sizeof(*funcs) + - offsetof(struct kpatch_patch_func, name)); + rela->offset = (unsigned int)(index * sizeof(*funcs) + + offsetof(struct kpatch_patch_func, name)); -@@ -2891,6 +2915,7 @@ static void kpatch_create_intermediate_sections(struct kpatch_elf *kelf, - struct lookup_result result; - char *sym_objname; - int ret, vmlinux, external; +@@ -3274,6 +3283,7 @@ static void kpatch_create_intermediate_sections(struct kpatch_elf *kelf, + bool special; + bool vmlinux = !strcmp(objname, "vmlinux"); + struct special_section *s; + long ref_offset; - vmlinux = !strcmp(objname, "vmlinux"); - -@@ -3102,12 +3127,32 @@ 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); + /* count rela entries that need to be dynamic */ + nr = 0; +@@ -3370,12 +3380,34 @@ static void kpatch_create_intermediate_sections(struct kpatch_elf *kelf, + rela->sym->name, symbol.objname, + symbol.sympos); + ref_offset = 0; /* Fill in ksyms[index] */ if (vmlinux) - ksyms[index].src = result.value; + ksyms[index].src = symbol.addr; - else + else { /* for modules, src is discovered at runtime */ ksyms[index].src = 0; -+ if (lookup_is_duplicate_symbol(table, rela->sym->name, objname, -+ result.pos)) { -+ struct lookup_refsym refsym; ++ } ++ ++ if (lookup_is_duplicate_symbol(table, rela->sym->name, objname, ++ symbol.sympos)) { ++ struct lookup_refsym refsym; + -+ if (lookup_ref_symbol_offset(table, rela->sym->name, -+ &refsym, objname, &ref_offset)) -+ ERROR("unresolvable ambiguity on symbol %s\n", -+ rela->sym->name); ++ if (lookup_ref_symbol_offset(table, rela->sym, ++ &refsym, objname, &ref_offset)) ++ ERROR("unresolvable ambiguity on symbol %s\n", ++ rela->sym->name); + -+ /* add rela to fill in ref_name field */ -+ ALLOC_LINK(rela2, &krela_sec->rela->relas); -+ rela2->sym = strsym; -+ rela2->type = absolute_rela_type; -+ rela2->addend = offset_of_string(&kelf->strings, -+ refsym.name); -+ rela2->offset = (unsigned int)(index * sizeof(*krelas) + ++ /* add rela to fill in ref_name field */ ++ ALLOC_LINK(rela2, &krela_sec->rela->relas); ++ rela2->sym = strsym; ++ rela2->type = ABSOLUTE_RELA_TYPE; ++ rela2->addend = offset_of_string(&kelf->strings, ++ refsym.name); ++ rela2->offset = (unsigned int)(index * sizeof(*krelas) + + offsetof(struct kpatch_relocation, ref_name)); -+ } + } - ksyms[index].pos = result.pos; ++ + ksyms[index].sympos = symbol.sympos; ksyms[index].type = rela->sym->type; ksyms[index].bind = rela->sym->bind; -@@ -3116,7 +3161,8 @@ static void kpatch_create_intermediate_sections(struct kpatch_elf *kelf, +@@ -3384,7 +3416,8 @@ 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->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 = (unsigned int)(index * sizeof(*ksyms) + \ offsetof(struct kpatch_symbol, name)); -@@ -3135,6 +3181,7 @@ static void kpatch_create_intermediate_sections(struct kpatch_elf *kelf, +@@ -3403,6 +3436,7 @@ static void kpatch_create_intermediate_sections(struct kpatch_elf *kelf, krelas[index].addend = rela->addend; krelas[index].type = rela->type; - krelas[index].external = external; + krelas[index].external = !vmlinux && symbol.exported; + krelas[index].ref_offset = ref_offset; /* add rela to fill in krelas[index].dest field */ ALLOC_LINK(rela2, &krela_sec->rela->relas); diff --git a/kpatch-build/create-klp-module.c b/kpatch-build/create-klp-module.c -index a97b146..5b89b73 100644 +index d1b03fe..547e587 100644 --- a/kpatch-build/create-klp-module.c +++ b/kpatch-build/create-klp-module.c @@ -38,7 +38,9 @@ enum loglevel loglevel = NORMAL; @@ -166,11 +153,11 @@ index a97b146..5b89b73 100644 objname = strings + rela->addend; -- snprintf(pos, 32, "%lu", ksym->pos); +- snprintf(pos, 32, "%lu", ksym->sympos); /* .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(pos, 32, "%lu", ksym->sympos); + snprintf(buf, 256, KLP_SYM_PREFIX "%s.%s,%s", objname, name, pos); + } else { + snprintf(pos, 32, "%ld", ref_offset); @@ -213,10 +200,10 @@ index a97b146..5b89b73 100644 ERROR("error finding or adding ksym to symtab"); diff --git a/kpatch-build/kpatch-build b/kpatch-build/kpatch-build -index 4896136..8bef7fb 100755 +index 3aca1f3..722d362 100755 --- a/kpatch-build/kpatch-build +++ b/kpatch-build/kpatch-build -@@ -1015,6 +1015,18 @@ for i in $FILES; do +@@ -1162,6 +1162,18 @@ for i in $FILES; do SYMTAB="${KOBJFILE_PATH}.symtab" SYMVERS_FILE="$SRCDIR/Module.symvers" @@ -224,9 +211,9 @@ index 4896136..8bef7fb 100755 + remove_patches + cd "$SRCDIR" || die + if [ -z "$USERMODBUILDDIR" ];then -+ CROSS_COMPILE="$ARCH_COMPILE" make "-j$CPUS" ${KOBJFILE} 2>&1 | logger || die ++ make "-j$CPUS" $TARGETS 2>&1 | logger || die + else -+ CROSS_COMPILE="$ARCH_COMPILE" make -C "$USERMODBUILDDIR" M="$USERMODBUILDDIR" "-j$CPUS" $USERMODFLAGS $TARGETS 2>&1 | logger || die ++ make -C "$USERMODBUILDDIR" M="$USERMODBUILDDIR" $USERMODFLAGS "-j$CPUS" $TARGETS 2>&1 | logger || die + fi + cp ${KOBJFILE} ${KOBJFILE_PATH} + apply_patches @@ -236,7 +223,7 @@ index 4896136..8bef7fb 100755 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 7230cd4..5322e7a 100644 +index 2036cb3..2589959 100644 --- a/kpatch-build/kpatch-intermediate.h +++ b/kpatch-build/kpatch-intermediate.h @@ -39,6 +39,8 @@ struct kpatch_relocation { @@ -249,10 +236,10 @@ index 7230cd4..5322e7a 100644 struct kpatch_arch { diff --git a/kpatch-build/lookup.c b/kpatch-build/lookup.c -index 4e2fcb9..1dd183f 100644 +index e81e934..238541c 100644 --- a/kpatch-build/lookup.c +++ b/kpatch-build/lookup.c -@@ -44,6 +44,7 @@ struct object_symbol { +@@ -45,6 +45,7 @@ struct object_symbol { unsigned long size; char *name; int type, bind; @@ -260,18 +247,18 @@ index 4e2fcb9..1dd183f 100644 }; struct export_symbol { -@@ -248,6 +249,7 @@ static void symtab_read(struct lookup_table *table, char *path) +@@ -297,6 +298,7 @@ static void symtab_read(struct lookup_table *table, char *path) - table->obj_syms[i].value = value; + table->obj_syms[i].addr = addr; 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; -@@ -398,6 +400,17 @@ 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++; +@@ -457,6 +459,17 @@ static bool lookup_local_symbol(struct lookup_table *table, + if (sym->bind == STB_LOCAL && !strcmp(sym->name, + lookup_sym->name)) + sympos++; + else { + /* + * symbol name longer than KSYM_NAME_LEN will be truncated @@ -279,22 +266,23 @@ index 4e2fcb9..1dd183f 100644 + * 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 (strlen(lookup_sym->name) >= KSYM_NAME_LEN-1 && ++ !strncmp(sym->name, lookup_sym->name, KSYM_NAME_LEN-1)) ++ sympos++; + } - if (table->local_syms == sym) { + if (lookup_sym->lookup_table_file_sym == sym) { in_file = 1; -@@ -429,16 +442,27 @@ int lookup_global_symbol(struct lookup_table *table, char *name, - struct lookup_result *result) +@@ -527,11 +540,22 @@ static bool lookup_global_symbol(struct lookup_table *table, char *name, { struct object_symbol *sym; -+ unsigned long pos = 0; int i; ++ unsigned long sympos = 0; memset(result, 0, sizeof(*result)); for_each_obj_symbol(i, sym, table) { +-+ if ((sym->bind == STB_GLOBAL || sym->bind == STB_WEAK +-+ || sym->bind == STB_GNU_UNIQUE) && + /* + * symbol name longer than KSYM_NAME_LEN will be truncated + * by kernel, so we can not find it using its original @@ -303,22 +291,27 @@ index 4e2fcb9..1dd183f 100644 + */ + if (strlen(name) >= KSYM_NAME_LEN-1 && + !strncmp(sym->name, name, KSYM_NAME_LEN-1)) -+ pos++; ++ sympos++; + - if ((sym->bind == STB_GLOBAL || sym->bind == STB_WEAK - || sym->bind == STB_GNU_UNIQUE) && ++ 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; + + if (result->objname) +@@ -540,7 +564,7 @@ static bool lookup_global_symbol(struct lookup_table *table, char *name, + result->objname = table->objname; + result->addr = sym->addr; + result->size = sym->size; +- result->sympos = 0; /* always 0 for global symbols */ ++ result->sympos = sympos; + result->global = true; + result->exported = is_exported(table, name); } - } -@@ -485,6 +509,109 @@ char *lookup_exported_symbol_objname(struct lookup_table *table, char *name) - return NULL; - } +@@ -560,3 +584,132 @@ bool lookup_symbol(struct lookup_table *table, struct symbol *sym, + return lookup_exported_symbol(table, sym->name, result); + } ++ +int lookup_is_duplicate_symbol(struct lookup_table *table, char *name, + char *objname, unsigned long pos) +{ @@ -349,20 +342,21 @@ index 4e2fcb9..1dd183f 100644 + return 0; +} + -+struct object_symbol *lookup_find_symbol_by_name(struct lookup_table *table, char *name) ++struct object_symbol *lookup_find_symbol(struct lookup_table *table, ++ struct symbol *lookup_sym) +{ + struct object_symbol *sym; + unsigned long pos = 0; + int i, match = 0, in_file = 0; + -+ if (!table->local_syms) ++ if (!lookup_sym->lookup_table_file_sym) + return NULL; + + for_each_obj_symbol(i, sym, table) { -+ if (sym->bind == STB_LOCAL && !strcmp(sym->name, name)) ++ if (sym->bind == STB_LOCAL && !strcmp(sym->name, lookup_sym->name)) + pos++; + -+ if (table->local_syms == sym) { ++ if (lookup_sym->lookup_table_file_sym == sym) { + in_file = 1; + continue; + } @@ -373,7 +367,7 @@ index 4e2fcb9..1dd183f 100644 + if (sym->type == STT_FILE) + break; + -+ if (sym->bind == STB_LOCAL && !strcmp(sym->name, name)) { ++ if (sym->bind == STB_LOCAL && !strcmp(sym->name, lookup_sym->name)) { + match = 1; + break; + } @@ -382,7 +376,7 @@ index 4e2fcb9..1dd183f 100644 + if (!match) { + for_each_obj_symbol(i, sym, table) { + if ((sym->bind == STB_GLOBAL || sym->bind == STB_WEAK) && -+ !strcmp(sym->name, name)) { ++ !strcmp(sym->name, lookup_sym->name)) { + return sym; + } + } @@ -392,29 +386,30 @@ index 4e2fcb9..1dd183f 100644 + return sym; +} + -+int lookup_ref_symbol_offset(struct lookup_table *table, char *name, ++int lookup_ref_symbol_offset(struct lookup_table *table, ++ struct symbol *lookup_sym, + 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); ++ orig_sym = lookup_find_symbol(table, lookup_sym); + if (!orig_sym) + 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 || ++ if (!strcmp(sym->name, lookup_sym->name) || sym->type == STT_FILE || + sym->sec_index != orig_sym->sec_index || + strchr(sym->name, '.')) + continue; + + 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; ++ refsym->addr = sym->addr; ++ *offset = (long)orig_sym->addr- (long)sym->addr; + return 0; + } + } @@ -422,46 +417,66 @@ index 4e2fcb9..1dd183f 100644 + return 1; +} + - #if 0 /* for local testing */ - static void find_this(struct lookup_table *table, char *sym, char *hint) - { ++/* ++ * In case sometimes the sympos of duplicate symbols are different in vmlinux and ++ * /proc/kallsyms, and causes lookup_local_symbol to save wrong sympos in result, ++ * this function returns correct sympos of the symbol, by comparing ++ * address value with the symbol in vmlinux symbol table. ++ */ ++unsigned long get_vmlinux_duplicate_symbol_pos(struct lookup_table *table, ++ char *name, unsigned long addr) ++{ ++ struct object_symbol *sym; ++ unsigned long pos = 1; ++ int i; ++ ++ for_each_obj_symbol(i, sym, table) { ++ if (strcmp(sym->name, name)) ++ continue; ++ ++ if (sym->addr < addr) ++ pos++; ++ } ++ ++ return pos; ++} diff --git a/kpatch-build/lookup.h b/kpatch-build/lookup.h -index 420d0f0..6f640fd 100644 +index e1277f1..21aceb4 100644 --- a/kpatch-build/lookup.h +++ b/kpatch-build/lookup.h -@@ -1,6 +1,9 @@ - #ifndef _LOOKUP_H_ - #define _LOOKUP_H_ +@@ -4,6 +4,8 @@ + #include + #include "kpatch-elf.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; +@@ -14,10 +16,23 @@ struct lookup_result { + bool global, exported; }; +struct lookup_refsym { + char *name; -+ unsigned long value; ++ unsigned long addr; +}; + - struct lookup_table *lookup_open(char *symtab_path, char *symvers_path, - char *hint, struct sym_compare_type *locals); + struct lookup_table *lookup_open(char *symtab_path, char *objname, + char *symvers_path, struct kpatch_elf *kelf); void lookup_close(struct lookup_table *table); -@@ -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); + bool lookup_symbol(struct lookup_table *table, struct symbol *sym, + struct lookup_result *result); +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, ++int lookup_ref_symbol_offset(struct lookup_table *table, ++ struct symbol *lookup_sym, + struct lookup_refsym *refsym, char *objname, + long *offset); ++unsigned long get_vmlinux_duplicate_symbol_pos(struct lookup_table *table, char *name, ++ unsigned long addr); #endif /* _LOOKUP_H_ */ -- -2.18.1 +2.23.0 diff --git a/0013-Add-running-kernel-symbol-table-to-help-symbol-looku.patch b/0012-Add-running-kernel-symbol-table-to-help-symbol-looku.patch similarity index 44% rename from 0013-Add-running-kernel-symbol-table-to-help-symbol-looku.patch rename to 0012-Add-running-kernel-symbol-table-to-help-symbol-looku.patch index 199b2245fdb83caeaef44ddf43328492ae67bb6f..b1d280ce349e7a04b5e081f79ba70fe4d9bb92f1 100644 --- a/0013-Add-running-kernel-symbol-table-to-help-symbol-looku.patch +++ b/0012-Add-running-kernel-symbol-table-to-help-symbol-looku.patch @@ -1,7 +1,7 @@ -From 5e6c1b2c91af547ad53faafeec20cddaedf7aaa4 Mon Sep 17 00:00:00 2001 +From 344dfff72d5a2d574d8d7804277bf587af45743d Mon Sep 17 00:00:00 2001 From: Zhipeng Xie Date: Wed, 26 Feb 2020 20:28:13 -0500 -Subject: [PATCH 13/23] Add running kernel symbol table to help symbol lookup +Subject: [PATCH 12/24] 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 @@ -9,42 +9,14 @@ symbol lookup. Signed-off-by: Zhipeng Xie --- - kpatch-build/create-diff-object.c | 7 ++- - kpatch-build/lookup.c | 74 ++++++++++++++++++++++++++++++- - kpatch-build/lookup.h | 3 +- - 3 files changed, 81 insertions(+), 3 deletions(-) + kpatch-build/lookup.c | 73 +++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 73 insertions(+) -diff --git a/kpatch-build/create-diff-object.c b/kpatch-build/create-diff-object.c -index 73c557b..c5320d4 100644 ---- a/kpatch-build/create-diff-object.c -+++ b/kpatch-build/create-diff-object.c -@@ -3597,6 +3597,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); -@@ -3710,8 +3711,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 1dd183f..03a5b32 100644 +index 238541c..2cdff67 100644 --- a/kpatch-build/lookup.c +++ b/kpatch-build/lookup.c -@@ -45,6 +45,7 @@ struct object_symbol { +@@ -46,6 +46,7 @@ struct object_symbol { char *name; int type, bind; int sec_index; @@ -52,7 +24,7 @@ index 1dd183f..03a5b32 100644 }; struct export_symbol { -@@ -284,6 +285,57 @@ static void symtab_read(struct lookup_table *table, char *path) +@@ -409,10 +410,62 @@ static void symvers_read(struct lookup_table *table, char *path) fclose(file); } @@ -97,7 +69,7 @@ index 1dd183f..03a5b32 100644 + continue; + if (sym1->sec_index != sym2->sec_index) + continue; -+ if ((long)sym1->value - (long)sym2->value == ++ if ((long)sym1->addr - (long)sym2->addr == + (long)sym1->kaddr - (long)sym2->kaddr) + continue; + @@ -107,29 +79,25 @@ index 1dd183f..03a5b32 100644 + fclose(file); +} + - /* - * Symvers file format is the following for kernels v5.3 and newer: - * -@@ -352,7 +404,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 *lookup_open(char *symtab_path, char *objname, + char *symvers_path, struct kpatch_elf *kelf) { struct lookup_table *table; ++ char *kallsyms; -@@ -363,6 +416,8 @@ struct lookup_table *lookup_open(char *symtab_path, char *symvers_path, - + table = malloc(sizeof(*table)); + if (!table) +@@ -422,6 +475,9 @@ struct lookup_table *lookup_open(char *symtab_path, char *objname, + table->objname = objname; symtab_read(table, symtab_path); symvers_read(table, symvers_path); ++ kallsyms = getenv("KALLSYMS"); + if (kallsyms) + ksymtab_read(table, kallsyms); - find_local_syms(table, hint, locals); - return table; -@@ -609,6 +664,23 @@ int lookup_ref_symbol_offset(struct lookup_table *table, char *name, + find_local_syms_multiple(table, kelf); + +@@ -687,6 +743,23 @@ int lookup_ref_symbol_offset(struct lookup_table *table, } } @@ -138,13 +106,13 @@ index 1dd183f..03a5b32 100644 + + /*find a unique symbol has kaddr*/ + for_each_obj_symbol(i, sym, table) { -+ if (!strcmp(sym->name, name) || sym->type == STT_FILE || ++ if (!strcmp(sym->name, lookup_sym->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; ++ refsym->addr = 0; + *offset = (long)orig_sym->kaddr - (long)sym->kaddr; + return 0; + } @@ -153,20 +121,6 @@ index 1dd183f..03a5b32 100644 return 1; } -diff --git a/kpatch-build/lookup.h b/kpatch-build/lookup.h -index 6f640fd..daeea73 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 +2.23.0 diff --git a/0013-livepatch-patch-hook-support-force-enable-disable.patch b/0013-livepatch-patch-hook-support-force-enable-disable.patch new file mode 100644 index 0000000000000000000000000000000000000000..1da4701c6ed27de77056abfbf620191ccf420c34 --- /dev/null +++ b/0013-livepatch-patch-hook-support-force-enable-disable.patch @@ -0,0 +1,154 @@ +From 88d2a5c88fcab0016db9347fbab41a22b9fb9a52 Mon Sep 17 00:00:00 2001 +From: Zhipeng Xie +Date: Wed, 26 Feb 2020 20:43:34 -0500 +Subject: [PATCH 13/24] livepatch-patch-hook: support force enable/disable + +we use force to indicate function which bypass stack check + +Signed-off-by: Zhipeng Xie +--- + kmod/patch/kpatch-patch.h | 1 + + kmod/patch/livepatch-patch-hook.c | 17 +++++++++++++++++ + kpatch-build/kpatch-build | 24 ++++++++++++++++++++---- + 3 files changed, 38 insertions(+), 4 deletions(-) + +diff --git a/kmod/patch/kpatch-patch.h b/kmod/patch/kpatch-patch.h +index 9df7818..6e39364 100644 +--- a/kmod/patch/kpatch-patch.h ++++ b/kmod/patch/kpatch-patch.h +@@ -64,4 +64,5 @@ struct kpatch_post_unpatch_callback { + char *objname; + }; + ++extern unsigned long __kpatch_force_funcs[], __kpatch_force_funcs_end[]; + #endif /* _KPATCH_PATCH_H_ */ +diff --git a/kmod/patch/livepatch-patch-hook.c b/kmod/patch/livepatch-patch-hook.c +index b578ef3..71439d9 100644 +--- a/kmod/patch/livepatch-patch-hook.c ++++ b/kmod/patch/livepatch-patch-hook.c +@@ -432,6 +432,16 @@ extern struct kpatch_patch_func __kpatch_funcs[], __kpatch_funcs_end[]; + extern struct kpatch_patch_dynrela __kpatch_dynrelas[], __kpatch_dynrelas_end[]; + #endif + ++static int patch_is_func_forced(unsigned long addr) ++{ ++ unsigned long *a; ++ ++ for (a = __kpatch_force_funcs; a < __kpatch_force_funcs_end; a++) ++ if (*a == addr) ++ return 1; ++ return 0; ++} ++ + static int __init patch_init(void) + { + struct kpatch_patch_func *kfunc; +@@ -520,6 +530,13 @@ 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(__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 722d362..9a98bfc 100755 +--- a/kpatch-build/kpatch-build ++++ b/kpatch-build/kpatch-build +@@ -383,28 +383,32 @@ find_special_section_data_aarch64() { + # shellcheck disable=SC2086 + SPECIAL_VARS="$(readelf -wi "$VMLINUX" | + gawk --non-decimal-data $AWK_OPTIONS ' +- BEGIN { a = b = e = j = 0 } ++ BEGIN { a = b = e = j = c = f = 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} + + # 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 } ++ c == 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} + 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} + + # Bail out once we have everything +- a == 2 && b == 2 && e == 2 && (j == 2 || skip_j) {exit}')" ++ a == 2 && b == 2 && e == 2 && (j == 2 || skip_j) && c == 3 {exit}')" + + [[ -n "$SPECIAL_VARS" ]] && eval "$SPECIAL_VARS" + +@@ -437,7 +441,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 = j = s = i = 0 } ++ BEGIN { a = b = p = e = o = j = s = i = c = f = 0 } + + # Set state if name matches + a == 0 && /DW_AT_name.* alt_instr[[:space:]]*$/ {a = 1; next} +@@ -448,6 +452,7 @@ find_special_section_data() { + j == 0 && /DW_AT_name.* jump_entry[[:space:]]*$/ {j = 1; next} + s == 0 && /DW_AT_name.* static_call_site[[:space:]]*$/ {s = 1; next} + i == 0 && /DW_AT_name.* pi_entry[[:space:]]*$/ {i = 1; next} ++ c == 0 && /DW_AT_name.* klp_func[[:space:]]*$/ {c = 1; next} + + # Reset state unless this abbrev describes the struct size + a == 1 && !/DW_AT_byte_size/ { a = 0; next } +@@ -458,6 +463,8 @@ find_special_section_data() { + j == 1 && !/DW_AT_byte_size/ { j = 0; next } + s == 1 && !/DW_AT_byte_size/ { s = 0; next } + i == 1 && !/DW_AT_byte_size/ { i = 0; next } ++ c == 1 && /DW_TAG_structure_type/ { c = 3; next } ++ c == 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} +@@ -468,9 +475,10 @@ find_special_section_data() { + j == 1 {printf("export JUMP_STRUCT_SIZE=%d\n", $4); j = 2} + s == 1 {printf("export STATIC_CALL_STRUCT_SIZE=%d\n", $4); s = 2} + i == 1 {printf("export PRINTK_INDEX_STRUCT_SIZE=%d\n", $4); i = 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) && (j == 2 || skip_j) && (s == 2 || skip_s) && (i == 2 || skip_i) {exit}')" ++ a == 2 && b == 2 && (p == 2 || skip_p) && e == 2 && (o == 2 || skip_o) && (j == 2 || skip_j) && (s == 2 || skip_s) && (i == 2 || skip_i) && c == 3 {exit}')" + + [[ -n "$SPECIAL_VARS" ]] && eval "$SPECIAL_VARS" + +@@ -1231,6 +1239,14 @@ if [[ -n "$DISABLE_AFTER_LOAD" ]];then + export KCPPFLAGS="-DDISABLE_AFTER_LOAD $KCPPFLAGS" + 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 ++ + save_env + + echo "Building patch module: $MODNAME.ko" +-- +2.23.0 + diff --git a/0015-kpatch-build-ignore-debuginfo-in-patch.patch b/0014-kpatch-build-ignore-debuginfo-in-patch.patch similarity index 67% rename from 0015-kpatch-build-ignore-debuginfo-in-patch.patch rename to 0014-kpatch-build-ignore-debuginfo-in-patch.patch index 94f31ca8eec19d305bd347ca3058b0dca659fdd7..423827fdc96ca544e0f9b20f93daac19d6ecbde5 100644 --- a/0015-kpatch-build-ignore-debuginfo-in-patch.patch +++ b/0014-kpatch-build-ignore-debuginfo-in-patch.patch @@ -1,7 +1,7 @@ -From 48fef6d7eceb336816e45690d43093f8be919315 Mon Sep 17 00:00:00 2001 +From d28c18b094c18118427eadb4c63ab73cf64af4e6 Mon Sep 17 00:00:00 2001 From: Zhipeng Xie Date: Wed, 26 Feb 2020 21:01:02 -0500 -Subject: [PATCH 15/23] kpatch-build: ignore debuginfo in patch +Subject: [PATCH 14/24] kpatch-build: ignore debuginfo in patch Just ignore all .debug_* sections @@ -12,10 +12,10 @@ Signed-off-by: Zhipeng Xie 2 files changed, 19 insertions(+) diff --git a/kpatch-build/create-diff-object.c b/kpatch-build/create-diff-object.c -index c5320d4..bc3685b 100644 +index ea1e01b..8c5af6b 100644 --- a/kpatch-build/create-diff-object.c +++ b/kpatch-build/create-diff-object.c -@@ -2414,6 +2414,23 @@ static void kpatch_include_debug_sections(struct kpatch_elf *kelf) +@@ -2714,6 +2714,23 @@ static void kpatch_include_debug_sections(struct kpatch_elf *kelf) } } @@ -39,26 +39,26 @@ index c5320d4..bc3685b 100644 static void kpatch_mark_ignored_sections(struct kpatch_elf *kelf) { struct section *sec, *strsec, *ignoresec; -@@ -3682,6 +3699,7 @@ int main(int argc, char *argv[]) +@@ -3908,6 +3925,7 @@ int main(int argc, char *argv[]) new_globals_exist = kpatch_include_new_globals(kelf_patched); kpatch_include_new_static_var(kelf_patched); kpatch_include_debug_sections(kelf_patched); + kpatch_ignore_debug_sections(kelf_patched); - kpatch_process_special_sections(kelf_patched); + kpatch_process_special_sections(kelf_patched, lookup); diff --git a/kpatch-build/kpatch-build b/kpatch-build/kpatch-build -index 57487b1..c109ee3 100755 +index 9a98bfc..a0d8ba8 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" +@@ -1295,6 +1295,7 @@ KPATCH_LDFLAGS="$KPATCH_LDFLAGS" + save_env - if ! "$KPATCH_MODULE"; then - if [[ -z "$KPATCH_LDFLAGS" ]]; then + make "${MAKEVARS[@]}" 2>&1 | logger || die ++strip -g "$TEMPDIR/patch/$MODNAME.ko" + + if [[ "$USE_KLP" -eq 1 ]]; then + if [[ "$USE_KLP_ARCH" -eq 0 ]]; then -- -2.18.1 +2.23.0 diff --git a/0014-livepatch-patch-hook-support-force-enable-disable.patch b/0014-livepatch-patch-hook-support-force-enable-disable.patch deleted file mode 100644 index 6ffc163f36196bbe56ada394fb37b50f142bf524..0000000000000000000000000000000000000000 --- a/0014-livepatch-patch-hook-support-force-enable-disable.patch +++ /dev/null @@ -1,78 +0,0 @@ -From 62e9cb43c324c933b2934ce9d2923097b96dab1e Mon Sep 17 00:00:00 2001 -From: Zhipeng Xie -Date: Wed, 26 Feb 2020 20:43:34 -0500 -Subject: [PATCH 14/23] livepatch-patch-hook: support force enable/disable - -we use force to indicate function which bypass stack check - -Signed-off-by: Zhipeng Xie ---- - kmod/patch/kpatch-patch.h | 1 + - kmod/patch/livepatch-patch-hook.c | 18 ++++++++++++++++++ - kpatch-build/kpatch-build | 4 ++++ - 3 files changed, 23 insertions(+) - -diff --git a/kmod/patch/kpatch-patch.h b/kmod/patch/kpatch-patch.h -index 9df7818..6e39364 100644 ---- a/kmod/patch/kpatch-patch.h -+++ b/kmod/patch/kpatch-patch.h -@@ -64,4 +64,5 @@ struct kpatch_post_unpatch_callback { - char *objname; - }; - -+extern unsigned long __kpatch_force_funcs[], __kpatch_force_funcs_end[]; - #endif /* _KPATCH_PATCH_H_ */ -diff --git a/kmod/patch/livepatch-patch-hook.c b/kmod/patch/livepatch-patch-hook.c -index fb23a94..5a0de7f 100644 ---- a/kmod/patch/livepatch-patch-hook.c -+++ b/kmod/patch/livepatch-patch-hook.c -@@ -239,6 +239,17 @@ extern struct kpatch_post_patch_callback __kpatch_callbacks_post_patch[], __kpat - 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[]; - -+static int patch_is_func_forced(unsigned long addr) -+{ -+ unsigned long *a; -+ -+ for (a = __kpatch_force_funcs; a < __kpatch_force_funcs_end; a++) -+ if (*a == addr) -+ return 1; -+ return 0; -+} -+ -+ - #ifdef HAVE_CALLBACKS - static int add_callbacks_to_patch_objects(void) - { -@@ -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; -+#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 --- -2.18.1 - diff --git a/0016-add-object-in-kpatch.patch b/0015-add-object-in-kpatch.patch similarity index 70% rename from 0016-add-object-in-kpatch.patch rename to 0015-add-object-in-kpatch.patch index f907d2ae036b82c5ac7cb2cb32e8a1bf8c568020..c6950f2fd972f4839685921a548bfee02a18e05a 100644 --- a/0016-add-object-in-kpatch.patch +++ b/0015-add-object-in-kpatch.patch @@ -1,7 +1,7 @@ -From 24392c6f62e26afb192992808772bd19ceab5446 Mon Sep 17 00:00:00 2001 +From 8341b9ea6b889a887577772f6adfb49e1fea1bc1 Mon Sep 17 00:00:00 2001 From: Bin Yang Date: Tue, 16 Jul 2019 14:39:27 +0800 -Subject: [PATCH 16/23] add object in kpatch +Subject: [PATCH 15/24] add object in kpatch it is required by make_hotpatch users @@ -11,10 +11,10 @@ Signed-off-by: Bin Yang 1 file changed, 3 insertions(+) diff --git a/kpatch-build/kpatch-build b/kpatch-build/kpatch-build -index c109ee3..de448dc 100755 +index a0d8ba8..c21f3ca 100755 --- a/kpatch-build/kpatch-build +++ b/kpatch-build/kpatch-build -@@ -1071,6 +1071,8 @@ echo -n "Patched objects:" +@@ -1227,6 +1227,8 @@ echo -n "Patched objects:" for i in $(echo "${objnames[@]}" | tr ' ' '\n' | sort -u | tr '\n' ' ') do echo -n " $i" @@ -23,14 +23,14 @@ index c109ee3..de448dc 100755 done echo -@@ -1177,6 +1179,7 @@ UNDEFINED=$(comm -23 <(sort -u "${TEMPDIR}"/undefined_references) \ +@@ -1353,6 +1355,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 - [[ "$DEBUG" -eq 0 ]] && rm -f "$LOGFILE" + [[ "$DEBUG" -eq 0 && "$SKIPCLEANUP" -eq 0 ]] && rm -f "$LOGFILE" -- -2.18.1 +2.23.0 diff --git a/0017-create-diff-object-fix-.orc_unwind_ip-error.patch b/0016-create-diff-object-fix-.orc_unwind_ip-error.patch similarity index 51% rename from 0017-create-diff-object-fix-.orc_unwind_ip-error.patch rename to 0016-create-diff-object-fix-.orc_unwind_ip-error.patch index be975d26a07c17f1744dae4658f6bc7b6394571f..bfbfc70b01f5f72e076af8c679892b74dec00d93 100644 --- a/0017-create-diff-object-fix-.orc_unwind_ip-error.patch +++ b/0016-create-diff-object-fix-.orc_unwind_ip-error.patch @@ -1,7 +1,7 @@ -From a1d89dc3ab47d443e879d4553a9ff80e8b82a3ab Mon Sep 17 00:00:00 2001 +From 2dab7f74fecefab38fbd9c2d171e5a6090e66829 Mon Sep 17 00:00:00 2001 From: Zhipeng Xie Date: Thu, 27 Feb 2020 15:36:55 -0500 -Subject: [PATCH 17/23] create-diff-object: fix .orc_unwind_ip error +Subject: [PATCH 16/24] create-diff-object: fix .orc_unwind_ip error error: .orc_unwind_ip section header details differ from .orc_unwind_ip @@ -14,29 +14,29 @@ Signed-off-by: Zhipeng Xie 1 file changed, 6 insertions(+) diff --git a/kpatch-build/create-diff-object.c b/kpatch-build/create-diff-object.c -index bc3685b..20213a0 100644 +index 8c5af6b..5f51034 100644 --- a/kpatch-build/create-diff-object.c +++ b/kpatch-build/create-diff-object.c -@@ -975,6 +975,9 @@ static void kpatch_correlate_sections(struct list_head *seclist1, struct list_he +@@ -1079,6 +1079,9 @@ static void kpatch_correlate_sections(struct list_head *seclist_orig, continue; } -+ if (strstr(sec1->name, ".orc_unwind")) ++ if (strstr(sec_orig->name, ".orc_unwind")) + continue; + - kpatch_correlate_section(sec1, sec2); + kpatch_correlate_section(sec_orig, sec_patched); break; } -@@ -1020,6 +1023,9 @@ static void kpatch_correlate_symbols(struct list_head *symlist1, struct list_hea - sym1->sec->twin != sym2->sec) +@@ -1125,6 +1128,9 @@ static void kpatch_correlate_symbols(struct list_head *symlist_orig, + sym_orig->sec->twin != sym_patched->sec) continue; -+ if (strstr(sym1->name, ".orc_unwind")) ++ if (strstr(sym_orig->name, ".orc_unwind")) + continue; + - kpatch_correlate_symbol(sym1, sym2); + kpatch_correlate_symbol(sym_orig, sym_patched); break; } -- -2.18.1 +2.23.0 diff --git a/0017-create-diff-object-add-jump-label-support.patch b/0017-create-diff-object-add-jump-label-support.patch new file mode 100644 index 0000000000000000000000000000000000000000..30aebe6f13b2040d41eaa9315f6beb39fde93a10 --- /dev/null +++ b/0017-create-diff-object-add-jump-label-support.patch @@ -0,0 +1,67 @@ +From 78a04dd5a2a98e6442441b802e1f4aa017fae87a Mon Sep 17 00:00:00 2001 +From: Zhipeng Xie +Date: Mon, 2 Mar 2020 04:35:07 -0500 +Subject: [PATCH 17/24] create-diff-object: add jump label support + +This patch processes the __jump_table special section, and +only the jump_lable used by the changed functions will be +included in __jump_table section and solve this limitation. +(The livepatch in kernel should also be modified that processing +the tracepoint again after the dynamic relocation by livepatch.) + +Signed-off-by: Zhipeng Xie +--- + kpatch-build/create-diff-object.c | 9 +++++++-- + 1 file changed, 7 insertions(+), 2 deletions(-) + +diff --git a/kpatch-build/create-diff-object.c b/kpatch-build/create-diff-object.c +index 5f51034..6b915ae 100644 +--- a/kpatch-build/create-diff-object.c ++++ b/kpatch-build/create-diff-object.c +@@ -79,6 +79,7 @@ enum subsection { + enum loglevel loglevel = NORMAL; + + bool KLP_ARCH; ++char *KEEP_JUMP_LABEL = NULL; + + /******************* + * Data structures +@@ -2374,6 +2375,8 @@ static bool should_keep_jump_label(struct lookup_table *lookup, + if (tracepoint || dynamic_debug) + return false; + ++ if (KEEP_JUMP_LABEL) ++ return true; + /* + * This will be upgraded to an error after all jump labels have + * been reported. +@@ -2404,6 +2407,8 @@ static bool should_keep_jump_label(struct lookup_table *lookup, + if (tracepoint || dynamic_debug) + return false; + ++ if (KEEP_JUMP_LABEL) ++ return true; + /* + * This will be upgraded to an error after all jump labels have + * been reported. +@@ -2972,8 +2977,7 @@ static void kpatch_process_special_sections(struct kpatch_elf *kelf, + * labels and enable tracepoints in a patched function. + */ + list_for_each_entry(sec, &kelf->sections, list) { +- if (strcmp(sec->name, "__jump_table") && +- strcmp(sec->name, "__tracepoints") && ++ if (strcmp(sec->name, "__tracepoints") && + strcmp(sec->name, "__tracepoints_ptrs") && + strcmp(sec->name, "__tracepoints_strings")) + continue; +@@ -3865,6 +3869,7 @@ int main(int argc, char *argv[]) + char *parent_symtab, *mod_symvers, *patch_name, *output_obj; + char *no_profiling_calls = NULL; + ++ KEEP_JUMP_LABEL = getenv("KEEP_JUMP_LABEL"); + memset(&arguments, 0, sizeof(arguments)); + argp_parse (&argp, argc, argv, 0, NULL, &arguments); + if (arguments.debug) +-- +2.23.0 + diff --git a/0020-kpatch-build-add-compile-flag-fno-reorder-functions.patch b/0018-kpatch-build-add-compile-flag-fno-reorder-functions.patch similarity index 81% rename from 0020-kpatch-build-add-compile-flag-fno-reorder-functions.patch rename to 0018-kpatch-build-add-compile-flag-fno-reorder-functions.patch index 0e15c9fd622022cbcbfcd60268a0aa0c7e0733b8..59b2301f9b211312719162a000900b3b05a18dd1 100644 --- a/0020-kpatch-build-add-compile-flag-fno-reorder-functions.patch +++ b/0018-kpatch-build-add-compile-flag-fno-reorder-functions.patch @@ -1,7 +1,7 @@ -From 586dcb3d2ccd8e45c78d3d140f0190ab5a78ecb3 Mon Sep 17 00:00:00 2001 +From 46a24818a2227ad1b6f644c2499415021522ce55 Mon Sep 17 00:00:00 2001 From: Zhipeng Xie Date: Thu, 12 Mar 2020 06:56:21 -0400 -Subject: [PATCH 20/23] kpatch-build: add compile flag -fno-reorder-functions +Subject: [PATCH 18/24] kpatch-build: add compile flag -fno-reorder-functions Sometimes function foo with static variables can be put in .text.foo section in original binary and be put in @@ -23,18 +23,18 @@ Signed-off-by: Zhipeng Xie 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kpatch-build/kpatch-build b/kpatch-build/kpatch-build -index de448dc..ad7ab71 100755 +index c21f3ca..2ead6e4 100755 --- a/kpatch-build/kpatch-build +++ b/kpatch-build/kpatch-build -@@ -887,7 +887,7 @@ if [[ "$ARCH" = "ppc64le" ]]; then +@@ -994,7 +994,7 @@ if [[ "$ARCH" = "ppc64le" ]]; then ARCH_KCFLAGS="-mcmodel=large -fplugin=$PLUGINDIR/ppc64le-plugin.so" fi -export KCFLAGS="-I$DATADIR/patch -ffunction-sections -fdata-sections \ -+export KCFLAGS="-I$DATADIR/patch -ffunction-sections -fdata-sections -fno-reorder-functions\ - $ARCH_KCFLAGS $DEBUG_KCFLAGS ${GCC_ADD_OPTION}" ++export KCFLAGS="-I$DATADIR/patch -ffunction-sections -fdata-sections -fno-reorder-functions \ + $ARCH_KCFLAGS $DEBUG_KCFLAGS" echo "Reading special section data" -- -2.18.1 +2.23.0 diff --git a/0025-Fix-relocation-not-resolved-when-new-functions-expor.patch b/0019-Fix-relocation-not-resolved-when-new-functions-expor.patch similarity index 79% rename from 0025-Fix-relocation-not-resolved-when-new-functions-expor.patch rename to 0019-Fix-relocation-not-resolved-when-new-functions-expor.patch index 670a5ba65cc8c4ee3f73769c7d047090593096f8..4005ee14b6dd639c79382ab1aef40020e549b45a 100644 --- a/0025-Fix-relocation-not-resolved-when-new-functions-expor.patch +++ b/0019-Fix-relocation-not-resolved-when-new-functions-expor.patch @@ -1,7 +1,8 @@ -From 737ab3efcde45cde5fbe43ee977fc18b6912f356 Mon Sep 17 00:00:00 2001 +From 47a9749d381f02868b4f4bbe1bc841f3f38ac1a1 Mon Sep 17 00:00:00 2001 From: Zhipeng Xie Date: Sun, 22 Nov 2020 21:40:39 +0800 -Subject: [PATCH] Fix relocation not resolved when new functions exported only +Subject: [PATCH 19/24] Fix relocation not resolved when new functions exported + only When no functions changed and new functions exported, kobject is not created, so livepatch will not call klp_init_object and relocation @@ -12,8 +13,8 @@ Signed-off-by: Zhipeng Xie kmod/patch/kpatch-patch.h | 4 ++++ kmod/patch/kpatch.lds.S | 6 ++++++ kmod/patch/livepatch-patch-hook.c | 19 +++++++++++++++++++ - kpatch-build/create-diff-object.c | 24 ++++++++++++++++++++++++ - 4 files changed, 53 insertions(+) + kpatch-build/create-diff-object.c | 26 ++++++++++++++++++++++++++ + 4 files changed, 55 insertions(+) diff --git a/kmod/patch/kpatch-patch.h b/kmod/patch/kpatch-patch.h index 6e39364..33f2056 100644 @@ -46,10 +47,10 @@ index bc5de82..4c4d77b 100644 + } } diff --git a/kmod/patch/livepatch-patch-hook.c b/kmod/patch/livepatch-patch-hook.c -index 5a0de7f..d3fb1db 100644 +index 71439d9..9e56fe3 100644 --- a/kmod/patch/livepatch-patch-hook.c +++ b/kmod/patch/livepatch-patch-hook.c -@@ -249,6 +249,22 @@ static int patch_is_func_forced(unsigned long addr) +@@ -442,6 +442,22 @@ static int patch_is_func_forced(unsigned long addr) return 0; } @@ -69,10 +70,10 @@ index 5a0de7f..d3fb1db 100644 + return 0; +} + - - #ifdef HAVE_CALLBACKS - static int add_callbacks_to_patch_objects(void) -@@ -382,6 +398,9 @@ static int __init patch_init(void) + static int __init patch_init(void) + { + struct kpatch_patch_func *kfunc; +@@ -485,6 +501,9 @@ static int __init patch_init(void) if (ret) goto out; @@ -83,10 +84,10 @@ index 5a0de7f..d3fb1db 100644 ret = -ENOMEM; diff --git a/kpatch-build/create-diff-object.c b/kpatch-build/create-diff-object.c -index fca68b8..bea758e 100644 +index 6b915ae..0bef022 100644 --- a/kpatch-build/create-diff-object.c +++ b/kpatch-build/create-diff-object.c -@@ -2553,6 +2553,27 @@ static void kpatch_create_kpatch_arch_section(struct kpatch_elf *kelf, char *obj +@@ -2916,6 +2916,27 @@ static void kpatch_create_kpatch_arch_section(struct kpatch_elf *kelf, char *obj karch_sec->sh.sh_size = karch_sec->data->d_size; } @@ -106,24 +107,26 @@ index fca68b8..bea758e 100644 + /* entries[index].objname */ + ALLOC_LINK(rela, &kobj_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 = (unsigned int)(offsetof(struct kpatch_object, objname)); +} + - static void kpatch_process_special_sections(struct kpatch_elf *kelf) + static void kpatch_process_special_sections(struct kpatch_elf *kelf, + struct lookup_table *lookup) { - struct special_section *special; -@@ -3710,6 +3731,9 @@ int main(int argc, char *argv[]) +@@ -3973,6 +3994,11 @@ int main(int argc, char *argv[]) kpatch_create_intermediate_sections(kelf_out, lookup, parent_name, patch_name); kpatch_create_kpatch_arch_section(kelf_out, parent_name); kpatch_create_callbacks_objname_rela(kelf_out, parent_name); ++ + if (!num_changed && new_globals_exist) { -+ kpatch_create_kpatch_object_section(kelf_out, parent_name); ++ kpatch_create_kpatch_object_section(kelf_out, parent_name); + } ++ kpatch_build_strings_section_data(kelf_out); - gcc_add_option = getenv("GCC_ADD_OPTION"); + kpatch_create_mcount_sections(kelf_out); -- -2.18.1 +2.23.0 diff --git a/0019-create-diff-object-add-jump-label-support.patch b/0019-create-diff-object-add-jump-label-support.patch deleted file mode 100644 index 931c9b72d584ea04d999c5ece25b7dde4d1ce90c..0000000000000000000000000000000000000000 --- a/0019-create-diff-object-add-jump-label-support.patch +++ /dev/null @@ -1,91 +0,0 @@ -From c0b20224cf1b081fba152cb4944d762515561d89 Mon Sep 17 00:00:00 2001 -From: Zhipeng Xie -Date: Mon, 2 Mar 2020 04:35:07 -0500 -Subject: [PATCH 19/23] create-diff-object: add jump label support - -This patch processes the __jump_table special section, and -only the jump_lable used by the changed functions will be -included in __jump_table section and solve this limitation. -(The livepatch in kernel should also be modified that processing -the tracepoint again after the dynamic relocation by livepatch.) - -Signed-off-by: Zhipeng Xie ---- - kpatch-build/create-diff-object.c | 47 +------------------------------ - 1 file changed, 1 insertion(+), 46 deletions(-) - -diff --git a/kpatch-build/create-diff-object.c b/kpatch-build/create-diff-object.c -index 457d517..4fa4488 100644 ---- a/kpatch-build/create-diff-object.c -+++ b/kpatch-build/create-diff-object.c -@@ -2140,7 +2140,6 @@ static void kpatch_regenerate_special_section(struct kpatch_elf *kelf, - struct rela *rela, *safe; - char *src, *dest; - unsigned int group_size, src_offset, dest_offset, include; -- int jump_table = !strcmp(special->name, "__jump_table"); - - LIST_HEAD(newrelas); - -@@ -2180,49 +2179,6 @@ static void kpatch_regenerate_special_section(struct kpatch_elf *kelf, - if (!include) - continue; - -- /* -- * Jump labels (aka static keys or static branches) aren't -- * actually supported for the time being. Warn on all -- * non-tracepoint jump labels when they occur in a replacement -- * function. An inert tracepoint is harmless enough, but a -- * broken static key can cause unexpected behavior. -- * -- * Here we hard-code knowledge about the contents of the -- * jump_label struct. It has three fields: code, target, and -- * key. -- */ -- if (jump_table) { -- struct rela *code, *key; -- int i = 0; -- -- list_for_each_entry(rela, &sec->relas, list) { -- if (rela->offset >= src_offset && -- rela->offset < src_offset + group_size) { -- if (i == 0) -- code = rela; -- else if (i == 2) -- key = rela; -- i++; -- } -- } -- -- if (i != 3) -- ERROR("BUG: __jump_table has an unexpected format"); -- -- /* inert tracepoints are harmless */ -- if (!strncmp(key->sym->name, "__tracepoint_", 13)) -- continue; -- -- /* inert dynamic debug printks are harmless */ -- if (is_dynamic_debug_symbol(key->sym)) -- continue; -- -- ERROR("Found a jump label at %s()+0x%lx, using key %s. Jump labels aren't currently supported. Use static_key_enabled() instead.", -- code->sym->name, code->addend, key->sym->name); -- -- continue; -- } -- - /* - * Copy all relas in the group. It's possible that the relas - * aren't sorted (e.g. .rela.fixup), so go through the entire -@@ -2659,8 +2615,7 @@ static void kpatch_process_special_sections(struct kpatch_elf *kelf) - * jump labels and enable tracepoints in a patched function. - */ - list_for_each_entry(sec, &kelf->sections, list) { -- if (strcmp(sec->name, "__jump_table") && -- strcmp(sec->name, "__tracepoints") && -+ if (strcmp(sec->name, "__tracepoints") && - strcmp(sec->name, "__tracepoints_ptrs") && - strcmp(sec->name, "__tracepoints_strings")) - continue; --- -2.18.1 - diff --git a/0026-support-remove-static-variables-using-KPATCH_IGNORE_.patch b/0020-support-remove-static-variables-using-KPATCH_IGNORE_.patch similarity index 76% rename from 0026-support-remove-static-variables-using-KPATCH_IGNORE_.patch rename to 0020-support-remove-static-variables-using-KPATCH_IGNORE_.patch index a6b1270f33869b4e7666cb86b1f7055c5aeb776c..7b19d99670a7a9572b2ea00c9a203a5a9a6f1214 100644 --- a/0026-support-remove-static-variables-using-KPATCH_IGNORE_.patch +++ b/0020-support-remove-static-variables-using-KPATCH_IGNORE_.patch @@ -1,7 +1,8 @@ -From 0e08aa99583573953367d5c1ec21901325c7faee Mon Sep 17 00:00:00 2001 +From a81f64c1eae14f2b0da8168ca60b3d9beb0a9fb0 Mon Sep 17 00:00:00 2001 From: Zhipeng Xie Date: Wed, 30 Dec 2020 21:13:10 -0500 -Subject: [PATCH] support remove static variables using KPATCH_IGNORE_STATIC +Subject: [PATCH 20/24] support remove static variables using + KPATCH_IGNORE_STATIC Static variables will be removed due to compiler optimization. And some static variables can be treated as new variables, such as @@ -10,30 +11,31 @@ to tell kpatch to treat the static variables as new variables. Signed-off-by: Zhipeng Xie --- - kmod/patch/kpatch-macros.h | 3 +++ + kmod/patch/kpatch-macros.h | 4 +++ kpatch-build/create-diff-object.c | 45 ++++++++++++++++++++++++++++++- - 2 files changed, 47 insertions(+), 1 deletion(-) + 2 files changed, 48 insertions(+), 1 deletion(-) diff --git a/kmod/patch/kpatch-macros.h b/kmod/patch/kpatch-macros.h -index a60a267..9a30d68 100644 +index caaadbc..ee455d2 100644 --- a/kmod/patch/kpatch-macros.h +++ b/kmod/patch/kpatch-macros.h -@@ -5,6 +5,9 @@ - #include - #include +@@ -12,6 +12,10 @@ + # define __kpatch_section(section) __section(#section) + #endif +#define KPATCH_IGNORE_STATIC(_static) \ + char *__UNIQUE_ID(kpatch_ignore_static_) __section(.kpatch.ignore.statics) = _static; ++ + /* * KPATCH_IGNORE_SECTION macro * diff --git a/kpatch-build/create-diff-object.c b/kpatch-build/create-diff-object.c -index a2a9cab..211ea72 100644 +index 0bef022..f83000b 100644 --- a/kpatch-build/create-diff-object.c +++ b/kpatch-build/create-diff-object.c -@@ -1151,6 +1151,40 @@ static int kpatch_is_normal_static_local(struct symbol *sym) - return 1; +@@ -1345,6 +1345,40 @@ static struct rela *kpatch_find_static_twin_ref(struct section *rela_sec, struct + return NULL; } +static int kpatch_mark_ignored_statics(struct kpatch_elf *kelf, struct symbol *sym) @@ -73,7 +75,7 @@ index a2a9cab..211ea72 100644 /* * gcc renames static local variables by appending a period and a number. For * example, __foo could be renamed to __foo.31452. Unfortunately this number -@@ -1230,6 +1264,11 @@ static void kpatch_correlate_static_local_variables(struct kpatch_elf *base, +@@ -1425,6 +1459,11 @@ static void kpatch_correlate_static_local_variables(struct kpatch_elf *orig, if (sym->twin) continue; @@ -85,7 +87,7 @@ index a2a9cab..211ea72 100644 bundled = sym == sym->sec->sym; if (bundled && sym->sec == sec->base) { /* -@@ -1286,6 +1325,11 @@ static void kpatch_correlate_static_local_variables(struct kpatch_elf *base, +@@ -1482,6 +1521,11 @@ static void kpatch_correlate_static_local_variables(struct kpatch_elf *orig, if (!kpatch_is_normal_static_local(sym)) continue; @@ -94,10 +96,10 @@ index a2a9cab..211ea72 100644 + continue; + } + - if (!sym->twin || !sec->twin) - DIFF_FATAL("reference to static local variable %s in %s was removed", - sym->name, -@@ -1329,7 +1373,6 @@ static void kpatch_correlate_static_local_variables(struct kpatch_elf *base, + if (!sec->twin && sec->base->sym) { + struct symbol *parent = NULL; + +@@ -1525,7 +1569,6 @@ static void kpatch_correlate_static_local_variables(struct kpatch_elf *orig, log_normal("WARNING: unable to correlate static local variable %s used by %s, assuming variable is new\n", sym->name, kpatch_section_function_name(sec)); @@ -106,5 +108,5 @@ index a2a9cab..211ea72 100644 } } -- -2.18.1 +2.23.0 diff --git a/0021-create-diff-object-fix-segment-fault-when-sec2-rela-.patch b/0021-create-diff-object-fix-segment-fault-when-sec2-rela-.patch new file mode 100644 index 0000000000000000000000000000000000000000..50bff4d450a704082e2bdbe9cd6c04a1cc9fd1af --- /dev/null +++ b/0021-create-diff-object-fix-segment-fault-when-sec2-rela-.patch @@ -0,0 +1,31 @@ +From 2189dd022cda1973efdc198daa0525cbd2ee5bb2 Mon Sep 17 00:00:00 2001 +From: Zhipeng Xie +Date: Fri, 17 Sep 2021 10:22:24 +0800 +Subject: [PATCH 21/24] create-diff-object: fix segment fault when sec2->rela + is NULL + +when patched section has no rela section, we meet segment fault in +__kpatch_correlate_section. add sec2->rela check to fix it. + +Signed-off-by: Zhipeng Xie +Signed-off-by: hubin57 +--- + 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 f83000b..aa5c5c4 100644 +--- a/kpatch-build/create-diff-object.c ++++ b/kpatch-build/create-diff-object.c +@@ -1015,7 +1015,7 @@ static void kpatch_correlate_section(struct section *sec_orig, + __kpatch_correlate_section(sec_orig->base, sec_patched->base); + sec_orig = sec_orig->base; + sec_patched = sec_patched->base; +- } else if (sec_orig->rela) { ++ } else if (sec_orig->rela && sec_patched->rela) { + __kpatch_correlate_section(sec_orig->rela, sec_patched->rela); + } + +-- +2.23.0 + diff --git a/0021-kpatch-build-don-t-copy-.config-for-out-of-tree-modu.patch b/0021-kpatch-build-don-t-copy-.config-for-out-of-tree-modu.patch deleted file mode 100644 index 7ed26264753f841e2c4cc3a3e5f15bb7035acc0b..0000000000000000000000000000000000000000 --- a/0021-kpatch-build-don-t-copy-.config-for-out-of-tree-modu.patch +++ /dev/null @@ -1,28 +0,0 @@ -From cff73a8dca7069d9e558c65f0b76297feab09719 Mon Sep 17 00:00:00 2001 -From: Zhipeng Xie -Date: Thu, 12 Mar 2020 07:37:00 -0400 -Subject: [PATCH 21/23] kpatch-build: don't copy .config for out of tree module - -.config only need to be restored when the build patch for kernel - -Signed-off-by: Zhipeng Xie ---- - kpatch-build/kpatch-build | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/kpatch-build/kpatch-build b/kpatch-build/kpatch-build -index ad7ab71..fd34812 100755 ---- a/kpatch-build/kpatch-build -+++ b/kpatch-build/kpatch-build -@@ -828,7 +828,7 @@ fi - - [[ -z "$CONFIGFILE" ]] && CONFIGFILE="$SRCDIR"/.config - [[ ! -e "$CONFIGFILE" ]] && die "can't find config file" --[[ ! "$CONFIGFILE" -ef "$SRCDIR"/.config ]] && cp -f "$CONFIGFILE" "$SRCDIR/.config" -+[[ -z "$OOT_MODULE" ]] && [[ ! "$CONFIGFILE" -ef "$SRCDIR"/.config ]] && cp -f "$CONFIGFILE" "$SRCDIR/.config" - - # Build variables - Set some defaults, then adjust features - # according to .config and kernel version --- -2.18.1 - diff --git a/0022-support-force-enable-disable-for-x86.patch b/0022-support-force-enable-disable-for-x86.patch deleted file mode 100644 index 07dc053842e9932cd7f9ee53650292dc8d3081bf..0000000000000000000000000000000000000000 --- a/0022-support-force-enable-disable-for-x86.patch +++ /dev/null @@ -1,58 +0,0 @@ -From 11e57aa03ae87fa24028800851f34205a2aeb0d8 Mon Sep 17 00:00:00 2001 -From: Zhipeng Xie -Date: Wed, 15 Apr 2020 06:37:59 -0400 -Subject: [PATCH 22/23] support force enable/disable for x86 - -detect if the klp_func structure in vmlinux have force -member, if it has, export KLP_SUPPORT_FORCE=y. - -Signed-off-by: Zhipeng Xie ---- - kpatch-build/kpatch-build | 8 ++++++-- - 1 file changed, 6 insertions(+), 2 deletions(-) - -diff --git a/kpatch-build/kpatch-build b/kpatch-build/kpatch-build -index fd34812..523d5df 100755 ---- a/kpatch-build/kpatch-build -+++ b/kpatch-build/kpatch-build -@@ -373,7 +373,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 = j = 0 } -+ BEGIN { a = b = p = e = o = j = c = f = 0 } - - # Set state if name matches - a == 0 && /DW_AT_name.* alt_instr[[:space:]]*$/ {a = 1; next} -@@ -382,6 +382,7 @@ find_special_section_data() { - e == 0 && /DW_AT_name.* exception_table_entry[[:space:]]*$/ {e = 1; next} - o == 0 && /DW_AT_name.* orc_entry[[:space:]]*$/ {o = 1; next} - j == 0 && /DW_AT_name.* jump_entry[[:space:]]*$/ {j = 1; next} -+ c == 0 && /DW_AT_name.* klp_func[[:space:]]*$/ {c = 1; next} - - # Reset state unless this abbrev describes the struct size - a == 1 && !/DW_AT_byte_size/ { a = 0; next } -@@ -390,6 +391,8 @@ find_special_section_data() { - e == 1 && !/DW_AT_byte_size/ { e = 0; next } - o == 1 && !/DW_AT_byte_size/ { o = 0; next } - j == 1 && !/DW_AT_byte_size/ { j = 0; next } -+ c == 1 && /DW_TAG_structure_type/ { c = 3; next } -+ c == 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} -@@ -398,9 +401,10 @@ find_special_section_data() { - e == 1 {printf("export EX_STRUCT_SIZE=%d\n", $4); e = 2} - o == 1 {printf("export ORC_STRUCT_SIZE=%d\n", $4); o = 2} - j == 1 {printf("export JUMP_STRUCT_SIZE=%d\n", $4); j = 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) && (j == 2 || skip_j) {exit}')" -+ a == 2 && b == 2 && (p == 2 || skip_p) && e == 2 && (o == 2 || skip_o) && (j == 2 || skip_j) && c == 3 {exit}')" - - [[ -n "$SPECIAL_VARS" ]] && eval "$SPECIAL_VARS" - --- -2.18.1 - diff --git a/0018-use-original-reloc-for-symbols-from-modules.patch b/0022-use-original-reloc-for-symbols-exported-from-modules.patch similarity index 40% rename from 0018-use-original-reloc-for-symbols-from-modules.patch rename to 0022-use-original-reloc-for-symbols-exported-from-modules.patch index 7444cbcc37f19b1d19221fe7a0107a1b287c7ac2..b08b9904e6ee1a0f0302ff39cb83d6ad3bb29f93 100644 --- a/0018-use-original-reloc-for-symbols-from-modules.patch +++ b/0022-use-original-reloc-for-symbols-exported-from-modules.patch @@ -1,7 +1,7 @@ -From f162056f0448e676345e3205ef4b190f81b51295 Mon Sep 17 00:00:00 2001 +From b841186b9f8ced6a78953c0c109138f9aef7a53a Mon Sep 17 00:00:00 2001 From: Zhipeng Xie Date: Thu, 12 Mar 2020 05:10:55 -0400 -Subject: [PATCH 18/23] use original reloc for symbols from modules +Subject: [PATCH 22/24] use original reloc for symbols exported from modules symbols exported in a patch will generate a symbol version with object module name in Module.symvers, but the symbol is actually @@ -9,25 +9,28 @@ in patch module which cause livepatch symbol lookup failed. Signed-off-by: Zhipeng Xie --- - kpatch-build/create-diff-object.c | 4 +--- - 1 file changed, 1 insertion(+), 3 deletions(-) + kpatch-build/create-diff-object.c | 8 +------- + 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/kpatch-build/create-diff-object.c b/kpatch-build/create-diff-object.c -index 20213a0..457d517 100644 +index aa5c5c4..59d491d 100644 --- a/kpatch-build/create-diff-object.c +++ b/kpatch-build/create-diff-object.c -@@ -3141,10 +3141,8 @@ static void kpatch_create_intermediate_sections(struct kpatch_elf *kelf, - if (!strcmp(sym_objname, "vmlinux")) - continue; +@@ -3317,13 +3317,7 @@ static bool need_dynrela(struct lookup_table *table, struct section *sec, const + return false; + } -- if (!strcmp(sym_objname, objname)) -- continue; -- - external = 1; -+ continue; - } - } - log_debug("lookup for %s @ 0x%016lx len %lu\n", +- /* +- * The symbol is exported by the to-be-patched module, or by +- * another module which the patched module depends on. Use a +- * dynrela because of late module loading: the patch module may +- * be loaded before the to-be-patched (or other) module. +- */ +- return true; ++ return false; + } + + if (symbol.global) { -- -2.18.1 +2.23.0 diff --git a/0007-create-diff-object-create-dynamic-relocs-for-changed.patch b/0023-create-diff-object-create-dynamic-relocs-for-changed.patch similarity index 45% rename from 0007-create-diff-object-create-dynamic-relocs-for-changed.patch rename to 0023-create-diff-object-create-dynamic-relocs-for-changed.patch index a24b56778d1bbb04e120f611f51847f710bb98b2..565b9548dc509d1b644e6600cfc25dddb80ef79e 100644 --- a/0007-create-diff-object-create-dynamic-relocs-for-changed.patch +++ b/0023-create-diff-object-create-dynamic-relocs-for-changed.patch @@ -1,7 +1,7 @@ -From 66d1b112903b4942cc1033a1be93ae79c1ecf8ef Mon Sep 17 00:00:00 2001 +From 7fa14b0c6f2e42cdf76b44b1337eb27e5b777d14 Mon Sep 17 00:00:00 2001 From: Zhipeng Xie Date: Fri, 2 Nov 2018 17:25:38 +0000 -Subject: [PATCH 07/23] create-diff-object: create dynamic relocs for changed +Subject: [PATCH 23/24] create-diff-object: create dynamic relocs for changed functions in this object Currently, we only create dynamic relocs for changed functions of @@ -22,50 +22,26 @@ Signed-off-by: Zhou Chengming Signed-off-by: Li Bin Signed-off-by: Zhipeng Xie --- - kpatch-build/create-diff-object.c | 23 +++++++++++++++++++---- - 1 file changed, 19 insertions(+), 4 deletions(-) + 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 ba2976b..8ce3b59 100644 +index 59d491d..3a12ee1 100644 --- a/kpatch-build/create-diff-object.c +++ b/kpatch-build/create-diff-object.c -@@ -2900,6 +2900,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; -+ } - } - } +@@ -3238,6 +3238,12 @@ static bool need_dynrela(struct lookup_table *table, struct section *sec, const + return false; -@@ -2982,10 +2990,17 @@ static void kpatch_create_intermediate_sections(struct kpatch_elf *kelf, - /* An unchanged local symbol */ - ret = lookup_local_symbol(table, - rela->sym->name, &result); -- if (ret) -- ERROR("lookup_local_symbol %s needed for %s", -- rela->sym->name, sec->base->name); -- -+ if (ret) { -+ /* -+ * maybe it is a global symbol converted in -+ * kpatch_create_patches_sections -+ */ -+ ret = lookup_global_symbol(table, -+ rela->sym->name, &result); -+ if (ret) -+ ERROR("lookup_local_symbol %s needed for %s", -+ rela->sym->name, sec->base->name); -+ } - } - else if (vmlinux) { - /* + 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) ++ return true; + /* + * Internal symbols usually don't need dynrelas, because they + * live in the patch module and can be relocated normally. -- -2.18.1 +2.23.0 diff --git a/0023-create-diff-object-fix-duplicate-symbols-for-vmlinux.patch b/0023-create-diff-object-fix-duplicate-symbols-for-vmlinux.patch deleted file mode 100644 index 002668f39a6fbcf2bad4927176a1f8a924247c98..0000000000000000000000000000000000000000 --- a/0023-create-diff-object-fix-duplicate-symbols-for-vmlinux.patch +++ /dev/null @@ -1,65 +0,0 @@ -From 459018cfabc65e9f29bf25476c727b4d5d8089c4 Mon Sep 17 00:00:00 2001 -From: Zhipeng Xie -Date: Wed, 22 Apr 2020 05:55:33 -0400 -Subject: [PATCH 23/23] create-diff-object: fix duplicate symbols for vmlinux - -symbol pos in vmlinux may be different with runtime -/proc/kallsyms, use ref_name and ref_offset method too. - -Signed-off-by: Zhipeng Xie ---- - kpatch-build/create-diff-object.c | 36 ++++++++++++++++--------------- - 1 file changed, 19 insertions(+), 17 deletions(-) - -diff --git a/kpatch-build/create-diff-object.c b/kpatch-build/create-diff-object.c -index 4fa4488..ad5746b 100644 ---- a/kpatch-build/create-diff-object.c -+++ b/kpatch-build/create-diff-object.c -@@ -3110,25 +3110,27 @@ 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, objname, -- result.pos)) { -- struct lookup_refsym refsym; -- -- if (lookup_ref_symbol_offset(table, rela->sym->name, -- &refsym, objname, &ref_offset)) -- ERROR("unresolvable ambiguity on symbol %s\n", -- rela->sym->name); -- -- /* add rela to fill in ref_name field */ -- ALLOC_LINK(rela2, &krela_sec->rela->relas); -- rela2->sym = strsym; -- rela2->type = absolute_rela_type; -- rela2->addend = offset_of_string(&kelf->strings, -- refsym.name); -- rela2->offset = (unsigned int)(index * sizeof(*krelas) + -+ } -+ -+ if (lookup_is_duplicate_symbol(table, rela->sym->name, objname, -+ result.pos)) { -+ struct lookup_refsym refsym; -+ -+ if (lookup_ref_symbol_offset(table, rela->sym->name, -+ &refsym, objname, &ref_offset)) -+ ERROR("unresolvable ambiguity on symbol %s\n", -+ rela->sym->name); -+ -+ /* add rela to fill in ref_name field */ -+ ALLOC_LINK(rela2, &krela_sec->rela->relas); -+ rela2->sym = strsym; -+ rela2->type = absolute_rela_type; -+ rela2->addend = offset_of_string(&kelf->strings, -+ refsym.name); -+ rela2->offset = (unsigned int)(index * sizeof(*krelas) + - offsetof(struct kpatch_relocation, ref_name)); -- } - } -+ - ksyms[index].pos = result.pos; - ksyms[index].type = rela->sym->type; - ksyms[index].bind = rela->sym->bind; --- -2.18.1 - diff --git a/0024-kpatch-build-support-CROSS_COMPILE.patch b/0024-kpatch-build-support-CROSS_COMPILE.patch new file mode 100644 index 0000000000000000000000000000000000000000..56160d5f3d70b2fc80dea346812e732186755bb1 --- /dev/null +++ b/0024-kpatch-build-support-CROSS_COMPILE.patch @@ -0,0 +1,29 @@ +From ea05261d87f22ecebcc5e4abac662960e732e33b Mon Sep 17 00:00:00 2001 +From: Zhipeng Xie +Date: Tue, 16 Nov 2021 20:21:31 +0800 +Subject: [PATCH 24/24] kpatch-build: support CROSS_COMPILE + +some Makefile use $(CROSS_COMPILE)gcc to compile .o +file, append CROSS_COMPILE to MAKEVARS to make it +run into kpatch-cc. + +Signed-off-by: Zhipeng Xie +--- + kpatch-build/kpatch-build | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/kpatch-build/kpatch-build b/kpatch-build/kpatch-build +index 2ead6e4..6a9e818 100755 +--- a/kpatch-build/kpatch-build ++++ b/kpatch-build/kpatch-build +@@ -1016,6 +1016,7 @@ if [ "$CONFIG_CC_IS_CLANG" -eq 1 ]; then + MAKEVARS+=("HOSTCC=clang") + else + MAKEVARS+=("CC=${KPATCH_CC_PREFIX}gcc") ++ MAKEVARS+=("CROSS_COMPILE=${KPATCH_CC_PREFIX}") + fi + + if [ "$CONFIG_LD_IS_LLD" -eq 1 ]; then +-- +2.23.0 + diff --git a/0024-optimize-for-out-of-tree-module.patch b/0024-optimize-for-out-of-tree-module.patch deleted file mode 100644 index 032ca8370156cab2004e9c25c507a9ff7cc3427a..0000000000000000000000000000000000000000 --- a/0024-optimize-for-out-of-tree-module.patch +++ /dev/null @@ -1,44 +0,0 @@ -From aef88b0908ee9d36131c63493c02359a04d1304c Mon Sep 17 00:00:00 2001 -From: Zhipeng Xie -Date: Fri, 13 Nov 2020 03:05:22 -0500 -Subject: [PATCH] optimize for out of tree module - -some out-of-tree modules's Module.symvers not in SRCDIR -some out-of-tree modules's obj has relative path like /xxx/./xxx.o - -Signed-off-by: Zhipeng Xie ---- - kpatch-build/kpatch-build | 1 + - kpatch-build/kpatch-gcc | 4 +++- - 2 files changed, 4 insertions(+), 1 deletion(-) - -diff --git a/kpatch-build/kpatch-build b/kpatch-build/kpatch-build -index 523d5df..6238bc8 100755 ---- a/kpatch-build/kpatch-build -+++ b/kpatch-build/kpatch-build -@@ -1035,6 +1035,7 @@ for i in $FILES; do - BUILDDIR="/lib/modules/$ARCHVERSION/build/" - SYMVERS_FILE="$TEMPDIR/Module.symvers" - [[ -e $SRCDIR/Module.symvers ]] && cp "$SRCDIR/Module.symvers" "$SYMVERS_FILE" -+ [[ -e $USERMODBUILDDIR/Module.symvers ]] && cp "$USERMODBUILDDIR/Module.symvers" $SYMVERS_FILE - awk '{ print $1 "\t" $2 "\t" $3 "\t" $4}' "${BUILDDIR}/Module.symvers" >> "$SYMVERS_FILE" - fi - fi -diff --git a/kpatch-build/kpatch-gcc b/kpatch-build/kpatch-gcc -index 6ad6ebc..2b2490e 100755 ---- a/kpatch-build/kpatch-gcc -+++ b/kpatch-build/kpatch-gcc -@@ -25,7 +25,9 @@ if [[ "$TOOLCHAINCMD" =~ "${ARCH_COMPILE}gcc" || - - [[ "$obj" = */.tmp_*.o ]] && obj="${obj/.tmp_/}" - relobj=${obj//$KPATCH_GCC_SRCDIR\//} -- case "$relobj" in -+ tmpobj=$(readlink -f $obj) -+ relobj2=${tmpobj//$KPATCH_GCC_SRCDIR\//} -+ case "$relobj2" in - *.mod.o|\ - *built-in.o|\ - *built-in.a|\ --- -2.18.1 - diff --git a/0027-create-build-diff-support-for-.cold-functions-with-n.patch b/0027-create-build-diff-support-for-.cold-functions-with-n.patch deleted file mode 100644 index e1d8df05d3e5d28fcc5cb2f00fd7e0c5e48fa120..0000000000000000000000000000000000000000 --- a/0027-create-build-diff-support-for-.cold-functions-with-n.patch +++ /dev/null @@ -1,42 +0,0 @@ -From 55a2778284c088f4c383cf364bef18f1b5b88531 Mon Sep 17 00:00:00 2001 -From: Artem Savkov -Date: Thu, 4 Mar 2021 12:47:43 +0100 -Subject: [PATCH] create-build-diff: support for .cold functions with no id - suffix - -create-build-diff expects .cold functions to be suffixed by an id, which -is not always the case. Drop the trailing '.' when searching for cold -functions. - -Fixes: #1160 - -Signed-off-by: Artem Savkov ---- - kpatch-build/create-diff-object.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/kpatch-build/create-diff-object.c b/kpatch-build/create-diff-object.c -index 6b19e1e..d20f2f1 100644 ---- a/kpatch-build/create-diff-object.c -+++ b/kpatch-build/create-diff-object.c -@@ -124,7 +124,7 @@ static int is_bundleable(struct symbol *sym) - if (sym->type == STT_FUNC && - !strncmp(sym->sec->name, ".text.unlikely.",15) && - (!strcmp(sym->sec->name + 15, sym->name) || -- (strstr(sym->name, ".cold.") && -+ (strstr(sym->name, ".cold") && - !strncmp(sym->sec->name + 15, sym->name, strlen(sym->sec->name) - 15)))) - return 1; - -@@ -248,7 +248,7 @@ static void kpatch_detect_child_functions(struct kpatch_elf *kelf) - list_for_each_entry(sym, &kelf->symbols, list) { - char *coldstr; - -- coldstr = strstr(sym->name, ".cold."); -+ coldstr = strstr(sym->name, ".cold"); - if (coldstr != NULL) { - char *pname; - --- -2.27.0 - diff --git a/0028-lookup-Add-__UNIQUE_ID_-to-maybe_discarded_sym-list.patch b/0028-lookup-Add-__UNIQUE_ID_-to-maybe_discarded_sym-list.patch deleted file mode 100644 index f7def25a0f02080e71d2f95f92c153e3b3eec1fd..0000000000000000000000000000000000000000 --- a/0028-lookup-Add-__UNIQUE_ID_-to-maybe_discarded_sym-list.patch +++ /dev/null @@ -1,62 +0,0 @@ -From b381a0cc0b900d042ff6a718ef9795101310d702 Mon Sep 17 00:00:00 2001 -From: Kamalesh Babulal -Date: Wed, 17 Jun 2020 19:51:56 +0530 -Subject: [PATCH] lookup: Add __UNIQUE_ID_ to maybe_discarded_sym list - -Linux kernel tristate config options allows selected feature, either to -be built-in to the kernel or to be built as a kernel module. When built -as a kernel module, it's expected that the module, will be built with -module information such as author, license, description and others. - -For each of the modinfo, a corresponding __UNIQUE_ID_ symbol is -generated. Their lookup succeeds in the case of module but fails when -selected to built-in to the kernel, the reason being that the kernel -discards these __UNIQUE_ID_ symbols during linking. Add __UNIQUE_ID_ -symbols to maybe_discarded_sym list, to avoid failure in case of -table->object is vmlinux. - -i.e.: - # cat .config|grep IOSCHED_BFQ (can be compiled as module too) - CONFIG_IOSCHED_BFQ=y - - # readelf -sW ./block/bfq-iosched.o|grep UNIQUE - 219: 0000000000000000 54 OBJECT LOCAL DEFAULT 267 __UNIQUE_ID_description223 - 220: 0000000000000036 16 OBJECT LOCAL DEFAULT 267 __UNIQUE_ID_license222 - 221: 0000000000000046 19 OBJECT LOCAL DEFAULT 267 __UNIQUE_ID_file221 - 222: 0000000000000059 25 OBJECT LOCAL DEFAULT 267 __UNIQUE_ID_author220 - 223: 0000000000000072 22 OBJECT LOCAL DEFAULT 267 __UNIQUE_ID_alias219 - -the line below before the kpatch error, is a debug printf to find the failing lookup symbol: -Failed lookup for __UNIQUE_ID_description223 -/root/kpatch/kpatch-build/create-diff-object: ERROR: bfq-iosched.o: find_local_syms: 180: couldn't find matching bfq-iosched.c local symbols in ./vmlinux symbol table - -with the patch, it successfully builds with both y/m config options: -... -bfq-iosched.o: changed function: bfq_idle_slice_timer -Patched objects: vmlinux -Building patch module: -livepatch-0001-block-bfq-fix-use-after-free-in-b.ko -SUCCESS - -Signed-off-by: Kamalesh Babulal ---- - 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 4f8c779..9086c9c 100644 ---- a/kpatch-build/lookup.c -+++ b/kpatch-build/lookup.c -@@ -83,7 +83,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, "__addressable_", 14)) -+ !strncmp(name, "__addressable_", 14) || -+ !strncmp(name, "__UNIQUE_ID_", 12)) - return 1; - - return 0; --- -2.27.0 - diff --git a/README.md b/README.md index 0682b35c3db1b6d5f4878bd7c8d09811c459a911..5159c801d25843ce3c04ace182cb87889407ef79 100644 --- a/README.md +++ b/README.md @@ -163,10 +163,11 @@ livepatch -r cmdline ## 编译更新补丁工具 ```bash -yum install -y git rpm-build elfutils-libelf-devel uname-build-checks gdb-headless +yum install -y git rpm-build elfutils-libelf-devel gdb-headless git clone https://gitee.com/src-openeuler/kpatch.git mkdir -p ~/rpmbuild/SOURCES/ /bin/cp kpatch/* ~/rpmbuild/SOURCES/ rpmbuild -ba kpatch/kpatch.spec rpm -Uvh ~/rpmbuild/RPMS/`arch`/kpatch*.rpm +rpm -Uvh ~/rpmbuild/RPMS/noarch/kpatch*.rpm ``` diff --git a/kpatch-0.9.1.tar.gz b/kpatch-0.9.1.tar.gz deleted file mode 100644 index 0893f72ee5fc9584cc1d585d9f60fe106098e3d8..0000000000000000000000000000000000000000 Binary files a/kpatch-0.9.1.tar.gz and /dev/null differ diff --git a/kpatch-0.9.5.tar.gz b/kpatch-0.9.5.tar.gz new file mode 100644 index 0000000000000000000000000000000000000000..866cbbbded222463ce497f56cc14691de85130f6 Binary files /dev/null and b/kpatch-0.9.5.tar.gz differ diff --git a/kpatch.spec b/kpatch.spec index 19542e30cb5515839e793949999b8f23c9fed6c1..db91d2ad1c1f26dc18b671c52955d1b95edf7dcd 100644 --- a/kpatch.spec +++ b/kpatch.spec @@ -1,7 +1,7 @@ Name: kpatch Epoch: 1 -Version: 0.9.1 -Release: 15 +Version: 0.9.5 +Release: 1 Summary: A Linux dynamic kernel patching infrastructure License: GPLv2 @@ -12,36 +12,33 @@ Source1: os_hotpatch Source2: livepatch Source3: make_hotpatch -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 -Patch0018:0018-use-original-reloc-for-symbols-from-modules.patch -Patch0019:0019-create-diff-object-add-jump-label-support.patch -Patch0020:0020-kpatch-build-add-compile-flag-fno-reorder-functions.patch -Patch0021:0021-kpatch-build-don-t-copy-.config-for-out-of-tree-modu.patch -Patch0022:0022-support-force-enable-disable-for-x86.patch -Patch0023:0023-create-diff-object-fix-duplicate-symbols-for-vmlinux.patch -Patch0024:0024-optimize-for-out-of-tree-module.patch -Patch0025:0025-Fix-relocation-not-resolved-when-new-functions-expor.patch -Patch0026:0026-support-remove-static-variables-using-KPATCH_IGNORE_.patch -Patch0027:0027-create-build-diff-support-for-.cold-functions-with-n.patch -Patch0028:0028-lookup-Add-__UNIQUE_ID_-to-maybe_discarded_sym-list.patch - -BuildRequires: gcc elfutils-libelf-devel uname-build-checks kernel-devel git +#custom patch +Patch0001:0001-kpatch-add-aarch64-support.patch +Patch0002:0002-create-diff-object-fix-symbol-changed-sections-error.patch +Patch0003:0003-create-diff-object-support-kpatch_line_macro_change_.patch +Patch0004:0004-create-diff-object-support-skip-check-func-profiling.patch +Patch0005:0005-create-diff-object-new-static-var-should-be-included.patch +Patch0006:0006-create-diff-object-fix-correlate-static-local-variab.patch +Patch0007:0007-fix-rodata.str-problem.patch +Patch0008:0008-livepatch-patch-hook-support-no-active-after-load.patch +Patch0009:0009-kpatch-build-enhance-for-out-of-tree-module.patch +Patch0010:0010-support-c-kernel-module.patch +Patch0011:0011-symbol-lookup-enhancement.patch +Patch0012:0012-Add-running-kernel-symbol-table-to-help-symbol-looku.patch +Patch0013:0013-livepatch-patch-hook-support-force-enable-disable.patch +Patch0014:0014-kpatch-build-ignore-debuginfo-in-patch.patch +Patch0015:0015-add-object-in-kpatch.patch +Patch0016:0016-create-diff-object-fix-.orc_unwind_ip-error.patch +Patch0017:0017-create-diff-object-add-jump-label-support.patch +Patch0018:0018-kpatch-build-add-compile-flag-fno-reorder-functions.patch +Patch0019:0019-Fix-relocation-not-resolved-when-new-functions-expor.patch +Patch0020:0020-support-remove-static-variables-using-KPATCH_IGNORE_.patch +Patch0021:0021-create-diff-object-fix-segment-fault-when-sec2-rela-.patch +Patch0022:0022-use-original-reloc-for-symbols-exported-from-modules.patch +Patch0023:0023-create-diff-object-create-dynamic-relocs-for-changed.patch +Patch0024:0024-kpatch-build-support-CROSS_COMPILE.patch + +BuildRequires: gcc elfutils-libelf-devel kernel-devel git Requires: bc make gcc patch bison flex openssl-devel Recommends: %{name}-help = %{version}-%{release} @@ -100,6 +97,12 @@ popd %{_mandir}/man1/*.1.gz %changelog +* Sat Nov 13 2021 Zhipeng Xie -1:0.9.5-1 +- Type:enhancement +- ID:NA +- SUG:NA +- DESC:upgrade to upstream v0.9.5 + * Fri Jul 23 2021 Xinpeng Liu -1:0.9.1-15 - Type:enhancement - ID:NA diff --git a/make_compile_env.sh b/make_compile_env.sh new file mode 100644 index 0000000000000000000000000000000000000000..416c02f56db00e0fd8038071da5df0c42496a8fc --- /dev/null +++ b/make_compile_env.sh @@ -0,0 +1,42 @@ +#!/bin/bash +rm -rf kpatch_compile_env +yum install -y strace vim git rpm-build bc elfutils-libelf-devel gdb-headless make gcc patch bison flex openssl-devel kernel-source-`uname -r` kernel-debuginfo-`uname -r` kernel-devel-`uname -r` --installroot=`pwd`/kpatch_compile_env/ +mkdir -p kpatch_compile_env/kpatch +/bin/cp * kpatch_compile_env/kpatch/ +cat > kpatch_compile_env/installkpatch.sh < kpatch_compile_env/chroot.sh < kpatch_compile_env/unchroot.sh < kpatch_compile_env/usr/bin/openEuler_history</dev/null if [ $l_ret -eq 0 ] && [ -f "$G_TMP_DIR/$G_HOTPATCH" ];then