|
@@ -594,6 +594,15 @@ int arch_uprobe_post_xol(struct arch_uprobe *auprobe, struct pt_regs *regs)
|
|
|
struct uprobe_task *utask = current->utask;
|
|
|
|
|
|
WARN_ON_ONCE(current->thread.trap_nr != UPROBE_TRAP_NR);
|
|
|
+
|
|
|
+ if (auprobe->ops->post_xol) {
|
|
|
+ int err = auprobe->ops->post_xol(auprobe, regs);
|
|
|
+ if (err) {
|
|
|
+ arch_uprobe_abort_xol(auprobe, regs);
|
|
|
+ return err;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
current->thread.trap_nr = utask->autask.saved_trap_nr;
|
|
|
/*
|
|
|
* arch_uprobe_pre_xol() doesn't save the state of TIF_BLOCKSTEP
|
|
@@ -605,8 +614,6 @@ int arch_uprobe_post_xol(struct arch_uprobe *auprobe, struct pt_regs *regs)
|
|
|
else if (!(auprobe->fixups & UPROBE_FIX_SETF))
|
|
|
regs->flags &= ~X86_EFLAGS_TF;
|
|
|
|
|
|
- if (auprobe->ops->post_xol)
|
|
|
- return auprobe->ops->post_xol(auprobe, regs);
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
@@ -641,8 +648,9 @@ int arch_uprobe_exception_notify(struct notifier_block *self, unsigned long val,
|
|
|
|
|
|
/*
|
|
|
* This function gets called when XOL instruction either gets trapped or
|
|
|
- * the thread has a fatal signal, so reset the instruction pointer to its
|
|
|
- * probed address.
|
|
|
+ * the thread has a fatal signal, or if arch_uprobe_post_xol() failed.
|
|
|
+ * Reset the instruction pointer to its probed address for the potential
|
|
|
+ * restart or for post mortem analysis.
|
|
|
*/
|
|
|
void arch_uprobe_abort_xol(struct arch_uprobe *auprobe, struct pt_regs *regs)
|
|
|
{
|