kpatch/0003-create-diff-object-support-kpatch_line_macro_change_.patch
Zhipeng Xie 4424f7bf7e rebase from upstream v0.9.5
Signed-off-by: Zhipeng Xie <xiezhipeng1@huawei.com>
2021-11-19 12:02:33 +08:00

91 lines
2.6 KiB
Diff

From b71b6e5f46fdc3f1b709b58777cb0da7ec9fc008 Mon Sep 17 00:00:00 2001
From: Zhipeng Xie <xiezhipeng1@huawei.com>
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 <xiezhipeng1@huawei.com>
---
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