107 lines
3.1 KiB
Diff
107 lines
3.1 KiB
Diff
From d1bbff5da464148e5d277b601a31d7872b4e376b Mon Sep 17 00:00:00 2001
|
|
From: Zhipeng Xie <xiezhipeng1@huawei.com>
|
|
Date: Fri, 2 Nov 2018 17:26:00 +0000
|
|
Subject: [PATCH 1015/1015] create-diff-object: exclude line only change for
|
|
arm64
|
|
|
|
exclude line only change for arm64 by compare mov instruction
|
|
except immediate part.
|
|
|
|
Signed-off-by: Zhipeng Xie <xiezhipeng1@huawei.com>
|
|
---
|
|
kpatch-build/create-diff-object.c | 71 ++++++++++++++++++++++++++++++++++++-
|
|
1 files changed, 70 insertions(+), 1 deletions(-)
|
|
|
|
diff --git a/kpatch-build/create-diff-object.c b/kpatch-build/create-diff-object.c
|
|
index f8f3e15..12d8bd6 100644
|
|
--- a/kpatch-build/create-diff-object.c
|
|
+++ b/kpatch-build/create-diff-object.c
|
|
@@ -609,6 +609,68 @@ static int kpatch_line_macro_change_only(struct section *sec)
|
|
return 0;
|
|
}
|
|
#endif
|
|
+#define ARM64_INSTR_LEN 4
|
|
+static int arm64_kpatch_line_macro_change_only(struct section *sec)
|
|
+{
|
|
+ unsigned long start1, start2, size, offset;
|
|
+ struct rela *rela;
|
|
+ int lineonly = 0, found;
|
|
+ unsigned int mov_imm_mask = ((1<<16) - 1)<<5;
|
|
+
|
|
+ if (sec->status != CHANGED ||
|
|
+ is_rela_section(sec) ||
|
|
+ !is_text_section(sec) ||
|
|
+ sec->sh.sh_size != sec->twin->sh.sh_size ||
|
|
+ !sec->rela ||
|
|
+ sec->rela->status != SAME)
|
|
+ return 0;
|
|
+
|
|
+ start1 = (unsigned long)sec->twin->data->d_buf;
|
|
+ start2 = (unsigned long)sec->data->d_buf;
|
|
+ size = sec->sh.sh_size;
|
|
+ for (offset = 0; offset < size; offset += ARM64_INSTR_LEN) {
|
|
+ if (!memcmp((void *)start1 + offset, (void *)start2 + offset,
|
|
+ ARM64_INSTR_LEN))
|
|
+ continue;
|
|
+
|
|
+ /* verify it's a mov immediate to w1 */
|
|
+ if ((*(int *)(start1 + offset) & ~mov_imm_mask) !=
|
|
+ (*(int *)(start2 + offset) & ~mov_imm_mask))
|
|
+ return 0;
|
|
+
|
|
+ found = 0;
|
|
+ list_for_each_entry(rela, &sec->rela->relas, list) {
|
|
+ if (rela->offset < offset + ARM64_INSTR_LEN)
|
|
+ continue;
|
|
+ if (rela->string)
|
|
+ continue;
|
|
+ if (!strncmp(rela->sym->name, "__warned.", 9))
|
|
+ continue;
|
|
+ if (!strncmp(rela->sym->name, "warn_slowpath_", 14) ||
|
|
+ (!strcmp(rela->sym->name, "__warn_printk")) ||
|
|
+ (!strcmp(rela->sym->name, "__might_sleep")) ||
|
|
+ (!strcmp(rela->sym->name, "___might_sleep")) ||
|
|
+ (!strcmp(rela->sym->name, "__might_fault")) ||
|
|
+ (!strcmp(rela->sym->name, "printk")) ||
|
|
+ (!strcmp(rela->sym->name, "lockdep_rcu_suspicious"))) {
|
|
+ found = 1;
|
|
+ break;
|
|
+ }
|
|
+ return 0;
|
|
+ }
|
|
+ if (!found)
|
|
+ return 0;
|
|
+
|
|
+ lineonly = 1;
|
|
+ }
|
|
+
|
|
+ if (!lineonly)
|
|
+ ERROR("no instruction changes detected for changed section %s",
|
|
+ sec->name);
|
|
+
|
|
+ return 1;
|
|
+}
|
|
+
|
|
|
|
static void kpatch_compare_sections(struct list_head *seclist)
|
|
{
|
|
@@ -624,7 +686,14 @@ static void kpatch_compare_sections(struct list_head *seclist)
|
|
|
|
/* exclude WARN-only, might_sleep changes */
|
|
list_for_each_entry(sec, seclist, list) {
|
|
- if (kpatch_line_macro_change_only(sec)) {
|
|
+ int line_only;
|
|
+ if (arch == EM_X86_64)
|
|
+ line_only = kpatch_line_macro_change_only(sec);
|
|
+ else if (arch == EM_AARCH64)
|
|
+ line_only = arm64_kpatch_line_macro_change_only(sec);
|
|
+ else
|
|
+ line_only = 0;
|
|
+ if (line_only) {
|
|
log_debug("reverting macro / line number section %s status to SAME\n",
|
|
sec->name);
|
|
sec->status = SAME;
|
|
--
|
|
1.7.5.4
|
|
|