#ifdef CONFIG_X86_64
        unsigned long                   saved_scratch_register;
 #endif
+#define UPROBE_CLEAR_TF                        (1 << 0)
+       unsigned int                    restore_flags;
 };
 
 extern int  arch_uprobe_analyze_insn(struct arch_uprobe *aup, struct mm_struct *mm, unsigned long addr);
 
 /* Adjust the return address of a call insn */
 #define UPROBE_FIX_CALL        0x2
 
+/* Instruction will modify TF, don't change it */
+#define UPROBE_FIX_SETF        0x4
+
 #define UPROBE_FIX_RIP_AX      0x8000
 #define UPROBE_FIX_RIP_CX      0x4000
 
        insn_get_opcode(insn);  /* should be a nop */
 
        switch (OPCODE1(insn)) {
+       case 0x9d:
+               /* popf */
+               auprobe->fixups |= UPROBE_FIX_SETF;
+               break;
        case 0xc3:              /* ret/lret */
        case 0xcb:
        case 0xc2:
        }
        return false;
 }
+
+void arch_uprobe_enable_step(struct arch_uprobe *auprobe)
+{
+       struct uprobe_task      *utask          = current->utask;
+       struct arch_uprobe_task *autask         = &utask->autask;
+
+       autask->restore_flags = 0;
+       if (!test_tsk_thread_flag(current, TIF_SINGLESTEP) &&
+                       !(auprobe->fixups & UPROBE_FIX_SETF))
+               autask->restore_flags |= UPROBE_CLEAR_TF;
+       /*
+        * The state of TIF_BLOCKSTEP is not saved. With the TF flag set we
+        * would to examine the opcode and the flags to make it right. Without
+        * TF block stepping makes no sense.
+        */
+       user_enable_single_step(current);
+}
+
+void arch_uprobe_disable_step(struct arch_uprobe *auprobe)
+{
+       struct uprobe_task *utask               = current->utask;
+       struct arch_uprobe_task *autask         = &utask->autask;
+
+       if (autask->restore_flags & UPROBE_CLEAR_TF)
+               user_disable_single_step(current);
+}