All of lore.kernel.org
 help / color / mirror / Atom feed
From: liuj97@gmail.com (Jiang Liu)
To: linux-arm-kernel@lists.infradead.org
Subject: [PATCH v1 2/7] arm64: introduce interfaces to hotpatch kernel and module code
Date: Wed, 25 Sep 2013 18:44:22 +0800	[thread overview]
Message-ID: <1380105868-31985-3-git-send-email-liuj97@gmail.com> (raw)
In-Reply-To: <1380105868-31985-1-git-send-email-liuj97@gmail.com>

From: Jiang Liu <jiang.liu@huawei.com>

Introduce aarch64_insn_patch_text() and __aarch64_insn_patch_text()
to patch kernel and module code.

Function aarch64_insn_patch_text() is a heavy version which may use
stop_machine() to serialize all online CPUs, and function
__aarch64_insn_patch_text() is light version without explicitly
serialization.

Signed-off-by: Jiang Liu <jiang.liu@huawei.com>
Cc: Jiang Liu <liuj97@gmail.com>
---
 arch/arm64/include/asm/insn.h |  2 ++
 arch/arm64/kernel/insn.c      | 64 +++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 66 insertions(+)

diff --git a/arch/arm64/include/asm/insn.h b/arch/arm64/include/asm/insn.h
index e7d1bc8..0ea7193 100644
--- a/arch/arm64/include/asm/insn.h
+++ b/arch/arm64/include/asm/insn.h
@@ -49,5 +49,7 @@ __AARCH64_INSN_FUNCS(nop,	0xFFFFFFFF, 0xD503201F)
 enum aarch64_insn_class aarch64_get_insn_class(u32 insn);
 
 bool aarch64_insn_hotpatch_safe(u32 old_insn, u32 new_insn);
+int aarch64_insn_patch_text(void *addr, u32 *insns, int cnt);
+int __aarch64_insn_patch_text(void *addr, u32 *insns, int cnt);
 
 #endif	/* _ASM_ARM64_INSN_H */
diff --git a/arch/arm64/kernel/insn.c b/arch/arm64/kernel/insn.c
index 8541c3a..50facfc 100644
--- a/arch/arm64/kernel/insn.c
+++ b/arch/arm64/kernel/insn.c
@@ -15,6 +15,8 @@
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 #include <linux/kernel.h>
+#include <linux/stop_machine.h>
+#include <asm/cacheflush.h>
 #include <asm/insn.h>
 
 static int aarch64_insn_cls[] = {
@@ -69,3 +71,65 @@ bool __kprobes aarch64_insn_hotpatch_safe(u32 old_insn, u32 new_insn)
 	return __aarch64_insn_hotpatch_safe(old_insn) &&
 	       __aarch64_insn_hotpatch_safe(new_insn);
 }
+
+struct aarch64_insn_patch {
+	void	*text_addr;
+	u32	*new_insns;
+	int	insn_cnt;
+};
+
+int __kprobes __aarch64_insn_patch_text(void *addr, u32 *insns, int cnt)
+{
+	int i;
+	u32 *tp = addr;
+
+	/* instructions must be word aligned */
+	if (cnt <= 0 || ((uintptr_t)addr & 0x3))
+		return -EINVAL;
+
+	for (i = 0; i < cnt; i++)
+		tp[i] = insns[i];
+
+	flush_icache_range((uintptr_t)tp, (uintptr_t)tp + cnt * sizeof(u32));
+
+	return 0;
+}
+
+static int __kprobes aarch64_insn_patch_text_cb(void *arg)
+{
+	struct aarch64_insn_patch *pp = arg;
+
+	return __aarch64_insn_patch_text(pp->text_addr, pp->new_insns,
+					 pp->insn_cnt);
+}
+
+int __kprobes aarch64_insn_patch_text(void *addr, u32 *insns, int cnt)
+{
+	int ret;
+	bool safe = false;
+
+	/* instructions must be word aligned */
+	if (cnt <= 0 || ((uintptr_t)addr & 0x3))
+		return -EINVAL;
+
+	if (cnt == 1)
+		safe = aarch64_insn_hotpatch_safe(*(u32 *)addr, insns[0]);
+
+	if (safe) {
+		ret = __aarch64_insn_patch_text(addr, insns, cnt);
+	} else {
+		struct aarch64_insn_patch patch = {
+			.text_addr = addr,
+			.new_insns = insns,
+			.insn_cnt = cnt,
+		};
+
+		/*
+		 * Execute __aarch64_insn_patch_text() on every online CPU,
+		 * which ensure serialization among all online CPUs.
+		 */
+		ret = stop_machine(aarch64_insn_patch_text_cb, &patch, NULL);
+	}
+
+	return ret;
+}
-- 
1.8.1.2

WARNING: multiple messages have this Message-ID (diff)
From: Jiang Liu <liuj97@gmail.com>
To: Steven Rostedt <rostedt@goodmis.org>,
	Catalin Marinas <catalin.marinas@arm.com>,
	Will Deacon <will.deacon@arm.com>,
	Jiang Liu <jiang.liu@huawei.com>,
	linux-arm-kernel@lists.infradead.org,
	linux-kernel@vger.kernel.org
Cc: Jiang Liu <liuj97@gmail.com>
Subject: [PATCH v1 2/7] arm64: introduce interfaces to hotpatch kernel and module code
Date: Wed, 25 Sep 2013 18:44:22 +0800	[thread overview]
Message-ID: <1380105868-31985-3-git-send-email-liuj97@gmail.com> (raw)
In-Reply-To: <1380105868-31985-1-git-send-email-liuj97@gmail.com>

From: Jiang Liu <jiang.liu@huawei.com>

Introduce aarch64_insn_patch_text() and __aarch64_insn_patch_text()
to patch kernel and module code.

Function aarch64_insn_patch_text() is a heavy version which may use
stop_machine() to serialize all online CPUs, and function
__aarch64_insn_patch_text() is light version without explicitly
serialization.

Signed-off-by: Jiang Liu <jiang.liu@huawei.com>
Cc: Jiang Liu <liuj97@gmail.com>
---
 arch/arm64/include/asm/insn.h |  2 ++
 arch/arm64/kernel/insn.c      | 64 +++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 66 insertions(+)

diff --git a/arch/arm64/include/asm/insn.h b/arch/arm64/include/asm/insn.h
index e7d1bc8..0ea7193 100644
--- a/arch/arm64/include/asm/insn.h
+++ b/arch/arm64/include/asm/insn.h
@@ -49,5 +49,7 @@ __AARCH64_INSN_FUNCS(nop,	0xFFFFFFFF, 0xD503201F)
 enum aarch64_insn_class aarch64_get_insn_class(u32 insn);
 
 bool aarch64_insn_hotpatch_safe(u32 old_insn, u32 new_insn);
+int aarch64_insn_patch_text(void *addr, u32 *insns, int cnt);
+int __aarch64_insn_patch_text(void *addr, u32 *insns, int cnt);
 
 #endif	/* _ASM_ARM64_INSN_H */
diff --git a/arch/arm64/kernel/insn.c b/arch/arm64/kernel/insn.c
index 8541c3a..50facfc 100644
--- a/arch/arm64/kernel/insn.c
+++ b/arch/arm64/kernel/insn.c
@@ -15,6 +15,8 @@
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 #include <linux/kernel.h>
+#include <linux/stop_machine.h>
+#include <asm/cacheflush.h>
 #include <asm/insn.h>
 
 static int aarch64_insn_cls[] = {
@@ -69,3 +71,65 @@ bool __kprobes aarch64_insn_hotpatch_safe(u32 old_insn, u32 new_insn)
 	return __aarch64_insn_hotpatch_safe(old_insn) &&
 	       __aarch64_insn_hotpatch_safe(new_insn);
 }
+
+struct aarch64_insn_patch {
+	void	*text_addr;
+	u32	*new_insns;
+	int	insn_cnt;
+};
+
+int __kprobes __aarch64_insn_patch_text(void *addr, u32 *insns, int cnt)
+{
+	int i;
+	u32 *tp = addr;
+
+	/* instructions must be word aligned */
+	if (cnt <= 0 || ((uintptr_t)addr & 0x3))
+		return -EINVAL;
+
+	for (i = 0; i < cnt; i++)
+		tp[i] = insns[i];
+
+	flush_icache_range((uintptr_t)tp, (uintptr_t)tp + cnt * sizeof(u32));
+
+	return 0;
+}
+
+static int __kprobes aarch64_insn_patch_text_cb(void *arg)
+{
+	struct aarch64_insn_patch *pp = arg;
+
+	return __aarch64_insn_patch_text(pp->text_addr, pp->new_insns,
+					 pp->insn_cnt);
+}
+
+int __kprobes aarch64_insn_patch_text(void *addr, u32 *insns, int cnt)
+{
+	int ret;
+	bool safe = false;
+
+	/* instructions must be word aligned */
+	if (cnt <= 0 || ((uintptr_t)addr & 0x3))
+		return -EINVAL;
+
+	if (cnt == 1)
+		safe = aarch64_insn_hotpatch_safe(*(u32 *)addr, insns[0]);
+
+	if (safe) {
+		ret = __aarch64_insn_patch_text(addr, insns, cnt);
+	} else {
+		struct aarch64_insn_patch patch = {
+			.text_addr = addr,
+			.new_insns = insns,
+			.insn_cnt = cnt,
+		};
+
+		/*
+		 * Execute __aarch64_insn_patch_text() on every online CPU,
+		 * which ensure serialization among all online CPUs.
+		 */
+		ret = stop_machine(aarch64_insn_patch_text_cb, &patch, NULL);
+	}
+
+	return ret;
+}
-- 
1.8.1.2


  parent reply	other threads:[~2013-09-25 10:44 UTC|newest]

Thread overview: 44+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-09-25 10:44 [PATCH v1 0/7] Optimize jump label implementation on ARM64 Jiang Liu
2013-09-25 10:44 ` Jiang Liu
2013-09-25 10:44 ` [PATCH v1 1/7] arm64: introduce basic aarch64 instruction decoding helpers Jiang Liu
2013-09-25 10:44   ` Jiang Liu
2013-09-25 12:58   ` Christopher Covington
2013-09-25 12:58     ` Christopher Covington
2013-09-25 15:50     ` Jiang Liu
2013-09-25 15:50       ` Jiang Liu
2013-09-25 10:44 ` Jiang Liu [this message]
2013-09-25 10:44   ` [PATCH v1 2/7] arm64: introduce interfaces to hotpatch kernel and module code Jiang Liu
2013-09-25 14:35   ` Steven Rostedt
2013-09-25 14:35     ` Steven Rostedt
2013-09-25 14:42     ` Sandeepa Prabhu
2013-09-25 14:42       ` Sandeepa Prabhu
2013-09-25 15:16       ` Steven Rostedt
2013-09-25 15:16         ` Steven Rostedt
2013-09-26  2:47         ` Sandeepa Prabhu
2013-09-26  2:47           ` Sandeepa Prabhu
2013-09-25 14:35   ` Sandeepa Prabhu
2013-09-25 14:35     ` Sandeepa Prabhu
2013-09-25 15:54     ` Jiang Liu
2013-09-25 15:54       ` Jiang Liu
2013-09-26  2:51       ` Sandeepa Prabhu
2013-09-26  2:51         ` Sandeepa Prabhu
2013-09-27 15:41     ` Jiang Liu
2013-09-27 15:41       ` Jiang Liu
2013-09-28  1:22       ` Sandeepa Prabhu
2013-09-28  1:22         ` Sandeepa Prabhu
2013-09-25 10:44 ` [PATCH v1 3/7] arm64: move encode_insn_immediate() from module.c to insn.c Jiang Liu
2013-09-25 10:44   ` Jiang Liu
2013-09-25 10:44 ` [PATCH v1 4/7] arm64: introduce aarch64_insn_gen_{nop|branch_imm}() helper functions Jiang Liu
2013-09-25 10:44   ` Jiang Liu
2013-09-25 10:44 ` [PATCH v1 5/7] arm64, jump label: detect %c support for ARM64 Jiang Liu
2013-09-25 10:44   ` Jiang Liu
2013-09-25 10:44 ` [PATCH v1 6/7] arm64, jump label: optimize jump label implementation Jiang Liu
2013-09-25 10:44   ` Jiang Liu
2013-09-25 10:44 ` [PATCH v1 7/7] jump_label: use defined macros instead of hard-coding for better readability Jiang Liu
2013-09-25 10:44   ` Jiang Liu
2013-09-25 14:53   ` Steven Rostedt
2013-09-25 14:53     ` Steven Rostedt
2013-09-25 15:47     ` Jiang Liu
2013-09-25 15:47       ` Jiang Liu
2013-09-25 16:30       ` Steven Rostedt
2013-09-25 16:30         ` Steven Rostedt

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1380105868-31985-3-git-send-email-liuj97@gmail.com \
    --to=liuj97@gmail.com \
    --cc=linux-arm-kernel@lists.infradead.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.