From: dave.long@linaro.org (David Long)
To: linux-arm-kernel@lists.infradead.org
Subject: [PATCH v15 03/10] arm64: add conditional instruction simulation support
Date: Fri, 8 Jul 2016 12:35:47 -0400 [thread overview]
Message-ID: <1467995754-32508-4-git-send-email-dave.long@linaro.org> (raw)
In-Reply-To: <1467995754-32508-1-git-send-email-dave.long@linaro.org>
From: "David A. Long" <dave.long@linaro.org>
Cease using the arm32 arm_check_condition() function and replace it with
a local version for use in deprecated instruction support on arm64. Also
make the function table used by this available for future use by kprobes
and/or uprobes.
This function is derived from code written by Sandeepa Prabhu.
Signed-off-by: Sandeepa Prabhu <sandeepa.s.prabhu@gmail.com>
Signed-off-by: David A. Long <dave.long@linaro.org>
Acked-by: Masami Hiramatsu <mhiramat@kernel.org>
---
arch/arm64/include/asm/insn.h | 3 ++
arch/arm64/kernel/Makefile | 3 +-
arch/arm64/kernel/armv8_deprecated.c | 19 ++++++-
arch/arm64/kernel/insn.c | 98 ++++++++++++++++++++++++++++++++++++
4 files changed, 119 insertions(+), 4 deletions(-)
diff --git a/arch/arm64/include/asm/insn.h b/arch/arm64/include/asm/insn.h
index 497f7a2..a44abbd 100644
--- a/arch/arm64/include/asm/insn.h
+++ b/arch/arm64/include/asm/insn.h
@@ -406,6 +406,9 @@ u32 aarch64_insn_extract_system_reg(u32 insn);
u32 aarch32_insn_extract_reg_num(u32 insn, int offset);
u32 aarch32_insn_mcr_extract_opc2(u32 insn);
u32 aarch32_insn_mcr_extract_crm(u32 insn);
+
+typedef bool (pstate_check_t)(unsigned long);
+extern pstate_check_t * const aarch32_opcode_cond_checks[16];
#endif /* __ASSEMBLY__ */
#endif /* __ASM_INSN_H */
diff --git a/arch/arm64/kernel/Makefile b/arch/arm64/kernel/Makefile
index 2173149..4653aca 100644
--- a/arch/arm64/kernel/Makefile
+++ b/arch/arm64/kernel/Makefile
@@ -26,8 +26,7 @@ $(obj)/%.stub.o: $(obj)/%.o FORCE
$(call if_changed,objcopy)
arm64-obj-$(CONFIG_COMPAT) += sys32.o kuser32.o signal32.o \
- sys_compat.o entry32.o \
- ../../arm/kernel/opcodes.o
+ sys_compat.o entry32.o
arm64-obj-$(CONFIG_FUNCTION_TRACER) += ftrace.o entry-ftrace.o
arm64-obj-$(CONFIG_MODULES) += arm64ksyms.o module.o
arm64-obj-$(CONFIG_ARM64_MODULE_PLTS) += module-plts.o
diff --git a/arch/arm64/kernel/armv8_deprecated.c b/arch/arm64/kernel/armv8_deprecated.c
index c37202c..2934894 100644
--- a/arch/arm64/kernel/armv8_deprecated.c
+++ b/arch/arm64/kernel/armv8_deprecated.c
@@ -366,6 +366,21 @@ static int emulate_swpX(unsigned int address, unsigned int *data,
return res;
}
+#define ARM_OPCODE_CONDITION_UNCOND 0xf
+
+static unsigned int __kprobes aarch32_check_condition(u32 opcode, u32 psr)
+{
+ u32 cc_bits = opcode >> 28;
+
+ if (cc_bits != ARM_OPCODE_CONDITION_UNCOND) {
+ if ((*aarch32_opcode_cond_checks[cc_bits])(psr))
+ return ARM_OPCODE_CONDTEST_PASS;
+ else
+ return ARM_OPCODE_CONDTEST_FAIL;
+ }
+ return ARM_OPCODE_CONDTEST_UNCOND;
+}
+
/*
* swp_handler logs the id of calling process, dissects the instruction, sanity
* checks the memory location, calls emulate_swpX for the actual operation and
@@ -380,7 +395,7 @@ static int swp_handler(struct pt_regs *regs, u32 instr)
type = instr & TYPE_SWPB;
- switch (arm_check_condition(instr, regs->pstate)) {
+ switch (aarch32_check_condition(instr, regs->pstate)) {
case ARM_OPCODE_CONDTEST_PASS:
break;
case ARM_OPCODE_CONDTEST_FAIL:
@@ -461,7 +476,7 @@ static int cp15barrier_handler(struct pt_regs *regs, u32 instr)
{
perf_sw_event(PERF_COUNT_SW_EMULATION_FAULTS, 1, regs, regs->pc);
- switch (arm_check_condition(instr, regs->pstate)) {
+ switch (aarch32_check_condition(instr, regs->pstate)) {
case ARM_OPCODE_CONDTEST_PASS:
break;
case ARM_OPCODE_CONDTEST_FAIL:
diff --git a/arch/arm64/kernel/insn.c b/arch/arm64/kernel/insn.c
index 28c6110f..5cb2f3d 100644
--- a/arch/arm64/kernel/insn.c
+++ b/arch/arm64/kernel/insn.c
@@ -1234,3 +1234,101 @@ u32 aarch32_insn_mcr_extract_crm(u32 insn)
{
return insn & CRM_MASK;
}
+
+static bool __kprobes __check_eq(unsigned long pstate)
+{
+ return (pstate & PSR_Z_BIT) != 0;
+}
+
+static bool __kprobes __check_ne(unsigned long pstate)
+{
+ return (pstate & PSR_Z_BIT) == 0;
+}
+
+static bool __kprobes __check_cs(unsigned long pstate)
+{
+ return (pstate & PSR_C_BIT) != 0;
+}
+
+static bool __kprobes __check_cc(unsigned long pstate)
+{
+ return (pstate & PSR_C_BIT) == 0;
+}
+
+static bool __kprobes __check_mi(unsigned long pstate)
+{
+ return (pstate & PSR_N_BIT) != 0;
+}
+
+static bool __kprobes __check_pl(unsigned long pstate)
+{
+ return (pstate & PSR_N_BIT) == 0;
+}
+
+static bool __kprobes __check_vs(unsigned long pstate)
+{
+ return (pstate & PSR_V_BIT) != 0;
+}
+
+static bool __kprobes __check_vc(unsigned long pstate)
+{
+ return (pstate & PSR_V_BIT) == 0;
+}
+
+static bool __kprobes __check_hi(unsigned long pstate)
+{
+ pstate &= ~(pstate >> 1); /* PSR_C_BIT &= ~PSR_Z_BIT */
+ return (pstate & PSR_C_BIT) != 0;
+}
+
+static bool __kprobes __check_ls(unsigned long pstate)
+{
+ pstate &= ~(pstate >> 1); /* PSR_C_BIT &= ~PSR_Z_BIT */
+ return (pstate & PSR_C_BIT) == 0;
+}
+
+static bool __kprobes __check_ge(unsigned long pstate)
+{
+ pstate ^= (pstate << 3); /* PSR_N_BIT ^= PSR_V_BIT */
+ return (pstate & PSR_N_BIT) == 0;
+}
+
+static bool __kprobes __check_lt(unsigned long pstate)
+{
+ pstate ^= (pstate << 3); /* PSR_N_BIT ^= PSR_V_BIT */
+ return (pstate & PSR_N_BIT) != 0;
+}
+
+static bool __kprobes __check_gt(unsigned long pstate)
+{
+ /*PSR_N_BIT ^= PSR_V_BIT */
+ unsigned long temp = pstate ^ (pstate << 3);
+
+ temp |= (pstate << 1); /*PSR_N_BIT |= PSR_Z_BIT */
+ return (temp & PSR_N_BIT) == 0;
+}
+
+static bool __kprobes __check_le(unsigned long pstate)
+{
+ /*PSR_N_BIT ^= PSR_V_BIT */
+ unsigned long temp = pstate ^ (pstate << 3);
+
+ temp |= (pstate << 1); /*PSR_N_BIT |= PSR_Z_BIT */
+ return (temp & PSR_N_BIT) != 0;
+}
+
+static bool __kprobes __check_al(unsigned long pstate)
+{
+ return true;
+}
+
+/*
+ * Note that the ARMv8 ARM calls condition code 0b1111 "nv", but states that
+ * it behaves identically to 0b1110 ("al").
+ */
+pstate_check_t * const aarch32_opcode_cond_checks[16] = {
+ __check_eq, __check_ne, __check_cs, __check_cc,
+ __check_mi, __check_pl, __check_vs, __check_vc,
+ __check_hi, __check_ls, __check_ge, __check_lt,
+ __check_gt, __check_le, __check_al, __check_al
+};
--
2.5.0
next prev parent reply other threads:[~2016-07-08 16:35 UTC|newest]
Thread overview: 71+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-07-08 16:35 [PATCH v15 00/10] arm64: Add kernel probes (kprobes) support David Long
2016-07-08 16:35 ` [PATCH v15 01/10] arm64: Add HAVE_REGS_AND_STACK_ACCESS_API feature David Long
2016-07-15 10:57 ` Catalin Marinas
2016-07-15 14:51 ` David Long
2016-07-15 15:13 ` Catalin Marinas
2016-07-15 17:51 ` David Long
2016-07-19 14:17 ` Catalin Marinas
2016-07-08 16:35 ` [PATCH v15 02/10] arm64: Add more test functions to insn.c David Long
2016-07-08 16:35 ` David Long [this message]
2016-07-08 16:35 ` [PATCH v15 04/10] arm64: Kprobes with single stepping support David Long
2016-07-20 9:36 ` Marc Zyngier
2016-07-20 11:16 ` Catalin Marinas
2016-07-20 19:08 ` David Long
2016-07-21 8:44 ` Marc Zyngier
2016-07-20 15:49 ` Catalin Marinas
2016-07-21 14:50 ` David Long
2016-07-20 16:09 ` Marc Zyngier
2016-07-20 16:28 ` Catalin Marinas
2016-07-20 16:31 ` Marc Zyngier
2016-07-20 16:46 ` Marc Zyngier
2016-07-20 17:04 ` Catalin Marinas
2016-07-21 16:33 ` David Long
2016-07-21 17:16 ` Catalin Marinas
2016-07-21 17:23 ` Marc Zyngier
2016-07-21 18:33 ` David Long
2016-07-22 10:16 ` Catalin Marinas
2016-07-22 15:51 ` David Long
2016-07-25 17:13 ` Catalin Marinas
2016-07-25 22:27 ` David Long
2016-07-27 11:50 ` Daniel Thompson
2016-07-27 22:13 ` David Long
2016-07-28 14:40 ` Catalin Marinas
2016-07-29 9:01 ` Daniel Thompson
2016-08-04 4:47 ` David Long
2016-08-08 11:13 ` Daniel Thompson
2016-08-08 14:29 ` David Long
2016-08-08 22:49 ` Masami Hiramatsu
2016-08-09 17:23 ` Catalin Marinas
2016-08-10 20:41 ` David Long
2016-08-08 22:19 ` Masami Hiramatsu
2016-07-26 9:50 ` Daniel Thompson
2016-07-26 16:55 ` Catalin Marinas
2016-07-27 10:01 ` Dave Martin
2016-07-26 17:54 ` Mark Rutland
2016-07-27 11:19 ` Daniel Thompson
2016-07-27 11:38 ` Dave Martin
2016-07-27 11:42 ` Daniel Thompson
2016-07-27 13:38 ` Mark Rutland
2016-07-08 16:35 ` [PATCH v15 05/10] arm64: Blacklist non-kprobe-able symbol David Long
2016-07-08 16:35 ` [PATCH v15 06/10] arm64: Treat all entry code as non-kprobe-able David Long
2016-07-15 16:47 ` Catalin Marinas
2016-07-19 0:53 ` David Long
2016-07-08 16:35 ` [PATCH v15 07/10] arm64: kprobes instruction simulation support David Long
2016-07-10 22:51 ` Paul Gortmaker
2016-07-08 16:35 ` [PATCH v15 08/10] arm64: Add trampoline code for kretprobes David Long
2016-07-19 13:46 ` Catalin Marinas
2016-07-20 18:28 ` David Long
2016-07-08 16:35 ` [PATCH v15 09/10] arm64: Add kernel return probes support (kretprobes) David Long
2016-07-08 16:35 ` [PATCH v15 10/10] kprobes: Add arm64 case in kprobe example module David Long
2016-07-14 16:22 ` [PATCH v15 00/10] arm64: Add kernel probes (kprobes) support Catalin Marinas
2016-07-14 17:09 ` William Cohen
2016-07-15 7:50 ` Catalin Marinas
2016-07-15 8:01 ` Marc Zyngier
2016-07-15 8:59 ` Alex Bennée
2016-07-15 9:04 ` Marc Zyngier
2016-07-15 9:53 ` Marc Zyngier
2016-07-14 17:56 ` David Long
2016-07-19 13:57 ` Catalin Marinas
2016-07-19 14:01 ` David Long
2016-07-19 18:27 ` Catalin Marinas
2016-07-19 19:38 ` David Long
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=1467995754-32508-4-git-send-email-dave.long@linaro.org \
--to=dave.long@linaro.org \
--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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).