All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/24] ARM: kprobes: Migrate ARM instruction decoding to data tables
@ 2011-07-13  9:05 Tixy
  2011-07-13  9:05 ` [PATCH 01/24] ARM: kprobes: Migrate ARM space_1111 to decoding tables Tixy
                   ` (23 more replies)
  0 siblings, 24 replies; 26+ messages in thread
From: Tixy @ 2011-07-13  9:05 UTC (permalink / raw)
  To: linux-arm-kernel

This patch series migrates kprobes' ARM instruction decoding to use the
table driven methods introduced by the Thumb-2 support changes. It also
requires rewriting the instruction emulation routines to make them
compatible with this.

This saves 2kB of space in the kernel binary and reduces the source code
by 500 lines.

 arch/arm/kernel/kprobes-arm.c    | 1914 ++++++++++++++------------------------
 arch/arm/kernel/kprobes-common.c |   15 +
 arch/arm/kernel/kprobes.h        |   28 +
 3 files changed, 744 insertions(+), 1213 deletions(-)

^ permalink raw reply	[flat|nested] 26+ messages in thread

* [PATCH 01/24] ARM: kprobes: Migrate ARM space_1111 to decoding tables
  2011-07-13  9:05 [PATCH 0/24] ARM: kprobes: Migrate ARM instruction decoding to data tables Tixy
@ 2011-07-13  9:05 ` Tixy
  2011-07-13  9:05 ` [PATCH 02/24] ARM: kprobes: Add alu_write_pc() Tixy
                   ` (22 subsequent siblings)
  23 siblings, 0 replies; 26+ messages in thread
From: Tixy @ 2011-07-13  9:05 UTC (permalink / raw)
  To: linux-arm-kernel

From: Jon Medhurst <tixy@yxit.co.uk>

Signed-off-by: Jon Medhurst <tixy@yxit.co.uk>
---
 arch/arm/kernel/kprobes-arm.c |   56 ++++++++++++++++++----------------------
 1 files changed, 25 insertions(+), 31 deletions(-)

diff --git a/arch/arm/kernel/kprobes-arm.c b/arch/arm/kernel/kprobes-arm.c
index c6f2c69..ea96214 100644
--- a/arch/arm/kernel/kprobes-arm.c
+++ b/arch/arm/kernel/kprobes-arm.c
@@ -896,41 +896,35 @@ prep_emulate_rdhi16rdlo12rs8rm0_wflags(kprobe_opcode_t insn,
  * number of tests needed.
  */
 
-static enum kprobe_insn __kprobes
-space_1111(kprobe_opcode_t insn, struct arch_specific_insn *asi)
-{
-	/* memory hint : 1111 0100 x001 xxxx xxxx xxxx xxxx xxxx : */
-	/* PLDI        : 1111 0100 x101 xxxx xxxx xxxx xxxx xxxx : */
-	/* PLDW        : 1111 0101 x001 xxxx xxxx xxxx xxxx xxxx : */
-	/* PLD         : 1111 0101 x101 xxxx xxxx xxxx xxxx xxxx : */
-	if ((insn & 0xfe300000) == 0xf4100000) {
-		asi->insn_handler = emulate_nop;
-		return INSN_GOOD_NO_SLOT;
-	}
+static const union decode_item arm_1111_table[] = {
+	/* Unconditional instructions					*/
 
-	/* BLX(1) : 1111 101x xxxx xxxx xxxx xxxx xxxx xxxx : */
-	if ((insn & 0xfe000000) == 0xfa000000) {
-		asi->insn_handler = simulate_blx1;
-		return INSN_GOOD_NO_SLOT;
-	}
+	/* memory hint		1111 0100 x001 xxxx xxxx xxxx xxxx xxxx */
+	/* PLDI (immediate)	1111 0100 x101 xxxx xxxx xxxx xxxx xxxx */
+	/* PLDW (immediate)	1111 0101 x001 xxxx xxxx xxxx xxxx xxxx */
+	/* PLD (immediate)	1111 0101 x101 xxxx xxxx xxxx xxxx xxxx */
+	DECODE_SIMULATE	(0xfe300000, 0xf4100000, kprobe_simulate_nop),
 
-	/* CPS   : 1111 0001 0000 xxx0 xxxx xxxx xx0x xxxx */
-	/* SETEND: 1111 0001 0000 0001 xxxx xxxx 0000 xxxx */
+	/* BLX (immediate)	1111 101x xxxx xxxx xxxx xxxx xxxx xxxx */
+	DECODE_SIMULATE	(0xfe000000, 0xfa000000, simulate_blx1),
 
-	/* SRS   : 1111 100x x1x0 xxxx xxxx xxxx xxxx xxxx */
-	/* RFE   : 1111 100x x0x1 xxxx xxxx xxxx xxxx xxxx */
+	/* CPS			1111 0001 0000 xxx0 xxxx xxxx xx0x xxxx */
+	/* SETEND		1111 0001 0000 0001 xxxx xxxx 0000 xxxx */
+	/* SRS			1111 100x x1x0 xxxx xxxx xxxx xxxx xxxx */
+	/* RFE			1111 100x x0x1 xxxx xxxx xxxx xxxx xxxx */
 
 	/* Coprocessor instructions... */
-	/* MCRR2 : 1111 1100 0100 xxxx xxxx xxxx xxxx xxxx : (Rd != Rn) */
-	/* MRRC2 : 1111 1100 0101 xxxx xxxx xxxx xxxx xxxx : (Rd != Rn) */
-	/* LDC2  : 1111 110x xxx1 xxxx xxxx xxxx xxxx xxxx */
-	/* STC2  : 1111 110x xxx0 xxxx xxxx xxxx xxxx xxxx */
-	/* CDP2  : 1111 1110 xxxx xxxx xxxx xxxx xxx0 xxxx */
-	/* MCR2  : 1111 1110 xxx0 xxxx xxxx xxxx xxx1 xxxx */
-	/* MRC2  : 1111 1110 xxx1 xxxx xxxx xxxx xxx1 xxxx */
-
-	return INSN_REJECTED;
-}
+	/* MCRR2		1111 1100 0100 xxxx xxxx xxxx xxxx xxxx */
+	/* MRRC2		1111 1100 0101 xxxx xxxx xxxx xxxx xxxx */
+	/* LDC2			1111 110x xxx1 xxxx xxxx xxxx xxxx xxxx */
+	/* STC2			1111 110x xxx0 xxxx xxxx xxxx xxxx xxxx */
+	/* CDP2			1111 1110 xxxx xxxx xxxx xxxx xxx0 xxxx */
+	/* MCR2			1111 1110 xxx0 xxxx xxxx xxxx xxx1 xxxx */
+	/* MRC2			1111 1110 xxx1 xxxx xxxx xxxx xxx1 xxxx */
+
+	/* Other unallocated instructions...				*/
+	DECODE_END
+};
 
 static enum kprobe_insn __kprobes
 space_cccc_000x(kprobe_opcode_t insn, struct arch_specific_insn *asi)
@@ -1477,7 +1471,7 @@ arm_kprobe_decode_insn(kprobe_opcode_t insn, struct arch_specific_insn *asi)
 
 	if ((insn & 0xf0000000) == 0xf0000000)
 
-		return space_1111(insn, asi);
+		return kprobe_decode_insn(insn, asi, arm_1111_table, false);
 
 	else if ((insn & 0x0e000000) == 0x00000000)
 
-- 
1.7.2.5

^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH 02/24] ARM: kprobes: Add alu_write_pc()
  2011-07-13  9:05 [PATCH 0/24] ARM: kprobes: Migrate ARM instruction decoding to data tables Tixy
  2011-07-13  9:05 ` [PATCH 01/24] ARM: kprobes: Migrate ARM space_1111 to decoding tables Tixy
@ 2011-07-13  9:05 ` Tixy
  2011-07-13  9:05 ` [PATCH 03/24] ARM: kprobes: Add BLX macro Tixy
                   ` (21 subsequent siblings)
  23 siblings, 0 replies; 26+ messages in thread
From: Tixy @ 2011-07-13  9:05 UTC (permalink / raw)
  To: linux-arm-kernel

From: Jon Medhurst <tixy@yxit.co.uk>

This writes a new value to PC which was obtained as the result of an ARM
ALU instruction. For ARMv7 and later this performs interworking.

On ARM kernels we shouldn't encounter any ALU instructions trying to
switch to Thumb mode so support for this isn't strictly necessary.
However, the approach taken in all other instruction decoding is for us
to avoid unpredictable modification of the PC for security reasons. This
is usually achieved by rejecting insertion of probes on problematic
instruction, but for ALU instructions we can't do this as it depends on
the contents of the CPU registers at the time the probe is hit. So, as
we require some form of run-time checking to trap undesirable PC
modification, we may as well simulate the instructions correctly, i.e.
in the way they would behave in the absence of a probe.

Signed-off-by: Jon Medhurst <tixy@yxit.co.uk>
---
 arch/arm/kernel/kprobes.h        |   28 ++++++++++++++++++++++++++++
 arch/arm/kernel/kprobes-common.c |   15 +++++++++++++++
 2 files changed, 43 insertions(+), 0 deletions(-)

diff --git a/arch/arm/kernel/kprobes.h b/arch/arm/kernel/kprobes.h
index c442852..a6aeda0 100644
--- a/arch/arm/kernel/kprobes.h
+++ b/arch/arm/kernel/kprobes.h
@@ -133,6 +133,34 @@ static inline void __kprobes load_write_pc(long pcv, struct pt_regs *regs)
 }
 
 
+#if __LINUX_ARM_ARCH__ >= 7
+
+#define alu_write_pc_interworks true
+#define test_alu_write_pc_interworking()
+
+#elif __LINUX_ARM_ARCH__ <= 5
+
+/* Kernels built for <= ARMv5 should never run on >= ARMv6 hardware, so... */
+#define alu_write_pc_interworks false
+#define test_alu_write_pc_interworking()
+
+#else /* __LINUX_ARM_ARCH__ == 6 */
+
+/* We could be an ARMv6 binary on ARMv7 hardware so we need a run-time check. */
+extern bool alu_write_pc_interworks;
+void __init test_alu_write_pc_interworking(void);
+
+#endif /* __LINUX_ARM_ARCH__ == 6 */
+
+static inline void __kprobes alu_write_pc(long pcv, struct pt_regs *regs)
+{
+	if (alu_write_pc_interworks)
+		bx_write_pc(pcv, regs);
+	else
+		regs->ARM_pc = pcv;
+}
+
+
 void __kprobes kprobe_simulate_nop(struct kprobe *p, struct pt_regs *regs);
 void __kprobes kprobe_emulate_none(struct kprobe *p, struct pt_regs *regs);
 
diff --git a/arch/arm/kernel/kprobes-common.c b/arch/arm/kernel/kprobes-common.c
index 32bb0f2..a5394fb4 100644
--- a/arch/arm/kernel/kprobes-common.c
+++ b/arch/arm/kernel/kprobes-common.c
@@ -59,10 +59,25 @@ void __init test_load_write_pc_interworking(void)
 #endif /* !test_load_write_pc_interworking */
 
 
+#ifndef test_alu_write_pc_interworking
+
+bool alu_write_pc_interworks;
+
+void __init test_alu_write_pc_interworking(void)
+{
+	int arch = cpu_architecture();
+	BUG_ON(arch == CPU_ARCH_UNKNOWN);
+	alu_write_pc_interworks = arch >= CPU_ARCH_ARMv7;
+}
+
+#endif /* !test_alu_write_pc_interworking */
+
+
 void __init arm_kprobe_decode_init(void)
 {
 	find_str_pc_offset();
 	test_load_write_pc_interworking();
+	test_alu_write_pc_interworking();
 }
 
 
-- 
1.7.2.5

^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH 03/24] ARM: kprobes: Add BLX macro
  2011-07-13  9:05 [PATCH 0/24] ARM: kprobes: Migrate ARM instruction decoding to data tables Tixy
  2011-07-13  9:05 ` [PATCH 01/24] ARM: kprobes: Migrate ARM space_1111 to decoding tables Tixy
  2011-07-13  9:05 ` [PATCH 02/24] ARM: kprobes: Add alu_write_pc() Tixy
@ 2011-07-13  9:05 ` Tixy
  2011-07-13  9:05 ` [PATCH 04/24] ARM: kprobes: Add emulate_rd12rn16rm0rs8_rwflags() Tixy
                   ` (20 subsequent siblings)
  23 siblings, 0 replies; 26+ messages in thread
From: Tixy @ 2011-07-13  9:05 UTC (permalink / raw)
  To: linux-arm-kernel

From: Jon Medhurst <tixy@yxit.co.uk>

This is for use by inline assembler which will be added to kprobes-arm.c
It saves memory when used on newer ARM architectures and also provides
correct interworking should ARM probes be required on Thumb kernels in
the future.

Signed-off-by: Jon Medhurst <tixy@yxit.co.uk>
---
 arch/arm/kernel/kprobes-arm.c |    7 +++++++
 1 files changed, 7 insertions(+), 0 deletions(-)

diff --git a/arch/arm/kernel/kprobes-arm.c b/arch/arm/kernel/kprobes-arm.c
index ea96214..80a9411 100644
--- a/arch/arm/kernel/kprobes-arm.c
+++ b/arch/arm/kernel/kprobes-arm.c
@@ -67,6 +67,13 @@
 
 #define branch_displacement(insn) sign_extend(((insn) & 0xffffff) << 2, 25)
 
+#if  __LINUX_ARM_ARCH__ >= 6
+#define BLX(reg)	"blx	"reg"		\n\t"
+#else
+#define BLX(reg)	"mov	lr, pc		\n\t"	\
+			"mov	pc, "reg"	\n\t"
+#endif
+
 #define is_r15(insn, bitpos) (((insn) & (0xf << bitpos)) == (0xf << bitpos))
 
 #define PSR_fs	(PSR_f|PSR_s)
-- 
1.7.2.5

^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH 04/24] ARM: kprobes: Add emulate_rd12rn16rm0rs8_rwflags()
  2011-07-13  9:05 [PATCH 0/24] ARM: kprobes: Migrate ARM instruction decoding to data tables Tixy
                   ` (2 preceding siblings ...)
  2011-07-13  9:05 ` [PATCH 03/24] ARM: kprobes: Add BLX macro Tixy
@ 2011-07-13  9:05 ` Tixy
  2011-07-13  9:05 ` [PATCH 05/24] ARM: kprobes: Migrate ARM data-processing (register) instructions to decoding tables Tixy
                   ` (19 subsequent siblings)
  23 siblings, 0 replies; 26+ messages in thread
From: Tixy @ 2011-07-13  9:05 UTC (permalink / raw)
  To: linux-arm-kernel

From: Jon Medhurst <tixy@yxit.co.uk>

This is the emulation function for the instruction format used by the
ARM data-processing instructions.

Signed-off-by: Jon Medhurst <tixy@yxit.co.uk>
---
 arch/arm/kernel/kprobes-arm.c |   35 +++++++++++++++++++++++++++++++++++
 1 files changed, 35 insertions(+), 0 deletions(-)

diff --git a/arch/arm/kernel/kprobes-arm.c b/arch/arm/kernel/kprobes-arm.c
index 80a9411..6e38bd4 100644
--- a/arch/arm/kernel/kprobes-arm.c
+++ b/arch/arm/kernel/kprobes-arm.c
@@ -893,6 +893,41 @@ prep_emulate_rdhi16rdlo12rs8rm0_wflags(kprobe_opcode_t insn,
 	return INSN_GOOD;
 }
 
+static void __kprobes
+emulate_rd12rn16rm0rs8_rwflags(struct kprobe *p, struct pt_regs *regs)
+{
+	kprobe_opcode_t insn = p->opcode;
+	unsigned long pc = (unsigned long)p->addr + 8;
+	int rd = (insn >> 12) & 0xf;
+	int rn = (insn >> 16) & 0xf;
+	int rm = insn & 0xf;
+	int rs = (insn >> 8) & 0xf;
+
+	register unsigned long rdv asm("r0") = regs->uregs[rd];
+	register unsigned long rnv asm("r2") = (rn == 15) ? pc
+							  : regs->uregs[rn];
+	register unsigned long rmv asm("r3") = (rm == 15) ? pc
+							  : regs->uregs[rm];
+	register unsigned long rsv asm("r1") = regs->uregs[rs];
+	unsigned long cpsr = regs->ARM_cpsr;
+
+	__asm__ __volatile__ (
+		"msr	cpsr_fs, %[cpsr]	\n\t"
+		BLX("%[fn]")
+		"mrs	%[cpsr], cpsr		\n\t"
+		: "=r" (rdv), [cpsr] "=r" (cpsr)
+		: "0" (rdv), "r" (rnv), "r" (rmv), "r" (rsv),
+		  "1" (cpsr), [fn] "r" (p->ainsn.insn_fn)
+		: "lr", "memory", "cc"
+	);
+
+	if (rd == 15)
+		alu_write_pc(rdv, regs);
+	else
+		regs->uregs[rd] = rdv;
+	regs->ARM_cpsr = (regs->ARM_cpsr & ~APSR_MASK) | (cpsr & APSR_MASK);
+}
+
 /*
  * For the instruction masking and comparisons in all the "space_*"
  * functions below, Do _not_ rearrange the order of tests unless
-- 
1.7.2.5

^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH 05/24] ARM: kprobes: Migrate ARM data-processing (register) instructions to decoding tables
  2011-07-13  9:05 [PATCH 0/24] ARM: kprobes: Migrate ARM instruction decoding to data tables Tixy
                   ` (3 preceding siblings ...)
  2011-07-13  9:05 ` [PATCH 04/24] ARM: kprobes: Add emulate_rd12rn16rm0rs8_rwflags() Tixy
@ 2011-07-13  9:05 ` Tixy
  2011-07-13  9:05 ` [PATCH 06/24] ARM: kprobes: Add emulate_ldrdstrd() Tixy
                   ` (18 subsequent siblings)
  23 siblings, 0 replies; 26+ messages in thread
From: Tixy @ 2011-07-13  9:05 UTC (permalink / raw)
  To: linux-arm-kernel

From: Jon Medhurst <tixy@yxit.co.uk>

Signed-off-by: Jon Medhurst <tixy@yxit.co.uk>
---
 arch/arm/kernel/kprobes-arm.c |  111 +++++++++++++++++++++++------------------
 1 files changed, 63 insertions(+), 48 deletions(-)

diff --git a/arch/arm/kernel/kprobes-arm.c b/arch/arm/kernel/kprobes-arm.c
index 6e38bd4..8e4b718 100644
--- a/arch/arm/kernel/kprobes-arm.c
+++ b/arch/arm/kernel/kprobes-arm.c
@@ -968,6 +968,68 @@ static const union decode_item arm_1111_table[] = {
 	DECODE_END
 };
 
+static const union decode_item arm_cccc_000x_table[] = {
+	/* Data-processing (register)					*/
+
+	/* <op>S PC, ...	cccc 000x xxx1 xxxx 1111 xxxx xxxx xxxx */
+	DECODE_REJECT	(0x0e10f000, 0x0010f000),
+
+	/* MOV IP, SP		1110 0001 1010 0000 1100 0000 0000 1101 */
+	DECODE_SIMULATE	(0xffffffff, 0xe1a0c00d, simulate_mov_ipsp),
+
+	/* TST (register)	cccc 0001 0001 xxxx xxxx xxxx xxx0 xxxx */
+	/* TEQ (register)	cccc 0001 0011 xxxx xxxx xxxx xxx0 xxxx */
+	/* CMP (register)	cccc 0001 0101 xxxx xxxx xxxx xxx0 xxxx */
+	/* CMN (register)	cccc 0001 0111 xxxx xxxx xxxx xxx0 xxxx */
+	DECODE_EMULATEX	(0x0f900010, 0x01100000, emulate_rd12rn16rm0rs8_rwflags,
+						 REGS(ANY, 0, 0, 0, ANY)),
+
+	/* MOV (register)	cccc 0001 101x xxxx xxxx xxxx xxx0 xxxx */
+	/* MVN (register)	cccc 0001 111x xxxx xxxx xxxx xxx0 xxxx */
+	DECODE_EMULATEX	(0x0fa00010, 0x01a00000, emulate_rd12rn16rm0rs8_rwflags,
+						 REGS(0, ANY, 0, 0, ANY)),
+
+	/* AND (register)	cccc 0000 000x xxxx xxxx xxxx xxx0 xxxx */
+	/* EOR (register)	cccc 0000 001x xxxx xxxx xxxx xxx0 xxxx */
+	/* SUB (register)	cccc 0000 010x xxxx xxxx xxxx xxx0 xxxx */
+	/* RSB (register)	cccc 0000 011x xxxx xxxx xxxx xxx0 xxxx */
+	/* ADD (register)	cccc 0000 100x xxxx xxxx xxxx xxx0 xxxx */
+	/* ADC (register)	cccc 0000 101x xxxx xxxx xxxx xxx0 xxxx */
+	/* SBC (register)	cccc 0000 110x xxxx xxxx xxxx xxx0 xxxx */
+	/* RSC (register)	cccc 0000 111x xxxx xxxx xxxx xxx0 xxxx */
+	/* ORR (register)	cccc 0001 100x xxxx xxxx xxxx xxx0 xxxx */
+	/* BIC (register)	cccc 0001 110x xxxx xxxx xxxx xxx0 xxxx */
+	DECODE_EMULATEX	(0x0e000010, 0x00000000, emulate_rd12rn16rm0rs8_rwflags,
+						 REGS(ANY, ANY, 0, 0, ANY)),
+
+	/* TST (reg-shift reg)	cccc 0001 0001 xxxx xxxx xxxx 0xx1 xxxx */
+	/* TEQ (reg-shift reg)	cccc 0001 0011 xxxx xxxx xxxx 0xx1 xxxx */
+	/* CMP (reg-shift reg)	cccc 0001 0101 xxxx xxxx xxxx 0xx1 xxxx */
+	/* CMN (reg-shift reg)	cccc 0001 0111 xxxx xxxx xxxx 0xx1 xxxx */
+	DECODE_EMULATEX	(0x0f900090, 0x01100010, emulate_rd12rn16rm0rs8_rwflags,
+						 REGS(ANY, 0, NOPC, 0, ANY)),
+
+	/* MOV (reg-shift reg)	cccc 0001 101x xxxx xxxx xxxx 0xx1 xxxx */
+	/* MVN (reg-shift reg)	cccc 0001 111x xxxx xxxx xxxx 0xx1 xxxx */
+	DECODE_EMULATEX	(0x0fa00090, 0x01a00010, emulate_rd12rn16rm0rs8_rwflags,
+						 REGS(0, ANY, NOPC, 0, ANY)),
+
+	/* AND (reg-shift reg)	cccc 0000 000x xxxx xxxx xxxx 0xx1 xxxx */
+	/* EOR (reg-shift reg)	cccc 0000 001x xxxx xxxx xxxx 0xx1 xxxx */
+	/* SUB (reg-shift reg)	cccc 0000 010x xxxx xxxx xxxx 0xx1 xxxx */
+	/* RSB (reg-shift reg)	cccc 0000 011x xxxx xxxx xxxx 0xx1 xxxx */
+	/* ADD (reg-shift reg)	cccc 0000 100x xxxx xxxx xxxx 0xx1 xxxx */
+	/* ADC (reg-shift reg)	cccc 0000 101x xxxx xxxx xxxx 0xx1 xxxx */
+	/* SBC (reg-shift reg)	cccc 0000 110x xxxx xxxx xxxx 0xx1 xxxx */
+	/* RSC (reg-shift reg)	cccc 0000 111x xxxx xxxx xxxx 0xx1 xxxx */
+	/* ORR (reg-shift reg)	cccc 0001 100x xxxx xxxx xxxx 0xx1 xxxx */
+	/* BIC (reg-shift reg)	cccc 0001 110x xxxx xxxx xxxx 0xx1 xxxx */
+	DECODE_EMULATEX	(0x0e000090, 0x00000010, emulate_rd12rn16rm0rs8_rwflags,
+						 REGS(ANY, ANY, NOPC, 0, ANY)),
+
+	DECODE_END
+};
+
 static enum kprobe_insn __kprobes
 space_cccc_000x(kprobe_opcode_t insn, struct arch_specific_insn *asi)
 {
@@ -1126,54 +1188,7 @@ space_cccc_000x(kprobe_opcode_t insn, struct arch_specific_insn *asi)
 		return prep_emulate_ldr_str(insn, asi);
 	}
 
-	/* cccc 000x xxxx xxxx xxxx xxxx xxxx xxxx xxxx */
-
-	/*
-	 * ALU op with S bit and Rd == 15 :
-	 *	cccc 000x xxx1 xxxx 1111 xxxx xxxx xxxx
-	 */
-	if ((insn & 0x0e10f000) == 0x0010f000)
-		return INSN_REJECTED;
-
-	/*
-	 * "mov ip, sp" is the most common kprobe'd instruction by far.
-	 * Check and optimize for it explicitly.
-	 */
-	if (insn == 0xe1a0c00d) {
-		asi->insn_handler = simulate_mov_ipsp;
-		return INSN_GOOD_NO_SLOT;
-	}
-
-	/*
-	 * Data processing: Immediate-shift / Register-shift
-	 * ALU op : cccc 000x xxxx xxxx xxxx xxxx xxxx xxxx
-	 * CPY    : cccc 0001 1010 xxxx xxxx 0000 0000 xxxx
-	 * MOV    : cccc 0001 101x xxxx xxxx xxxx xxxx xxxx
-	 * *S (bit 20) updates condition codes
-	 * ADC/SBC/RSC reads the C flag
-	 */
-	insn &= 0xfff00ff0;	/* Rn = r0, Rd = r0 */
-	insn |= 0x00000001;	/* Rm = r1 */
-	if (insn & 0x010) {
-		insn &= 0xfffff0ff;     /* register shift */
-		insn |= 0x00000200;     /* Rs = r2 */
-	}
-	asi->insn[0] = insn;
-
-	if ((insn & 0x0f900000) == 0x01100000) {
-		/*
-		 * TST : cccc 0001 0001 xxxx xxxx xxxx xxxx xxxx
-		 * TEQ : cccc 0001 0011 xxxx xxxx xxxx xxxx xxxx
-		 * CMP : cccc 0001 0101 xxxx xxxx xxxx xxxx xxxx
-		 * CMN : cccc 0001 0111 xxxx xxxx xxxx xxxx xxxx
-		 */
-		asi->insn_handler = emulate_alu_tests;
-	} else {
-		/* ALU ops which write to Rd */
-		asi->insn_handler = (insn & (1 << 20)) ?  /* S-bit */
-				emulate_alu_rwflags : emulate_alu_rflags;
-	}
-	return INSN_GOOD;
+	return kprobe_decode_insn(insn, asi, arm_cccc_000x_table, false);
 }
 
 static enum kprobe_insn __kprobes
-- 
1.7.2.5

^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH 06/24] ARM: kprobes: Add emulate_ldrdstrd()
  2011-07-13  9:05 [PATCH 0/24] ARM: kprobes: Migrate ARM instruction decoding to data tables Tixy
                   ` (4 preceding siblings ...)
  2011-07-13  9:05 ` [PATCH 05/24] ARM: kprobes: Migrate ARM data-processing (register) instructions to decoding tables Tixy
@ 2011-07-13  9:05 ` Tixy
  2011-07-13  9:05 ` [PATCH 07/24] ARM: kprobes: Migrate ARM LDRD and STRD to decoding tables Tixy
                   ` (17 subsequent siblings)
  23 siblings, 0 replies; 26+ messages in thread
From: Tixy @ 2011-07-13  9:05 UTC (permalink / raw)
  To: linux-arm-kernel

From: Jon Medhurst <tixy@yxit.co.uk>

This is an emulation function for the LDRD and STRD instructions.

Signed-off-by: Jon Medhurst <tixy@yxit.co.uk>
---
 arch/arm/kernel/kprobes-arm.c |   29 +++++++++++++++++++++++++++++
 1 files changed, 29 insertions(+), 0 deletions(-)

diff --git a/arch/arm/kernel/kprobes-arm.c b/arch/arm/kernel/kprobes-arm.c
index 8e4b718..2b43d05 100644
--- a/arch/arm/kernel/kprobes-arm.c
+++ b/arch/arm/kernel/kprobes-arm.c
@@ -894,6 +894,35 @@ prep_emulate_rdhi16rdlo12rs8rm0_wflags(kprobe_opcode_t insn,
 }
 
 static void __kprobes
+emulate_ldrdstrd(struct kprobe *p, struct pt_regs *regs)
+{
+	kprobe_opcode_t insn = p->opcode;
+	unsigned long pc = (unsigned long)p->addr + 8;
+	int rt = (insn >> 12) & 0xf;
+	int rn = (insn >> 16) & 0xf;
+	int rm = insn & 0xf;
+
+	register unsigned long rtv asm("r0") = regs->uregs[rt];
+	register unsigned long rt2v asm("r1") = regs->uregs[rt+1];
+	register unsigned long rnv asm("r2") = (rn == 15) ? pc
+							  : regs->uregs[rn];
+	register unsigned long rmv asm("r3") = regs->uregs[rm];
+
+	__asm__ __volatile__ (
+		BLX("%[fn]")
+		: "=r" (rtv), "=r" (rt2v), "=r" (rnv)
+		: "0" (rtv), "1" (rt2v), "2" (rnv), "r" (rmv),
+		  [fn] "r" (p->ainsn.insn_fn)
+		: "lr", "memory", "cc"
+	);
+
+	regs->uregs[rt] = rtv;
+	regs->uregs[rt+1] = rt2v;
+	if (is_writeback(insn))
+		regs->uregs[rn] = rnv;
+}
+
+static void __kprobes
 emulate_rd12rn16rm0rs8_rwflags(struct kprobe *p, struct pt_regs *regs)
 {
 	kprobe_opcode_t insn = p->opcode;
-- 
1.7.2.5

^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH 07/24] ARM: kprobes: Migrate ARM LDRD and STRD to decoding tables
  2011-07-13  9:05 [PATCH 0/24] ARM: kprobes: Migrate ARM instruction decoding to data tables Tixy
                   ` (5 preceding siblings ...)
  2011-07-13  9:05 ` [PATCH 06/24] ARM: kprobes: Add emulate_ldrdstrd() Tixy
@ 2011-07-13  9:05 ` Tixy
  2011-07-13  9:05 ` [PATCH 08/24] ARM: kprobes: Migrate ARM space_cccc_000x " Tixy
                   ` (16 subsequent siblings)
  23 siblings, 0 replies; 26+ messages in thread
From: Tixy @ 2011-07-13  9:05 UTC (permalink / raw)
  To: linux-arm-kernel

From: Jon Medhurst <tixy@yxit.co.uk>

Signed-off-by: Jon Medhurst <tixy@yxit.co.uk>
---
 arch/arm/kernel/kprobes-arm.c |   37 ++++++++++++++++++++-----------------
 1 files changed, 20 insertions(+), 17 deletions(-)

diff --git a/arch/arm/kernel/kprobes-arm.c b/arch/arm/kernel/kprobes-arm.c
index 2b43d05..e590ff6 100644
--- a/arch/arm/kernel/kprobes-arm.c
+++ b/arch/arm/kernel/kprobes-arm.c
@@ -997,6 +997,23 @@ static const union decode_item arm_1111_table[] = {
 	DECODE_END
 };
 
+static const union decode_item arm_cccc_000x_____1xx1_table[] = {
+	/* LDRD/STRD lr,pc,{...	cccc 000x x0x0 xxxx 111x xxxx 1101 xxxx */
+	DECODE_REJECT	(0x0e10e0d0, 0x0000e0d0),
+
+	/* LDRD (register)	cccc 000x x0x0 xxxx xxxx xxxx 1101 xxxx */
+	/* STRD (register)	cccc 000x x0x0 xxxx xxxx xxxx 1111 xxxx */
+	DECODE_EMULATEX	(0x0e5000d0, 0x000000d0, emulate_ldrdstrd,
+						 REGS(NOPCWB, NOPCX, 0, 0, NOPC)),
+
+	/* LDRD (immediate)	cccc 000x x1x0 xxxx xxxx xxxx 1101 xxxx */
+	/* STRD (immediate)	cccc 000x x1x0 xxxx xxxx xxxx 1111 xxxx */
+	DECODE_EMULATEX	(0x0e5000d0, 0x004000d0, emulate_ldrdstrd,
+						 REGS(NOPCWB, NOPCX, 0, 0, 0)),
+
+	DECODE_END
+};
+
 static const union decode_item arm_cccc_000x_table[] = {
 	/* Data-processing (register)					*/
 
@@ -1192,23 +1209,9 @@ space_cccc_000x(kprobe_opcode_t insn, struct arch_specific_insn *asi)
 			}
 
 		} else if ((insn & 0x0e1000d0) == 0x00000d0) {
-			/* STRD/LDRD */
-			if ((insn & 0x0000e000) == 0x0000e000)
-				return INSN_REJECTED;	/* Rd is LR or PC */
-			if (is_writeback(insn) && is_r15(insn, 16))
-				return INSN_REJECTED;	/* Writeback to PC */
-
-			insn &= 0xfff00fff;
-			insn |= 0x00002000;	/* Rn = r0, Rd = r2 */
-			if (!(insn & (1 << 22))) {
-				/* Register index */
-				insn &= ~0xf;
-				insn |= 1;	/* Rm = r1 */
-			}
-			asi->insn[0] = insn;
-			asi->insn_handler =
-				(insn & (1 << 5)) ? emulate_strd : emulate_ldrd;
-			return INSN_GOOD;
+
+			return kprobe_decode_insn(insn, asi, arm_cccc_000x_____1xx1_table,
+									false);
 		}
 
 		/* LDRH/STRH/LDRSB/LDRSH */
-- 
1.7.2.5

^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH 08/24] ARM: kprobes: Migrate ARM space_cccc_000x to decoding tables
  2011-07-13  9:05 [PATCH 0/24] ARM: kprobes: Migrate ARM instruction decoding to data tables Tixy
                   ` (6 preceding siblings ...)
  2011-07-13  9:05 ` [PATCH 07/24] ARM: kprobes: Migrate ARM LDRD and STRD to decoding tables Tixy
@ 2011-07-13  9:05 ` Tixy
  2011-07-13  9:05 ` [PATCH 09/24] ARM: kprobes: Migrate ARM space_cccc_001x " Tixy
                   ` (15 subsequent siblings)
  23 siblings, 0 replies; 26+ messages in thread
From: Tixy @ 2011-07-13  9:05 UTC (permalink / raw)
  To: linux-arm-kernel

From: Jon Medhurst <tixy@yxit.co.uk>

Signed-off-by: Jon Medhurst <tixy@yxit.co.uk>
---
 arch/arm/kernel/kprobes-arm.c |  254 +++++++++++++++++++----------------------
 1 files changed, 117 insertions(+), 137 deletions(-)

diff --git a/arch/arm/kernel/kprobes-arm.c b/arch/arm/kernel/kprobes-arm.c
index e590ff6..ef350a5 100644
--- a/arch/arm/kernel/kprobes-arm.c
+++ b/arch/arm/kernel/kprobes-arm.c
@@ -997,7 +997,99 @@ static const union decode_item arm_1111_table[] = {
 	DECODE_END
 };
 
+static const union decode_item arm_cccc_0001_0xx0____0xxx_table[] = {
+	/* Miscellaneous instructions					*/
+
+	/* MRS cpsr		cccc 0001 0000 xxxx xxxx xxxx 0000 xxxx */
+	DECODE_SIMULATEX(0x0ff000f0, 0x01000000, simulate_mrs,
+						 REGS(0, NOPC, 0, 0, 0)),
+
+	/* BX			cccc 0001 0010 xxxx xxxx xxxx 0001 xxxx */
+	DECODE_SIMULATE	(0x0ff000f0, 0x01200010, simulate_blx2bx),
+
+	/* BLX (register)	cccc 0001 0010 xxxx xxxx xxxx 0011 xxxx */
+	DECODE_SIMULATEX(0x0ff000f0, 0x01200030, simulate_blx2bx,
+						 REGS(0, 0, 0, 0, NOPC)),
+
+	/* CLZ			cccc 0001 0110 xxxx xxxx xxxx 0001 xxxx */
+	DECODE_CUSTOM	(0x0ff000f0, 0x01600010, prep_emulate_rd12rm0),
+
+	/* QADD			cccc 0001 0000 xxxx xxxx xxxx 0101 xxxx */
+	/* QSUB			cccc 0001 0010 xxxx xxxx xxxx 0101 xxxx */
+	/* QDADD		cccc 0001 0100 xxxx xxxx xxxx 0101 xxxx */
+	/* QDSUB		cccc 0001 0110 xxxx xxxx xxxx 0101 xxxx */
+	DECODE_CUSTOM	(0x0f9000f0, 0x01000050, prep_emulate_rd12rn16rm0_wflags),
+
+	/* BXJ			cccc 0001 0010 xxxx xxxx xxxx 0010 xxxx */
+	/* MSR			cccc 0001 0x10 xxxx xxxx xxxx 0000 xxxx */
+	/* MRS spsr		cccc 0001 0100 xxxx xxxx xxxx 0000 xxxx */
+	/* BKPT			1110 0001 0010 xxxx xxxx xxxx 0111 xxxx */
+	/* SMC			cccc 0001 0110 xxxx xxxx xxxx 0111 xxxx */
+	/* And unallocated instructions...				*/
+	DECODE_END
+};
+
+static const union decode_item arm_cccc_0001_0xx0____1xx0_table[] = {
+	/* Halfword multiply and multiply-accumulate			*/
+
+	/* SMLALxy		cccc 0001 0100 xxxx xxxx xxxx 1xx0 xxxx */
+	DECODE_CUSTOM	(0x0ff00090, 0x01400080, prep_emulate_rdhi16rdlo12rs8rm0_wflags),
+
+	/* SMULWy		cccc 0001 0010 xxxx xxxx xxxx 1x10 xxxx */
+	DECODE_OR	(0x0ff000b0, 0x012000a0),
+	/* SMULxy		cccc 0001 0110 xxxx xxxx xxxx 1xx0 xxxx */
+	DECODE_CUSTOM	(0x0ff00090, 0x01600080, prep_emulate_rd16rs8rm0_wflags),
+
+	/* SMLAxy		cccc 0001 0000 xxxx xxxx xxxx 1xx0 xxxx */
+	DECODE_OR	(0x0ff00090, 0x01000080),
+	/* SMLAWy		cccc 0001 0010 xxxx xxxx xxxx 1x00 xxxx */
+	DECODE_CUSTOM	(0x0ff000b0, 0x01200080, prep_emulate_rd16rn12rs8rm0_wflags),
+
+	DECODE_END
+};
+
+static const union decode_item arm_cccc_0000_____1001_table[] = {
+	/* Multiply and multiply-accumulate				*/
+
+	/* MUL			cccc 0000 0000 xxxx xxxx xxxx 1001 xxxx */
+	/* MULS			cccc 0000 0001 xxxx xxxx xxxx 1001 xxxx */
+	DECODE_CUSTOM	(0x0fe000f0, 0x00000090, prep_emulate_rd16rs8rm0_wflags),
+
+	/* MLA			cccc 0000 0010 xxxx xxxx xxxx 1001 xxxx */
+	/* MLAS			cccc 0000 0011 xxxx xxxx xxxx 1001 xxxx */
+	DECODE_OR	(0x0fe000f0, 0x00200090),
+	/* MLS			cccc 0000 0110 xxxx xxxx xxxx 1001 xxxx */
+	DECODE_CUSTOM	(0x0ff000f0, 0x00600090, prep_emulate_rd16rn12rs8rm0_wflags),
+
+	/* UMAAL		cccc 0000 0100 xxxx xxxx xxxx 1001 xxxx */
+	DECODE_OR	(0x0ff000f0, 0x00400090),
+	/* UMULL		cccc 0000 1000 xxxx xxxx xxxx 1001 xxxx */
+	/* UMULLS		cccc 0000 1001 xxxx xxxx xxxx 1001 xxxx */
+	/* UMLAL		cccc 0000 1010 xxxx xxxx xxxx 1001 xxxx */
+	/* UMLALS		cccc 0000 1011 xxxx xxxx xxxx 1001 xxxx */
+	/* SMULL		cccc 0000 1100 xxxx xxxx xxxx 1001 xxxx */
+	/* SMULLS		cccc 0000 1101 xxxx xxxx xxxx 1001 xxxx */
+	/* SMLAL		cccc 0000 1110 xxxx xxxx xxxx 1001 xxxx */
+	/* SMLALS		cccc 0000 1111 xxxx xxxx xxxx 1001 xxxx */
+	DECODE_CUSTOM	(0x0f8000f0, 0x00800090, prep_emulate_rdhi16rdlo12rs8rm0_wflags),
+
+	DECODE_END
+};
+
+static const union decode_item arm_cccc_0001_____1001_table[] = {
+	/* Synchronization primitives					*/
+
+	/* SMP/SWPB		cccc 0001 0x00 xxxx xxxx xxxx 1001 xxxx */
+	DECODE_CUSTOM	(0x0fb000f0, 0x01000090, prep_emulate_rd12rn16rm0_wflags),
+
+	/* LDREX/STREX{,D,B,H}	cccc 0001 1xxx xxxx xxxx xxxx 1001 xxxx */
+	/* And unallocated instructions...				*/
+	DECODE_END
+};
+
 static const union decode_item arm_cccc_000x_____1xx1_table[] = {
+	/* Extra load/store instructions				*/
+
 	/* LDRD/STRD lr,pc,{...	cccc 000x x0x0 xxxx 111x xxxx 1101 xxxx */
 	DECODE_REJECT	(0x0e10e0d0, 0x0000e0d0),
 
@@ -1011,6 +1103,20 @@ static const union decode_item arm_cccc_000x_____1xx1_table[] = {
 	DECODE_EMULATEX	(0x0e5000d0, 0x004000d0, emulate_ldrdstrd,
 						 REGS(NOPCWB, NOPCX, 0, 0, 0)),
 
+	/* Reject Rd is PC */
+	/* TODO: fold this into next entry when it is made a DECODE_EMULATE */
+	DECODE_REJECT	(0x0000f000, 0x0000f000),
+
+	/* STRH (register)	cccc 000x x0x0 xxxx xxxx xxxx 1011 xxxx */
+	/* LDRH (register)	cccc 000x x0x1 xxxx xxxx xxxx 1011 xxxx */
+	/* LDRSB (register)	cccc 000x x0x1 xxxx xxxx xxxx 1101 xxxx */
+	/* LDRSH (register)	cccc 000x x0x1 xxxx xxxx xxxx 1111 xxxx */
+	/* STRH (immediate)	cccc 000x x1x0 xxxx xxxx xxxx 1011 xxxx */
+	/* LDRH (immediate)	cccc 000x x1x1 xxxx xxxx xxxx 1011 xxxx */
+	/* LDRSB (immediate)	cccc 000x x1x1 xxxx xxxx xxxx 1101 xxxx */
+	/* LDRSH (immediate)	cccc 000x x1x1 xxxx xxxx xxxx 1111 xxxx */
+	DECODE_CUSTOM	(0x0e000090, 0x00000090, prep_emulate_ldr_str),
+
 	DECODE_END
 };
 
@@ -1079,146 +1185,20 @@ static const union decode_item arm_cccc_000x_table[] = {
 static enum kprobe_insn __kprobes
 space_cccc_000x(kprobe_opcode_t insn, struct arch_specific_insn *asi)
 {
-	/* cccc 0001 0xx0 xxxx xxxx xxxx xxxx xxx0 xxxx */
-	if ((insn & 0x0f900010) == 0x01000000) {
-
-		/* MRS cpsr : cccc 0001 0000 xxxx xxxx xxxx 0000 xxxx */
-		if ((insn & 0x0ff000f0) == 0x01000000) {
-			if (is_r15(insn, 12))
-				return INSN_REJECTED;	/* Rd is PC */
-			asi->insn_handler = simulate_mrs;
-			return INSN_GOOD_NO_SLOT;
-		}
-
-		/* SMLALxy : cccc 0001 0100 xxxx xxxx xxxx 1xx0 xxxx */
-		if ((insn & 0x0ff00090) == 0x01400080)
-			return prep_emulate_rdhi16rdlo12rs8rm0_wflags(insn,
-									asi);
-
-		/* SMULWy : cccc 0001 0010 xxxx xxxx xxxx 1x10 xxxx */
-		/* SMULxy : cccc 0001 0110 xxxx xxxx xxxx 1xx0 xxxx */
-		if ((insn & 0x0ff000b0) == 0x012000a0 ||
-		    (insn & 0x0ff00090) == 0x01600080)
-			return prep_emulate_rd16rs8rm0_wflags(insn, asi);
-
-		/* SMLAxy : cccc 0001 0000 xxxx xxxx xxxx 1xx0 xxxx : Q */
-		/* SMLAWy : cccc 0001 0010 xxxx xxxx xxxx 1x00 xxxx : Q */
-		if ((insn & 0x0ff00090) == 0x01000080 ||
-		    (insn & 0x0ff000b0) == 0x01200080)
-			return prep_emulate_rd16rn12rs8rm0_wflags(insn, asi);
-
-		/* BXJ      : cccc 0001 0010 xxxx xxxx xxxx 0010 xxxx */
-		/* MSR      : cccc 0001 0x10 xxxx xxxx xxxx 0000 xxxx */
-		/* MRS spsr : cccc 0001 0100 xxxx xxxx xxxx 0000 xxxx */
-
-		/* Other instruction encodings aren't yet defined */
-		return INSN_REJECTED;
-	}
-
-	/* cccc 0001 0xx0 xxxx xxxx xxxx xxxx 0xx1 xxxx */
-	else if ((insn & 0x0f900090) == 0x01000010) {
-
-		/* BLX(2) : cccc 0001 0010 xxxx xxxx xxxx 0011 xxxx */
-		/* BX     : cccc 0001 0010 xxxx xxxx xxxx 0001 xxxx */
-		if ((insn & 0x0ff000d0) == 0x01200010) {
-			if ((insn & 0x0ff000ff) == 0x0120003f)
-				return INSN_REJECTED; /* BLX pc */
-			asi->insn_handler = simulate_blx2bx;
-			return INSN_GOOD_NO_SLOT;
-		}
-
-		/* CLZ : cccc 0001 0110 xxxx xxxx xxxx 0001 xxxx */
-		if ((insn & 0x0ff000f0) == 0x01600010)
-			return prep_emulate_rd12rm0(insn, asi);
+	if ((insn & 0x0f900080) == 0x01000000)
+		return kprobe_decode_insn(insn, asi, arm_cccc_0001_0xx0____0xxx_table, false);
 
-		/* QADD    : cccc 0001 0000 xxxx xxxx xxxx 0101 xxxx :Q */
-		/* QSUB    : cccc 0001 0010 xxxx xxxx xxxx 0101 xxxx :Q */
-		/* QDADD   : cccc 0001 0100 xxxx xxxx xxxx 0101 xxxx :Q */
-		/* QDSUB   : cccc 0001 0110 xxxx xxxx xxxx 0101 xxxx :Q */
-		if ((insn & 0x0f9000f0) == 0x01000050)
-			return prep_emulate_rd12rn16rm0_wflags(insn, asi);
+	if ((insn & 0x0f900090) == 0x01000080)
+		return kprobe_decode_insn(insn, asi, arm_cccc_0001_0xx0____1xx0_table, false);
 
-		/* BKPT : 1110 0001 0010 xxxx xxxx xxxx 0111 xxxx */
-		/* SMC  : cccc 0001 0110 xxxx xxxx xxxx 0111 xxxx */
+	if ((insn & 0x0f0000f0) == 0x00000090)
+		return kprobe_decode_insn(insn, asi, arm_cccc_0000_____1001_table, false);
 
-		/* Other instruction encodings aren't yet defined */
-		return INSN_REJECTED;
-	}
+	if ((insn & 0x0f0000f0) == 0x01000090)
+		return kprobe_decode_insn(insn, asi, arm_cccc_0001_____1001_table, false);
 
-	/* cccc 0000 xxxx xxxx xxxx xxxx xxxx 1001 xxxx */
-	else if ((insn & 0x0f0000f0) == 0x00000090) {
-
-		/* MUL    : cccc 0000 0000 xxxx xxxx xxxx 1001 xxxx :   */
-		/* MULS   : cccc 0000 0001 xxxx xxxx xxxx 1001 xxxx :cc */
-		/* MLA    : cccc 0000 0010 xxxx xxxx xxxx 1001 xxxx :   */
-		/* MLAS   : cccc 0000 0011 xxxx xxxx xxxx 1001 xxxx :cc */
-		/* UMAAL  : cccc 0000 0100 xxxx xxxx xxxx 1001 xxxx :   */
-		/* undef  : cccc 0000 0101 xxxx xxxx xxxx 1001 xxxx :   */
-		/* MLS    : cccc 0000 0110 xxxx xxxx xxxx 1001 xxxx :   */
-		/* undef  : cccc 0000 0111 xxxx xxxx xxxx 1001 xxxx :   */
-		/* UMULL  : cccc 0000 1000 xxxx xxxx xxxx 1001 xxxx :   */
-		/* UMULLS : cccc 0000 1001 xxxx xxxx xxxx 1001 xxxx :cc */
-		/* UMLAL  : cccc 0000 1010 xxxx xxxx xxxx 1001 xxxx :   */
-		/* UMLALS : cccc 0000 1011 xxxx xxxx xxxx 1001 xxxx :cc */
-		/* SMULL  : cccc 0000 1100 xxxx xxxx xxxx 1001 xxxx :   */
-		/* SMULLS : cccc 0000 1101 xxxx xxxx xxxx 1001 xxxx :cc */
-		/* SMLAL  : cccc 0000 1110 xxxx xxxx xxxx 1001 xxxx :   */
-		/* SMLALS : cccc 0000 1111 xxxx xxxx xxxx 1001 xxxx :cc */
-		if ((insn & 0x00d00000) == 0x00500000)
-			return INSN_REJECTED;
-		else if ((insn & 0x00e00000) == 0x00000000)
-			return prep_emulate_rd16rs8rm0_wflags(insn, asi);
-		else if ((insn & 0x00a00000) == 0x00200000)
-			return prep_emulate_rd16rn12rs8rm0_wflags(insn, asi);
-		else
-			return prep_emulate_rdhi16rdlo12rs8rm0_wflags(insn,
-									asi);
-	}
-
-	/* cccc 000x xxxx xxxx xxxx xxxx xxxx 1xx1 xxxx */
-	else if ((insn & 0x0e000090) == 0x00000090) {
-
-		/* SWP   : cccc 0001 0000 xxxx xxxx xxxx 1001 xxxx */
-		/* SWPB  : cccc 0001 0100 xxxx xxxx xxxx 1001 xxxx */
-		/* ???   : cccc 0001 0x01 xxxx xxxx xxxx 1001 xxxx */
-		/* ???   : cccc 0001 0x10 xxxx xxxx xxxx 1001 xxxx */
-		/* ???   : cccc 0001 0x11 xxxx xxxx xxxx 1001 xxxx */
-		/* STREX : cccc 0001 1000 xxxx xxxx xxxx 1001 xxxx */
-		/* LDREX : cccc 0001 1001 xxxx xxxx xxxx 1001 xxxx */
-		/* STREXD: cccc 0001 1010 xxxx xxxx xxxx 1001 xxxx */
-		/* LDREXD: cccc 0001 1011 xxxx xxxx xxxx 1001 xxxx */
-		/* STREXB: cccc 0001 1100 xxxx xxxx xxxx 1001 xxxx */
-		/* LDREXB: cccc 0001 1101 xxxx xxxx xxxx 1001 xxxx */
-		/* STREXH: cccc 0001 1110 xxxx xxxx xxxx 1001 xxxx */
-		/* LDREXH: cccc 0001 1111 xxxx xxxx xxxx 1001 xxxx */
-
-		/* LDRD  : cccc 000x xxx0 xxxx xxxx xxxx 1101 xxxx */
-		/* STRD  : cccc 000x xxx0 xxxx xxxx xxxx 1111 xxxx */
-		/* LDRH  : cccc 000x xxx1 xxxx xxxx xxxx 1011 xxxx */
-		/* STRH  : cccc 000x xxx0 xxxx xxxx xxxx 1011 xxxx */
-		/* LDRSB : cccc 000x xxx1 xxxx xxxx xxxx 1101 xxxx */
-		/* LDRSH : cccc 000x xxx1 xxxx xxxx xxxx 1111 xxxx */
-		if ((insn & 0x0f0000f0) == 0x01000090) {
-			if ((insn & 0x0fb000f0) == 0x01000090) {
-				/* SWP/SWPB */
-				return prep_emulate_rd12rn16rm0_wflags(insn,
-									asi);
-			} else {
-				/* STREX/LDREX variants and unallocaed space */
-				return INSN_REJECTED;
-			}
-
-		} else if ((insn & 0x0e1000d0) == 0x00000d0) {
-
-			return kprobe_decode_insn(insn, asi, arm_cccc_000x_____1xx1_table,
-									false);
-		}
-
-		/* LDRH/STRH/LDRSB/LDRSH */
-		if (is_r15(insn, 12))
-			return INSN_REJECTED;	/* Rd is PC */
-		return prep_emulate_ldr_str(insn, asi);
-	}
+	if ((insn & 0x0e000090) == 0x00000090)
+		return kprobe_decode_insn(insn, asi, arm_cccc_000x_____1xx1_table, false);
 
 	return kprobe_decode_insn(insn, asi, arm_cccc_000x_table, false);
 }
-- 
1.7.2.5

^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH 09/24] ARM: kprobes: Migrate ARM space_cccc_001x to decoding tables
  2011-07-13  9:05 [PATCH 0/24] ARM: kprobes: Migrate ARM instruction decoding to data tables Tixy
                   ` (7 preceding siblings ...)
  2011-07-13  9:05 ` [PATCH 08/24] ARM: kprobes: Migrate ARM space_cccc_000x " Tixy
@ 2011-07-13  9:05 ` Tixy
  2011-07-13  9:05 ` [PATCH 10/24] ARM: kprobes: Add emulate_rd12rn16rm0_rwflags_nopc() Tixy
                   ` (14 subsequent siblings)
  23 siblings, 0 replies; 26+ messages in thread
From: Tixy @ 2011-07-13  9:05 UTC (permalink / raw)
  To: linux-arm-kernel

From: Jon Medhurst <tixy@yxit.co.uk>

Signed-off-by: Jon Medhurst <tixy@yxit.co.uk>
---
 arch/arm/kernel/kprobes-arm.c |  116 ++++++++++++++++++-----------------------
 1 files changed, 50 insertions(+), 66 deletions(-)

diff --git a/arch/arm/kernel/kprobes-arm.c b/arch/arm/kernel/kprobes-arm.c
index ef350a5..f2eed03 100644
--- a/arch/arm/kernel/kprobes-arm.c
+++ b/arch/arm/kernel/kprobes-arm.c
@@ -1203,72 +1203,56 @@ space_cccc_000x(kprobe_opcode_t insn, struct arch_specific_insn *asi)
 	return kprobe_decode_insn(insn, asi, arm_cccc_000x_table, false);
 }
 
-static enum kprobe_insn __kprobes
-space_cccc_001x(kprobe_opcode_t insn, struct arch_specific_insn *asi)
-{
-	/* MOVW  : cccc 0011 0000 xxxx xxxx xxxx xxxx xxxx */
-	/* MOVT  : cccc 0011 0100 xxxx xxxx xxxx xxxx xxxx */
-	if ((insn & 0x0fb00000) == 0x03000000)
-		return prep_emulate_rd12_modify(insn, asi);
-
-	/* hints : cccc 0011 0010 0000 xxxx xxxx xxxx xxxx */
-	if ((insn & 0x0fff0000) == 0x03200000) {
-		unsigned op2 = insn & 0x000000ff;
-		if (op2 == 0x01 || op2 == 0x04) {
-			/* YIELD : cccc 0011 0010 0000 xxxx xxxx 0000 0001 */
-			/* SEV   : cccc 0011 0010 0000 xxxx xxxx 0000 0100 */
-			asi->insn[0] = insn;
-			asi->insn_handler = emulate_none;
-			return INSN_GOOD;
-		} else if (op2 <= 0x03) {
-			/* NOP   : cccc 0011 0010 0000 xxxx xxxx 0000 0000 */
-			/* WFE   : cccc 0011 0010 0000 xxxx xxxx 0000 0010 */
-			/* WFI   : cccc 0011 0010 0000 xxxx xxxx 0000 0011 */
-			/*
-			 * We make WFE and WFI true NOPs to avoid stalls due
-			 * to missing events whilst processing the probe.
-			 */
-			asi->insn_handler = emulate_nop;
-			return INSN_GOOD_NO_SLOT;
-		}
-		/* For DBG and unallocated hints it's safest to reject them */
-		return INSN_REJECTED;
-	}
+static const union decode_item arm_cccc_001x_table[] = {
+	/* Data-processing (immediate)					*/
+
+	/* MOVW			cccc 0011 0000 xxxx xxxx xxxx xxxx xxxx */
+	/* MOVT			cccc 0011 0100 xxxx xxxx xxxx xxxx xxxx */
+	DECODE_CUSTOM	(0x0fb00000, 0x03000000, prep_emulate_rd12_modify),
+
+	/* YIELD		cccc 0011 0010 0000 xxxx xxxx 0000 0001 */
+	DECODE_OR	(0x0fff00ff, 0x03200001),
+	/* SEV			cccc 0011 0010 0000 xxxx xxxx 0000 0100 */
+	DECODE_EMULATE	(0x0fff00ff, 0x03200004, kprobe_emulate_none),
+	/* NOP			cccc 0011 0010 0000 xxxx xxxx 0000 0000 */
+	/* WFE			cccc 0011 0010 0000 xxxx xxxx 0000 0010 */
+	/* WFI			cccc 0011 0010 0000 xxxx xxxx 0000 0011 */
+	DECODE_SIMULATE	(0x0fff00fc, 0x03200000, kprobe_simulate_nop),
+	/* DBG			cccc 0011 0010 0000 xxxx xxxx ffff xxxx */
+	/* unallocated hints	cccc 0011 0010 0000 xxxx xxxx xxxx xxxx */
+	/* MSR (immediate)	cccc 0011 0x10 xxxx xxxx xxxx xxxx xxxx */
+	DECODE_REJECT	(0x0fb00000, 0x03200000),
+
+	/* <op>S PC, ...	cccc 001x xxx1 xxxx 1111 xxxx xxxx xxxx */
+	DECODE_REJECT	(0x0e10f000, 0x0210f000),
+
+	/* TST (immediate)	cccc 0011 0001 xxxx xxxx xxxx xxxx xxxx */
+	/* TEQ (immediate)	cccc 0011 0011 xxxx xxxx xxxx xxxx xxxx */
+	/* CMP (immediate)	cccc 0011 0101 xxxx xxxx xxxx xxxx xxxx */
+	/* CMN (immediate)	cccc 0011 0111 xxxx xxxx xxxx xxxx xxxx */
+	DECODE_EMULATEX	(0x0f900000, 0x03100000, emulate_rd12rn16rm0rs8_rwflags,
+						 REGS(ANY, 0, 0, 0, 0)),
+
+	/* MOV (immediate)	cccc 0011 101x xxxx xxxx xxxx xxxx xxxx */
+	/* MVN (immediate)	cccc 0011 111x xxxx xxxx xxxx xxxx xxxx */
+	DECODE_EMULATEX	(0x0fa00000, 0x03a00000, emulate_rd12rn16rm0rs8_rwflags,
+						 REGS(0, ANY, 0, 0, 0)),
+
+	/* AND (immediate)	cccc 0010 000x xxxx xxxx xxxx xxxx xxxx */
+	/* EOR (immediate)	cccc 0010 001x xxxx xxxx xxxx xxxx xxxx */
+	/* SUB (immediate)	cccc 0010 010x xxxx xxxx xxxx xxxx xxxx */
+	/* RSB (immediate)	cccc 0010 011x xxxx xxxx xxxx xxxx xxxx */
+	/* ADD (immediate)	cccc 0010 100x xxxx xxxx xxxx xxxx xxxx */
+	/* ADC (immediate)	cccc 0010 101x xxxx xxxx xxxx xxxx xxxx */
+	/* SBC (immediate)	cccc 0010 110x xxxx xxxx xxxx xxxx xxxx */
+	/* RSC (immediate)	cccc 0010 111x xxxx xxxx xxxx xxxx xxxx */
+	/* ORR (immediate)	cccc 0011 100x xxxx xxxx xxxx xxxx xxxx */
+	/* BIC (immediate)	cccc 0011 110x xxxx xxxx xxxx xxxx xxxx */
+	DECODE_EMULATEX	(0x0e000000, 0x02000000, emulate_rd12rn16rm0rs8_rwflags,
+						 REGS(ANY, ANY, 0, 0, 0)),
 
-	/*
-	 * MSR   : cccc 0011 0x10 xxxx xxxx xxxx xxxx xxxx
-	 * ALU op with S bit and Rd == 15 :
-	 *	   cccc 001x xxx1 xxxx 1111 xxxx xxxx xxxx
-	 */
-	if ((insn & 0x0fb00000) == 0x03200000 ||	/* MSR */
-	    (insn & 0x0e10f000) == 0x0210f000)		/* ALU s-bit, R15  */
-		return INSN_REJECTED;
-
-	/*
-	 * Data processing: 32-bit Immediate
-	 * ALU op : cccc 001x xxxx xxxx xxxx xxxx xxxx xxxx
-	 * MOV    : cccc 0011 101x xxxx xxxx xxxx xxxx xxxx
-	 * *S (bit 20) updates condition codes
-	 * ADC/SBC/RSC reads the C flag
-	 */
-	insn &= 0xfff00fff;	/* Rn = r0 and Rd = r0 */
-	asi->insn[0] = insn;
-
-	if ((insn & 0x0f900000) == 0x03100000) {
-		/*
-		 * TST : cccc 0011 0001 xxxx xxxx xxxx xxxx xxxx
-		 * TEQ : cccc 0011 0011 xxxx xxxx xxxx xxxx xxxx
-		 * CMP : cccc 0011 0101 xxxx xxxx xxxx xxxx xxxx
-		 * CMN : cccc 0011 0111 xxxx xxxx xxxx xxxx xxxx
-		 */
-		asi->insn_handler = emulate_alu_tests_imm;
-	} else {
-		/* ALU ops which write to Rd */
-		asi->insn_handler = (insn & (1 << 20)) ?  /* S-bit */
-			emulate_alu_imm_rwflags : emulate_alu_imm_rflags;
-	}
-	return INSN_GOOD;
-}
+	DECODE_END
+};
 
 static enum kprobe_insn __kprobes
 space_cccc_0110__1(kprobe_opcode_t insn, struct arch_specific_insn *asi)
@@ -1548,7 +1532,7 @@ arm_kprobe_decode_insn(kprobe_opcode_t insn, struct arch_specific_insn *asi)
 
 	else if ((insn & 0x0e000000) == 0x02000000)
 
-		return space_cccc_001x(insn, asi);
+		return kprobe_decode_insn(insn, asi, arm_cccc_001x_table, false);
 
 	else if ((insn & 0x0f000010) == 0x06000010)
 
-- 
1.7.2.5

^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH 10/24] ARM: kprobes: Add emulate_rd12rn16rm0_rwflags_nopc()
  2011-07-13  9:05 [PATCH 0/24] ARM: kprobes: Migrate ARM instruction decoding to data tables Tixy
                   ` (8 preceding siblings ...)
  2011-07-13  9:05 ` [PATCH 09/24] ARM: kprobes: Migrate ARM space_cccc_001x " Tixy
@ 2011-07-13  9:05 ` Tixy
  2011-07-13  9:06 ` [PATCH 11/24] ARM: kprobes: Migrate ARM space_cccc_0110__1 to decoding tables Tixy
                   ` (13 subsequent siblings)
  23 siblings, 0 replies; 26+ messages in thread
From: Tixy @ 2011-07-13  9:05 UTC (permalink / raw)
  To: linux-arm-kernel

From: Jon Medhurst <tixy@yxit.co.uk>

This is the emulation function for the instruction format used by the
ARM media instructions.

Signed-off-by: Jon Medhurst <tixy@yxit.co.uk>
---
 arch/arm/kernel/kprobes-arm.c |   27 +++++++++++++++++++++++++++
 1 files changed, 27 insertions(+), 0 deletions(-)

diff --git a/arch/arm/kernel/kprobes-arm.c b/arch/arm/kernel/kprobes-arm.c
index f2eed03..eb11a56 100644
--- a/arch/arm/kernel/kprobes-arm.c
+++ b/arch/arm/kernel/kprobes-arm.c
@@ -957,6 +957,33 @@ emulate_rd12rn16rm0rs8_rwflags(struct kprobe *p, struct pt_regs *regs)
 	regs->ARM_cpsr = (regs->ARM_cpsr & ~APSR_MASK) | (cpsr & APSR_MASK);
 }
 
+static void __kprobes
+emulate_rd12rn16rm0_rwflags_nopc(struct kprobe *p, struct pt_regs *regs)
+{
+	kprobe_opcode_t insn = p->opcode;
+	int rd = (insn >> 12) & 0xf;
+	int rn = (insn >> 16) & 0xf;
+	int rm = insn & 0xf;
+
+	register unsigned long rdv asm("r0") = regs->uregs[rd];
+	register unsigned long rnv asm("r2") = regs->uregs[rn];
+	register unsigned long rmv asm("r3") = regs->uregs[rm];
+	unsigned long cpsr = regs->ARM_cpsr;
+
+	__asm__ __volatile__ (
+		"msr	cpsr_fs, %[cpsr]	\n\t"
+		BLX("%[fn]")
+		"mrs	%[cpsr], cpsr		\n\t"
+		: "=r" (rdv), [cpsr] "=r" (cpsr)
+		: "0" (rdv), "r" (rnv), "r" (rmv),
+		  "1" (cpsr), [fn] "r" (p->ainsn.insn_fn)
+		: "lr", "memory", "cc"
+	);
+
+	regs->uregs[rd] = rdv;
+	regs->ARM_cpsr = (regs->ARM_cpsr & ~APSR_MASK) | (cpsr & APSR_MASK);
+}
+
 /*
  * For the instruction masking and comparisons in all the "space_*"
  * functions below, Do _not_ rearrange the order of tests unless
-- 
1.7.2.5

^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH 11/24] ARM: kprobes: Migrate ARM space_cccc_0110__1 to decoding tables
  2011-07-13  9:05 [PATCH 0/24] ARM: kprobes: Migrate ARM instruction decoding to data tables Tixy
                   ` (9 preceding siblings ...)
  2011-07-13  9:05 ` [PATCH 10/24] ARM: kprobes: Add emulate_rd12rn16rm0_rwflags_nopc() Tixy
@ 2011-07-13  9:06 ` Tixy
  2011-07-13  9:06 ` [PATCH 12/24] ARM: kprobes: Migrate ARM space_cccc_0111__1 " Tixy
                   ` (12 subsequent siblings)
  23 siblings, 0 replies; 26+ messages in thread
From: Tixy @ 2011-07-13  9:06 UTC (permalink / raw)
  To: linux-arm-kernel

From: Jon Medhurst <tixy@yxit.co.uk>

Signed-off-by: Jon Medhurst <tixy@yxit.co.uk>
---
 arch/arm/kernel/kprobes-arm.c |  217 +++++++++++++++++------------------------
 1 files changed, 91 insertions(+), 126 deletions(-)

diff --git a/arch/arm/kernel/kprobes-arm.c b/arch/arm/kernel/kprobes-arm.c
index eb11a56..6203505 100644
--- a/arch/arm/kernel/kprobes-arm.c
+++ b/arch/arm/kernel/kprobes-arm.c
@@ -1281,132 +1281,97 @@ static const union decode_item arm_cccc_001x_table[] = {
 	DECODE_END
 };
 
-static enum kprobe_insn __kprobes
-space_cccc_0110__1(kprobe_opcode_t insn, struct arch_specific_insn *asi)
-{
-	/* SEL : cccc 0110 1000 xxxx xxxx xxxx 1011 xxxx GE: !!! */
-	if ((insn & 0x0ff000f0) == 0x068000b0) {
-		if (is_r15(insn, 12))
-			return INSN_REJECTED;	/* Rd is PC */
-		insn &= 0xfff00ff0;	/* Rd = r0, Rn = r0 */
-		insn |= 0x00000001;	/* Rm = r1 */
-		asi->insn[0] = insn;
-		asi->insn_handler = emulate_sel;
-		return INSN_GOOD;
-	}
-
-	/* SSAT   : cccc 0110 101x xxxx xxxx xxxx xx01 xxxx :Q */
-	/* USAT   : cccc 0110 111x xxxx xxxx xxxx xx01 xxxx :Q */
-	/* SSAT16 : cccc 0110 1010 xxxx xxxx xxxx 0011 xxxx :Q */
-	/* USAT16 : cccc 0110 1110 xxxx xxxx xxxx 0011 xxxx :Q */
-	if ((insn & 0x0fa00030) == 0x06a00010 ||
-	    (insn & 0x0fb000f0) == 0x06a00030) {
-		if (is_r15(insn, 12))
-			return INSN_REJECTED;	/* Rd is PC */
-		insn &= 0xffff0ff0;	/* Rd = r0, Rm = r0 */
-		asi->insn[0] = insn;
-		asi->insn_handler = emulate_sat;
-		return INSN_GOOD;
-	}
-
-	/* REV    : cccc 0110 1011 xxxx xxxx xxxx 0011 xxxx */
-	/* REV16  : cccc 0110 1011 xxxx xxxx xxxx 1011 xxxx */
-	/* RBIT   : cccc 0110 1111 xxxx xxxx xxxx 0011 xxxx */
-	/* REVSH  : cccc 0110 1111 xxxx xxxx xxxx 1011 xxxx */
-	if ((insn & 0x0ff00070) == 0x06b00030 ||
-	    (insn & 0x0ff00070) == 0x06f00030)
-		return prep_emulate_rd12rm0(insn, asi);
-
-	/* ???       : cccc 0110 0000 xxxx xxxx xxxx xxx1 xxxx :   */
-	/* SADD16    : cccc 0110 0001 xxxx xxxx xxxx 0001 xxxx :GE */
-	/* SADDSUBX  : cccc 0110 0001 xxxx xxxx xxxx 0011 xxxx :GE */
-	/* SSUBADDX  : cccc 0110 0001 xxxx xxxx xxxx 0101 xxxx :GE */
-	/* SSUB16    : cccc 0110 0001 xxxx xxxx xxxx 0111 xxxx :GE */
-	/* SADD8     : cccc 0110 0001 xxxx xxxx xxxx 1001 xxxx :GE */
-	/* ???       : cccc 0110 0001 xxxx xxxx xxxx 1011 xxxx :   */
-	/* ???       : cccc 0110 0001 xxxx xxxx xxxx 1101 xxxx :   */
-	/* SSUB8     : cccc 0110 0001 xxxx xxxx xxxx 1111 xxxx :GE */
-	/* QADD16    : cccc 0110 0010 xxxx xxxx xxxx 0001 xxxx :   */
-	/* QADDSUBX  : cccc 0110 0010 xxxx xxxx xxxx 0011 xxxx :   */
-	/* QSUBADDX  : cccc 0110 0010 xxxx xxxx xxxx 0101 xxxx :   */
-	/* QSUB16    : cccc 0110 0010 xxxx xxxx xxxx 0111 xxxx :   */
-	/* QADD8     : cccc 0110 0010 xxxx xxxx xxxx 1001 xxxx :   */
-	/* ???       : cccc 0110 0010 xxxx xxxx xxxx 1011 xxxx :   */
-	/* ???       : cccc 0110 0010 xxxx xxxx xxxx 1101 xxxx :   */
-	/* QSUB8     : cccc 0110 0010 xxxx xxxx xxxx 1111 xxxx :   */
-	/* SHADD16   : cccc 0110 0011 xxxx xxxx xxxx 0001 xxxx :   */
-	/* SHADDSUBX : cccc 0110 0011 xxxx xxxx xxxx 0011 xxxx :   */
-	/* SHSUBADDX : cccc 0110 0011 xxxx xxxx xxxx 0101 xxxx :   */
-	/* SHSUB16   : cccc 0110 0011 xxxx xxxx xxxx 0111 xxxx :   */
-	/* SHADD8    : cccc 0110 0011 xxxx xxxx xxxx 1001 xxxx :   */
-	/* ???       : cccc 0110 0011 xxxx xxxx xxxx 1011 xxxx :   */
-	/* ???       : cccc 0110 0011 xxxx xxxx xxxx 1101 xxxx :   */
-	/* SHSUB8    : cccc 0110 0011 xxxx xxxx xxxx 1111 xxxx :   */
-	/* ???       : cccc 0110 0100 xxxx xxxx xxxx xxx1 xxxx :   */
-	/* UADD16    : cccc 0110 0101 xxxx xxxx xxxx 0001 xxxx :GE */
-	/* UADDSUBX  : cccc 0110 0101 xxxx xxxx xxxx 0011 xxxx :GE */
-	/* USUBADDX  : cccc 0110 0101 xxxx xxxx xxxx 0101 xxxx :GE */
-	/* USUB16    : cccc 0110 0101 xxxx xxxx xxxx 0111 xxxx :GE */
-	/* UADD8     : cccc 0110 0101 xxxx xxxx xxxx 1001 xxxx :GE */
-	/* ???       : cccc 0110 0101 xxxx xxxx xxxx 1011 xxxx :   */
-	/* ???       : cccc 0110 0101 xxxx xxxx xxxx 1101 xxxx :   */
-	/* USUB8     : cccc 0110 0101 xxxx xxxx xxxx 1111 xxxx :GE */
-	/* UQADD16   : cccc 0110 0110 xxxx xxxx xxxx 0001 xxxx :   */
-	/* UQADDSUBX : cccc 0110 0110 xxxx xxxx xxxx 0011 xxxx :   */
-	/* UQSUBADDX : cccc 0110 0110 xxxx xxxx xxxx 0101 xxxx :   */
-	/* UQSUB16   : cccc 0110 0110 xxxx xxxx xxxx 0111 xxxx :   */
-	/* UQADD8    : cccc 0110 0110 xxxx xxxx xxxx 1001 xxxx :   */
-	/* ???       : cccc 0110 0110 xxxx xxxx xxxx 1011 xxxx :   */
-	/* ???       : cccc 0110 0110 xxxx xxxx xxxx 1101 xxxx :   */
-	/* UQSUB8    : cccc 0110 0110 xxxx xxxx xxxx 1111 xxxx :   */
-	/* UHADD16   : cccc 0110 0111 xxxx xxxx xxxx 0001 xxxx :   */
-	/* UHADDSUBX : cccc 0110 0111 xxxx xxxx xxxx 0011 xxxx :   */
-	/* UHSUBADDX : cccc 0110 0111 xxxx xxxx xxxx 0101 xxxx :   */
-	/* UHSUB16   : cccc 0110 0111 xxxx xxxx xxxx 0111 xxxx :   */
-	/* UHADD8    : cccc 0110 0111 xxxx xxxx xxxx 1001 xxxx :   */
-	/* ???       : cccc 0110 0111 xxxx xxxx xxxx 1011 xxxx :   */
-	/* ???       : cccc 0110 0111 xxxx xxxx xxxx 1101 xxxx :   */
-	/* UHSUB8    : cccc 0110 0111 xxxx xxxx xxxx 1111 xxxx :   */
-	if ((insn & 0x0f800010) == 0x06000010) {
-		if ((insn & 0x00300000) == 0x00000000 ||
-		    (insn & 0x000000e0) == 0x000000a0 ||
-		    (insn & 0x000000e0) == 0x000000c0)
-			return INSN_REJECTED;	/* Unallocated space */
-		return prep_emulate_rd12rn16rm0_wflags(insn, asi);
-	}
-
-	/* PKHBT     : cccc 0110 1000 xxxx xxxx xxxx x001 xxxx :   */
-	/* PKHTB     : cccc 0110 1000 xxxx xxxx xxxx x101 xxxx :   */
-	if ((insn & 0x0ff00030) == 0x06800010)
-		return prep_emulate_rd12rn16rm0_wflags(insn, asi);
-
-	/* SXTAB16   : cccc 0110 1000 xxxx xxxx xxxx 0111 xxxx :   */
-	/* SXTB16    : cccc 0110 1000 1111 xxxx xxxx 0111 xxxx :   */
-	/* ???       : cccc 0110 1001 xxxx xxxx xxxx 0111 xxxx :   */
-	/* SXTAB     : cccc 0110 1010 xxxx xxxx xxxx 0111 xxxx :   */
-	/* SXTB      : cccc 0110 1010 1111 xxxx xxxx 0111 xxxx :   */
-	/* SXTAH     : cccc 0110 1011 xxxx xxxx xxxx 0111 xxxx :   */
-	/* SXTH      : cccc 0110 1011 1111 xxxx xxxx 0111 xxxx :   */
-	/* UXTAB16   : cccc 0110 1100 xxxx xxxx xxxx 0111 xxxx :   */
-	/* UXTB16    : cccc 0110 1100 1111 xxxx xxxx 0111 xxxx :   */
-	/* ???       : cccc 0110 1101 xxxx xxxx xxxx 0111 xxxx :   */
-	/* UXTAB     : cccc 0110 1110 xxxx xxxx xxxx 0111 xxxx :   */
-	/* UXTB      : cccc 0110 1110 1111 xxxx xxxx 0111 xxxx :   */
-	/* UXTAH     : cccc 0110 1111 xxxx xxxx xxxx 0111 xxxx :   */
-	/* UXTH      : cccc 0110 1111 1111 xxxx xxxx 0111 xxxx :   */
-	if ((insn & 0x0f8000f0) == 0x06800070) {
-		if ((insn & 0x00300000) == 0x00100000)
-			return INSN_REJECTED;	/* Unallocated space */
-
-		if ((insn & 0x000f0000) == 0x000f0000)
-			return prep_emulate_rd12rm0(insn, asi);
-		else
-			return prep_emulate_rd12rn16rm0_wflags(insn, asi);
-	}
+static const union decode_item arm_cccc_0110_____xxx1_table[] = {
+	/* Media instructions						*/
+
+	/* SEL			cccc 0110 1000 xxxx xxxx xxxx 1011 xxxx */
+	DECODE_EMULATEX	(0x0ff000f0, 0x068000b0, emulate_rd12rn16rm0_rwflags_nopc,
+						 REGS(NOPC, NOPC, 0, 0, NOPC)),
+
+	/* SSAT			cccc 0110 101x xxxx xxxx xxxx xx01 xxxx */
+	/* USAT			cccc 0110 111x xxxx xxxx xxxx xx01 xxxx */
+	DECODE_OR(0x0fa00030, 0x06a00010),
+	/* SSAT16		cccc 0110 1010 xxxx xxxx xxxx 0011 xxxx */
+	/* USAT16		cccc 0110 1110 xxxx xxxx xxxx 0011 xxxx */
+	DECODE_EMULATEX	(0x0fb000f0, 0x06a00030, emulate_rd12rn16rm0_rwflags_nopc,
+						 REGS(0, NOPC, 0, 0, NOPC)),
+
+	/* REV			cccc 0110 1011 xxxx xxxx xxxx 0011 xxxx */
+	/* REV16		cccc 0110 1011 xxxx xxxx xxxx 1011 xxxx */
+	/* RBIT			cccc 0110 1111 xxxx xxxx xxxx 0011 xxxx */
+	/* REVSH		cccc 0110 1111 xxxx xxxx xxxx 1011 xxxx */
+	DECODE_CUSTOM	(0x0fb00070, 0x06b00030, prep_emulate_rd12rm0),
+
+	/* ???			cccc 0110 0x00 xxxx xxxx xxxx xxx1 xxxx */
+	DECODE_REJECT	(0x0fb00010, 0x06000010),
+	/* ???			cccc 0110 0xxx xxxx xxxx xxxx 1011 xxxx */
+	DECODE_REJECT	(0x0f8000f0, 0x060000b0),
+	/* ???			cccc 0110 0xxx xxxx xxxx xxxx 1101 xxxx */
+	DECODE_REJECT	(0x0f8000f0, 0x060000d0),
+	/* SADD16		cccc 0110 0001 xxxx xxxx xxxx 0001 xxxx */
+	/* SADDSUBX		cccc 0110 0001 xxxx xxxx xxxx 0011 xxxx */
+	/* SSUBADDX		cccc 0110 0001 xxxx xxxx xxxx 0101 xxxx */
+	/* SSUB16		cccc 0110 0001 xxxx xxxx xxxx 0111 xxxx */
+	/* SADD8		cccc 0110 0001 xxxx xxxx xxxx 1001 xxxx */
+	/* SSUB8		cccc 0110 0001 xxxx xxxx xxxx 1111 xxxx */
+	/* QADD16		cccc 0110 0010 xxxx xxxx xxxx 0001 xxxx */
+	/* QADDSUBX		cccc 0110 0010 xxxx xxxx xxxx 0011 xxxx */
+	/* QSUBADDX		cccc 0110 0010 xxxx xxxx xxxx 0101 xxxx */
+	/* QSUB16		cccc 0110 0010 xxxx xxxx xxxx 0111 xxxx */
+	/* QADD8		cccc 0110 0010 xxxx xxxx xxxx 1001 xxxx */
+	/* QSUB8		cccc 0110 0010 xxxx xxxx xxxx 1111 xxxx */
+	/* SHADD16		cccc 0110 0011 xxxx xxxx xxxx 0001 xxxx */
+	/* SHADDSUBX		cccc 0110 0011 xxxx xxxx xxxx 0011 xxxx */
+	/* SHSUBADDX		cccc 0110 0011 xxxx xxxx xxxx 0101 xxxx */
+	/* SHSUB16		cccc 0110 0011 xxxx xxxx xxxx 0111 xxxx */
+	/* SHADD8		cccc 0110 0011 xxxx xxxx xxxx 1001 xxxx */
+	/* SHSUB8		cccc 0110 0011 xxxx xxxx xxxx 1111 xxxx */
+	/* UADD16		cccc 0110 0101 xxxx xxxx xxxx 0001 xxxx */
+	/* UADDSUBX		cccc 0110 0101 xxxx xxxx xxxx 0011 xxxx */
+	/* USUBADDX		cccc 0110 0101 xxxx xxxx xxxx 0101 xxxx */
+	/* USUB16		cccc 0110 0101 xxxx xxxx xxxx 0111 xxxx */
+	/* UADD8		cccc 0110 0101 xxxx xxxx xxxx 1001 xxxx */
+	/* USUB8		cccc 0110 0101 xxxx xxxx xxxx 1111 xxxx */
+	/* UQADD16		cccc 0110 0110 xxxx xxxx xxxx 0001 xxxx */
+	/* UQADDSUBX		cccc 0110 0110 xxxx xxxx xxxx 0011 xxxx */
+	/* UQSUBADDX		cccc 0110 0110 xxxx xxxx xxxx 0101 xxxx */
+	/* UQSUB16		cccc 0110 0110 xxxx xxxx xxxx 0111 xxxx */
+	/* UQADD8		cccc 0110 0110 xxxx xxxx xxxx 1001 xxxx */
+	/* UQSUB8		cccc 0110 0110 xxxx xxxx xxxx 1111 xxxx */
+	/* UHADD16		cccc 0110 0111 xxxx xxxx xxxx 0001 xxxx */
+	/* UHADDSUBX		cccc 0110 0111 xxxx xxxx xxxx 0011 xxxx */
+	/* UHSUBADDX		cccc 0110 0111 xxxx xxxx xxxx 0101 xxxx */
+	/* UHSUB16		cccc 0110 0111 xxxx xxxx xxxx 0111 xxxx */
+	/* UHADD8		cccc 0110 0111 xxxx xxxx xxxx 1001 xxxx */
+	/* UHSUB8		cccc 0110 0111 xxxx xxxx xxxx 1111 xxxx */
+	DECODE_CUSTOM	(0x0f800010, 0x06000010, prep_emulate_rd12rn16rm0_wflags),
+
+	/* PKHBT		cccc 0110 1000 xxxx xxxx xxxx x001 xxxx */
+	/* PKHTB		cccc 0110 1000 xxxx xxxx xxxx x101 xxxx */
+	DECODE_CUSTOM	(0x0ff00030, 0x06800010, prep_emulate_rd12rn16rm0_wflags),
+
+	/* ???			cccc 0110 1001 xxxx xxxx xxxx 0111 xxxx */
+	/* ???			cccc 0110 1101 xxxx xxxx xxxx 0111 xxxx */
+	DECODE_REJECT	(0x0fb000f0, 0x06900070),
+
+	/* SXTB16		cccc 0110 1000 1111 xxxx xxxx 0111 xxxx */
+	/* SXTB			cccc 0110 1010 1111 xxxx xxxx 0111 xxxx */
+	/* SXTH			cccc 0110 1011 1111 xxxx xxxx 0111 xxxx */
+	/* UXTB16		cccc 0110 1100 1111 xxxx xxxx 0111 xxxx */
+	/* UXTB			cccc 0110 1110 1111 xxxx xxxx 0111 xxxx */
+	/* UXTH			cccc 0110 1111 1111 xxxx xxxx 0111 xxxx */
+	DECODE_CUSTOM	(0x0f8f00f0, 0x068f0070, prep_emulate_rd12rm0),
+
+	/* SXTAB16		cccc 0110 1000 xxxx xxxx xxxx 0111 xxxx */
+	/* SXTAB		cccc 0110 1010 xxxx xxxx xxxx 0111 xxxx */
+	/* SXTAH		cccc 0110 1011 xxxx xxxx xxxx 0111 xxxx */
+	/* UXTAB16		cccc 0110 1100 xxxx xxxx xxxx 0111 xxxx */
+	/* UXTAB		cccc 0110 1110 xxxx xxxx xxxx 0111 xxxx */
+	/* UXTAH		cccc 0110 1111 xxxx xxxx xxxx 0111 xxxx */
+	DECODE_CUSTOM	(0x0f8000f0, 0x06800070, prep_emulate_rd12rn16rm0_wflags),
 
-	/* Other instruction encodings aren't yet defined */
-	return INSN_REJECTED;
-}
+	DECODE_END
+};
 
 static enum kprobe_insn __kprobes
 space_cccc_0111__1(kprobe_opcode_t insn, struct arch_specific_insn *asi)
@@ -1563,7 +1528,7 @@ arm_kprobe_decode_insn(kprobe_opcode_t insn, struct arch_specific_insn *asi)
 
 	else if ((insn & 0x0f000010) == 0x06000010)
 
-		return space_cccc_0110__1(insn, asi);
+		return kprobe_decode_insn(insn, asi, arm_cccc_0110_____xxx1_table, false);
 
 	else if ((insn & 0x0f000010) == 0x07000010)
 
-- 
1.7.2.5

^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH 12/24] ARM: kprobes: Migrate ARM space_cccc_0111__1 to decoding tables
  2011-07-13  9:05 [PATCH 0/24] ARM: kprobes: Migrate ARM instruction decoding to data tables Tixy
                   ` (10 preceding siblings ...)
  2011-07-13  9:06 ` [PATCH 11/24] ARM: kprobes: Migrate ARM space_cccc_0110__1 to decoding tables Tixy
@ 2011-07-13  9:06 ` Tixy
  2011-07-13  9:06 ` [PATCH 13/24] ARM: kprobes: Migrate ARM space_cccc_01xx " Tixy
                   ` (11 subsequent siblings)
  23 siblings, 0 replies; 26+ messages in thread
From: Tixy @ 2011-07-13  9:06 UTC (permalink / raw)
  To: linux-arm-kernel

From: Jon Medhurst <tixy@yxit.co.uk>

Signed-off-by: Jon Medhurst <tixy@yxit.co.uk>
---
 arch/arm/kernel/kprobes-arm.c |   82 ++++++++++++++++++-----------------------
 1 files changed, 36 insertions(+), 46 deletions(-)

diff --git a/arch/arm/kernel/kprobes-arm.c b/arch/arm/kernel/kprobes-arm.c
index 6203505..58faacc 100644
--- a/arch/arm/kernel/kprobes-arm.c
+++ b/arch/arm/kernel/kprobes-arm.c
@@ -1373,57 +1373,47 @@ static const union decode_item arm_cccc_0110_____xxx1_table[] = {
 	DECODE_END
 };
 
-static enum kprobe_insn __kprobes
-space_cccc_0111__1(kprobe_opcode_t insn, struct arch_specific_insn *asi)
-{
-	/* Undef : cccc 0111 1111 xxxx xxxx xxxx 1111 xxxx */
-	if ((insn & 0x0ff000f0) == 0x03f000f0)
-		return INSN_REJECTED;
+static const union decode_item arm_cccc_0111_____xxx1_table[] = {
+	/* Media instructions						*/
 
-	/* SMLALD : cccc 0111 0100 xxxx xxxx xxxx 00x1 xxxx */
-	/* SMLSLD : cccc 0111 0100 xxxx xxxx xxxx 01x1 xxxx */
-	if ((insn & 0x0ff00090) == 0x07400010)
-		return prep_emulate_rdhi16rdlo12rs8rm0_wflags(insn, asi);
-
-	/* SMLAD  : cccc 0111 0000 xxxx xxxx xxxx 00x1 xxxx :Q */
-	/* SMUAD  : cccc 0111 0000 xxxx 1111 xxxx 00x1 xxxx :Q */
-	/* SMLSD  : cccc 0111 0000 xxxx xxxx xxxx 01x1 xxxx :Q */
-	/* SMUSD  : cccc 0111 0000 xxxx 1111 xxxx 01x1 xxxx :  */
-	/* SMMLA  : cccc 0111 0101 xxxx xxxx xxxx 00x1 xxxx :  */
-	/* SMMUL  : cccc 0111 0101 xxxx 1111 xxxx 00x1 xxxx :  */
-	/* USADA8 : cccc 0111 1000 xxxx xxxx xxxx 0001 xxxx :  */
-	/* USAD8  : cccc 0111 1000 xxxx 1111 xxxx 0001 xxxx :  */
-	if ((insn & 0x0ff00090) == 0x07000010 ||
-	    (insn & 0x0ff000d0) == 0x07500010 ||
-	    (insn & 0x0ff000f0) == 0x07800010) {
-
-		if ((insn & 0x0000f000) == 0x0000f000)
-			return prep_emulate_rd16rs8rm0_wflags(insn, asi);
-		else
-			return prep_emulate_rd16rn12rs8rm0_wflags(insn, asi);
-	}
+	/* UNDEFINED		cccc 0111 1111 xxxx xxxx xxxx 1111 xxxx */
+	DECODE_REJECT	(0x0ff000f0, 0x07f000f0),
 
-	/* SMMLS  : cccc 0111 0101 xxxx xxxx xxxx 11x1 xxxx :  */
-	if ((insn & 0x0ff000d0) == 0x075000d0)
-		return prep_emulate_rd16rn12rs8rm0_wflags(insn, asi);
+	/* SMLALD		cccc 0111 0100 xxxx xxxx xxxx 00x1 xxxx */
+	/* SMLSLD		cccc 0111 0100 xxxx xxxx xxxx 01x1 xxxx */
+	DECODE_CUSTOM	(0x0ff00090, 0x07400010, prep_emulate_rdhi16rdlo12rs8rm0_wflags),
 
-	/* SBFX   : cccc 0111 101x xxxx xxxx xxxx x101 xxxx :  */
-	/* UBFX   : cccc 0111 111x xxxx xxxx xxxx x101 xxxx :  */
-	if ((insn & 0x0fa00070) == 0x07a00050)
-		return prep_emulate_rd12rm0(insn, asi);
+	/* SMUAD		cccc 0111 0000 xxxx 1111 xxxx 00x1 xxxx */
+	/* SMUSD		cccc 0111 0000 xxxx 1111 xxxx 01x1 xxxx */
+	DECODE_OR	(0x0ff0f090, 0x0700f010),
+	/* SMMUL		cccc 0111 0101 xxxx 1111 xxxx 00x1 xxxx */
+	DECODE_OR	(0x0ff0f0d0, 0x0750f010),
+	/* USAD8		cccc 0111 1000 xxxx 1111 xxxx 0001 xxxx */
+	DECODE_CUSTOM	(0x0ff0f0f0, 0x0780f010, prep_emulate_rd16rs8rm0_wflags),
 
-	/* BFI    : cccc 0111 110x xxxx xxxx xxxx x001 xxxx :  */
-	/* BFC    : cccc 0111 110x xxxx xxxx xxxx x001 1111 :  */
-	if ((insn & 0x0fe00070) == 0x07c00010) {
+	/* SMLAD		cccc 0111 0000 xxxx xxxx xxxx 00x1 xxxx */
+	/* SMLSD		cccc 0111 0000 xxxx xxxx xxxx 01x1 xxxx */
+	DECODE_OR	(0x0ff00090, 0x07000010),
+	/* SMMLA		cccc 0111 0101 xxxx xxxx xxxx 00x1 xxxx */
+	DECODE_OR	(0x0ff000d0, 0x07500010),
+	/* USADA8		cccc 0111 1000 xxxx xxxx xxxx 0001 xxxx */
+	DECODE_CUSTOM	(0x0ff000f0, 0x07800010, prep_emulate_rd16rn12rs8rm0_wflags),
 
-		if ((insn & 0x0000000f) == 0x0000000f)
-			return prep_emulate_rd12_modify(insn, asi);
-		else
-			return prep_emulate_rd12rn0_modify(insn, asi);
-	}
+	/* SMMLS		cccc 0111 0101 xxxx xxxx xxxx 11x1 xxxx */
+	DECODE_CUSTOM	(0x0ff000d0, 0x075000d0, prep_emulate_rd16rn12rs8rm0_wflags),
 
-	return INSN_REJECTED;
-}
+	/* SBFX			cccc 0111 101x xxxx xxxx xxxx x101 xxxx */
+	/* UBFX			cccc 0111 111x xxxx xxxx xxxx x101 xxxx */
+	DECODE_CUSTOM	(0x0fa00070, 0x07a00050, prep_emulate_rd12rm0),
+
+	/* BFC			cccc 0111 110x xxxx xxxx xxxx x001 1111 */
+	DECODE_CUSTOM	(0x0fe0007f, 0x07c0001f, prep_emulate_rd12_modify),
+
+	/* BFI			cccc 0111 110x xxxx xxxx xxxx x001 xxxx */
+	DECODE_CUSTOM	(0x0fe00070, 0x07c00010, prep_emulate_rd12rn0_modify),
+
+	DECODE_END
+};
 
 static enum kprobe_insn __kprobes
 space_cccc_01xx(kprobe_opcode_t insn, struct arch_specific_insn *asi)
@@ -1532,7 +1522,7 @@ arm_kprobe_decode_insn(kprobe_opcode_t insn, struct arch_specific_insn *asi)
 
 	else if ((insn & 0x0f000010) == 0x07000010)
 
-		return space_cccc_0111__1(insn, asi);
+		return kprobe_decode_insn(insn, asi, arm_cccc_0111_____xxx1_table, false);
 
 	else if ((insn & 0x0c000000) == 0x04000000)
 
-- 
1.7.2.5

^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH 13/24] ARM: kprobes: Migrate ARM space_cccc_01xx to decoding tables
  2011-07-13  9:05 [PATCH 0/24] ARM: kprobes: Migrate ARM instruction decoding to data tables Tixy
                   ` (11 preceding siblings ...)
  2011-07-13  9:06 ` [PATCH 12/24] ARM: kprobes: Migrate ARM space_cccc_0111__1 " Tixy
@ 2011-07-13  9:06 ` Tixy
  2011-07-13  9:06 ` [PATCH 14/24] ARM: kprobes: Migrate ARM space_cccc_100x " Tixy
                   ` (10 subsequent siblings)
  23 siblings, 0 replies; 26+ messages in thread
From: Tixy @ 2011-07-13  9:06 UTC (permalink / raw)
  To: linux-arm-kernel

From: Jon Medhurst <tixy@yxit.co.uk>

Signed-off-by: Jon Medhurst <tixy@yxit.co.uk>
---
 arch/arm/kernel/kprobes-arm.c |   37 +++++++++++++++++++------------------
 1 files changed, 19 insertions(+), 18 deletions(-)

diff --git a/arch/arm/kernel/kprobes-arm.c b/arch/arm/kernel/kprobes-arm.c
index 58faacc..319e6fe 100644
--- a/arch/arm/kernel/kprobes-arm.c
+++ b/arch/arm/kernel/kprobes-arm.c
@@ -1415,23 +1415,24 @@ static const union decode_item arm_cccc_0111_____xxx1_table[] = {
 	DECODE_END
 };
 
-static enum kprobe_insn __kprobes
-space_cccc_01xx(kprobe_opcode_t insn, struct arch_specific_insn *asi)
-{
-	/* LDR   : cccc 01xx x0x1 xxxx xxxx xxxx xxxx xxxx */
-	/* LDRB  : cccc 01xx x1x1 xxxx xxxx xxxx xxxx xxxx */
-	/* LDRBT : cccc 01x0 x111 xxxx xxxx xxxx xxxx xxxx */
-	/* LDRT  : cccc 01x0 x011 xxxx xxxx xxxx xxxx xxxx */
-	/* STR   : cccc 01xx x0x0 xxxx xxxx xxxx xxxx xxxx */
-	/* STRB  : cccc 01xx x1x0 xxxx xxxx xxxx xxxx xxxx */
-	/* STRBT : cccc 01x0 x110 xxxx xxxx xxxx xxxx xxxx */
-	/* STRT  : cccc 01x0 x010 xxxx xxxx xxxx xxxx xxxx */
-
-	if ((insn & 0x00500000) == 0x00500000 && is_r15(insn, 12))
-		return INSN_REJECTED;	/* LDRB into PC */
-
-	return prep_emulate_ldr_str(insn, asi);
-}
+static const union decode_item arm_cccc_01xx_table[] = {
+	/* Load/store word and unsigned byte				*/
+
+	/* LDRB/STRB pc,[...]	cccc 01xx x0xx xxxx xxxx xxxx xxxx xxxx */
+	DECODE_REJECT	(0x0c40f000, 0x0440f000),
+
+	/* LDR			cccc 01xx x0x1 xxxx xxxx xxxx xxxx xxxx */
+	/* LDRB			cccc 01xx x1x1 xxxx xxxx xxxx xxxx xxxx */
+	/* LDRBT		cccc 01x0 x111 xxxx xxxx xxxx xxxx xxxx */
+	/* LDRT			cccc 01x0 x011 xxxx xxxx xxxx xxxx xxxx */
+	/* STR			cccc 01xx x0x0 xxxx xxxx xxxx xxxx xxxx */
+	/* STRB			cccc 01xx x1x0 xxxx xxxx xxxx xxxx xxxx */
+	/* STRBT		cccc 01x0 x110 xxxx xxxx xxxx xxxx xxxx */
+	/* STRT			cccc 01x0 x010 xxxx xxxx xxxx xxxx xxxx */
+	DECODE_CUSTOM	(0x0c000000, 0x04000000, prep_emulate_ldr_str),
+
+	DECODE_END
+};
 
 static enum kprobe_insn __kprobes
 space_cccc_100x(kprobe_opcode_t insn, struct arch_specific_insn *asi)
@@ -1526,7 +1527,7 @@ arm_kprobe_decode_insn(kprobe_opcode_t insn, struct arch_specific_insn *asi)
 
 	else if ((insn & 0x0c000000) == 0x04000000)
 
-		return space_cccc_01xx(insn, asi);
+		return kprobe_decode_insn(insn, asi, arm_cccc_01xx_table, false);
 
 	else if ((insn & 0x0e000000) == 0x08000000)
 
-- 
1.7.2.5

^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH 14/24] ARM: kprobes: Migrate ARM space_cccc_100x to decoding tables
  2011-07-13  9:05 [PATCH 0/24] ARM: kprobes: Migrate ARM instruction decoding to data tables Tixy
                   ` (12 preceding siblings ...)
  2011-07-13  9:06 ` [PATCH 13/24] ARM: kprobes: Migrate ARM space_cccc_01xx " Tixy
@ 2011-07-13  9:06 ` Tixy
  2011-07-13  9:06 ` [PATCH 15/24] ARM: kprobes: Migrate remaining instruction decoding functions to tables Tixy
                   ` (9 subsequent siblings)
  23 siblings, 0 replies; 26+ messages in thread
From: Tixy @ 2011-07-13  9:06 UTC (permalink / raw)
  To: linux-arm-kernel

From: Jon Medhurst <tixy@yxit.co.uk>

Signed-off-by: Jon Medhurst <tixy@yxit.co.uk>
---
 arch/arm/kernel/kprobes-arm.c |   33 +++++++++++++--------------------
 1 files changed, 13 insertions(+), 20 deletions(-)

diff --git a/arch/arm/kernel/kprobes-arm.c b/arch/arm/kernel/kprobes-arm.c
index 319e6fe..b2fd2c8 100644
--- a/arch/arm/kernel/kprobes-arm.c
+++ b/arch/arm/kernel/kprobes-arm.c
@@ -1434,25 +1434,18 @@ static const union decode_item arm_cccc_01xx_table[] = {
 	DECODE_END
 };
 
-static enum kprobe_insn __kprobes
-space_cccc_100x(kprobe_opcode_t insn, struct arch_specific_insn *asi)
-{
-	/* LDM(2) : cccc 100x x101 xxxx 0xxx xxxx xxxx xxxx */
-	/* LDM(3) : cccc 100x x1x1 xxxx 1xxx xxxx xxxx xxxx */
-	if ((insn & 0x0e708000) == 0x85000000 ||
-	    (insn & 0x0e508000) == 0x85010000)
-		return INSN_REJECTED;
-
-	/* LDM(1) : cccc 100x x0x1 xxxx xxxx xxxx xxxx xxxx */
-	/* STM(1) : cccc 100x x0x0 xxxx xxxx xxxx xxxx xxxx */
-
-	/*
-	 * Make the instruction unconditional because the new emulation
-	 * functions don't bother to setup the PSR context.
-	 */
-	insn = (insn | 0xe0000000) & ~0x10000000;
-	return kprobe_decode_ldmstm(insn, asi);
-}
+static const union decode_item arm_cccc_100x_table[] = {
+	/* Block data transfer instructions				*/
+
+	/* LDM			cccc 100x x0x1 xxxx xxxx xxxx xxxx xxxx */
+	/* STM			cccc 100x x0x0 xxxx xxxx xxxx xxxx xxxx */
+	DECODE_CUSTOM	(0x0e400000, 0x08000000, kprobe_decode_ldmstm),
+
+	/* STM (user registers)	cccc 100x x1x0 xxxx xxxx xxxx xxxx xxxx */
+	/* LDM (user registers)	cccc 100x x1x1 xxxx 0xxx xxxx xxxx xxxx */
+	/* LDM (exception ret)	cccc 100x x1x1 xxxx 1xxx xxxx xxxx xxxx */
+	DECODE_END
+};
 
 static enum kprobe_insn __kprobes
 space_cccc_101x(kprobe_opcode_t insn, struct arch_specific_insn *asi)
@@ -1531,7 +1524,7 @@ arm_kprobe_decode_insn(kprobe_opcode_t insn, struct arch_specific_insn *asi)
 
 	else if ((insn & 0x0e000000) == 0x08000000)
 
-		return space_cccc_100x(insn, asi);
+		return kprobe_decode_insn(insn, asi, arm_cccc_100x_table, false);
 
 	else if ((insn & 0x0e000000) == 0x0a000000)
 
-- 
1.7.2.5

^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH 15/24] ARM: kprobes: Migrate remaining instruction decoding functions to tables
  2011-07-13  9:05 [PATCH 0/24] ARM: kprobes: Migrate ARM instruction decoding to data tables Tixy
                   ` (13 preceding siblings ...)
  2011-07-13  9:06 ` [PATCH 14/24] ARM: kprobes: Migrate ARM space_cccc_100x " Tixy
@ 2011-07-13  9:06 ` Tixy
  2011-07-13  9:06 ` [PATCH 16/24] ARM: kprobes: Add emulate_rd16rn12rm0rs8_rwflags_nopc() Tixy
                   ` (8 subsequent siblings)
  23 siblings, 0 replies; 26+ messages in thread
From: Tixy @ 2011-07-13  9:06 UTC (permalink / raw)
  To: linux-arm-kernel

From: Jon Medhurst <tixy@yxit.co.uk>

Signed-off-by: Jon Medhurst <tixy@yxit.co.uk>
---
 arch/arm/kernel/kprobes-arm.c |  170 ++++++++++++++++++++++-------------------
 1 files changed, 90 insertions(+), 80 deletions(-)

diff --git a/arch/arm/kernel/kprobes-arm.c b/arch/arm/kernel/kprobes-arm.c
index b2fd2c8..f271212 100644
--- a/arch/arm/kernel/kprobes-arm.c
+++ b/arch/arm/kernel/kprobes-arm.c
@@ -1209,27 +1209,6 @@ static const union decode_item arm_cccc_000x_table[] = {
 	DECODE_END
 };
 
-static enum kprobe_insn __kprobes
-space_cccc_000x(kprobe_opcode_t insn, struct arch_specific_insn *asi)
-{
-	if ((insn & 0x0f900080) == 0x01000000)
-		return kprobe_decode_insn(insn, asi, arm_cccc_0001_0xx0____0xxx_table, false);
-
-	if ((insn & 0x0f900090) == 0x01000080)
-		return kprobe_decode_insn(insn, asi, arm_cccc_0001_0xx0____1xx0_table, false);
-
-	if ((insn & 0x0f0000f0) == 0x00000090)
-		return kprobe_decode_insn(insn, asi, arm_cccc_0000_____1001_table, false);
-
-	if ((insn & 0x0f0000f0) == 0x01000090)
-		return kprobe_decode_insn(insn, asi, arm_cccc_0001_____1001_table, false);
-
-	if ((insn & 0x0e000090) == 0x00000090)
-		return kprobe_decode_insn(insn, asi, arm_cccc_000x_____1xx1_table, false);
-
-	return kprobe_decode_insn(insn, asi, arm_cccc_000x_table, false);
-}
-
 static const union decode_item arm_cccc_001x_table[] = {
 	/* Data-processing (immediate)					*/
 
@@ -1447,31 +1426,96 @@ static const union decode_item arm_cccc_100x_table[] = {
 	DECODE_END
 };
 
-static enum kprobe_insn __kprobes
-space_cccc_101x(kprobe_opcode_t insn, struct arch_specific_insn *asi)
-{
-	/* B  : cccc 1010 xxxx xxxx xxxx xxxx xxxx xxxx */
-	/* BL : cccc 1011 xxxx xxxx xxxx xxxx xxxx xxxx */
-	asi->insn_handler = simulate_bbl;
-	return INSN_GOOD_NO_SLOT;
-}
+const union decode_item kprobe_decode_arm_table[] = {
+	/*
+	 * Unconditional instructions
+	 *			1111 xxxx xxxx xxxx xxxx xxxx xxxx xxxx
+	 */
+	DECODE_TABLE	(0xf0000000, 0xf0000000, arm_1111_table),
+
+	/*
+	 * Miscellaneous instructions
+	 *			cccc 0001 0xx0 xxxx xxxx xxxx 0xxx xxxx
+	 */
+	DECODE_TABLE	(0x0f900080, 0x01000000, arm_cccc_0001_0xx0____0xxx_table),
+
+	/*
+	 * Halfword multiply and multiply-accumulate
+	 *			cccc 0001 0xx0 xxxx xxxx xxxx 1xx0 xxxx
+	 */
+	DECODE_TABLE	(0x0f900090, 0x01000080, arm_cccc_0001_0xx0____1xx0_table),
+
+	/*
+	 * Multiply and multiply-accumulate
+	 *			cccc 0000 xxxx xxxx xxxx xxxx 1001 xxxx
+	 */
+	DECODE_TABLE	(0x0f0000f0, 0x00000090, arm_cccc_0000_____1001_table),
+
+	/*
+	 * Synchronization primitives
+	 *			cccc 0001 xxxx xxxx xxxx xxxx 1001 xxxx
+	 */
+	DECODE_TABLE	(0x0f0000f0, 0x01000090, arm_cccc_0001_____1001_table),
+
+	/*
+	 * Extra load/store instructions
+	 *			cccc 000x xxxx xxxx xxxx xxxx 1xx1 xxxx
+	 */
+	DECODE_TABLE	(0x0e000090, 0x00000090, arm_cccc_000x_____1xx1_table),
+
+	/*
+	 * Data-processing (register)
+	 *			cccc 000x xxxx xxxx xxxx xxxx xxx0 xxxx
+	 * Data-processing (register-shifted register)
+	 *			cccc 000x xxxx xxxx xxxx xxxx 0xx1 xxxx
+	 */
+	DECODE_TABLE	(0x0e000000, 0x00000000, arm_cccc_000x_table),
+
+	/*
+	 * Data-processing (immediate)
+	 *			cccc 001x xxxx xxxx xxxx xxxx xxxx xxxx
+	 */
+	DECODE_TABLE	(0x0e000000, 0x02000000, arm_cccc_001x_table),
+
+	/*
+	 * Media instructions
+	 *			cccc 011x xxxx xxxx xxxx xxxx xxx1 xxxx
+	 */
+	DECODE_TABLE	(0x0f000010, 0x06000010, arm_cccc_0110_____xxx1_table),
+	DECODE_TABLE	(0x0f000010, 0x07000010, arm_cccc_0111_____xxx1_table),
+
+	/*
+	 * Load/store word and unsigned byte
+	 *			cccc 01xx xxxx xxxx xxxx xxxx xxxx xxxx
+	 */
+	DECODE_TABLE	(0x0c000000, 0x04000000, arm_cccc_01xx_table),
+
+	/*
+	 * Block data transfer instructions
+	 *			cccc 100x xxxx xxxx xxxx xxxx xxxx xxxx
+	 */
+	DECODE_TABLE	(0x0e000000, 0x08000000, arm_cccc_100x_table),
+
+	/* B			cccc 1010 xxxx xxxx xxxx xxxx xxxx xxxx */
+	/* BL			cccc 1011 xxxx xxxx xxxx xxxx xxxx xxxx */
+	DECODE_SIMULATE	(0x0e000000, 0x0a000000, simulate_bbl),
+
+	/*
+	 * Supervisor Call, and coprocessor instructions
+	 */
+
+	/* MCRR			cccc 1100 0100 xxxx xxxx xxxx xxxx xxxx */
+	/* MRRC			cccc 1100 0101 xxxx xxxx xxxx xxxx xxxx */
+	/* LDC			cccc 110x xxx1 xxxx xxxx xxxx xxxx xxxx */
+	/* STC			cccc 110x xxx0 xxxx xxxx xxxx xxxx xxxx */
+	/* CDP			cccc 1110 xxxx xxxx xxxx xxxx xxx0 xxxx */
+	/* MCR			cccc 1110 xxx0 xxxx xxxx xxxx xxx1 xxxx */
+	/* MRC			cccc 1110 xxx1 xxxx xxxx xxxx xxx1 xxxx */
+	/* SVC			cccc 1111 xxxx xxxx xxxx xxxx xxxx xxxx */
+	DECODE_REJECT	(0x0c000000, 0x0c000000),
 
-static enum kprobe_insn __kprobes
-space_cccc_11xx(kprobe_opcode_t insn, struct arch_specific_insn *asi)
-{
-	/* Coprocessor instructions... */
-	/* MCRR : cccc 1100 0100 xxxx xxxx xxxx xxxx xxxx : (Rd!=Rn) */
-	/* MRRC : cccc 1100 0101 xxxx xxxx xxxx xxxx xxxx : (Rd!=Rn) */
-	/* LDC  : cccc 110x xxx1 xxxx xxxx xxxx xxxx xxxx */
-	/* STC  : cccc 110x xxx0 xxxx xxxx xxxx xxxx xxxx */
-	/* CDP  : cccc 1110 xxxx xxxx xxxx xxxx xxx0 xxxx */
-	/* MCR  : cccc 1110 xxx0 xxxx xxxx xxxx xxx1 xxxx */
-	/* MRC  : cccc 1110 xxx1 xxxx xxxx xxxx xxx1 xxxx */
-
-	/* SVC  : cccc 1111 xxxx xxxx xxxx xxxx xxxx xxxx */
-
-	return INSN_REJECTED;
-}
+	DECODE_END
+};
 
 static void __kprobes arm_singlestep(struct kprobe *p, struct pt_regs *regs)
 {
@@ -1496,39 +1540,5 @@ arm_kprobe_decode_insn(kprobe_opcode_t insn, struct arch_specific_insn *asi)
 {
 	asi->insn_singlestep = arm_singlestep;
 	asi->insn_check_cc = kprobe_condition_checks[insn>>28];
-	asi->insn[1] = KPROBE_RETURN_INSTRUCTION;
-
-	if ((insn & 0xf0000000) == 0xf0000000)
-
-		return kprobe_decode_insn(insn, asi, arm_1111_table, false);
-
-	else if ((insn & 0x0e000000) == 0x00000000)
-
-		return space_cccc_000x(insn, asi);
-
-	else if ((insn & 0x0e000000) == 0x02000000)
-
-		return kprobe_decode_insn(insn, asi, arm_cccc_001x_table, false);
-
-	else if ((insn & 0x0f000010) == 0x06000010)
-
-		return kprobe_decode_insn(insn, asi, arm_cccc_0110_____xxx1_table, false);
-
-	else if ((insn & 0x0f000010) == 0x07000010)
-
-		return kprobe_decode_insn(insn, asi, arm_cccc_0111_____xxx1_table, false);
-
-	else if ((insn & 0x0c000000) == 0x04000000)
-
-		return kprobe_decode_insn(insn, asi, arm_cccc_01xx_table, false);
-
-	else if ((insn & 0x0e000000) == 0x08000000)
-
-		return kprobe_decode_insn(insn, asi, arm_cccc_100x_table, false);
-
-	else if ((insn & 0x0e000000) == 0x0a000000)
-
-		return space_cccc_101x(insn, asi);
-
-	return space_cccc_11xx(insn, asi);
+	return kprobe_decode_insn(insn, asi, kprobe_decode_arm_table, false);
 }
-- 
1.7.2.5

^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH 16/24] ARM: kprobes: Add emulate_rd16rn12rm0rs8_rwflags_nopc()
  2011-07-13  9:05 [PATCH 0/24] ARM: kprobes: Migrate ARM instruction decoding to data tables Tixy
                   ` (14 preceding siblings ...)
  2011-07-13  9:06 ` [PATCH 15/24] ARM: kprobes: Migrate remaining instruction decoding functions to tables Tixy
@ 2011-07-13  9:06 ` Tixy
  2011-07-13  9:06 ` [PATCH 17/24] ARM: kprobes: Replace use of prep_emulate_rd12rn16rm0_wflags() Tixy
                   ` (7 subsequent siblings)
  23 siblings, 0 replies; 26+ messages in thread
From: Tixy @ 2011-07-13  9:06 UTC (permalink / raw)
  To: linux-arm-kernel

From: Jon Medhurst <tixy@yxit.co.uk>

This is the emulation function for the instruction format used by the
ARM multiply-accumulate instructions. These don't allow use of PC so we
don't have to add special cases for this.

This function is used to replace use of prep_emulate_rd16rs8rm0_wflags
and prep_emulate_rd16rn12rs8rm0_wflags.

Signed-off-by: Jon Medhurst <tixy@yxit.co.uk>
---
 arch/arm/kernel/kprobes-arm.c |   50 +++++++++++++++++++++++++++++++++++-----
 1 files changed, 43 insertions(+), 7 deletions(-)

diff --git a/arch/arm/kernel/kprobes-arm.c b/arch/arm/kernel/kprobes-arm.c
index f271212..d3b0506 100644
--- a/arch/arm/kernel/kprobes-arm.c
+++ b/arch/arm/kernel/kprobes-arm.c
@@ -984,6 +984,35 @@ emulate_rd12rn16rm0_rwflags_nopc(struct kprobe *p, struct pt_regs *regs)
 	regs->ARM_cpsr = (regs->ARM_cpsr & ~APSR_MASK) | (cpsr & APSR_MASK);
 }
 
+static void __kprobes
+emulate_rd16rn12rm0rs8_rwflags_nopc(struct kprobe *p, struct pt_regs *regs)
+{
+	kprobe_opcode_t insn = p->opcode;
+	int rd = (insn >> 16) & 0xf;
+	int rn = (insn >> 12) & 0xf;
+	int rm = insn & 0xf;
+	int rs = (insn >> 8) & 0xf;
+
+	register unsigned long rdv asm("r2") = regs->uregs[rd];
+	register unsigned long rnv asm("r0") = regs->uregs[rn];
+	register unsigned long rmv asm("r3") = regs->uregs[rm];
+	register unsigned long rsv asm("r1") = regs->uregs[rs];
+	unsigned long cpsr = regs->ARM_cpsr;
+
+	__asm__ __volatile__ (
+		"msr	cpsr_fs, %[cpsr]	\n\t"
+		BLX("%[fn]")
+		"mrs	%[cpsr], cpsr		\n\t"
+		: "=r" (rdv), [cpsr] "=r" (cpsr)
+		: "0" (rdv), "r" (rnv), "r" (rmv), "r" (rsv),
+		  "1" (cpsr), [fn] "r" (p->ainsn.insn_fn)
+		: "lr", "memory", "cc"
+	);
+
+	regs->uregs[rd] = rdv;
+	regs->ARM_cpsr = (regs->ARM_cpsr & ~APSR_MASK) | (cpsr & APSR_MASK);
+}
+
 /*
  * For the instruction masking and comparisons in all the "space_*"
  * functions below, Do _not_ rearrange the order of tests unless
@@ -1065,12 +1094,14 @@ static const union decode_item arm_cccc_0001_0xx0____1xx0_table[] = {
 	/* SMULWy		cccc 0001 0010 xxxx xxxx xxxx 1x10 xxxx */
 	DECODE_OR	(0x0ff000b0, 0x012000a0),
 	/* SMULxy		cccc 0001 0110 xxxx xxxx xxxx 1xx0 xxxx */
-	DECODE_CUSTOM	(0x0ff00090, 0x01600080, prep_emulate_rd16rs8rm0_wflags),
+	DECODE_EMULATEX	(0x0ff00090, 0x01600080, emulate_rd16rn12rm0rs8_rwflags_nopc,
+						 REGS(NOPC, 0, NOPC, 0, NOPC)),
 
 	/* SMLAxy		cccc 0001 0000 xxxx xxxx xxxx 1xx0 xxxx */
 	DECODE_OR	(0x0ff00090, 0x01000080),
 	/* SMLAWy		cccc 0001 0010 xxxx xxxx xxxx 1x00 xxxx */
-	DECODE_CUSTOM	(0x0ff000b0, 0x01200080, prep_emulate_rd16rn12rs8rm0_wflags),
+	DECODE_EMULATEX	(0x0ff000b0, 0x01200080, emulate_rd16rn12rm0rs8_rwflags_nopc,
+						 REGS(NOPC, NOPC, NOPC, 0, NOPC)),
 
 	DECODE_END
 };
@@ -1080,13 +1111,15 @@ static const union decode_item arm_cccc_0000_____1001_table[] = {
 
 	/* MUL			cccc 0000 0000 xxxx xxxx xxxx 1001 xxxx */
 	/* MULS			cccc 0000 0001 xxxx xxxx xxxx 1001 xxxx */
-	DECODE_CUSTOM	(0x0fe000f0, 0x00000090, prep_emulate_rd16rs8rm0_wflags),
+	DECODE_EMULATEX	(0x0fe000f0, 0x00000090, emulate_rd16rn12rm0rs8_rwflags_nopc,
+						 REGS(NOPC, 0, NOPC, 0, NOPC)),
 
 	/* MLA			cccc 0000 0010 xxxx xxxx xxxx 1001 xxxx */
 	/* MLAS			cccc 0000 0011 xxxx xxxx xxxx 1001 xxxx */
 	DECODE_OR	(0x0fe000f0, 0x00200090),
 	/* MLS			cccc 0000 0110 xxxx xxxx xxxx 1001 xxxx */
-	DECODE_CUSTOM	(0x0ff000f0, 0x00600090, prep_emulate_rd16rn12rs8rm0_wflags),
+	DECODE_EMULATEX	(0x0ff000f0, 0x00600090, emulate_rd16rn12rm0rs8_rwflags_nopc,
+						 REGS(NOPC, NOPC, NOPC, 0, NOPC)),
 
 	/* UMAAL		cccc 0000 0100 xxxx xxxx xxxx 1001 xxxx */
 	DECODE_OR	(0x0ff000f0, 0x00400090),
@@ -1368,7 +1401,8 @@ static const union decode_item arm_cccc_0111_____xxx1_table[] = {
 	/* SMMUL		cccc 0111 0101 xxxx 1111 xxxx 00x1 xxxx */
 	DECODE_OR	(0x0ff0f0d0, 0x0750f010),
 	/* USAD8		cccc 0111 1000 xxxx 1111 xxxx 0001 xxxx */
-	DECODE_CUSTOM	(0x0ff0f0f0, 0x0780f010, prep_emulate_rd16rs8rm0_wflags),
+	DECODE_EMULATEX	(0x0ff0f0f0, 0x0780f010, emulate_rd16rn12rm0rs8_rwflags_nopc,
+						 REGS(NOPC, 0, NOPC, 0, NOPC)),
 
 	/* SMLAD		cccc 0111 0000 xxxx xxxx xxxx 00x1 xxxx */
 	/* SMLSD		cccc 0111 0000 xxxx xxxx xxxx 01x1 xxxx */
@@ -1376,10 +1410,12 @@ static const union decode_item arm_cccc_0111_____xxx1_table[] = {
 	/* SMMLA		cccc 0111 0101 xxxx xxxx xxxx 00x1 xxxx */
 	DECODE_OR	(0x0ff000d0, 0x07500010),
 	/* USADA8		cccc 0111 1000 xxxx xxxx xxxx 0001 xxxx */
-	DECODE_CUSTOM	(0x0ff000f0, 0x07800010, prep_emulate_rd16rn12rs8rm0_wflags),
+	DECODE_EMULATEX	(0x0ff000f0, 0x07800010, emulate_rd16rn12rm0rs8_rwflags_nopc,
+						 REGS(NOPC, NOPCX, NOPC, 0, NOPC)),
 
 	/* SMMLS		cccc 0111 0101 xxxx xxxx xxxx 11x1 xxxx */
-	DECODE_CUSTOM	(0x0ff000d0, 0x075000d0, prep_emulate_rd16rn12rs8rm0_wflags),
+	DECODE_EMULATEX	(0x0ff000d0, 0x075000d0, emulate_rd16rn12rm0rs8_rwflags_nopc,
+						 REGS(NOPC, NOPC, NOPC, 0, NOPC)),
 
 	/* SBFX			cccc 0111 101x xxxx xxxx xxxx x101 xxxx */
 	/* UBFX			cccc 0111 111x xxxx xxxx xxxx x101 xxxx */
-- 
1.7.2.5

^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH 17/24] ARM: kprobes: Replace use of prep_emulate_rd12rn16rm0_wflags()
  2011-07-13  9:05 [PATCH 0/24] ARM: kprobes: Migrate ARM instruction decoding to data tables Tixy
                   ` (15 preceding siblings ...)
  2011-07-13  9:06 ` [PATCH 16/24] ARM: kprobes: Add emulate_rd16rn12rm0rs8_rwflags_nopc() Tixy
@ 2011-07-13  9:06 ` Tixy
  2011-07-13  9:06 ` [PATCH 18/24] ARM: kprobes: Add emulate_rd12rm0_noflags_nopc() Tixy
                   ` (6 subsequent siblings)
  23 siblings, 0 replies; 26+ messages in thread
From: Tixy @ 2011-07-13  9:06 UTC (permalink / raw)
  To: linux-arm-kernel

From: Jon Medhurst <tixy@yxit.co.uk>

These can now use emulate_rd12rn16rm0_rwflags_nopc().

Signed-off-by: Jon Medhurst <tixy@yxit.co.uk>
---
 arch/arm/kernel/kprobes-arm.c |   15 ++++++++++-----
 1 files changed, 10 insertions(+), 5 deletions(-)

diff --git a/arch/arm/kernel/kprobes-arm.c b/arch/arm/kernel/kprobes-arm.c
index d3b0506..2131506 100644
--- a/arch/arm/kernel/kprobes-arm.c
+++ b/arch/arm/kernel/kprobes-arm.c
@@ -1074,7 +1074,8 @@ static const union decode_item arm_cccc_0001_0xx0____0xxx_table[] = {
 	/* QSUB			cccc 0001 0010 xxxx xxxx xxxx 0101 xxxx */
 	/* QDADD		cccc 0001 0100 xxxx xxxx xxxx 0101 xxxx */
 	/* QDSUB		cccc 0001 0110 xxxx xxxx xxxx 0101 xxxx */
-	DECODE_CUSTOM	(0x0f9000f0, 0x01000050, prep_emulate_rd12rn16rm0_wflags),
+	DECODE_EMULATEX	(0x0f9000f0, 0x01000050, emulate_rd12rn16rm0_rwflags_nopc,
+						 REGS(NOPC, NOPC, 0, 0, NOPC)),
 
 	/* BXJ			cccc 0001 0010 xxxx xxxx xxxx 0010 xxxx */
 	/* MSR			cccc 0001 0x10 xxxx xxxx xxxx 0000 xxxx */
@@ -1140,7 +1141,8 @@ static const union decode_item arm_cccc_0001_____1001_table[] = {
 	/* Synchronization primitives					*/
 
 	/* SMP/SWPB		cccc 0001 0x00 xxxx xxxx xxxx 1001 xxxx */
-	DECODE_CUSTOM	(0x0fb000f0, 0x01000090, prep_emulate_rd12rn16rm0_wflags),
+	DECODE_EMULATEX	(0x0fb000f0, 0x01000090, emulate_rd12rn16rm0_rwflags_nopc,
+						 REGS(NOPC, NOPC, 0, 0, NOPC)),
 
 	/* LDREX/STREX{,D,B,H}	cccc 0001 1xxx xxxx xxxx xxxx 1001 xxxx */
 	/* And unallocated instructions...				*/
@@ -1356,11 +1358,13 @@ static const union decode_item arm_cccc_0110_____xxx1_table[] = {
 	/* UHSUB16		cccc 0110 0111 xxxx xxxx xxxx 0111 xxxx */
 	/* UHADD8		cccc 0110 0111 xxxx xxxx xxxx 1001 xxxx */
 	/* UHSUB8		cccc 0110 0111 xxxx xxxx xxxx 1111 xxxx */
-	DECODE_CUSTOM	(0x0f800010, 0x06000010, prep_emulate_rd12rn16rm0_wflags),
+	DECODE_EMULATEX	(0x0f800010, 0x06000010, emulate_rd12rn16rm0_rwflags_nopc,
+						 REGS(NOPC, NOPC, 0, 0, NOPC)),
 
 	/* PKHBT		cccc 0110 1000 xxxx xxxx xxxx x001 xxxx */
 	/* PKHTB		cccc 0110 1000 xxxx xxxx xxxx x101 xxxx */
-	DECODE_CUSTOM	(0x0ff00030, 0x06800010, prep_emulate_rd12rn16rm0_wflags),
+	DECODE_EMULATEX	(0x0ff00030, 0x06800010, emulate_rd12rn16rm0_rwflags_nopc,
+						 REGS(NOPC, NOPC, 0, 0, NOPC)),
 
 	/* ???			cccc 0110 1001 xxxx xxxx xxxx 0111 xxxx */
 	/* ???			cccc 0110 1101 xxxx xxxx xxxx 0111 xxxx */
@@ -1380,7 +1384,8 @@ static const union decode_item arm_cccc_0110_____xxx1_table[] = {
 	/* UXTAB16		cccc 0110 1100 xxxx xxxx xxxx 0111 xxxx */
 	/* UXTAB		cccc 0110 1110 xxxx xxxx xxxx 0111 xxxx */
 	/* UXTAH		cccc 0110 1111 xxxx xxxx xxxx 0111 xxxx */
-	DECODE_CUSTOM	(0x0f8000f0, 0x06800070, prep_emulate_rd12rn16rm0_wflags),
+	DECODE_EMULATEX	(0x0f8000f0, 0x06800070, emulate_rd12rn16rm0_rwflags_nopc,
+						 REGS(NOPCX, NOPC, 0, 0, NOPC)),
 
 	DECODE_END
 };
-- 
1.7.2.5

^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH 18/24] ARM: kprobes: Add emulate_rd12rm0_noflags_nopc()
  2011-07-13  9:05 [PATCH 0/24] ARM: kprobes: Migrate ARM instruction decoding to data tables Tixy
                   ` (16 preceding siblings ...)
  2011-07-13  9:06 ` [PATCH 17/24] ARM: kprobes: Replace use of prep_emulate_rd12rn16rm0_wflags() Tixy
@ 2011-07-13  9:06 ` Tixy
  2011-07-13  9:06 ` [PATCH 19/24] ARM: kprobes: Add emulate_rdlo12rdhi16rn0rm8_rwflags_nopc() Tixy
                   ` (5 subsequent siblings)
  23 siblings, 0 replies; 26+ messages in thread
From: Tixy @ 2011-07-13  9:06 UTC (permalink / raw)
  To: linux-arm-kernel

From: Jon Medhurst <tixy@yxit.co.uk>

This is the emulation function for the instruction format used by the
ARM bit-field manipulation instructions.

Various other instruction forms can also make use of this and it is used
to replace use of prep_emulate_rd12{rm0}{_modify}

Signed-off-by: Jon Medhurst <tixy@yxit.co.uk>
---
 arch/arm/kernel/kprobes-arm.c |   41 ++++++++++++++++++++++++++++++++++-------
 1 files changed, 34 insertions(+), 7 deletions(-)

diff --git a/arch/arm/kernel/kprobes-arm.c b/arch/arm/kernel/kprobes-arm.c
index 2131506..688101f 100644
--- a/arch/arm/kernel/kprobes-arm.c
+++ b/arch/arm/kernel/kprobes-arm.c
@@ -1013,6 +1013,26 @@ emulate_rd16rn12rm0rs8_rwflags_nopc(struct kprobe *p, struct pt_regs *regs)
 	regs->ARM_cpsr = (regs->ARM_cpsr & ~APSR_MASK) | (cpsr & APSR_MASK);
 }
 
+static void __kprobes
+emulate_rd12rm0_noflags_nopc(struct kprobe *p, struct pt_regs *regs)
+{
+	kprobe_opcode_t insn = p->opcode;
+	int rd = (insn >> 12) & 0xf;
+	int rm = insn & 0xf;
+
+	register unsigned long rdv asm("r0") = regs->uregs[rd];
+	register unsigned long rmv asm("r3") = regs->uregs[rm];
+
+	__asm__ __volatile__ (
+		BLX("%[fn]")
+		: "=r" (rdv)
+		: "0" (rdv), "r" (rmv), [fn] "r" (p->ainsn.insn_fn)
+		: "lr", "memory", "cc"
+	);
+
+	regs->uregs[rd] = rdv;
+}
+
 /*
  * For the instruction masking and comparisons in all the "space_*"
  * functions below, Do _not_ rearrange the order of tests unless
@@ -1068,7 +1088,8 @@ static const union decode_item arm_cccc_0001_0xx0____0xxx_table[] = {
 						 REGS(0, 0, 0, 0, NOPC)),
 
 	/* CLZ			cccc 0001 0110 xxxx xxxx xxxx 0001 xxxx */
-	DECODE_CUSTOM	(0x0ff000f0, 0x01600010, prep_emulate_rd12rm0),
+	DECODE_EMULATEX	(0x0ff000f0, 0x01600010, emulate_rd12rm0_noflags_nopc,
+						 REGS(0, NOPC, 0, 0, NOPC)),
 
 	/* QADD			cccc 0001 0000 xxxx xxxx xxxx 0101 xxxx */
 	/* QSUB			cccc 0001 0010 xxxx xxxx xxxx 0101 xxxx */
@@ -1249,7 +1270,8 @@ static const union decode_item arm_cccc_001x_table[] = {
 
 	/* MOVW			cccc 0011 0000 xxxx xxxx xxxx xxxx xxxx */
 	/* MOVT			cccc 0011 0100 xxxx xxxx xxxx xxxx xxxx */
-	DECODE_CUSTOM	(0x0fb00000, 0x03000000, prep_emulate_rd12_modify),
+	DECODE_EMULATEX	(0x0fb00000, 0x03000000, emulate_rd12rm0_noflags_nopc,
+						 REGS(0, NOPC, 0, 0, 0)),
 
 	/* YIELD		cccc 0011 0010 0000 xxxx xxxx 0000 0001 */
 	DECODE_OR	(0x0fff00ff, 0x03200001),
@@ -1314,7 +1336,8 @@ static const union decode_item arm_cccc_0110_____xxx1_table[] = {
 	/* REV16		cccc 0110 1011 xxxx xxxx xxxx 1011 xxxx */
 	/* RBIT			cccc 0110 1111 xxxx xxxx xxxx 0011 xxxx */
 	/* REVSH		cccc 0110 1111 xxxx xxxx xxxx 1011 xxxx */
-	DECODE_CUSTOM	(0x0fb00070, 0x06b00030, prep_emulate_rd12rm0),
+	DECODE_EMULATEX	(0x0fb00070, 0x06b00030, emulate_rd12rm0_noflags_nopc,
+						 REGS(0, NOPC, 0, 0, NOPC)),
 
 	/* ???			cccc 0110 0x00 xxxx xxxx xxxx xxx1 xxxx */
 	DECODE_REJECT	(0x0fb00010, 0x06000010),
@@ -1376,7 +1399,8 @@ static const union decode_item arm_cccc_0110_____xxx1_table[] = {
 	/* UXTB16		cccc 0110 1100 1111 xxxx xxxx 0111 xxxx */
 	/* UXTB			cccc 0110 1110 1111 xxxx xxxx 0111 xxxx */
 	/* UXTH			cccc 0110 1111 1111 xxxx xxxx 0111 xxxx */
-	DECODE_CUSTOM	(0x0f8f00f0, 0x068f0070, prep_emulate_rd12rm0),
+	DECODE_EMULATEX	(0x0f8f00f0, 0x068f0070, emulate_rd12rm0_noflags_nopc,
+						 REGS(0, NOPC, 0, 0, NOPC)),
 
 	/* SXTAB16		cccc 0110 1000 xxxx xxxx xxxx 0111 xxxx */
 	/* SXTAB		cccc 0110 1010 xxxx xxxx xxxx 0111 xxxx */
@@ -1424,13 +1448,16 @@ static const union decode_item arm_cccc_0111_____xxx1_table[] = {
 
 	/* SBFX			cccc 0111 101x xxxx xxxx xxxx x101 xxxx */
 	/* UBFX			cccc 0111 111x xxxx xxxx xxxx x101 xxxx */
-	DECODE_CUSTOM	(0x0fa00070, 0x07a00050, prep_emulate_rd12rm0),
+	DECODE_EMULATEX	(0x0fa00070, 0x07a00050, emulate_rd12rm0_noflags_nopc,
+						 REGS(0, NOPC, 0, 0, NOPC)),
 
 	/* BFC			cccc 0111 110x xxxx xxxx xxxx x001 1111 */
-	DECODE_CUSTOM	(0x0fe0007f, 0x07c0001f, prep_emulate_rd12_modify),
+	DECODE_EMULATEX	(0x0fe0007f, 0x07c0001f, emulate_rd12rm0_noflags_nopc,
+						 REGS(0, NOPC, 0, 0, 0)),
 
 	/* BFI			cccc 0111 110x xxxx xxxx xxxx x001 xxxx */
-	DECODE_CUSTOM	(0x0fe00070, 0x07c00010, prep_emulate_rd12rn0_modify),
+	DECODE_EMULATEX	(0x0fe00070, 0x07c00010, emulate_rd12rm0_noflags_nopc,
+						 REGS(0, NOPC, 0, 0, NOPCX)),
 
 	DECODE_END
 };
-- 
1.7.2.5

^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH 19/24] ARM: kprobes: Add emulate_rdlo12rdhi16rn0rm8_rwflags_nopc()
  2011-07-13  9:05 [PATCH 0/24] ARM: kprobes: Migrate ARM instruction decoding to data tables Tixy
                   ` (17 preceding siblings ...)
  2011-07-13  9:06 ` [PATCH 18/24] ARM: kprobes: Add emulate_rd12rm0_noflags_nopc() Tixy
@ 2011-07-13  9:06 ` Tixy
  2011-07-13  9:06 ` [PATCH 20/24] ARM: kprobes: Add new versions of emulate_ldr() and emulate_str() Tixy
                   ` (4 subsequent siblings)
  23 siblings, 0 replies; 26+ messages in thread
From: Tixy @ 2011-07-13  9:06 UTC (permalink / raw)
  To: linux-arm-kernel

From: Jon Medhurst <tixy@yxit.co.uk>

This is the emulation function for the instruction format used by the
ARM multiply long instructions. It replaces use of
prep_emulate_rdhi16rdlo12rs8rm0_wflags().

Signed-off-by: Jon Medhurst <tixy@yxit.co.uk>
---
 arch/arm/kernel/kprobes-arm.c |   39 ++++++++++++++++++++++++++++++++++++---
 1 files changed, 36 insertions(+), 3 deletions(-)

diff --git a/arch/arm/kernel/kprobes-arm.c b/arch/arm/kernel/kprobes-arm.c
index 688101f..bb38ae3 100644
--- a/arch/arm/kernel/kprobes-arm.c
+++ b/arch/arm/kernel/kprobes-arm.c
@@ -1033,6 +1033,36 @@ emulate_rd12rm0_noflags_nopc(struct kprobe *p, struct pt_regs *regs)
 	regs->uregs[rd] = rdv;
 }
 
+static void __kprobes
+emulate_rdlo12rdhi16rn0rm8_rwflags_nopc(struct kprobe *p, struct pt_regs *regs)
+{
+	kprobe_opcode_t insn = p->opcode;
+	int rdlo = (insn >> 12) & 0xf;
+	int rdhi = (insn >> 16) & 0xf;
+	int rn = insn & 0xf;
+	int rm = (insn >> 8) & 0xf;
+
+	register unsigned long rdlov asm("r0") = regs->uregs[rdlo];
+	register unsigned long rdhiv asm("r2") = regs->uregs[rdhi];
+	register unsigned long rnv asm("r3") = regs->uregs[rn];
+	register unsigned long rmv asm("r1") = regs->uregs[rm];
+	unsigned long cpsr = regs->ARM_cpsr;
+
+	__asm__ __volatile__ (
+		"msr	cpsr_fs, %[cpsr]	\n\t"
+		BLX("%[fn]")
+		"mrs	%[cpsr], cpsr		\n\t"
+		: "=r" (rdlov), "=r" (rdhiv), [cpsr] "=r" (cpsr)
+		: "0" (rdlov), "1" (rdhiv), "r" (rnv), "r" (rmv),
+		  "2" (cpsr), [fn] "r" (p->ainsn.insn_fn)
+		: "lr", "memory", "cc"
+	);
+
+	regs->uregs[rdlo] = rdlov;
+	regs->uregs[rdhi] = rdhiv;
+	regs->ARM_cpsr = (regs->ARM_cpsr & ~APSR_MASK) | (cpsr & APSR_MASK);
+}
+
 /*
  * For the instruction masking and comparisons in all the "space_*"
  * functions below, Do _not_ rearrange the order of tests unless
@@ -1111,7 +1141,8 @@ static const union decode_item arm_cccc_0001_0xx0____1xx0_table[] = {
 	/* Halfword multiply and multiply-accumulate			*/
 
 	/* SMLALxy		cccc 0001 0100 xxxx xxxx xxxx 1xx0 xxxx */
-	DECODE_CUSTOM	(0x0ff00090, 0x01400080, prep_emulate_rdhi16rdlo12rs8rm0_wflags),
+	DECODE_EMULATEX	(0x0ff00090, 0x01400080, emulate_rdlo12rdhi16rn0rm8_rwflags_nopc,
+						 REGS(NOPC, NOPC, NOPC, 0, NOPC)),
 
 	/* SMULWy		cccc 0001 0010 xxxx xxxx xxxx 1x10 xxxx */
 	DECODE_OR	(0x0ff000b0, 0x012000a0),
@@ -1153,7 +1184,8 @@ static const union decode_item arm_cccc_0000_____1001_table[] = {
 	/* SMULLS		cccc 0000 1101 xxxx xxxx xxxx 1001 xxxx */
 	/* SMLAL		cccc 0000 1110 xxxx xxxx xxxx 1001 xxxx */
 	/* SMLALS		cccc 0000 1111 xxxx xxxx xxxx 1001 xxxx */
-	DECODE_CUSTOM	(0x0f8000f0, 0x00800090, prep_emulate_rdhi16rdlo12rs8rm0_wflags),
+	DECODE_EMULATEX	(0x0f8000f0, 0x00800090, emulate_rdlo12rdhi16rn0rm8_rwflags_nopc,
+						 REGS(NOPC, NOPC, NOPC, 0, NOPC)),
 
 	DECODE_END
 };
@@ -1422,7 +1454,8 @@ static const union decode_item arm_cccc_0111_____xxx1_table[] = {
 
 	/* SMLALD		cccc 0111 0100 xxxx xxxx xxxx 00x1 xxxx */
 	/* SMLSLD		cccc 0111 0100 xxxx xxxx xxxx 01x1 xxxx */
-	DECODE_CUSTOM	(0x0ff00090, 0x07400010, prep_emulate_rdhi16rdlo12rs8rm0_wflags),
+	DECODE_EMULATEX	(0x0ff00090, 0x07400010, emulate_rdlo12rdhi16rn0rm8_rwflags_nopc,
+						 REGS(NOPC, NOPC, NOPC, 0, NOPC)),
 
 	/* SMUAD		cccc 0111 0000 xxxx 1111 xxxx 00x1 xxxx */
 	/* SMUSD		cccc 0111 0000 xxxx 1111 xxxx 01x1 xxxx */
-- 
1.7.2.5

^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH 20/24] ARM: kprobes: Add new versions of emulate_ldr() and emulate_str()
  2011-07-13  9:05 [PATCH 0/24] ARM: kprobes: Migrate ARM instruction decoding to data tables Tixy
                   ` (18 preceding siblings ...)
  2011-07-13  9:06 ` [PATCH 19/24] ARM: kprobes: Add emulate_rdlo12rdhi16rn0rm8_rwflags_nopc() Tixy
@ 2011-07-13  9:06 ` Tixy
  2011-07-13  9:06 ` [PATCH 21/24] ARM: kprobes: Use " Tixy
                   ` (3 subsequent siblings)
  23 siblings, 0 replies; 26+ messages in thread
From: Tixy @ 2011-07-13  9:06 UTC (permalink / raw)
  To: linux-arm-kernel

From: Jon Medhurst <tixy@yxit.co.uk>

These use the register calling conventions required by the new decoding
table framework for calling simulated instructions.

We rename the old versions of these functions to *_old for now.

Signed-off-by: Jon Medhurst <tixy@yxit.co.uk>
---
 arch/arm/kernel/kprobes-arm.c |   63 +++++++++++++++++++++++++++++++++++++++--
 1 files changed, 60 insertions(+), 3 deletions(-)

diff --git a/arch/arm/kernel/kprobes-arm.c b/arch/arm/kernel/kprobes-arm.c
index bb38ae3..d252e78 100644
--- a/arch/arm/kernel/kprobes-arm.c
+++ b/arch/arm/kernel/kprobes-arm.c
@@ -502,7 +502,7 @@ static void __kprobes emulate_strd(struct kprobe *p, struct pt_regs *regs)
 		regs->uregs[rn] = rnv_wb;
 }
 
-static void __kprobes emulate_ldr(struct kprobe *p, struct pt_regs *regs)
+static void __kprobes emulate_ldr_old(struct kprobe *p, struct pt_regs *regs)
 {
 	insn_llret_3arg_fn_t *i_fn = (insn_llret_3arg_fn_t *)&p->ainsn.insn[0];
 	kprobe_opcode_t insn = p->opcode;
@@ -535,7 +535,7 @@ static void __kprobes emulate_ldr(struct kprobe *p, struct pt_regs *regs)
 	regs->uregs[rd] = rdv;
 }
 
-static void __kprobes emulate_str(struct kprobe *p, struct pt_regs *regs)
+static void __kprobes emulate_str_old(struct kprobe *p, struct pt_regs *regs)
 {
 	insn_3arg_fn_t *i_fn = (insn_3arg_fn_t *)&p->ainsn.insn[0];
 	kprobe_opcode_t insn = p->opcode;
@@ -795,7 +795,7 @@ prep_emulate_ldr_str(kprobe_opcode_t insn, struct arch_specific_insn *asi)
 		insn |= 2;	/* Rm = r2 */
 	}
 	asi->insn[0] = insn;
-	asi->insn_handler = (insn & (1 << 20)) ? emulate_ldr : emulate_str;
+	asi->insn_handler = (insn & (1 << 20)) ? emulate_ldr_old : emulate_str_old;
 	return INSN_GOOD;
 }
 
@@ -923,6 +923,63 @@ emulate_ldrdstrd(struct kprobe *p, struct pt_regs *regs)
 }
 
 static void __kprobes
+emulate_ldr(struct kprobe *p, struct pt_regs *regs)
+{
+	kprobe_opcode_t insn = p->opcode;
+	unsigned long pc = (unsigned long)p->addr + 8;
+	int rt = (insn >> 12) & 0xf;
+	int rn = (insn >> 16) & 0xf;
+	int rm = insn & 0xf;
+
+	register unsigned long rtv asm("r0");
+	register unsigned long rnv asm("r2") = (rn == 15) ? pc
+							  : regs->uregs[rn];
+	register unsigned long rmv asm("r3") = regs->uregs[rm];
+
+	__asm__ __volatile__ (
+		BLX("%[fn]")
+		: "=r" (rtv), "=r" (rnv)
+		: "1" (rnv), "r" (rmv), [fn] "r" (p->ainsn.insn_fn)
+		: "lr", "memory", "cc"
+	);
+
+	if (rt == 15)
+		load_write_pc(rtv, regs);
+	else
+		regs->uregs[rt] = rtv;
+
+	if (is_writeback(insn))
+		regs->uregs[rn] = rnv;
+}
+
+static void __kprobes
+emulate_str(struct kprobe *p, struct pt_regs *regs)
+{
+	kprobe_opcode_t insn = p->opcode;
+	unsigned long rtpc = (unsigned long)p->addr + str_pc_offset;
+	unsigned long rnpc = (unsigned long)p->addr + 8;
+	int rt = (insn >> 12) & 0xf;
+	int rn = (insn >> 16) & 0xf;
+	int rm = insn & 0xf;
+
+	register unsigned long rtv asm("r0") = (rt == 15) ? rtpc
+							  : regs->uregs[rt];
+	register unsigned long rnv asm("r2") = (rn == 15) ? rnpc
+							  : regs->uregs[rn];
+	register unsigned long rmv asm("r3") = regs->uregs[rm];
+
+	__asm__ __volatile__ (
+		BLX("%[fn]")
+		: "=r" (rnv)
+		: "r" (rtv), "0" (rnv), "r" (rmv), [fn] "r" (p->ainsn.insn_fn)
+		: "lr", "memory", "cc"
+	);
+
+	if (is_writeback(insn))
+		regs->uregs[rn] = rnv;
+}
+
+static void __kprobes
 emulate_rd12rn16rm0rs8_rwflags(struct kprobe *p, struct pt_regs *regs)
 {
 	kprobe_opcode_t insn = p->opcode;
-- 
1.7.2.5

^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH 21/24] ARM: kprobes: Use new versions of emulate_ldr() and emulate_str()
  2011-07-13  9:05 [PATCH 0/24] ARM: kprobes: Migrate ARM instruction decoding to data tables Tixy
                   ` (19 preceding siblings ...)
  2011-07-13  9:06 ` [PATCH 20/24] ARM: kprobes: Add new versions of emulate_ldr() and emulate_str() Tixy
@ 2011-07-13  9:06 ` Tixy
  2011-07-13  9:06 ` [PATCH 22/24] ARM: kprobes: Reject probing of unprivileged load and store instructions Tixy
                   ` (2 subsequent siblings)
  23 siblings, 0 replies; 26+ messages in thread
From: Tixy @ 2011-07-13  9:06 UTC (permalink / raw)
  To: linux-arm-kernel

From: Jon Medhurst <tixy@yxit.co.uk>

Signed-off-by: Jon Medhurst <tixy@yxit.co.uk>
---
 arch/arm/kernel/kprobes-arm.c |   44 +++++++++++++++++++++++++++-------------
 1 files changed, 30 insertions(+), 14 deletions(-)

diff --git a/arch/arm/kernel/kprobes-arm.c b/arch/arm/kernel/kprobes-arm.c
index d252e78..1ee38ad 100644
--- a/arch/arm/kernel/kprobes-arm.c
+++ b/arch/arm/kernel/kprobes-arm.c
@@ -1275,19 +1275,25 @@ static const union decode_item arm_cccc_000x_____1xx1_table[] = {
 	DECODE_EMULATEX	(0x0e5000d0, 0x004000d0, emulate_ldrdstrd,
 						 REGS(NOPCWB, NOPCX, 0, 0, 0)),
 
-	/* Reject Rd is PC */
-	/* TODO: fold this into next entry when it is made a DECODE_EMULATE */
-	DECODE_REJECT	(0x0000f000, 0x0000f000),
-
 	/* STRH (register)	cccc 000x x0x0 xxxx xxxx xxxx 1011 xxxx */
+	DECODE_EMULATEX	(0x0e5000f0, 0x000000b0, emulate_str,
+						 REGS(NOPCWB, NOPC, 0, 0, NOPC)),
+
 	/* LDRH (register)	cccc 000x x0x1 xxxx xxxx xxxx 1011 xxxx */
 	/* LDRSB (register)	cccc 000x x0x1 xxxx xxxx xxxx 1101 xxxx */
 	/* LDRSH (register)	cccc 000x x0x1 xxxx xxxx xxxx 1111 xxxx */
+	DECODE_EMULATEX	(0x0e500090, 0x00100090, emulate_ldr,
+						 REGS(NOPCWB, NOPC, 0, 0, NOPC)),
+
 	/* STRH (immediate)	cccc 000x x1x0 xxxx xxxx xxxx 1011 xxxx */
+	DECODE_EMULATEX	(0x0e5000f0, 0x004000b0, emulate_str,
+						 REGS(NOPCWB, NOPC, 0, 0, 0)),
+
 	/* LDRH (immediate)	cccc 000x x1x1 xxxx xxxx xxxx 1011 xxxx */
 	/* LDRSB (immediate)	cccc 000x x1x1 xxxx xxxx xxxx 1101 xxxx */
 	/* LDRSH (immediate)	cccc 000x x1x1 xxxx xxxx xxxx 1111 xxxx */
-	DECODE_CUSTOM	(0x0e000090, 0x00000090, prep_emulate_ldr_str),
+	DECODE_EMULATEX	(0x0e500090, 0x00500090, emulate_ldr,
+						 REGS(NOPCWB, NOPC, 0, 0, 0)),
 
 	DECODE_END
 };
@@ -1558,15 +1564,25 @@ static const union decode_item arm_cccc_01xx_table[] = {
 	/* LDRB/STRB pc,[...]	cccc 01xx x0xx xxxx xxxx xxxx xxxx xxxx */
 	DECODE_REJECT	(0x0c40f000, 0x0440f000),
 
-	/* LDR			cccc 01xx x0x1 xxxx xxxx xxxx xxxx xxxx */
-	/* LDRB			cccc 01xx x1x1 xxxx xxxx xxxx xxxx xxxx */
-	/* LDRBT		cccc 01x0 x111 xxxx xxxx xxxx xxxx xxxx */
-	/* LDRT			cccc 01x0 x011 xxxx xxxx xxxx xxxx xxxx */
-	/* STR			cccc 01xx x0x0 xxxx xxxx xxxx xxxx xxxx */
-	/* STRB			cccc 01xx x1x0 xxxx xxxx xxxx xxxx xxxx */
-	/* STRBT		cccc 01x0 x110 xxxx xxxx xxxx xxxx xxxx */
-	/* STRT			cccc 01x0 x010 xxxx xxxx xxxx xxxx xxxx */
-	DECODE_CUSTOM	(0x0c000000, 0x04000000, prep_emulate_ldr_str),
+	/* STR (immediate)	cccc 010x x0x0 xxxx xxxx xxxx xxxx xxxx */
+	/* STRB (immediate)	cccc 010x x1x0 xxxx xxxx xxxx xxxx xxxx */
+	DECODE_EMULATEX	(0x0e100000, 0x04000000, emulate_str,
+						 REGS(NOPCWB, ANY, 0, 0, 0)),
+
+	/* LDR (immediate)	cccc 010x x0x1 xxxx xxxx xxxx xxxx xxxx */
+	/* LDRB (immediate)	cccc 010x x1x1 xxxx xxxx xxxx xxxx xxxx */
+	DECODE_EMULATEX	(0x0e100000, 0x04100000, emulate_ldr,
+						 REGS(NOPCWB, ANY, 0, 0, 0)),
+
+	/* STR (register)	cccc 011x x0x0 xxxx xxxx xxxx xxxx xxxx */
+	/* STRB (register)	cccc 011x x1x0 xxxx xxxx xxxx xxxx xxxx */
+	DECODE_EMULATEX	(0x0e100000, 0x06000000, emulate_str,
+						 REGS(NOPCWB, ANY, 0, 0, NOPC)),
+
+	/* LDR (register)	cccc 011x x0x1 xxxx xxxx xxxx xxxx xxxx */
+	/* LDRB (register)	cccc 011x x1x1 xxxx xxxx xxxx xxxx xxxx */
+	DECODE_EMULATEX	(0x0e100000, 0x06100000, emulate_ldr,
+						 REGS(NOPCWB, ANY, 0, 0, NOPC)),
 
 	DECODE_END
 };
-- 
1.7.2.5

^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH 22/24] ARM: kprobes: Reject probing of unprivileged load and store instructions
  2011-07-13  9:05 [PATCH 0/24] ARM: kprobes: Migrate ARM instruction decoding to data tables Tixy
                   ` (20 preceding siblings ...)
  2011-07-13  9:06 ` [PATCH 21/24] ARM: kprobes: Use " Tixy
@ 2011-07-13  9:06 ` Tixy
  2011-07-13  9:06 ` [PATCH 23/24] ARM: kprobes: Decode ARM preload (immediate) instructions Tixy
  2011-07-13  9:06 ` [PATCH 24/24] ARM: kprobes: Remove now unused code Tixy
  23 siblings, 0 replies; 26+ messages in thread
From: Tixy @ 2011-07-13  9:06 UTC (permalink / raw)
  To: linux-arm-kernel

From: Jon Medhurst <tixy@yxit.co.uk>

These occur extremely rarely in the kernel and writing test cases for
them is difficult.

Signed-off-by: Jon Medhurst <tixy@yxit.co.uk>
---
 arch/arm/kernel/kprobes-arm.c |   13 +++++++++++++
 1 files changed, 13 insertions(+), 0 deletions(-)

diff --git a/arch/arm/kernel/kprobes-arm.c b/arch/arm/kernel/kprobes-arm.c
index 1ee38ad..70e540b 100644
--- a/arch/arm/kernel/kprobes-arm.c
+++ b/arch/arm/kernel/kprobes-arm.c
@@ -1262,6 +1262,13 @@ static const union decode_item arm_cccc_0001_____1001_table[] = {
 static const union decode_item arm_cccc_000x_____1xx1_table[] = {
 	/* Extra load/store instructions				*/
 
+	/* STRHT		cccc 0000 xx10 xxxx xxxx xxxx 1011 xxxx */
+	/* ???			cccc 0000 xx10 xxxx xxxx xxxx 11x1 xxxx */
+	/* LDRHT		cccc 0000 xx11 xxxx xxxx xxxx 1011 xxxx */
+	/* LDRSBT		cccc 0000 xx11 xxxx xxxx xxxx 1101 xxxx */
+	/* LDRSHT		cccc 0000 xx11 xxxx xxxx xxxx 1111 xxxx */
+	DECODE_REJECT	(0x0f200090, 0x00200090),
+
 	/* LDRD/STRD lr,pc,{...	cccc 000x x0x0 xxxx 111x xxxx 1101 xxxx */
 	DECODE_REJECT	(0x0e10e0d0, 0x0000e0d0),
 
@@ -1564,6 +1571,12 @@ static const union decode_item arm_cccc_01xx_table[] = {
 	/* LDRB/STRB pc,[...]	cccc 01xx x0xx xxxx xxxx xxxx xxxx xxxx */
 	DECODE_REJECT	(0x0c40f000, 0x0440f000),
 
+	/* STRT			cccc 01x0 x010 xxxx xxxx xxxx xxxx xxxx */
+	/* LDRT			cccc 01x0 x011 xxxx xxxx xxxx xxxx xxxx */
+	/* STRBT		cccc 01x0 x110 xxxx xxxx xxxx xxxx xxxx */
+	/* LDRBT		cccc 01x0 x111 xxxx xxxx xxxx xxxx xxxx */
+	DECODE_REJECT	(0x0d200000, 0x04200000),
+
 	/* STR (immediate)	cccc 010x x0x0 xxxx xxxx xxxx xxxx xxxx */
 	/* STRB (immediate)	cccc 010x x1x0 xxxx xxxx xxxx xxxx xxxx */
 	DECODE_EMULATEX	(0x0e100000, 0x04000000, emulate_str,
-- 
1.7.2.5

^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH 23/24] ARM: kprobes: Decode ARM preload (immediate) instructions
  2011-07-13  9:05 [PATCH 0/24] ARM: kprobes: Migrate ARM instruction decoding to data tables Tixy
                   ` (21 preceding siblings ...)
  2011-07-13  9:06 ` [PATCH 22/24] ARM: kprobes: Reject probing of unprivileged load and store instructions Tixy
@ 2011-07-13  9:06 ` Tixy
  2011-07-13  9:06 ` [PATCH 24/24] ARM: kprobes: Remove now unused code Tixy
  23 siblings, 0 replies; 26+ messages in thread
From: Tixy @ 2011-07-13  9:06 UTC (permalink / raw)
  To: linux-arm-kernel

From: Jon Medhurst <tixy@yxit.co.uk>

These were missing from the previous implementation.

Signed-off-by: Jon Medhurst <tixy@yxit.co.uk>
---
 arch/arm/kernel/kprobes-arm.c |    6 ++++++
 1 files changed, 6 insertions(+), 0 deletions(-)

diff --git a/arch/arm/kernel/kprobes-arm.c b/arch/arm/kernel/kprobes-arm.c
index 70e540b..8a58c99 100644
--- a/arch/arm/kernel/kprobes-arm.c
+++ b/arch/arm/kernel/kprobes-arm.c
@@ -1139,6 +1139,12 @@ static const union decode_item arm_1111_table[] = {
 	/* PLD (immediate)	1111 0101 x101 xxxx xxxx xxxx xxxx xxxx */
 	DECODE_SIMULATE	(0xfe300000, 0xf4100000, kprobe_simulate_nop),
 
+	/* memory hint		1111 0110 x001 xxxx xxxx xxxx xxx0 xxxx */
+	/* PLDI (register)	1111 0110 x101 xxxx xxxx xxxx xxx0 xxxx */
+	/* PLDW (register)	1111 0111 x001 xxxx xxxx xxxx xxx0 xxxx */
+	/* PLD (register)	1111 0111 x101 xxxx xxxx xxxx xxx0 xxxx */
+	DECODE_SIMULATE	(0xfe300010, 0xf6100000, kprobe_simulate_nop),
+
 	/* BLX (immediate)	1111 101x xxxx xxxx xxxx xxxx xxxx xxxx */
 	DECODE_SIMULATE	(0xfe000000, 0xfa000000, simulate_blx1),
 
-- 
1.7.2.5

^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH 24/24] ARM: kprobes: Remove now unused code
  2011-07-13  9:05 [PATCH 0/24] ARM: kprobes: Migrate ARM instruction decoding to data tables Tixy
                   ` (22 preceding siblings ...)
  2011-07-13  9:06 ` [PATCH 23/24] ARM: kprobes: Decode ARM preload (immediate) instructions Tixy
@ 2011-07-13  9:06 ` Tixy
  2011-07-13 16:04   ` Nicolas Pitre
  23 siblings, 1 reply; 26+ messages in thread
From: Tixy @ 2011-07-13  9:06 UTC (permalink / raw)
  To: linux-arm-kernel

From: Jon Medhurst <tixy@yxit.co.uk>

Signed-off-by: Jon Medhurst <tixy@yxit.co.uk>
---
 arch/arm/kernel/kprobes-arm.c |  738 -----------------------------------------
 1 files changed, 0 insertions(+), 738 deletions(-)

diff --git a/arch/arm/kernel/kprobes-arm.c b/arch/arm/kernel/kprobes-arm.c
index 8a58c99..79203ee 100644
--- a/arch/arm/kernel/kprobes-arm.c
+++ b/arch/arm/kernel/kprobes-arm.c
@@ -74,300 +74,6 @@
 			"mov	pc, "reg"	\n\t"
 #endif
 
-#define is_r15(insn, bitpos) (((insn) & (0xf << bitpos)) == (0xf << bitpos))
-
-#define PSR_fs	(PSR_f|PSR_s)
-
-#define KPROBE_RETURN_INSTRUCTION	0xe1a0f00e	/* mov pc, lr */
-
-typedef long (insn_0arg_fn_t)(void);
-typedef long (insn_1arg_fn_t)(long);
-typedef long (insn_2arg_fn_t)(long, long);
-typedef long (insn_3arg_fn_t)(long, long, long);
-typedef long (insn_4arg_fn_t)(long, long, long, long);
-typedef long long (insn_llret_0arg_fn_t)(void);
-typedef long long (insn_llret_3arg_fn_t)(long, long, long);
-typedef long long (insn_llret_4arg_fn_t)(long, long, long, long);
-
-union reg_pair {
-	long long	dr;
-#ifdef __LITTLE_ENDIAN
-	struct { long	r0, r1; };
-#else
-	struct { long	r1, r0; };
-#endif
-};
-
-/*
- * The insnslot_?arg_r[w]flags() functions below are to keep the
- * msr -> *fn -> mrs instruction sequences indivisible so that
- * the state of the CPSR flags aren't inadvertently modified
- * just before or just after the call.
- */
-
-static inline long __kprobes
-insnslot_0arg_rflags(long cpsr, insn_0arg_fn_t *fn)
-{
-	register long ret asm("r0");
-
-	__asm__ __volatile__ (
-		"msr	cpsr_fs, %[cpsr]	\n\t"
-		"mov	lr, pc			\n\t"
-		"mov	pc, %[fn]		\n\t"
-		: "=r" (ret)
-		: [cpsr] "r" (cpsr), [fn] "r" (fn)
-		: "lr", "cc"
-	);
-	return ret;
-}
-
-static inline long long __kprobes
-insnslot_llret_0arg_rflags(long cpsr, insn_llret_0arg_fn_t *fn)
-{
-	register long ret0 asm("r0");
-	register long ret1 asm("r1");
-	union reg_pair fnr;
-
-	__asm__ __volatile__ (
-		"msr	cpsr_fs, %[cpsr]	\n\t"
-		"mov	lr, pc			\n\t"
-		"mov	pc, %[fn]		\n\t"
-		: "=r" (ret0), "=r" (ret1)
-		: [cpsr] "r" (cpsr), [fn] "r" (fn)
-		: "lr", "cc"
-	);
-	fnr.r0 = ret0;
-	fnr.r1 = ret1;
-	return fnr.dr;
-}
-
-static inline long __kprobes
-insnslot_1arg_rflags(long r0, long cpsr, insn_1arg_fn_t *fn)
-{
-	register long rr0 asm("r0") = r0;
-	register long ret asm("r0");
-
-	__asm__ __volatile__ (
-		"msr	cpsr_fs, %[cpsr]	\n\t"
-		"mov	lr, pc			\n\t"
-		"mov	pc, %[fn]		\n\t"
-		: "=r" (ret)
-		: "0" (rr0), [cpsr] "r" (cpsr), [fn] "r" (fn)
-		: "lr", "cc"
-	);
-	return ret;
-}
-
-static inline long __kprobes
-insnslot_2arg_rflags(long r0, long r1, long cpsr, insn_2arg_fn_t *fn)
-{
-	register long rr0 asm("r0") = r0;
-	register long rr1 asm("r1") = r1;
-	register long ret asm("r0");
-
-	__asm__ __volatile__ (
-		"msr	cpsr_fs, %[cpsr]	\n\t"
-		"mov	lr, pc			\n\t"
-		"mov	pc, %[fn]		\n\t"
-		: "=r" (ret)
-		: "0" (rr0), "r" (rr1),
-		  [cpsr] "r" (cpsr), [fn] "r" (fn)
-		: "lr", "cc"
-	);
-	return ret;
-}
-
-static inline long __kprobes
-insnslot_3arg_rflags(long r0, long r1, long r2, long cpsr, insn_3arg_fn_t *fn)
-{
-	register long rr0 asm("r0") = r0;
-	register long rr1 asm("r1") = r1;
-	register long rr2 asm("r2") = r2;
-	register long ret asm("r0");
-
-	__asm__ __volatile__ (
-		"msr	cpsr_fs, %[cpsr]	\n\t"
-		"mov	lr, pc			\n\t"
-		"mov	pc, %[fn]		\n\t"
-		: "=r" (ret)
-		: "0" (rr0), "r" (rr1), "r" (rr2),
-		  [cpsr] "r" (cpsr), [fn] "r" (fn)
-		: "lr", "cc"
-	);
-	return ret;
-}
-
-static inline long long __kprobes
-insnslot_llret_3arg_rflags(long r0, long r1, long r2, long cpsr,
-			   insn_llret_3arg_fn_t *fn)
-{
-	register long rr0 asm("r0") = r0;
-	register long rr1 asm("r1") = r1;
-	register long rr2 asm("r2") = r2;
-	register long ret0 asm("r0");
-	register long ret1 asm("r1");
-	union reg_pair fnr;
-
-	__asm__ __volatile__ (
-		"msr	cpsr_fs, %[cpsr]	\n\t"
-		"mov	lr, pc			\n\t"
-		"mov	pc, %[fn]		\n\t"
-		: "=r" (ret0), "=r" (ret1)
-		: "0" (rr0), "r" (rr1), "r" (rr2),
-		  [cpsr] "r" (cpsr), [fn] "r" (fn)
-		: "lr", "cc"
-	);
-	fnr.r0 = ret0;
-	fnr.r1 = ret1;
-	return fnr.dr;
-}
-
-static inline long __kprobes
-insnslot_4arg_rflags(long r0, long r1, long r2, long r3, long cpsr,
-		     insn_4arg_fn_t *fn)
-{
-	register long rr0 asm("r0") = r0;
-	register long rr1 asm("r1") = r1;
-	register long rr2 asm("r2") = r2;
-	register long rr3 asm("r3") = r3;
-	register long ret asm("r0");
-
-	__asm__ __volatile__ (
-		"msr	cpsr_fs, %[cpsr]	\n\t"
-		"mov	lr, pc			\n\t"
-		"mov	pc, %[fn]		\n\t"
-		: "=r" (ret)
-		: "0" (rr0), "r" (rr1), "r" (rr2), "r" (rr3),
-		  [cpsr] "r" (cpsr), [fn] "r" (fn)
-		: "lr", "cc"
-	);
-	return ret;
-}
-
-static inline long __kprobes
-insnslot_1arg_rwflags(long r0, long *cpsr, insn_1arg_fn_t *fn)
-{
-	register long rr0 asm("r0") = r0;
-	register long ret asm("r0");
-	long oldcpsr = *cpsr;
-	long newcpsr;
-
-	__asm__ __volatile__ (
-		"msr	cpsr_fs, %[oldcpsr]	\n\t"
-		"mov	lr, pc			\n\t"
-		"mov	pc, %[fn]		\n\t"
-		"mrs	%[newcpsr], cpsr	\n\t"
-		: "=r" (ret), [newcpsr] "=r" (newcpsr)
-		: "0" (rr0), [oldcpsr] "r" (oldcpsr), [fn] "r" (fn)
-		: "lr", "cc"
-	);
-	*cpsr = (oldcpsr & ~PSR_fs) | (newcpsr & PSR_fs);
-	return ret;
-}
-
-static inline long __kprobes
-insnslot_2arg_rwflags(long r0, long r1, long *cpsr, insn_2arg_fn_t *fn)
-{
-	register long rr0 asm("r0") = r0;
-	register long rr1 asm("r1") = r1;
-	register long ret asm("r0");
-	long oldcpsr = *cpsr;
-	long newcpsr;
-
-	__asm__ __volatile__ (
-		"msr	cpsr_fs, %[oldcpsr]	\n\t"
-		"mov	lr, pc			\n\t"
-		"mov	pc, %[fn]		\n\t"
-		"mrs	%[newcpsr], cpsr	\n\t"
-		: "=r" (ret), [newcpsr] "=r" (newcpsr)
-		: "0" (rr0), "r" (rr1), [oldcpsr] "r" (oldcpsr), [fn] "r" (fn)
-		: "lr", "cc"
-	);
-	*cpsr = (oldcpsr & ~PSR_fs) | (newcpsr & PSR_fs);
-	return ret;
-}
-
-static inline long __kprobes
-insnslot_3arg_rwflags(long r0, long r1, long r2, long *cpsr,
-		      insn_3arg_fn_t *fn)
-{
-	register long rr0 asm("r0") = r0;
-	register long rr1 asm("r1") = r1;
-	register long rr2 asm("r2") = r2;
-	register long ret asm("r0");
-	long oldcpsr = *cpsr;
-	long newcpsr;
-
-	__asm__ __volatile__ (
-		"msr	cpsr_fs, %[oldcpsr]	\n\t"
-		"mov	lr, pc			\n\t"
-		"mov	pc, %[fn]		\n\t"
-		"mrs	%[newcpsr], cpsr	\n\t"
-		: "=r" (ret), [newcpsr] "=r" (newcpsr)
-		: "0" (rr0), "r" (rr1), "r" (rr2),
-		  [oldcpsr] "r" (oldcpsr), [fn] "r" (fn)
-		: "lr", "cc"
-	);
-	*cpsr = (oldcpsr & ~PSR_fs) | (newcpsr & PSR_fs);
-	return ret;
-}
-
-static inline long __kprobes
-insnslot_4arg_rwflags(long r0, long r1, long r2, long r3, long *cpsr,
-		      insn_4arg_fn_t *fn)
-{
-	register long rr0 asm("r0") = r0;
-	register long rr1 asm("r1") = r1;
-	register long rr2 asm("r2") = r2;
-	register long rr3 asm("r3") = r3;
-	register long ret asm("r0");
-	long oldcpsr = *cpsr;
-	long newcpsr;
-
-	__asm__ __volatile__ (
-		"msr	cpsr_fs, %[oldcpsr]	\n\t"
-		"mov	lr, pc			\n\t"
-		"mov	pc, %[fn]		\n\t"
-		"mrs	%[newcpsr], cpsr	\n\t"
-		: "=r" (ret), [newcpsr] "=r" (newcpsr)
-		: "0" (rr0), "r" (rr1), "r" (rr2), "r" (rr3),
-		  [oldcpsr] "r" (oldcpsr), [fn] "r" (fn)
-		: "lr", "cc"
-	);
-	*cpsr = (oldcpsr & ~PSR_fs) | (newcpsr & PSR_fs);
-	return ret;
-}
-
-static inline long long __kprobes
-insnslot_llret_4arg_rwflags(long r0, long r1, long r2, long r3, long *cpsr,
-			    insn_llret_4arg_fn_t *fn)
-{
-	register long rr0 asm("r0") = r0;
-	register long rr1 asm("r1") = r1;
-	register long rr2 asm("r2") = r2;
-	register long rr3 asm("r3") = r3;
-	register long ret0 asm("r0");
-	register long ret1 asm("r1");
-	long oldcpsr = *cpsr;
-	long newcpsr;
-	union reg_pair fnr;
-
-	__asm__ __volatile__ (
-		"msr	cpsr_fs, %[oldcpsr]	\n\t"
-		"mov	lr, pc			\n\t"
-		"mov	pc, %[fn]		\n\t"
-		"mrs	%[newcpsr], cpsr	\n\t"
-		: "=r" (ret0), "=r" (ret1), [newcpsr] "=r" (newcpsr)
-		: "0" (rr0), "r" (rr1), "r" (rr2), "r" (rr3),
-		  [oldcpsr] "r" (oldcpsr), [fn] "r" (fn)
-		: "lr", "cc"
-	);
-	*cpsr = (oldcpsr & ~PSR_fs) | (newcpsr & PSR_fs);
-	fnr.r0 = ret0;
-	fnr.r1 = ret1;
-	return fnr.dr;
-}
-
 /*
  * To avoid the complications of mimicing single-stepping on a
  * processor without a Next-PC or a single-step mode, and to
@@ -449,450 +155,6 @@ static void __kprobes simulate_mov_ipsp(struct kprobe *p, struct pt_regs *regs)
 	regs->uregs[12] = regs->uregs[13];
 }
 
-static void __kprobes emulate_ldrd(struct kprobe *p, struct pt_regs *regs)
-{
-	insn_2arg_fn_t *i_fn = (insn_2arg_fn_t *)&p->ainsn.insn[0];
-	kprobe_opcode_t insn = p->opcode;
-	long ppc = (long)p->addr + 8;
-	int rd = (insn >> 12) & 0xf;
-	int rn = (insn >> 16) & 0xf;
-	int rm = insn & 0xf;  /* rm may be invalid, don't care. */
-	long rmv = (rm == 15) ? ppc : regs->uregs[rm];
-	long rnv = (rn == 15) ? ppc : regs->uregs[rn];
-
-	/* Not following the C calling convention here, so need asm(). */
-	__asm__ __volatile__ (
-		"ldr	r0, %[rn]	\n\t"
-		"ldr	r1, %[rm]	\n\t"
-		"msr	cpsr_fs, %[cpsr]\n\t"
-		"mov	lr, pc		\n\t"
-		"mov	pc, %[i_fn]	\n\t"
-		"str	r0, %[rn]	\n\t"	/* in case of writeback */
-		"str	r2, %[rd0]	\n\t"
-		"str	r3, %[rd1]	\n\t"
-		: [rn]  "+m" (rnv),
-		  [rd0] "=m" (regs->uregs[rd]),
-		  [rd1] "=m" (regs->uregs[rd+1])
-		: [rm]   "m" (rmv),
-		  [cpsr] "r" (regs->ARM_cpsr),
-		  [i_fn] "r" (i_fn)
-		: "r0", "r1", "r2", "r3", "lr", "cc"
-	);
-	if (is_writeback(insn))
-		regs->uregs[rn] = rnv;
-}
-
-static void __kprobes emulate_strd(struct kprobe *p, struct pt_regs *regs)
-{
-	insn_4arg_fn_t *i_fn = (insn_4arg_fn_t *)&p->ainsn.insn[0];
-	kprobe_opcode_t insn = p->opcode;
-	long ppc = (long)p->addr + 8;
-	int rd = (insn >> 12) & 0xf;
-	int rn = (insn >> 16) & 0xf;
-	int rm  = insn & 0xf;
-	long rnv = (rn == 15) ? ppc : regs->uregs[rn];
-	/* rm/rmv may be invalid, don't care. */
-	long rmv = (rm == 15) ? ppc : regs->uregs[rm];
-	long rnv_wb;
-
-	rnv_wb = insnslot_4arg_rflags(rnv, rmv, regs->uregs[rd],
-					       regs->uregs[rd+1],
-					       regs->ARM_cpsr, i_fn);
-	if (is_writeback(insn))
-		regs->uregs[rn] = rnv_wb;
-}
-
-static void __kprobes emulate_ldr_old(struct kprobe *p, struct pt_regs *regs)
-{
-	insn_llret_3arg_fn_t *i_fn = (insn_llret_3arg_fn_t *)&p->ainsn.insn[0];
-	kprobe_opcode_t insn = p->opcode;
-	long ppc = (long)p->addr + 8;
-	union reg_pair fnr;
-	int rd = (insn >> 12) & 0xf;
-	int rn = (insn >> 16) & 0xf;
-	int rm = insn & 0xf;
-	long rdv;
-	long rnv = (rn == 15) ? ppc : regs->uregs[rn];
-	long rmv = (rm == 15) ? ppc : regs->uregs[rm];
-	long cpsr = regs->ARM_cpsr;
-
-	fnr.dr = insnslot_llret_3arg_rflags(rnv, 0, rmv, cpsr, i_fn);
-	if (rn != 15)
-		regs->uregs[rn] = fnr.r0;  /* Save Rn in case of writeback. */
-	rdv = fnr.r1;
-
-	if (rd == 15) {
-#if __LINUX_ARM_ARCH__ >= 5
-		cpsr &= ~PSR_T_BIT;
-		if (rdv & 0x1)
-			cpsr |= PSR_T_BIT;
-		regs->ARM_cpsr = cpsr;
-		rdv &= ~0x1;
-#else
-		rdv &= ~0x2;
-#endif
-	}
-	regs->uregs[rd] = rdv;
-}
-
-static void __kprobes emulate_str_old(struct kprobe *p, struct pt_regs *regs)
-{
-	insn_3arg_fn_t *i_fn = (insn_3arg_fn_t *)&p->ainsn.insn[0];
-	kprobe_opcode_t insn = p->opcode;
-	long iaddr = (long)p->addr;
-	int rd = (insn >> 12) & 0xf;
-	int rn = (insn >> 16) & 0xf;
-	int rm = insn & 0xf;
-	long rdv = (rd == 15) ? iaddr + str_pc_offset : regs->uregs[rd];
-	long rnv = (rn == 15) ? iaddr +  8 : regs->uregs[rn];
-	long rmv = regs->uregs[rm];  /* rm/rmv may be invalid, don't care. */
-	long rnv_wb;
-
-	rnv_wb = insnslot_3arg_rflags(rnv, rdv, rmv, regs->ARM_cpsr, i_fn);
-	if (rn != 15)
-		regs->uregs[rn] = rnv_wb;  /* Save Rn in case of writeback. */
-}
-
-static void __kprobes emulate_sat(struct kprobe *p, struct pt_regs *regs)
-{
-	insn_1arg_fn_t *i_fn = (insn_1arg_fn_t *)&p->ainsn.insn[0];
-	kprobe_opcode_t insn = p->opcode;
-	int rd = (insn >> 12) & 0xf;
-	int rm = insn & 0xf;
-	long rmv = regs->uregs[rm];
-
-	/* Writes Q flag */
-	regs->uregs[rd] = insnslot_1arg_rwflags(rmv, &regs->ARM_cpsr, i_fn);
-}
-
-static void __kprobes emulate_sel(struct kprobe *p, struct pt_regs *regs)
-{
-	insn_2arg_fn_t *i_fn = (insn_2arg_fn_t *)&p->ainsn.insn[0];
-	kprobe_opcode_t insn = p->opcode;
-	int rd = (insn >> 12) & 0xf;
-	int rn = (insn >> 16) & 0xf;
-	int rm = insn & 0xf;
-	long rnv = regs->uregs[rn];
-	long rmv = regs->uregs[rm];
-
-	/* Reads GE bits */
-	regs->uregs[rd] = insnslot_2arg_rflags(rnv, rmv, regs->ARM_cpsr, i_fn);
-}
-
-static void __kprobes emulate_none(struct kprobe *p, struct pt_regs *regs)
-{
-	insn_0arg_fn_t *i_fn = (insn_0arg_fn_t *)&p->ainsn.insn[0];
-
-	insnslot_0arg_rflags(regs->ARM_cpsr, i_fn);
-}
-
-static void __kprobes emulate_nop(struct kprobe *p, struct pt_regs *regs)
-{
-}
-
-static void __kprobes
-emulate_rd12_modify(struct kprobe *p, struct pt_regs *regs)
-{
-	insn_1arg_fn_t *i_fn = (insn_1arg_fn_t *)&p->ainsn.insn[0];
-	kprobe_opcode_t insn = p->opcode;
-	int rd = (insn >> 12) & 0xf;
-	long rdv = regs->uregs[rd];
-
-	regs->uregs[rd] = insnslot_1arg_rflags(rdv, regs->ARM_cpsr, i_fn);
-}
-
-static void __kprobes
-emulate_rd12rn0_modify(struct kprobe *p, struct pt_regs *regs)
-{
-	insn_2arg_fn_t *i_fn = (insn_2arg_fn_t *)&p->ainsn.insn[0];
-	kprobe_opcode_t insn = p->opcode;
-	int rd = (insn >> 12) & 0xf;
-	int rn = insn & 0xf;
-	long rdv = regs->uregs[rd];
-	long rnv = regs->uregs[rn];
-
-	regs->uregs[rd] = insnslot_2arg_rflags(rdv, rnv, regs->ARM_cpsr, i_fn);
-}
-
-static void __kprobes emulate_rd12rm0(struct kprobe *p, struct pt_regs *regs)
-{
-	insn_1arg_fn_t *i_fn = (insn_1arg_fn_t *)&p->ainsn.insn[0];
-	kprobe_opcode_t insn = p->opcode;
-	int rd = (insn >> 12) & 0xf;
-	int rm = insn & 0xf;
-	long rmv = regs->uregs[rm];
-
-	regs->uregs[rd] = insnslot_1arg_rflags(rmv, regs->ARM_cpsr, i_fn);
-}
-
-static void __kprobes
-emulate_rd12rn16rm0_rwflags(struct kprobe *p, struct pt_regs *regs)
-{
-	insn_2arg_fn_t *i_fn = (insn_2arg_fn_t *)&p->ainsn.insn[0];
-	kprobe_opcode_t insn = p->opcode;
-	int rd = (insn >> 12) & 0xf;
-	int rn = (insn >> 16) & 0xf;
-	int rm = insn & 0xf;
-	long rnv = regs->uregs[rn];
-	long rmv = regs->uregs[rm];
-
-	regs->uregs[rd] =
-		insnslot_2arg_rwflags(rnv, rmv, &regs->ARM_cpsr, i_fn);
-}
-
-static void __kprobes
-emulate_rd16rn12rs8rm0_rwflags(struct kprobe *p, struct pt_regs *regs)
-{
-	insn_3arg_fn_t *i_fn = (insn_3arg_fn_t *)&p->ainsn.insn[0];
-	kprobe_opcode_t insn = p->opcode;
-	int rd = (insn >> 16) & 0xf;
-	int rn = (insn >> 12) & 0xf;
-	int rs = (insn >> 8) & 0xf;
-	int rm = insn & 0xf;
-	long rnv = regs->uregs[rn];
-	long rsv = regs->uregs[rs];
-	long rmv = regs->uregs[rm];
-
-	regs->uregs[rd] =
-		insnslot_3arg_rwflags(rnv, rsv, rmv, &regs->ARM_cpsr, i_fn);
-}
-
-static void __kprobes
-emulate_rd16rs8rm0_rwflags(struct kprobe *p, struct pt_regs *regs)
-{
-	insn_2arg_fn_t *i_fn = (insn_2arg_fn_t *)&p->ainsn.insn[0];
-	kprobe_opcode_t insn = p->opcode;
-	int rd = (insn >> 16) & 0xf;
-	int rs = (insn >> 8) & 0xf;
-	int rm = insn & 0xf;
-	long rsv = regs->uregs[rs];
-	long rmv = regs->uregs[rm];
-
-	regs->uregs[rd] =
-		insnslot_2arg_rwflags(rsv, rmv, &regs->ARM_cpsr, i_fn);
-}
-
-static void __kprobes
-emulate_rdhi16rdlo12rs8rm0_rwflags(struct kprobe *p, struct pt_regs *regs)
-{
-	insn_llret_4arg_fn_t *i_fn = (insn_llret_4arg_fn_t *)&p->ainsn.insn[0];
-	kprobe_opcode_t insn = p->opcode;
-	union reg_pair fnr;
-	int rdhi = (insn >> 16) & 0xf;
-	int rdlo = (insn >> 12) & 0xf;
-	int rs   = (insn >> 8) & 0xf;
-	int rm   = insn & 0xf;
-	long rsv = regs->uregs[rs];
-	long rmv = regs->uregs[rm];
-
-	fnr.dr = insnslot_llret_4arg_rwflags(regs->uregs[rdhi],
-					     regs->uregs[rdlo], rsv, rmv,
-					     &regs->ARM_cpsr, i_fn);
-	regs->uregs[rdhi] = fnr.r0;
-	regs->uregs[rdlo] = fnr.r1;
-}
-
-static void __kprobes
-emulate_alu_imm_rflags(struct kprobe *p, struct pt_regs *regs)
-{
-	insn_1arg_fn_t *i_fn = (insn_1arg_fn_t *)&p->ainsn.insn[0];
-	kprobe_opcode_t insn = p->opcode;
-	int rd = (insn >> 12) & 0xf;
-	int rn = (insn >> 16) & 0xf;
-	long rnv = (rn == 15) ? (long)p->addr + 8 : regs->uregs[rn];
-
-	regs->uregs[rd] = insnslot_1arg_rflags(rnv, regs->ARM_cpsr, i_fn);
-}
-
-static void __kprobes
-emulate_alu_imm_rwflags(struct kprobe *p, struct pt_regs *regs)
-{
-	insn_1arg_fn_t *i_fn = (insn_1arg_fn_t *)&p->ainsn.insn[0];
-	kprobe_opcode_t insn = p->opcode;
-	int rd = (insn >> 12) & 0xf;
-	int rn = (insn >> 16) & 0xf;
-	long rnv = (rn == 15) ? (long)p->addr + 8 : regs->uregs[rn];
-
-	regs->uregs[rd] = insnslot_1arg_rwflags(rnv, &regs->ARM_cpsr, i_fn);
-}
-
-static void __kprobes
-emulate_alu_tests_imm(struct kprobe *p, struct pt_regs *regs)
-{
-	insn_1arg_fn_t *i_fn = (insn_1arg_fn_t *)&p->ainsn.insn[0];
-	kprobe_opcode_t insn = p->opcode;
-	int rn = (insn >> 16) & 0xf;
-	long rnv = (rn == 15) ? (long)p->addr + 8 : regs->uregs[rn];
-
-	insnslot_1arg_rwflags(rnv, &regs->ARM_cpsr, i_fn);
-}
-
-static void __kprobes
-emulate_alu_rflags(struct kprobe *p, struct pt_regs *regs)
-{
-	insn_3arg_fn_t *i_fn = (insn_3arg_fn_t *)&p->ainsn.insn[0];
-	kprobe_opcode_t insn = p->opcode;
-	long ppc = (long)p->addr + 8;
-	int rd = (insn >> 12) & 0xf;
-	int rn = (insn >> 16) & 0xf;	/* rn/rnv/rs/rsv may be */
-	int rs = (insn >> 8) & 0xf;	/* invalid, don't care. */
-	int rm = insn & 0xf;
-	long rnv = (rn == 15) ? ppc : regs->uregs[rn];
-	long rmv = (rm == 15) ? ppc : regs->uregs[rm];
-	long rsv = regs->uregs[rs];
-
-	regs->uregs[rd] =
-		insnslot_3arg_rflags(rnv, rmv, rsv, regs->ARM_cpsr, i_fn);
-}
-
-static void __kprobes
-emulate_alu_rwflags(struct kprobe *p, struct pt_regs *regs)
-{
-	insn_3arg_fn_t *i_fn = (insn_3arg_fn_t *)&p->ainsn.insn[0];
-	kprobe_opcode_t insn = p->opcode;
-	long ppc = (long)p->addr + 8;
-	int rd = (insn >> 12) & 0xf;
-	int rn = (insn >> 16) & 0xf;	/* rn/rnv/rs/rsv may be */
-	int rs = (insn >> 8) & 0xf;	/* invalid, don't care. */
-	int rm = insn & 0xf;
-	long rnv = (rn == 15) ? ppc : regs->uregs[rn];
-	long rmv = (rm == 15) ? ppc : regs->uregs[rm];
-	long rsv = regs->uregs[rs];
-
-	regs->uregs[rd] =
-		insnslot_3arg_rwflags(rnv, rmv, rsv, &regs->ARM_cpsr, i_fn);
-}
-
-static void __kprobes
-emulate_alu_tests(struct kprobe *p, struct pt_regs *regs)
-{
-	insn_3arg_fn_t *i_fn = (insn_3arg_fn_t *)&p->ainsn.insn[0];
-	kprobe_opcode_t insn = p->opcode;
-	long ppc = (long)p->addr + 8;
-	int rn = (insn >> 16) & 0xf;
-	int rs = (insn >> 8) & 0xf;	/* rs/rsv may be invalid, don't care. */
-	int rm = insn & 0xf;
-	long rnv = (rn == 15) ? ppc : regs->uregs[rn];
-	long rmv = (rm == 15) ? ppc : regs->uregs[rm];
-	long rsv = regs->uregs[rs];
-
-	insnslot_3arg_rwflags(rnv, rmv, rsv, &regs->ARM_cpsr, i_fn);
-}
-
-static enum kprobe_insn __kprobes
-prep_emulate_ldr_str(kprobe_opcode_t insn, struct arch_specific_insn *asi)
-{
-	int not_imm = (insn & (1 << 26)) ? (insn & (1 << 25))
-					 : (~insn & (1 << 22));
-
-	if (is_writeback(insn) && is_r15(insn, 16))
-		return INSN_REJECTED;	/* Writeback to PC */
-
-	insn &= 0xfff00fff;
-	insn |= 0x00001000;	/* Rn = r0, Rd = r1 */
-	if (not_imm) {
-		insn &= ~0xf;
-		insn |= 2;	/* Rm = r2 */
-	}
-	asi->insn[0] = insn;
-	asi->insn_handler = (insn & (1 << 20)) ? emulate_ldr_old : emulate_str_old;
-	return INSN_GOOD;
-}
-
-static enum kprobe_insn __kprobes
-prep_emulate_rd12_modify(kprobe_opcode_t insn, struct arch_specific_insn *asi)
-{
-	if (is_r15(insn, 12))
-		return INSN_REJECTED;	/* Rd is PC */
-
-	insn &= 0xffff0fff;	/* Rd = r0 */
-	asi->insn[0] = insn;
-	asi->insn_handler = emulate_rd12_modify;
-	return INSN_GOOD;
-}
-
-static enum kprobe_insn __kprobes
-prep_emulate_rd12rn0_modify(kprobe_opcode_t insn,
-			    struct arch_specific_insn *asi)
-{
-	if (is_r15(insn, 12))
-		return INSN_REJECTED;	/* Rd is PC */
-
-	insn &= 0xffff0ff0;	/* Rd = r0 */
-	insn |= 0x00000001;	/* Rn = r1 */
-	asi->insn[0] = insn;
-	asi->insn_handler = emulate_rd12rn0_modify;
-	return INSN_GOOD;
-}
-
-static enum kprobe_insn __kprobes
-prep_emulate_rd12rm0(kprobe_opcode_t insn, struct arch_specific_insn *asi)
-{
-	if (is_r15(insn, 12))
-		return INSN_REJECTED;	/* Rd is PC */
-
-	insn &= 0xffff0ff0;	/* Rd = r0, Rm = r0 */
-	asi->insn[0] = insn;
-	asi->insn_handler = emulate_rd12rm0;
-	return INSN_GOOD;
-}
-
-static enum kprobe_insn __kprobes
-prep_emulate_rd12rn16rm0_wflags(kprobe_opcode_t insn,
-				struct arch_specific_insn *asi)
-{
-	if (is_r15(insn, 12))
-		return INSN_REJECTED;	/* Rd is PC */
-
-	insn &= 0xfff00ff0;	/* Rd = r0, Rn = r0 */
-	insn |= 0x00000001;	/* Rm = r1 */
-	asi->insn[0] = insn;
-	asi->insn_handler = emulate_rd12rn16rm0_rwflags;
-	return INSN_GOOD;
-}
-
-static enum kprobe_insn __kprobes
-prep_emulate_rd16rs8rm0_wflags(kprobe_opcode_t insn,
-			       struct arch_specific_insn *asi)
-{
-	if (is_r15(insn, 16))
-		return INSN_REJECTED;	/* Rd is PC */
-
-	insn &= 0xfff0f0f0;	/* Rd = r0, Rs = r0 */
-	insn |= 0x00000001;	/* Rm = r1          */
-	asi->insn[0] = insn;
-	asi->insn_handler = emulate_rd16rs8rm0_rwflags;
-	return INSN_GOOD;
-}
-
-static enum kprobe_insn __kprobes
-prep_emulate_rd16rn12rs8rm0_wflags(kprobe_opcode_t insn,
-				   struct arch_specific_insn *asi)
-{
-	if (is_r15(insn, 16))
-		return INSN_REJECTED;	/* Rd is PC */
-
-	insn &= 0xfff000f0;	/* Rd = r0, Rn = r0 */
-	insn |= 0x00000102;	/* Rs = r1, Rm = r2 */
-	asi->insn[0] = insn;
-	asi->insn_handler = emulate_rd16rn12rs8rm0_rwflags;
-	return INSN_GOOD;
-}
-
-static enum kprobe_insn __kprobes
-prep_emulate_rdhi16rdlo12rs8rm0_wflags(kprobe_opcode_t insn,
-				       struct arch_specific_insn *asi)
-{
-	if (is_r15(insn, 16) || is_r15(insn, 12))
-		return INSN_REJECTED;	/* RdHi or RdLo is PC */
-
-	insn &= 0xfff000f0;	/* RdHi = r0, RdLo = r1 */
-	insn |= 0x00001203;	/* Rs = r2, Rm = r3 */
-	asi->insn[0] = insn;
-	asi->insn_handler = emulate_rdhi16rdlo12rs8rm0_rwflags;
-	return INSN_GOOD;
-}
-
 static void __kprobes
 emulate_ldrdstrd(struct kprobe *p, struct pt_regs *regs)
 {
-- 
1.7.2.5

^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH 24/24] ARM: kprobes: Remove now unused code
  2011-07-13  9:06 ` [PATCH 24/24] ARM: kprobes: Remove now unused code Tixy
@ 2011-07-13 16:04   ` Nicolas Pitre
  0 siblings, 0 replies; 26+ messages in thread
From: Nicolas Pitre @ 2011-07-13 16:04 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, 13 Jul 2011, Tixy wrote:

> From: Jon Medhurst <tixy@yxit.co.uk>
> 
> Signed-off-by: Jon Medhurst <tixy@yxit.co.uk>
> ---
>  arch/arm/kernel/kprobes-arm.c |  738 -----------------------------------------
>  1 files changed, 0 insertions(+), 738 deletions(-)

I certainly like this one.

Acked-by: Nicolas Pitre <nicolas.pitre@linaro.org>

This is also valid for the whole series.  Again, this is excellent work.



> 
> diff --git a/arch/arm/kernel/kprobes-arm.c b/arch/arm/kernel/kprobes-arm.c
> index 8a58c99..79203ee 100644
> --- a/arch/arm/kernel/kprobes-arm.c
> +++ b/arch/arm/kernel/kprobes-arm.c
> @@ -74,300 +74,6 @@
>  			"mov	pc, "reg"	\n\t"
>  #endif
>  
> -#define is_r15(insn, bitpos) (((insn) & (0xf << bitpos)) == (0xf << bitpos))
> -
> -#define PSR_fs	(PSR_f|PSR_s)
> -
> -#define KPROBE_RETURN_INSTRUCTION	0xe1a0f00e	/* mov pc, lr */
> -
> -typedef long (insn_0arg_fn_t)(void);
> -typedef long (insn_1arg_fn_t)(long);
> -typedef long (insn_2arg_fn_t)(long, long);
> -typedef long (insn_3arg_fn_t)(long, long, long);
> -typedef long (insn_4arg_fn_t)(long, long, long, long);
> -typedef long long (insn_llret_0arg_fn_t)(void);
> -typedef long long (insn_llret_3arg_fn_t)(long, long, long);
> -typedef long long (insn_llret_4arg_fn_t)(long, long, long, long);
> -
> -union reg_pair {
> -	long long	dr;
> -#ifdef __LITTLE_ENDIAN
> -	struct { long	r0, r1; };
> -#else
> -	struct { long	r1, r0; };
> -#endif
> -};
> -
> -/*
> - * The insnslot_?arg_r[w]flags() functions below are to keep the
> - * msr -> *fn -> mrs instruction sequences indivisible so that
> - * the state of the CPSR flags aren't inadvertently modified
> - * just before or just after the call.
> - */
> -
> -static inline long __kprobes
> -insnslot_0arg_rflags(long cpsr, insn_0arg_fn_t *fn)
> -{
> -	register long ret asm("r0");
> -
> -	__asm__ __volatile__ (
> -		"msr	cpsr_fs, %[cpsr]	\n\t"
> -		"mov	lr, pc			\n\t"
> -		"mov	pc, %[fn]		\n\t"
> -		: "=r" (ret)
> -		: [cpsr] "r" (cpsr), [fn] "r" (fn)
> -		: "lr", "cc"
> -	);
> -	return ret;
> -}
> -
> -static inline long long __kprobes
> -insnslot_llret_0arg_rflags(long cpsr, insn_llret_0arg_fn_t *fn)
> -{
> -	register long ret0 asm("r0");
> -	register long ret1 asm("r1");
> -	union reg_pair fnr;
> -
> -	__asm__ __volatile__ (
> -		"msr	cpsr_fs, %[cpsr]	\n\t"
> -		"mov	lr, pc			\n\t"
> -		"mov	pc, %[fn]		\n\t"
> -		: "=r" (ret0), "=r" (ret1)
> -		: [cpsr] "r" (cpsr), [fn] "r" (fn)
> -		: "lr", "cc"
> -	);
> -	fnr.r0 = ret0;
> -	fnr.r1 = ret1;
> -	return fnr.dr;
> -}
> -
> -static inline long __kprobes
> -insnslot_1arg_rflags(long r0, long cpsr, insn_1arg_fn_t *fn)
> -{
> -	register long rr0 asm("r0") = r0;
> -	register long ret asm("r0");
> -
> -	__asm__ __volatile__ (
> -		"msr	cpsr_fs, %[cpsr]	\n\t"
> -		"mov	lr, pc			\n\t"
> -		"mov	pc, %[fn]		\n\t"
> -		: "=r" (ret)
> -		: "0" (rr0), [cpsr] "r" (cpsr), [fn] "r" (fn)
> -		: "lr", "cc"
> -	);
> -	return ret;
> -}
> -
> -static inline long __kprobes
> -insnslot_2arg_rflags(long r0, long r1, long cpsr, insn_2arg_fn_t *fn)
> -{
> -	register long rr0 asm("r0") = r0;
> -	register long rr1 asm("r1") = r1;
> -	register long ret asm("r0");
> -
> -	__asm__ __volatile__ (
> -		"msr	cpsr_fs, %[cpsr]	\n\t"
> -		"mov	lr, pc			\n\t"
> -		"mov	pc, %[fn]		\n\t"
> -		: "=r" (ret)
> -		: "0" (rr0), "r" (rr1),
> -		  [cpsr] "r" (cpsr), [fn] "r" (fn)
> -		: "lr", "cc"
> -	);
> -	return ret;
> -}
> -
> -static inline long __kprobes
> -insnslot_3arg_rflags(long r0, long r1, long r2, long cpsr, insn_3arg_fn_t *fn)
> -{
> -	register long rr0 asm("r0") = r0;
> -	register long rr1 asm("r1") = r1;
> -	register long rr2 asm("r2") = r2;
> -	register long ret asm("r0");
> -
> -	__asm__ __volatile__ (
> -		"msr	cpsr_fs, %[cpsr]	\n\t"
> -		"mov	lr, pc			\n\t"
> -		"mov	pc, %[fn]		\n\t"
> -		: "=r" (ret)
> -		: "0" (rr0), "r" (rr1), "r" (rr2),
> -		  [cpsr] "r" (cpsr), [fn] "r" (fn)
> -		: "lr", "cc"
> -	);
> -	return ret;
> -}
> -
> -static inline long long __kprobes
> -insnslot_llret_3arg_rflags(long r0, long r1, long r2, long cpsr,
> -			   insn_llret_3arg_fn_t *fn)
> -{
> -	register long rr0 asm("r0") = r0;
> -	register long rr1 asm("r1") = r1;
> -	register long rr2 asm("r2") = r2;
> -	register long ret0 asm("r0");
> -	register long ret1 asm("r1");
> -	union reg_pair fnr;
> -
> -	__asm__ __volatile__ (
> -		"msr	cpsr_fs, %[cpsr]	\n\t"
> -		"mov	lr, pc			\n\t"
> -		"mov	pc, %[fn]		\n\t"
> -		: "=r" (ret0), "=r" (ret1)
> -		: "0" (rr0), "r" (rr1), "r" (rr2),
> -		  [cpsr] "r" (cpsr), [fn] "r" (fn)
> -		: "lr", "cc"
> -	);
> -	fnr.r0 = ret0;
> -	fnr.r1 = ret1;
> -	return fnr.dr;
> -}
> -
> -static inline long __kprobes
> -insnslot_4arg_rflags(long r0, long r1, long r2, long r3, long cpsr,
> -		     insn_4arg_fn_t *fn)
> -{
> -	register long rr0 asm("r0") = r0;
> -	register long rr1 asm("r1") = r1;
> -	register long rr2 asm("r2") = r2;
> -	register long rr3 asm("r3") = r3;
> -	register long ret asm("r0");
> -
> -	__asm__ __volatile__ (
> -		"msr	cpsr_fs, %[cpsr]	\n\t"
> -		"mov	lr, pc			\n\t"
> -		"mov	pc, %[fn]		\n\t"
> -		: "=r" (ret)
> -		: "0" (rr0), "r" (rr1), "r" (rr2), "r" (rr3),
> -		  [cpsr] "r" (cpsr), [fn] "r" (fn)
> -		: "lr", "cc"
> -	);
> -	return ret;
> -}
> -
> -static inline long __kprobes
> -insnslot_1arg_rwflags(long r0, long *cpsr, insn_1arg_fn_t *fn)
> -{
> -	register long rr0 asm("r0") = r0;
> -	register long ret asm("r0");
> -	long oldcpsr = *cpsr;
> -	long newcpsr;
> -
> -	__asm__ __volatile__ (
> -		"msr	cpsr_fs, %[oldcpsr]	\n\t"
> -		"mov	lr, pc			\n\t"
> -		"mov	pc, %[fn]		\n\t"
> -		"mrs	%[newcpsr], cpsr	\n\t"
> -		: "=r" (ret), [newcpsr] "=r" (newcpsr)
> -		: "0" (rr0), [oldcpsr] "r" (oldcpsr), [fn] "r" (fn)
> -		: "lr", "cc"
> -	);
> -	*cpsr = (oldcpsr & ~PSR_fs) | (newcpsr & PSR_fs);
> -	return ret;
> -}
> -
> -static inline long __kprobes
> -insnslot_2arg_rwflags(long r0, long r1, long *cpsr, insn_2arg_fn_t *fn)
> -{
> -	register long rr0 asm("r0") = r0;
> -	register long rr1 asm("r1") = r1;
> -	register long ret asm("r0");
> -	long oldcpsr = *cpsr;
> -	long newcpsr;
> -
> -	__asm__ __volatile__ (
> -		"msr	cpsr_fs, %[oldcpsr]	\n\t"
> -		"mov	lr, pc			\n\t"
> -		"mov	pc, %[fn]		\n\t"
> -		"mrs	%[newcpsr], cpsr	\n\t"
> -		: "=r" (ret), [newcpsr] "=r" (newcpsr)
> -		: "0" (rr0), "r" (rr1), [oldcpsr] "r" (oldcpsr), [fn] "r" (fn)
> -		: "lr", "cc"
> -	);
> -	*cpsr = (oldcpsr & ~PSR_fs) | (newcpsr & PSR_fs);
> -	return ret;
> -}
> -
> -static inline long __kprobes
> -insnslot_3arg_rwflags(long r0, long r1, long r2, long *cpsr,
> -		      insn_3arg_fn_t *fn)
> -{
> -	register long rr0 asm("r0") = r0;
> -	register long rr1 asm("r1") = r1;
> -	register long rr2 asm("r2") = r2;
> -	register long ret asm("r0");
> -	long oldcpsr = *cpsr;
> -	long newcpsr;
> -
> -	__asm__ __volatile__ (
> -		"msr	cpsr_fs, %[oldcpsr]	\n\t"
> -		"mov	lr, pc			\n\t"
> -		"mov	pc, %[fn]		\n\t"
> -		"mrs	%[newcpsr], cpsr	\n\t"
> -		: "=r" (ret), [newcpsr] "=r" (newcpsr)
> -		: "0" (rr0), "r" (rr1), "r" (rr2),
> -		  [oldcpsr] "r" (oldcpsr), [fn] "r" (fn)
> -		: "lr", "cc"
> -	);
> -	*cpsr = (oldcpsr & ~PSR_fs) | (newcpsr & PSR_fs);
> -	return ret;
> -}
> -
> -static inline long __kprobes
> -insnslot_4arg_rwflags(long r0, long r1, long r2, long r3, long *cpsr,
> -		      insn_4arg_fn_t *fn)
> -{
> -	register long rr0 asm("r0") = r0;
> -	register long rr1 asm("r1") = r1;
> -	register long rr2 asm("r2") = r2;
> -	register long rr3 asm("r3") = r3;
> -	register long ret asm("r0");
> -	long oldcpsr = *cpsr;
> -	long newcpsr;
> -
> -	__asm__ __volatile__ (
> -		"msr	cpsr_fs, %[oldcpsr]	\n\t"
> -		"mov	lr, pc			\n\t"
> -		"mov	pc, %[fn]		\n\t"
> -		"mrs	%[newcpsr], cpsr	\n\t"
> -		: "=r" (ret), [newcpsr] "=r" (newcpsr)
> -		: "0" (rr0), "r" (rr1), "r" (rr2), "r" (rr3),
> -		  [oldcpsr] "r" (oldcpsr), [fn] "r" (fn)
> -		: "lr", "cc"
> -	);
> -	*cpsr = (oldcpsr & ~PSR_fs) | (newcpsr & PSR_fs);
> -	return ret;
> -}
> -
> -static inline long long __kprobes
> -insnslot_llret_4arg_rwflags(long r0, long r1, long r2, long r3, long *cpsr,
> -			    insn_llret_4arg_fn_t *fn)
> -{
> -	register long rr0 asm("r0") = r0;
> -	register long rr1 asm("r1") = r1;
> -	register long rr2 asm("r2") = r2;
> -	register long rr3 asm("r3") = r3;
> -	register long ret0 asm("r0");
> -	register long ret1 asm("r1");
> -	long oldcpsr = *cpsr;
> -	long newcpsr;
> -	union reg_pair fnr;
> -
> -	__asm__ __volatile__ (
> -		"msr	cpsr_fs, %[oldcpsr]	\n\t"
> -		"mov	lr, pc			\n\t"
> -		"mov	pc, %[fn]		\n\t"
> -		"mrs	%[newcpsr], cpsr	\n\t"
> -		: "=r" (ret0), "=r" (ret1), [newcpsr] "=r" (newcpsr)
> -		: "0" (rr0), "r" (rr1), "r" (rr2), "r" (rr3),
> -		  [oldcpsr] "r" (oldcpsr), [fn] "r" (fn)
> -		: "lr", "cc"
> -	);
> -	*cpsr = (oldcpsr & ~PSR_fs) | (newcpsr & PSR_fs);
> -	fnr.r0 = ret0;
> -	fnr.r1 = ret1;
> -	return fnr.dr;
> -}
> -
>  /*
>   * To avoid the complications of mimicing single-stepping on a
>   * processor without a Next-PC or a single-step mode, and to
> @@ -449,450 +155,6 @@ static void __kprobes simulate_mov_ipsp(struct kprobe *p, struct pt_regs *regs)
>  	regs->uregs[12] = regs->uregs[13];
>  }
>  
> -static void __kprobes emulate_ldrd(struct kprobe *p, struct pt_regs *regs)
> -{
> -	insn_2arg_fn_t *i_fn = (insn_2arg_fn_t *)&p->ainsn.insn[0];
> -	kprobe_opcode_t insn = p->opcode;
> -	long ppc = (long)p->addr + 8;
> -	int rd = (insn >> 12) & 0xf;
> -	int rn = (insn >> 16) & 0xf;
> -	int rm = insn & 0xf;  /* rm may be invalid, don't care. */
> -	long rmv = (rm == 15) ? ppc : regs->uregs[rm];
> -	long rnv = (rn == 15) ? ppc : regs->uregs[rn];
> -
> -	/* Not following the C calling convention here, so need asm(). */
> -	__asm__ __volatile__ (
> -		"ldr	r0, %[rn]	\n\t"
> -		"ldr	r1, %[rm]	\n\t"
> -		"msr	cpsr_fs, %[cpsr]\n\t"
> -		"mov	lr, pc		\n\t"
> -		"mov	pc, %[i_fn]	\n\t"
> -		"str	r0, %[rn]	\n\t"	/* in case of writeback */
> -		"str	r2, %[rd0]	\n\t"
> -		"str	r3, %[rd1]	\n\t"
> -		: [rn]  "+m" (rnv),
> -		  [rd0] "=m" (regs->uregs[rd]),
> -		  [rd1] "=m" (regs->uregs[rd+1])
> -		: [rm]   "m" (rmv),
> -		  [cpsr] "r" (regs->ARM_cpsr),
> -		  [i_fn] "r" (i_fn)
> -		: "r0", "r1", "r2", "r3", "lr", "cc"
> -	);
> -	if (is_writeback(insn))
> -		regs->uregs[rn] = rnv;
> -}
> -
> -static void __kprobes emulate_strd(struct kprobe *p, struct pt_regs *regs)
> -{
> -	insn_4arg_fn_t *i_fn = (insn_4arg_fn_t *)&p->ainsn.insn[0];
> -	kprobe_opcode_t insn = p->opcode;
> -	long ppc = (long)p->addr + 8;
> -	int rd = (insn >> 12) & 0xf;
> -	int rn = (insn >> 16) & 0xf;
> -	int rm  = insn & 0xf;
> -	long rnv = (rn == 15) ? ppc : regs->uregs[rn];
> -	/* rm/rmv may be invalid, don't care. */
> -	long rmv = (rm == 15) ? ppc : regs->uregs[rm];
> -	long rnv_wb;
> -
> -	rnv_wb = insnslot_4arg_rflags(rnv, rmv, regs->uregs[rd],
> -					       regs->uregs[rd+1],
> -					       regs->ARM_cpsr, i_fn);
> -	if (is_writeback(insn))
> -		regs->uregs[rn] = rnv_wb;
> -}
> -
> -static void __kprobes emulate_ldr_old(struct kprobe *p, struct pt_regs *regs)
> -{
> -	insn_llret_3arg_fn_t *i_fn = (insn_llret_3arg_fn_t *)&p->ainsn.insn[0];
> -	kprobe_opcode_t insn = p->opcode;
> -	long ppc = (long)p->addr + 8;
> -	union reg_pair fnr;
> -	int rd = (insn >> 12) & 0xf;
> -	int rn = (insn >> 16) & 0xf;
> -	int rm = insn & 0xf;
> -	long rdv;
> -	long rnv = (rn == 15) ? ppc : regs->uregs[rn];
> -	long rmv = (rm == 15) ? ppc : regs->uregs[rm];
> -	long cpsr = regs->ARM_cpsr;
> -
> -	fnr.dr = insnslot_llret_3arg_rflags(rnv, 0, rmv, cpsr, i_fn);
> -	if (rn != 15)
> -		regs->uregs[rn] = fnr.r0;  /* Save Rn in case of writeback. */
> -	rdv = fnr.r1;
> -
> -	if (rd == 15) {
> -#if __LINUX_ARM_ARCH__ >= 5
> -		cpsr &= ~PSR_T_BIT;
> -		if (rdv & 0x1)
> -			cpsr |= PSR_T_BIT;
> -		regs->ARM_cpsr = cpsr;
> -		rdv &= ~0x1;
> -#else
> -		rdv &= ~0x2;
> -#endif
> -	}
> -	regs->uregs[rd] = rdv;
> -}
> -
> -static void __kprobes emulate_str_old(struct kprobe *p, struct pt_regs *regs)
> -{
> -	insn_3arg_fn_t *i_fn = (insn_3arg_fn_t *)&p->ainsn.insn[0];
> -	kprobe_opcode_t insn = p->opcode;
> -	long iaddr = (long)p->addr;
> -	int rd = (insn >> 12) & 0xf;
> -	int rn = (insn >> 16) & 0xf;
> -	int rm = insn & 0xf;
> -	long rdv = (rd == 15) ? iaddr + str_pc_offset : regs->uregs[rd];
> -	long rnv = (rn == 15) ? iaddr +  8 : regs->uregs[rn];
> -	long rmv = regs->uregs[rm];  /* rm/rmv may be invalid, don't care. */
> -	long rnv_wb;
> -
> -	rnv_wb = insnslot_3arg_rflags(rnv, rdv, rmv, regs->ARM_cpsr, i_fn);
> -	if (rn != 15)
> -		regs->uregs[rn] = rnv_wb;  /* Save Rn in case of writeback. */
> -}
> -
> -static void __kprobes emulate_sat(struct kprobe *p, struct pt_regs *regs)
> -{
> -	insn_1arg_fn_t *i_fn = (insn_1arg_fn_t *)&p->ainsn.insn[0];
> -	kprobe_opcode_t insn = p->opcode;
> -	int rd = (insn >> 12) & 0xf;
> -	int rm = insn & 0xf;
> -	long rmv = regs->uregs[rm];
> -
> -	/* Writes Q flag */
> -	regs->uregs[rd] = insnslot_1arg_rwflags(rmv, &regs->ARM_cpsr, i_fn);
> -}
> -
> -static void __kprobes emulate_sel(struct kprobe *p, struct pt_regs *regs)
> -{
> -	insn_2arg_fn_t *i_fn = (insn_2arg_fn_t *)&p->ainsn.insn[0];
> -	kprobe_opcode_t insn = p->opcode;
> -	int rd = (insn >> 12) & 0xf;
> -	int rn = (insn >> 16) & 0xf;
> -	int rm = insn & 0xf;
> -	long rnv = regs->uregs[rn];
> -	long rmv = regs->uregs[rm];
> -
> -	/* Reads GE bits */
> -	regs->uregs[rd] = insnslot_2arg_rflags(rnv, rmv, regs->ARM_cpsr, i_fn);
> -}
> -
> -static void __kprobes emulate_none(struct kprobe *p, struct pt_regs *regs)
> -{
> -	insn_0arg_fn_t *i_fn = (insn_0arg_fn_t *)&p->ainsn.insn[0];
> -
> -	insnslot_0arg_rflags(regs->ARM_cpsr, i_fn);
> -}
> -
> -static void __kprobes emulate_nop(struct kprobe *p, struct pt_regs *regs)
> -{
> -}
> -
> -static void __kprobes
> -emulate_rd12_modify(struct kprobe *p, struct pt_regs *regs)
> -{
> -	insn_1arg_fn_t *i_fn = (insn_1arg_fn_t *)&p->ainsn.insn[0];
> -	kprobe_opcode_t insn = p->opcode;
> -	int rd = (insn >> 12) & 0xf;
> -	long rdv = regs->uregs[rd];
> -
> -	regs->uregs[rd] = insnslot_1arg_rflags(rdv, regs->ARM_cpsr, i_fn);
> -}
> -
> -static void __kprobes
> -emulate_rd12rn0_modify(struct kprobe *p, struct pt_regs *regs)
> -{
> -	insn_2arg_fn_t *i_fn = (insn_2arg_fn_t *)&p->ainsn.insn[0];
> -	kprobe_opcode_t insn = p->opcode;
> -	int rd = (insn >> 12) & 0xf;
> -	int rn = insn & 0xf;
> -	long rdv = regs->uregs[rd];
> -	long rnv = regs->uregs[rn];
> -
> -	regs->uregs[rd] = insnslot_2arg_rflags(rdv, rnv, regs->ARM_cpsr, i_fn);
> -}
> -
> -static void __kprobes emulate_rd12rm0(struct kprobe *p, struct pt_regs *regs)
> -{
> -	insn_1arg_fn_t *i_fn = (insn_1arg_fn_t *)&p->ainsn.insn[0];
> -	kprobe_opcode_t insn = p->opcode;
> -	int rd = (insn >> 12) & 0xf;
> -	int rm = insn & 0xf;
> -	long rmv = regs->uregs[rm];
> -
> -	regs->uregs[rd] = insnslot_1arg_rflags(rmv, regs->ARM_cpsr, i_fn);
> -}
> -
> -static void __kprobes
> -emulate_rd12rn16rm0_rwflags(struct kprobe *p, struct pt_regs *regs)
> -{
> -	insn_2arg_fn_t *i_fn = (insn_2arg_fn_t *)&p->ainsn.insn[0];
> -	kprobe_opcode_t insn = p->opcode;
> -	int rd = (insn >> 12) & 0xf;
> -	int rn = (insn >> 16) & 0xf;
> -	int rm = insn & 0xf;
> -	long rnv = regs->uregs[rn];
> -	long rmv = regs->uregs[rm];
> -
> -	regs->uregs[rd] =
> -		insnslot_2arg_rwflags(rnv, rmv, &regs->ARM_cpsr, i_fn);
> -}
> -
> -static void __kprobes
> -emulate_rd16rn12rs8rm0_rwflags(struct kprobe *p, struct pt_regs *regs)
> -{
> -	insn_3arg_fn_t *i_fn = (insn_3arg_fn_t *)&p->ainsn.insn[0];
> -	kprobe_opcode_t insn = p->opcode;
> -	int rd = (insn >> 16) & 0xf;
> -	int rn = (insn >> 12) & 0xf;
> -	int rs = (insn >> 8) & 0xf;
> -	int rm = insn & 0xf;
> -	long rnv = regs->uregs[rn];
> -	long rsv = regs->uregs[rs];
> -	long rmv = regs->uregs[rm];
> -
> -	regs->uregs[rd] =
> -		insnslot_3arg_rwflags(rnv, rsv, rmv, &regs->ARM_cpsr, i_fn);
> -}
> -
> -static void __kprobes
> -emulate_rd16rs8rm0_rwflags(struct kprobe *p, struct pt_regs *regs)
> -{
> -	insn_2arg_fn_t *i_fn = (insn_2arg_fn_t *)&p->ainsn.insn[0];
> -	kprobe_opcode_t insn = p->opcode;
> -	int rd = (insn >> 16) & 0xf;
> -	int rs = (insn >> 8) & 0xf;
> -	int rm = insn & 0xf;
> -	long rsv = regs->uregs[rs];
> -	long rmv = regs->uregs[rm];
> -
> -	regs->uregs[rd] =
> -		insnslot_2arg_rwflags(rsv, rmv, &regs->ARM_cpsr, i_fn);
> -}
> -
> -static void __kprobes
> -emulate_rdhi16rdlo12rs8rm0_rwflags(struct kprobe *p, struct pt_regs *regs)
> -{
> -	insn_llret_4arg_fn_t *i_fn = (insn_llret_4arg_fn_t *)&p->ainsn.insn[0];
> -	kprobe_opcode_t insn = p->opcode;
> -	union reg_pair fnr;
> -	int rdhi = (insn >> 16) & 0xf;
> -	int rdlo = (insn >> 12) & 0xf;
> -	int rs   = (insn >> 8) & 0xf;
> -	int rm   = insn & 0xf;
> -	long rsv = regs->uregs[rs];
> -	long rmv = regs->uregs[rm];
> -
> -	fnr.dr = insnslot_llret_4arg_rwflags(regs->uregs[rdhi],
> -					     regs->uregs[rdlo], rsv, rmv,
> -					     &regs->ARM_cpsr, i_fn);
> -	regs->uregs[rdhi] = fnr.r0;
> -	regs->uregs[rdlo] = fnr.r1;
> -}
> -
> -static void __kprobes
> -emulate_alu_imm_rflags(struct kprobe *p, struct pt_regs *regs)
> -{
> -	insn_1arg_fn_t *i_fn = (insn_1arg_fn_t *)&p->ainsn.insn[0];
> -	kprobe_opcode_t insn = p->opcode;
> -	int rd = (insn >> 12) & 0xf;
> -	int rn = (insn >> 16) & 0xf;
> -	long rnv = (rn == 15) ? (long)p->addr + 8 : regs->uregs[rn];
> -
> -	regs->uregs[rd] = insnslot_1arg_rflags(rnv, regs->ARM_cpsr, i_fn);
> -}
> -
> -static void __kprobes
> -emulate_alu_imm_rwflags(struct kprobe *p, struct pt_regs *regs)
> -{
> -	insn_1arg_fn_t *i_fn = (insn_1arg_fn_t *)&p->ainsn.insn[0];
> -	kprobe_opcode_t insn = p->opcode;
> -	int rd = (insn >> 12) & 0xf;
> -	int rn = (insn >> 16) & 0xf;
> -	long rnv = (rn == 15) ? (long)p->addr + 8 : regs->uregs[rn];
> -
> -	regs->uregs[rd] = insnslot_1arg_rwflags(rnv, &regs->ARM_cpsr, i_fn);
> -}
> -
> -static void __kprobes
> -emulate_alu_tests_imm(struct kprobe *p, struct pt_regs *regs)
> -{
> -	insn_1arg_fn_t *i_fn = (insn_1arg_fn_t *)&p->ainsn.insn[0];
> -	kprobe_opcode_t insn = p->opcode;
> -	int rn = (insn >> 16) & 0xf;
> -	long rnv = (rn == 15) ? (long)p->addr + 8 : regs->uregs[rn];
> -
> -	insnslot_1arg_rwflags(rnv, &regs->ARM_cpsr, i_fn);
> -}
> -
> -static void __kprobes
> -emulate_alu_rflags(struct kprobe *p, struct pt_regs *regs)
> -{
> -	insn_3arg_fn_t *i_fn = (insn_3arg_fn_t *)&p->ainsn.insn[0];
> -	kprobe_opcode_t insn = p->opcode;
> -	long ppc = (long)p->addr + 8;
> -	int rd = (insn >> 12) & 0xf;
> -	int rn = (insn >> 16) & 0xf;	/* rn/rnv/rs/rsv may be */
> -	int rs = (insn >> 8) & 0xf;	/* invalid, don't care. */
> -	int rm = insn & 0xf;
> -	long rnv = (rn == 15) ? ppc : regs->uregs[rn];
> -	long rmv = (rm == 15) ? ppc : regs->uregs[rm];
> -	long rsv = regs->uregs[rs];
> -
> -	regs->uregs[rd] =
> -		insnslot_3arg_rflags(rnv, rmv, rsv, regs->ARM_cpsr, i_fn);
> -}
> -
> -static void __kprobes
> -emulate_alu_rwflags(struct kprobe *p, struct pt_regs *regs)
> -{
> -	insn_3arg_fn_t *i_fn = (insn_3arg_fn_t *)&p->ainsn.insn[0];
> -	kprobe_opcode_t insn = p->opcode;
> -	long ppc = (long)p->addr + 8;
> -	int rd = (insn >> 12) & 0xf;
> -	int rn = (insn >> 16) & 0xf;	/* rn/rnv/rs/rsv may be */
> -	int rs = (insn >> 8) & 0xf;	/* invalid, don't care. */
> -	int rm = insn & 0xf;
> -	long rnv = (rn == 15) ? ppc : regs->uregs[rn];
> -	long rmv = (rm == 15) ? ppc : regs->uregs[rm];
> -	long rsv = regs->uregs[rs];
> -
> -	regs->uregs[rd] =
> -		insnslot_3arg_rwflags(rnv, rmv, rsv, &regs->ARM_cpsr, i_fn);
> -}
> -
> -static void __kprobes
> -emulate_alu_tests(struct kprobe *p, struct pt_regs *regs)
> -{
> -	insn_3arg_fn_t *i_fn = (insn_3arg_fn_t *)&p->ainsn.insn[0];
> -	kprobe_opcode_t insn = p->opcode;
> -	long ppc = (long)p->addr + 8;
> -	int rn = (insn >> 16) & 0xf;
> -	int rs = (insn >> 8) & 0xf;	/* rs/rsv may be invalid, don't care. */
> -	int rm = insn & 0xf;
> -	long rnv = (rn == 15) ? ppc : regs->uregs[rn];
> -	long rmv = (rm == 15) ? ppc : regs->uregs[rm];
> -	long rsv = regs->uregs[rs];
> -
> -	insnslot_3arg_rwflags(rnv, rmv, rsv, &regs->ARM_cpsr, i_fn);
> -}
> -
> -static enum kprobe_insn __kprobes
> -prep_emulate_ldr_str(kprobe_opcode_t insn, struct arch_specific_insn *asi)
> -{
> -	int not_imm = (insn & (1 << 26)) ? (insn & (1 << 25))
> -					 : (~insn & (1 << 22));
> -
> -	if (is_writeback(insn) && is_r15(insn, 16))
> -		return INSN_REJECTED;	/* Writeback to PC */
> -
> -	insn &= 0xfff00fff;
> -	insn |= 0x00001000;	/* Rn = r0, Rd = r1 */
> -	if (not_imm) {
> -		insn &= ~0xf;
> -		insn |= 2;	/* Rm = r2 */
> -	}
> -	asi->insn[0] = insn;
> -	asi->insn_handler = (insn & (1 << 20)) ? emulate_ldr_old : emulate_str_old;
> -	return INSN_GOOD;
> -}
> -
> -static enum kprobe_insn __kprobes
> -prep_emulate_rd12_modify(kprobe_opcode_t insn, struct arch_specific_insn *asi)
> -{
> -	if (is_r15(insn, 12))
> -		return INSN_REJECTED;	/* Rd is PC */
> -
> -	insn &= 0xffff0fff;	/* Rd = r0 */
> -	asi->insn[0] = insn;
> -	asi->insn_handler = emulate_rd12_modify;
> -	return INSN_GOOD;
> -}
> -
> -static enum kprobe_insn __kprobes
> -prep_emulate_rd12rn0_modify(kprobe_opcode_t insn,
> -			    struct arch_specific_insn *asi)
> -{
> -	if (is_r15(insn, 12))
> -		return INSN_REJECTED;	/* Rd is PC */
> -
> -	insn &= 0xffff0ff0;	/* Rd = r0 */
> -	insn |= 0x00000001;	/* Rn = r1 */
> -	asi->insn[0] = insn;
> -	asi->insn_handler = emulate_rd12rn0_modify;
> -	return INSN_GOOD;
> -}
> -
> -static enum kprobe_insn __kprobes
> -prep_emulate_rd12rm0(kprobe_opcode_t insn, struct arch_specific_insn *asi)
> -{
> -	if (is_r15(insn, 12))
> -		return INSN_REJECTED;	/* Rd is PC */
> -
> -	insn &= 0xffff0ff0;	/* Rd = r0, Rm = r0 */
> -	asi->insn[0] = insn;
> -	asi->insn_handler = emulate_rd12rm0;
> -	return INSN_GOOD;
> -}
> -
> -static enum kprobe_insn __kprobes
> -prep_emulate_rd12rn16rm0_wflags(kprobe_opcode_t insn,
> -				struct arch_specific_insn *asi)
> -{
> -	if (is_r15(insn, 12))
> -		return INSN_REJECTED;	/* Rd is PC */
> -
> -	insn &= 0xfff00ff0;	/* Rd = r0, Rn = r0 */
> -	insn |= 0x00000001;	/* Rm = r1 */
> -	asi->insn[0] = insn;
> -	asi->insn_handler = emulate_rd12rn16rm0_rwflags;
> -	return INSN_GOOD;
> -}
> -
> -static enum kprobe_insn __kprobes
> -prep_emulate_rd16rs8rm0_wflags(kprobe_opcode_t insn,
> -			       struct arch_specific_insn *asi)
> -{
> -	if (is_r15(insn, 16))
> -		return INSN_REJECTED;	/* Rd is PC */
> -
> -	insn &= 0xfff0f0f0;	/* Rd = r0, Rs = r0 */
> -	insn |= 0x00000001;	/* Rm = r1          */
> -	asi->insn[0] = insn;
> -	asi->insn_handler = emulate_rd16rs8rm0_rwflags;
> -	return INSN_GOOD;
> -}
> -
> -static enum kprobe_insn __kprobes
> -prep_emulate_rd16rn12rs8rm0_wflags(kprobe_opcode_t insn,
> -				   struct arch_specific_insn *asi)
> -{
> -	if (is_r15(insn, 16))
> -		return INSN_REJECTED;	/* Rd is PC */
> -
> -	insn &= 0xfff000f0;	/* Rd = r0, Rn = r0 */
> -	insn |= 0x00000102;	/* Rs = r1, Rm = r2 */
> -	asi->insn[0] = insn;
> -	asi->insn_handler = emulate_rd16rn12rs8rm0_rwflags;
> -	return INSN_GOOD;
> -}
> -
> -static enum kprobe_insn __kprobes
> -prep_emulate_rdhi16rdlo12rs8rm0_wflags(kprobe_opcode_t insn,
> -				       struct arch_specific_insn *asi)
> -{
> -	if (is_r15(insn, 16) || is_r15(insn, 12))
> -		return INSN_REJECTED;	/* RdHi or RdLo is PC */
> -
> -	insn &= 0xfff000f0;	/* RdHi = r0, RdLo = r1 */
> -	insn |= 0x00001203;	/* Rs = r2, Rm = r3 */
> -	asi->insn[0] = insn;
> -	asi->insn_handler = emulate_rdhi16rdlo12rs8rm0_rwflags;
> -	return INSN_GOOD;
> -}
> -
>  static void __kprobes
>  emulate_ldrdstrd(struct kprobe *p, struct pt_regs *regs)
>  {
> -- 
> 1.7.2.5
> 
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
> 

^ permalink raw reply	[flat|nested] 26+ messages in thread

end of thread, other threads:[~2011-07-13 16:04 UTC | newest]

Thread overview: 26+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-07-13  9:05 [PATCH 0/24] ARM: kprobes: Migrate ARM instruction decoding to data tables Tixy
2011-07-13  9:05 ` [PATCH 01/24] ARM: kprobes: Migrate ARM space_1111 to decoding tables Tixy
2011-07-13  9:05 ` [PATCH 02/24] ARM: kprobes: Add alu_write_pc() Tixy
2011-07-13  9:05 ` [PATCH 03/24] ARM: kprobes: Add BLX macro Tixy
2011-07-13  9:05 ` [PATCH 04/24] ARM: kprobes: Add emulate_rd12rn16rm0rs8_rwflags() Tixy
2011-07-13  9:05 ` [PATCH 05/24] ARM: kprobes: Migrate ARM data-processing (register) instructions to decoding tables Tixy
2011-07-13  9:05 ` [PATCH 06/24] ARM: kprobes: Add emulate_ldrdstrd() Tixy
2011-07-13  9:05 ` [PATCH 07/24] ARM: kprobes: Migrate ARM LDRD and STRD to decoding tables Tixy
2011-07-13  9:05 ` [PATCH 08/24] ARM: kprobes: Migrate ARM space_cccc_000x " Tixy
2011-07-13  9:05 ` [PATCH 09/24] ARM: kprobes: Migrate ARM space_cccc_001x " Tixy
2011-07-13  9:05 ` [PATCH 10/24] ARM: kprobes: Add emulate_rd12rn16rm0_rwflags_nopc() Tixy
2011-07-13  9:06 ` [PATCH 11/24] ARM: kprobes: Migrate ARM space_cccc_0110__1 to decoding tables Tixy
2011-07-13  9:06 ` [PATCH 12/24] ARM: kprobes: Migrate ARM space_cccc_0111__1 " Tixy
2011-07-13  9:06 ` [PATCH 13/24] ARM: kprobes: Migrate ARM space_cccc_01xx " Tixy
2011-07-13  9:06 ` [PATCH 14/24] ARM: kprobes: Migrate ARM space_cccc_100x " Tixy
2011-07-13  9:06 ` [PATCH 15/24] ARM: kprobes: Migrate remaining instruction decoding functions to tables Tixy
2011-07-13  9:06 ` [PATCH 16/24] ARM: kprobes: Add emulate_rd16rn12rm0rs8_rwflags_nopc() Tixy
2011-07-13  9:06 ` [PATCH 17/24] ARM: kprobes: Replace use of prep_emulate_rd12rn16rm0_wflags() Tixy
2011-07-13  9:06 ` [PATCH 18/24] ARM: kprobes: Add emulate_rd12rm0_noflags_nopc() Tixy
2011-07-13  9:06 ` [PATCH 19/24] ARM: kprobes: Add emulate_rdlo12rdhi16rn0rm8_rwflags_nopc() Tixy
2011-07-13  9:06 ` [PATCH 20/24] ARM: kprobes: Add new versions of emulate_ldr() and emulate_str() Tixy
2011-07-13  9:06 ` [PATCH 21/24] ARM: kprobes: Use " Tixy
2011-07-13  9:06 ` [PATCH 22/24] ARM: kprobes: Reject probing of unprivileged load and store instructions Tixy
2011-07-13  9:06 ` [PATCH 23/24] ARM: kprobes: Decode ARM preload (immediate) instructions Tixy
2011-07-13  9:06 ` [PATCH 24/24] ARM: kprobes: Remove now unused code Tixy
2011-07-13 16:04   ` Nicolas Pitre

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.