#define predicate(x)           ((x) & 0xf0000000)
 #define PREDICATE_ALWAYS       0xe0000000
 
+/*
+ * True if instr is a 32-bit thumb instruction. This works if instr
+ * is the first or only half-word of a thumb instruction. It also works
+ * when instr holds all 32-bits of a wide thumb instruction if stored
+ * in the form (first_half<<16)|(second_half)
+ */
+#define is_wide_instruction(instr)     ((unsigned)(instr) >= 0xe800)
+
 /*
  * kprobe-based event tracer support
  */
 
        .fn             = break_trap,
 };
 
-static int thumb2_break_trap(struct pt_regs *regs, unsigned int instr)
-{
-       unsigned int instr2;
-       void __user *pc;
-
-       /* Check the second half of the instruction.  */
-       pc = (void __user *)(instruction_pointer(regs) + 2);
-
-       if (processor_mode(regs) == SVC_MODE) {
-               instr2 = *(u16 *) pc;
-       } else {
-               get_user(instr2, (u16 __user *)pc);
-       }
-
-       if (instr2 == 0xa000) {
-               ptrace_break(current, regs);
-               return 0;
-       } else {
-               return 1;
-       }
-}
-
 static struct undef_hook thumb2_break_hook = {
-       .instr_mask     = 0xffff,
-       .instr_val      = 0xf7f0,
+       .instr_mask     = 0xffffffff,
+       .instr_val      = 0xf7f0a000,
        .cpsr_mask      = PSR_T_BIT,
        .cpsr_val       = PSR_T_BIT,
-       .fn             = thumb2_break_trap,
+       .fn             = break_trap,
 };
 
 static int __init ptrace_break_init(void)
 
        pc = (void __user *)instruction_pointer(regs);
 
        if (processor_mode(regs) == SVC_MODE) {
-               instr = *(u32 *) pc;
+#ifdef CONFIG_THUMB2_KERNEL
+               if (thumb_mode(regs)) {
+                       instr = ((u16 *)pc)[0];
+                       if (is_wide_instruction(instr)) {
+                               instr <<= 16;
+                               instr |= ((u16 *)pc)[1];
+                       }
+               } else
+#endif
+                       instr = *(u32 *) pc;
        } else if (thumb_mode(regs)) {
                get_user(instr, (u16 __user *)pc);
+               if (is_wide_instruction(instr)) {
+                       unsigned int instr2;
+                       get_user(instr2, (u16 __user *)pc+1);
+                       instr <<= 16;
+                       instr |= instr2;
+               }
        } else {
                get_user(instr, (u32 __user *)pc);
        }