Commit 8e02ae57 authored by Ingo Molnar's avatar Ingo Molnar

Merge branch 'uprobes/core' of...

Merge branch 'uprobes/core' of git://git.kernel.org/pub/scm/linux/kernel/git/oleg/misc into perf/uprobes

Pull uprobes updates from Oleg Nesterov:

  "This hopefully completes the previous 'fix the handling of relative
   jmp/call's' series, all changes except the last 3 unrelated fixes try
   to address TODO's mentioned in the changelogs."
Signed-off-by: default avatarIngo Molnar <mingo@kernel.org>
parents 3617660e 13f59c5e
...@@ -41,18 +41,21 @@ struct arch_uprobe { ...@@ -41,18 +41,21 @@ struct arch_uprobe {
u8 ixol[MAX_UINSN_BYTES]; u8 ixol[MAX_UINSN_BYTES];
}; };
u16 fixups;
const struct uprobe_xol_ops *ops; const struct uprobe_xol_ops *ops;
union { union {
#ifdef CONFIG_X86_64
unsigned long rip_rela_target_address;
#endif
struct { struct {
s32 offs; s32 offs;
u8 ilen; u8 ilen;
u8 opc1; u8 opc1;
} branch; } branch;
struct {
#ifdef CONFIG_X86_64
long riprel_target;
#endif
u8 fixups;
u8 ilen;
} def;
}; };
}; };
......
...@@ -413,12 +413,11 @@ void set_personality_ia32(bool x32) ...@@ -413,12 +413,11 @@ void set_personality_ia32(bool x32)
set_thread_flag(TIF_ADDR32); set_thread_flag(TIF_ADDR32);
/* Mark the associated mm as containing 32-bit tasks. */ /* Mark the associated mm as containing 32-bit tasks. */
if (current->mm)
current->mm->context.ia32_compat = 1;
if (x32) { if (x32) {
clear_thread_flag(TIF_IA32); clear_thread_flag(TIF_IA32);
set_thread_flag(TIF_X32); set_thread_flag(TIF_X32);
if (current->mm)
current->mm->context.ia32_compat = TIF_X32;
current->personality &= ~READ_IMPLIES_EXEC; current->personality &= ~READ_IMPLIES_EXEC;
/* is_compat_task() uses the presence of the x32 /* is_compat_task() uses the presence of the x32
syscall bit flag to determine compat status */ syscall bit flag to determine compat status */
...@@ -426,6 +425,8 @@ void set_personality_ia32(bool x32) ...@@ -426,6 +425,8 @@ void set_personality_ia32(bool x32)
} else { } else {
set_thread_flag(TIF_IA32); set_thread_flag(TIF_IA32);
clear_thread_flag(TIF_X32); clear_thread_flag(TIF_X32);
if (current->mm)
current->mm->context.ia32_compat = TIF_IA32;
current->personality |= force_personality32; current->personality |= force_personality32;
/* Prepare the first "return" to user space */ /* Prepare the first "return" to user space */
current_thread_info()->status |= TS_COMPAT; current_thread_info()->status |= TS_COMPAT;
......
This diff is collapsed.
...@@ -127,7 +127,7 @@ struct xol_area { ...@@ -127,7 +127,7 @@ struct xol_area {
*/ */
static bool valid_vma(struct vm_area_struct *vma, bool is_register) static bool valid_vma(struct vm_area_struct *vma, bool is_register)
{ {
vm_flags_t flags = VM_HUGETLB | VM_MAYEXEC | VM_SHARED; vm_flags_t flags = VM_HUGETLB | VM_MAYEXEC | VM_MAYSHARE;
if (is_register) if (is_register)
flags |= VM_WRITE; flags |= VM_WRITE;
......
...@@ -1009,56 +1009,60 @@ uprobe_filter_event(struct trace_uprobe *tu, struct perf_event *event) ...@@ -1009,56 +1009,60 @@ uprobe_filter_event(struct trace_uprobe *tu, struct perf_event *event)
return __uprobe_perf_filter(&tu->filter, event->hw.tp_target->mm); return __uprobe_perf_filter(&tu->filter, event->hw.tp_target->mm);
} }
static int uprobe_perf_open(struct trace_uprobe *tu, struct perf_event *event) static int uprobe_perf_close(struct trace_uprobe *tu, struct perf_event *event)
{ {
bool done; bool done;
write_lock(&tu->filter.rwlock); write_lock(&tu->filter.rwlock);
if (event->hw.tp_target) { if (event->hw.tp_target) {
/* list_del(&event->hw.tp_list);
* event->parent != NULL means copy_process(), we can avoid
* uprobe_apply(). current->mm must be probed and we can rely
* on dup_mmap() which preserves the already installed bp's.
*
* attr.enable_on_exec means that exec/mmap will install the
* breakpoints we need.
*/
done = tu->filter.nr_systemwide || done = tu->filter.nr_systemwide ||
event->parent || event->attr.enable_on_exec || (event->hw.tp_target->flags & PF_EXITING) ||
uprobe_filter_event(tu, event); uprobe_filter_event(tu, event);
list_add(&event->hw.tp_list, &tu->filter.perf_events);
} else { } else {
tu->filter.nr_systemwide--;
done = tu->filter.nr_systemwide; done = tu->filter.nr_systemwide;
tu->filter.nr_systemwide++;
} }
write_unlock(&tu->filter.rwlock); write_unlock(&tu->filter.rwlock);
if (!done) if (!done)
uprobe_apply(tu->inode, tu->offset, &tu->consumer, true); return uprobe_apply(tu->inode, tu->offset, &tu->consumer, false);
return 0; return 0;
} }
static int uprobe_perf_close(struct trace_uprobe *tu, struct perf_event *event) static int uprobe_perf_open(struct trace_uprobe *tu, struct perf_event *event)
{ {
bool done; bool done;
int err;
write_lock(&tu->filter.rwlock); write_lock(&tu->filter.rwlock);
if (event->hw.tp_target) { if (event->hw.tp_target) {
list_del(&event->hw.tp_list); /*
* event->parent != NULL means copy_process(), we can avoid
* uprobe_apply(). current->mm must be probed and we can rely
* on dup_mmap() which preserves the already installed bp's.
*
* attr.enable_on_exec means that exec/mmap will install the
* breakpoints we need.
*/
done = tu->filter.nr_systemwide || done = tu->filter.nr_systemwide ||
(event->hw.tp_target->flags & PF_EXITING) || event->parent || event->attr.enable_on_exec ||
uprobe_filter_event(tu, event); uprobe_filter_event(tu, event);
list_add(&event->hw.tp_list, &tu->filter.perf_events);
} else { } else {
tu->filter.nr_systemwide--;
done = tu->filter.nr_systemwide; done = tu->filter.nr_systemwide;
tu->filter.nr_systemwide++;
} }
write_unlock(&tu->filter.rwlock); write_unlock(&tu->filter.rwlock);
if (!done) err = 0;
uprobe_apply(tu->inode, tu->offset, &tu->consumer, false); if (!done) {
err = uprobe_apply(tu->inode, tu->offset, &tu->consumer, true);
return 0; if (err)
uprobe_perf_close(tu, event);
}
return err;
} }
static bool uprobe_perf_filter(struct uprobe_consumer *uc, static bool uprobe_perf_filter(struct uprobe_consumer *uc,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment