From 85c1123ab81c2b753c5fa8a854e51724f98b5e91 Mon Sep 17 00:00:00 2001 From: Zhipeng Xie Date: Thu, 20 Dec 2018 04:55:38 +0000 Subject: [PATCH 01/38] 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 | 2 +- kpatch-build/create-diff-object.c | 32 ++++++++++++++++++------------- kpatch-build/kpatch-build | 5 +++++ kpatch-build/kpatch-elf.c | 7 +++++++ kpatch-build/kpatch-elf.h | 1 + 5 files changed, 33 insertions(+), 14 deletions(-) diff --git a/kpatch-build/Makefile b/kpatch-build/Makefile index bebf3cd..5037677 100644 --- a/kpatch-build/Makefile +++ b/kpatch-build/Makefile @@ -22,7 +22,7 @@ PLUGIN_CFLAGS := $(filter-out -Wconversion, $(CFLAGS)) PLUGIN_CFLAGS += -shared -I$(GCC_PLUGINS_DIR)/include \ -Igcc-plugins -fPIC -fno-rtti -O2 -Wall endif -ifeq ($(filter $(ARCH),s390x x86_64 ppc64le),) +ifeq ($(filter $(ARCH),s390x x86_64 ppc64le aarch64),) $(error Unsupported architecture ${ARCH}, check https://github.com/dynup/kpatch/#supported-architectures) endif diff --git a/kpatch-build/create-diff-object.c b/kpatch-build/create-diff-object.c index 25710e9..e4c25a6 100644 --- a/kpatch-build/create-diff-object.c +++ b/kpatch-build/create-diff-object.c @@ -180,6 +180,8 @@ static bool is_gcc6_localentry_bundled_sym(struct kpatch_elf *kelf, return false; case S390: return false; + case ARM64: + return false; default: ERROR("unsupported arch"); } @@ -2415,48 +2417,48 @@ static bool static_call_sites_group_filter(struct lookup_table *lookup, static struct special_section special_sections[] = { { .name = "__bug_table", - .arch = X86_64 | PPC64 | S390, + .arch = X86_64 | PPC64 | S390 | ARM64, .group_size = bug_table_group_size, }, { .name = ".fixup", - .arch = X86_64 | PPC64 | S390, + .arch = X86_64 | PPC64 | S390 | ARM64, .group_size = fixup_group_size, }, { .name = "__ex_table", /* must come after .fixup */ - .arch = X86_64 | PPC64 | S390, + .arch = X86_64 | PPC64 | S390 | ARM64, .group_size = ex_table_group_size, }, { .name = "__jump_table", - .arch = X86_64 | PPC64 | S390, + .arch = X86_64 | PPC64 | S390 | ARM64, .group_size = jump_table_group_size, .group_filter = jump_table_group_filter, }, { .name = ".printk_index", - .arch = X86_64 | PPC64 | S390, + .arch = X86_64 | PPC64 | S390 | ARM64, .group_size = printk_index_group_size, }, { .name = ".smp_locks", - .arch = X86_64, + .arch = X86_64 | ARM64, .group_size = smp_locks_group_size, }, { .name = ".parainstructions", - .arch = X86_64, + .arch = X86_64 | ARM64, .group_size = parainstructions_group_size, }, { .name = ".altinstructions", - .arch = X86_64 | S390, + .arch = X86_64 | S390 | ARM64, .group_size = altinstructions_group_size, }, { .name = ".static_call_sites", - .arch = X86_64, + .arch = X86_64 | ARM64, .group_size = static_call_sites_group_size, .group_filter = static_call_sites_group_filter, }, @@ -2467,12 +2469,12 @@ static struct special_section special_sections[] = { }, { .name = ".retpoline_sites", - .arch = X86_64, + .arch = X86_64 | ARM64, .group_size = retpoline_sites_group_size, }, { .name = ".return_sites", - .arch = X86_64, + .arch = X86_64 | ARM64, .group_size = return_sites_group_size, }, { @@ -3241,7 +3243,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_klp_reloc(struct kpatch_elf *kelf, struct lookup_table *table, @@ -3715,7 +3719,8 @@ static void kpatch_create_mcount_sections(struct kpatch_elf *kelf) } switch(kelf->arch) { - case PPC64: { + case PPC64: + case ARM64: { bool found = false; list_for_each_entry(rela, &sym->sec->rela->relas, list) @@ -3958,6 +3963,7 @@ static void kpatch_find_func_profiling_calls(struct kpatch_elf *kelf) switch(kelf->arch) { case PPC64: + case ARM64: list_for_each_entry(rela, &sym->sec->rela->relas, list) { if (!strcmp(rela->sym->name, "_mcount")) { sym->has_func_profiling = 1; diff --git a/kpatch-build/kpatch-build b/kpatch-build/kpatch-build index d01a8d9..80d7209 100755 --- a/kpatch-build/kpatch-build +++ b/kpatch-build/kpatch-build @@ -350,6 +350,9 @@ find_special_section_data() { "s390x") check[a]=true # alt_instr ;; + "aarch64") + check[a]=true # alt_instr + ;; esac # Kernel CONFIG_ features @@ -357,6 +360,8 @@ find_special_section_data() { [[ -n "$CONFIG_JUMP_LABEL" ]] && check[j]=true # jump_entry [[ -n "$CONFIG_UNWINDER_ORC" ]] && check[o]=true # orc_entry + [[ "$ARCH" == "aarch64" ]] && unset check[p] + local c AWK_OPTIONS for c in "${!check[@]}"; do AWK_OPTIONS+=" -vcheck_${c}=1" diff --git a/kpatch-build/kpatch-elf.c b/kpatch-build/kpatch-elf.c index 374d424..d4aee86 100644 --- a/kpatch-build/kpatch-elf.c +++ b/kpatch-build/kpatch-elf.c @@ -142,6 +142,8 @@ unsigned int absolute_rela_type(struct kpatch_elf *kelf) return R_X86_64_64; case S390: return R_390_64; + case ARM64: + return R_AARCH64_ABS64; default: ERROR("unsupported arch"); } @@ -206,6 +208,7 @@ long rela_target_offset(struct kpatch_elf *kelf, struct section *relasec, switch(kelf->arch) { case PPC64: + case ARM64: add_off = 0; break; case X86_64: @@ -261,6 +264,7 @@ unsigned int insn_length(struct kpatch_elf *kelf, void *addr) return decoded_insn.length; case PPC64: + case ARM64: return 4; case S390: @@ -593,6 +597,9 @@ struct kpatch_elf *kpatch_elf_open(const char *name) case EM_S390: kelf->arch = S390; break; + case EM_AARCH64: + kelf->arch = ARM64; + break; default: ERROR("Unsupported target architecture"); } diff --git a/kpatch-build/kpatch-elf.h b/kpatch-build/kpatch-elf.h index e32209b..47e3117 100644 --- a/kpatch-build/kpatch-elf.h +++ b/kpatch-build/kpatch-elf.h @@ -115,6 +115,7 @@ enum architecture { PPC64 = 0x1 << 0, X86_64 = 0x1 << 1, S390 = 0x1 << 2, + ARM64 = 0x1 << 3, }; struct kpatch_elf { -- 2.33.0