summaryrefslogtreecommitdiffstats
path: root/kernel/events/uprobes.c
diff options
context:
space:
mode:
authorOleg Nesterov <oleg@redhat.com>2012-12-31 18:20:42 +0100
committerOleg Nesterov <oleg@redhat.com>2013-02-08 17:47:12 +0100
commit608e7427c0a06de0d70374a9fd7defc8eb228b7e (patch)
treefa9d008fc34cd270613b63bbd9fd724c563daa44 /kernel/events/uprobes.c
parentuprobes: Fix utask->xol_vaddr leak in pre_ssout() (diff)
downloadlinux-608e7427c0a06de0d70374a9fd7defc8eb228b7e.tar.xz
linux-608e7427c0a06de0d70374a9fd7defc8eb228b7e.zip
uprobes: Do not allocate current->utask unnecessary
handle_swbp() does get_utask() before can_skip_sstep() for no reason, we do not need ->utask if can_skip_sstep() succeeds. Move get_utask() to pre_ssout() who actually starts to use it. Move the initialization of utask->active_uprobe/state as well. This way the whole initialization is consolidated in pre_ssout(). Signed-off-by: Oleg Nesterov <oleg@redhat.com> Acked-by: Anton Arapov <anton@redhat.com>
Diffstat (limited to 'kernel/events/uprobes.c')
-rw-r--r--kernel/events/uprobes.c16
1 files changed, 6 insertions, 10 deletions
diff --git a/kernel/events/uprobes.c b/kernel/events/uprobes.c
index 0527379dac5b..071edcb3e62d 100644
--- a/kernel/events/uprobes.c
+++ b/kernel/events/uprobes.c
@@ -1308,7 +1308,9 @@ pre_ssout(struct uprobe *uprobe, struct pt_regs *regs, unsigned long bp_vaddr)
unsigned long xol_vaddr;
int err;
- utask = current->utask;
+ utask = get_utask();
+ if (!utask)
+ return -ENOMEM;
xol_vaddr = xol_get_insn_slot(uprobe);
if (!xol_vaddr)
@@ -1323,6 +1325,8 @@ pre_ssout(struct uprobe *uprobe, struct pt_regs *regs, unsigned long bp_vaddr)
return err;
}
+ utask->active_uprobe = uprobe;
+ utask->state = UTASK_SSTEP;
return 0;
}
@@ -1474,7 +1478,6 @@ static void handler_chain(struct uprobe *uprobe, struct pt_regs *regs)
*/
static void handle_swbp(struct pt_regs *regs)
{
- struct uprobe_task *utask;
struct uprobe *uprobe;
unsigned long bp_vaddr;
int uninitialized_var(is_swbp);
@@ -1512,19 +1515,12 @@ static void handle_swbp(struct pt_regs *regs)
if (unlikely(!test_bit(UPROBE_COPY_INSN, &uprobe->flags)))
goto out;
- utask = get_utask();
- if (!utask)
- goto out; /* re-execute the instruction. */
-
handler_chain(uprobe, regs);
if (can_skip_sstep(uprobe, regs))
goto out;
- if (!pre_ssout(uprobe, regs, bp_vaddr)) {
- utask->active_uprobe = uprobe;
- utask->state = UTASK_SSTEP;
+ if (!pre_ssout(uprobe, regs, bp_vaddr))
return;
- }
/* can_skip_sstep() succeeded, or restart if can't singlestep */
out: