Skip to contentSkip to conversation

ARM: kprobes: Fixes for ARM instruction emulation (part 4)

PATCH New Tixy 3 participants 11 messages Apr 12, 2011 Arm (32-bit)

lore
Share & tools
lore

Tixy

author
#0 lore raw

cover ARM: kprobes: Fixes for ARM instruction emulation (part 4)

(This is a fourth set of patches)

When kprobes are inserted into code an ARM instruction is replaced by a breakpoint. When this is hit, the original instruction must be emulated out-of-line. This patchset fixes even more bugs in the instruction decoding and emulation.

[PATCH 1/6] ARM: kprobes: Reject probing of LDRB instructions which load PC [PATCH 2/6] ARM: kprobes: Add emulation of RBIT instruction
[PATCH 3/6] ARM: kprobes: Reject probing of undefined media instructions
[PATCH 4/6] ARM: kprobes: Fix emulation of SXTB16, SXTB, SXTH, UXTB16, UXTB and UXTH instructions [PATCH 5/6] ARM: kprobes: Fix emulation of SMUAD, SMUSD and SMMUL instructions [PATCH 6/6] ARM: kprobes: Fix emulation of USAD8 instructions

author
#1 lore raw

PATCH 1/6 ARM: kprobes: Reject probing of LDRB instructions which load PC

From: Jon Medhurst <[email protected]>

These instructions are specified as UNPREDICTABLE.

---
 arch/arm/kernel/kprobes-decode.c |    4 ++++
 1 files changed, 4 insertions(+), 0 deletions(-)
arch/arm/kernel/kprobes-decode.c +4 -0
index bb239f6..7cb939a 100644
@@ -1416,6 +1416,10 @@ space_cccc_01xx(kprobe_opcode_t insn, struct arch_specific_insn *asi)
 	/* 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);
 }
 
Signature · 1 line
1.7.2.5
author
#2 lore raw

PATCH 2/6 ARM: kprobes: Add emulation of RBIT instruction

In reply to Tixy

From: Jon Medhurst <[email protected]>

The v6T2 RBIT instruction was accidentally being emulated correctly, this patch adds correct decoding for the instruction.

---
 arch/arm/kernel/kprobes-decode.c |    3 ++-
 1 files changed, 2 insertions(+), 1 deletions(-)
arch/arm/kernel/kprobes-decode.c +2 -1
index 7cb939a..f6367bf 100644
@@ -1320,9 +1320,10 @@ space_cccc_0110__1(kprobe_opcode_t insn, struct arch_specific_insn *asi)
 
 	/* 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 & 0x0ff000f0) == 0x06f000b0)
+	    (insn & 0x0ff00070) == 0x06f00030)
 		return prep_emulate_rd12rm0(insn, asi);
 
 	/* SADD16    : cccc 0110 0001 xxxx xxxx xxxx 0001 xxxx :GE */
Signature · 1 line
1.7.2.5
author
#3 lore raw

PATCH 3/6 ARM: kprobes: Reject probing of undefined media instructions

In reply to Tixy

From: Jon Medhurst <[email protected]>

The instructions space for media instructions contains some undefined patterns. We need to reject probing of these because they may in future become defined and the kprobes code may then emulate them faultily.

---
 arch/arm/kernel/kprobes-decode.c |   36 +++++++++++++++++++++++++++++++++++-
 1 files changed, 35 insertions(+), 1 deletions(-)
arch/arm/kernel/kprobes-decode.c +35 -1
index f6367bf..a824a79 100644
@@ -1326,52 +1326,86 @@ space_cccc_0110__1(kprobe_opcode_t insn, struct arch_specific_insn *asi)
 	    (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 :   */
 	/* SXTB      : cccc 0110 1010 xxxx xxxx xxxx 0111 xxxx :   */
+	/* ???       : cccc 0110 1001 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 :   */
+	/* ???       : cccc 0110 1101 xxxx xxxx xxxx 0111 xxxx :   */
 	/* UXTAB     : cccc 0110 1110 xxxx xxxx xxxx 0111 xxxx :   */
 	/* UXTAH     : cccc 0110 1111 xxxx xxxx xxxx 0111 xxxx :   */
-	return prep_emulate_rd12rn16rm0_wflags(insn, asi);
+	if ((insn & 0x0f8000f0) == 0x06800070) {
+		if ((insn & 0x00300000) == 0x00100000)
+			return INSN_REJECTED;	/* Unallocated space */
+		return prep_emulate_rd12rn16rm0_wflags(insn, asi);
+	}
+
+	/* Other instruction encodings aren't yet defined */
+	return INSN_REJECTED;
 }
 
 static enum kprobe_insn __kprobes
Signature · 1 line
1.7.2.5
author
#4 lore raw

PATCH 4/6 ARM: kprobes: Fix emulation of SXTB16, SXTB, SXTH, UXTB16, UXTB and UXTH instructions

In reply to Tixy

From: Jon Medhurst <[email protected]>

These sign extension instructions are encoded as extend-and-add instructions where the register to add is specified as r15. The decoding routines weren't checking for this and were using the incorrect emulation code, giving incorrect results.

---
 arch/arm/kernel/kprobes-decode.c |   14 ++++++++++++--
 1 files changed, 12 insertions(+), 2 deletions(-)
arch/arm/kernel/kprobes-decode.c +12 -2
index a824a79..30ba313 100644
@@ -1390,18 +1390,28 @@ space_cccc_0110__1(kprobe_opcode_t insn, struct arch_specific_insn *asi)
 		return prep_emulate_rd12rn16rm0_wflags(insn, asi);
 
 	/* SXTAB16   : cccc 0110 1000 xxxx xxxx xxxx 0111 xxxx :   */
-	/* SXTB      : cccc 0110 1010 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 */
-		return prep_emulate_rd12rn16rm0_wflags(insn, asi);
+
+		if ((insn & 0x000f0000) == 0x000f0000) {
+			return prep_emulate_rd12rm0(insn, asi);
+		} else {
+			return prep_emulate_rd12rn16rm0_wflags(insn, asi);
+		}
 	}
 
 	/* Other instruction encodings aren't yet defined */
Signature · 1 line
1.7.2.5
#5 lore raw

PATCH 4/6 ARM: kprobes: Fix emulation of SXTB16, SXTB, SXTH, UXTB16, UXTB and UXTH instructions

Hello.

Quoted 34 lines · Tixy

From: Jon Medhurst <[email protected]>

These sign extension instructions are encoded as extend-and-add instructions where the register to add is specified as r15. The decoding routines weren't checking for this and were using the incorrect emulation code, giving incorrect results.

---
  arch/arm/kernel/kprobes-decode.c |   14 ++++++++++++--
  1 files changed, 12 insertions(+), 2 deletions(-)
arch/arm/kernel/kprobes-decode.c +6 -1
index a824a79..30ba313 100644
@@ -1390,18 +1390,28 @@ space_cccc_0110__1(kprobe_opcode_t insn, struct arch_specific_insn *asi)
  		return prep_emulate_rd12rn16rm0_wflags(insn, asi);
 
  	/* SXTAB16   : cccc 0110 1000 xxxx xxxx xxxx 0111 xxxx :   */
-	/* SXTB      : cccc 0110 1010 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 :   */

arch/arm/kernel/kprobes-decode.c space_cccc_0110__1(kprobe_opcode_t insn, struct arch_specific_insn *asi) · line 1414

Quoted 10 lines
arch/arm/kernel/kprobes-decode.c +6 -1
  	if ((insn & 0x0f8000f0) == 0x06800070) {
  		if ((insn & 0x00300000) == 0x00100000)
  			return INSN_REJECTED;	/* Unallocated space */
-		return prep_emulate_rd12rn16rm0_wflags(insn, asi);
+
+		if ((insn & 0x000f0000) == 0x000f0000) {
+			return prep_emulate_rd12rm0(insn, asi);
+		} else {
+			return prep_emulate_rd12rn16rm0_wflags(insn, asi);
+		}

Why use {} around single statements? checkpatch.pl used to warn about this...

WBR, Sergei

author
#6 lore raw

PATCH 4/6 ARM: kprobes: Fix emulation of SXTB16, SXTB, SXTH, UXTB16, UXTB and UXTH instructions

Quoted 1 line · Sergei Shtylyov

Why use {} around single statements? checkpatch.pl used to warn about this...

It still does ;-)
I'll fix them.

Signature · 1 line
Tixy
author
#7 lore raw

PATCH 5/6 ARM: kprobes: Fix emulation of SMUAD, SMUSD and SMMUL instructions

In reply to Tixy

From: Jon Medhurst <[email protected]>

The signed multiply instructions were being decoded incorrectly.

---
 arch/arm/kernel/kprobes-decode.c |   22 +++++++++++++++-------
 1 files changed, 15 insertions(+), 7 deletions(-)
arch/arm/kernel/kprobes-decode.c +15 -7
index 30ba313..915b057 100644
@@ -1436,18 +1436,26 @@ space_cccc_0111__1(kprobe_opcode_t insn, struct arch_specific_insn *asi)
 		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 :  */
-	/* SMMLS  : cccc 0111 0101 xxxx xxxx xxxx 11x1 xxxx :  */
+	/* SMMUL  : cccc 0111 0101 xxxx 1111 xxxx 00x1 xxxx :  */
 	if ((insn & 0x0ff00090) == 0x07000010 ||
-	    (insn & 0x0ff000d0) == 0x07500010 ||
-	    (insn & 0x0ff000d0) == 0x075000d0)
+	    (insn & 0x0ff000d0) == 0x07500010) {
+
+		if ((insn & 0x0000f000) == 0x0000f000) {
+			return prep_emulate_rd16rs8rm0_wflags(insn, asi);
+		} else {
+			return prep_emulate_rd16rn12rs8rm0_wflags(insn, asi);
+		}
+	}
+
+	/* SMMLS  : cccc 0111 0101 xxxx xxxx xxxx 11x1 xxxx :  */
+	if ((insn & 0x0ff000d0) == 0x075000d0)
 		return prep_emulate_rd16rn12rs8rm0_wflags(insn, asi);
 
-	/* SMUSD  : cccc 0111 0000 xxxx xxxx xxxx 01x1 xxxx :  */
-	/* SMUAD  : cccc 0111 0000 xxxx 1111 xxxx 00x1 xxxx :Q */
-	/* SMMUL  : cccc 0111 0101 xxxx 1111 xxxx 00x1 xxxx :  */
-	return prep_emulate_rd16rs8rm0_wflags(insn, asi);
+	return INSN_REJECTED;
 }
 
 static enum kprobe_insn __kprobes
Signature · 1 line
1.7.2.5
#8 lore raw

PATCH 5/6 ARM: kprobes: Fix emulation of SMUAD, SMUSD and SMMUL instructions

Hello.

Quoted 23 lines · Tixy

From: Jon Medhurst<[email protected]>

The signed multiply instructions were being decoded incorrectly.

---
  arch/arm/kernel/kprobes-decode.c |   22 +++++++++++++++-------
  1 files changed, 15 insertions(+), 7 deletions(-)
arch/arm/kernel/kprobes-decode.c +3 -1
index 30ba313..915b057 100644
@@ -1436,18 +1436,26 @@ space_cccc_0111__1(kprobe_opcode_t insn, struct arch_specific_insn *asi)
  		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 :  */
-	/* SMMLS  : cccc 0111 0101 xxxx xxxx xxxx 11x1 xxxx :  */
+	/* SMMUL  : cccc 0111 0101 xxxx 1111 xxxx 00x1 xxxx :  */

arch/arm/kernel/kprobes-decode.c space_cccc_0111__1(kprobe_opcode_t insn, struct arch_specific_insn *asi) · line 1451

Quoted 10 lines
arch/arm/kernel/kprobes-decode.c +7 -2
  	if ((insn&  0x0ff00090) == 0x07000010 ||
-	    (insn&  0x0ff000d0) == 0x07500010 ||
-	    (insn&  0x0ff000d0) == 0x075000d0)
+	    (insn&  0x0ff000d0) == 0x07500010) {
+
+		if ((insn&  0x0000f000) == 0x0000f000) {
+			return prep_emulate_rd16rs8rm0_wflags(insn, asi);
+		} else {
+			return prep_emulate_rd16rn12rs8rm0_wflags(insn, asi);
+		}

Why use {} around the single statements here?

arch/arm/kernel/kprobes-decode.c space_cccc_0111__1(kprobe_opcode_t insn, struct arch_specific_insn *asi) · line 1456

Quoted 5 lines
arch/arm/kernel/kprobes-decode.c +4 -0
+	}
+
+	/* SMMLS  : cccc 0111 0101 xxxx xxxx xxxx 11x1 xxxx :  */
+	if ((insn & 0x0ff000d0) == 0x075000d0)
  		return prep_emulate_rd16rn12rs8rm0_wflags(insn, asi);

... but not here. It's at least inconsistent. :-)

WBR, Sergei

author
#9 lore raw

PATCH 6/6 ARM: kprobes: Fix emulation of USAD8 instructions

In reply to Tixy

From: Jon Medhurst <[email protected]>

The USAD8 instruction wasn't being explicitly decoded leading to the incorrect emulation routine being called. It can be correctly decoded in the same way as the signed multiply instructions so we move the decoding there.

---
 arch/arm/kernel/kprobes-decode.c |   10 ++++------
 1 files changed, 4 insertions(+), 6 deletions(-)
arch/arm/kernel/kprobes-decode.c +4 -6
index 915b057..43c2bf2 100644
@@ -1425,11 +1425,6 @@ space_cccc_0111__1(kprobe_opcode_t insn, struct arch_specific_insn *asi)
 	if ((insn & 0x0ff000f0) == 0x03f000f0)
 		return INSN_REJECTED;
 
-	/* USADA8 : cccc 0111 1000 xxxx xxxx xxxx 0001 xxxx */
-	/* USAD8  : cccc 0111 1000 xxxx 1111 xxxx 0001 xxxx */
-	if ((insn & 0x0ff000f0) == 0x07800010)
-		 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 */
 	if ((insn & 0x0ff00090) == 0x07400010)
@@ -1441,8 +1436,11 @@ space_cccc_0111__1(kprobe_opcode_t insn, struct arch_specific_insn *asi)
 	/* 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 & 0x0ff000d0) == 0x07500010 ||
+	    (insn & 0x0ff000f0) == 0x07800010) {
 
 		if ((insn & 0x0000f000) == 0x0000f000) {
 			return prep_emulate_rd16rs8rm0_wflags(insn, asi);
Signature · 1 line
1.7.2.5
#10 lore raw

cover ARM: kprobes: Fixes for ARM instruction emulation (part 4)

In reply to Tixy
Quoted 1 line · Tixy

(This is a fourth set of patches)

Looks good, merged in the usual branch.

Nicolas