91 lines
2.6 KiB
Diff
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
|
|
|