* [PATCH 1/3] uprobes: fix the usage of install_special_mapping()
2015-07-09 21:44 uprobes: minor fixes + name the xol vma Oleg Nesterov
@ 2015-07-09 21:44 ` Oleg Nesterov
2015-07-09 21:49 ` Andy Lutomirski
2015-07-09 21:44 ` [PATCH 2/3] uprobes: use vm_special_mapping to name the xol vma Oleg Nesterov
` (2 subsequent siblings)
3 siblings, 1 reply; 13+ messages in thread
From: Oleg Nesterov @ 2015-07-09 21:44 UTC (permalink / raw)
To: Ingo Molnar, Srikar Dronamraju
Cc: Andy Lutomirski, Kirill A. Shutemov, linux-kernel
install_special_mapping(pages) expects that "pages" is the zero-
terminated array while xol_add_vma() passes &area->page, this means
that special_mapping_fault() can wrongly use the next member in
xol_area (vaddr) as "struct page *".
Fortunately, this area is not expandable so pgoff != 0 isn't possible
(modulo bugs in special_mapping_vmops), but still this does not look
good.
Signed-off-by: Oleg Nesterov <oleg@redhat.com>
---
kernel/events/uprobes.c | 16 ++++++++--------
1 files changed, 8 insertions(+), 8 deletions(-)
diff --git a/kernel/events/uprobes.c b/kernel/events/uprobes.c
index 0f370ef..bd35bee 100644
--- a/kernel/events/uprobes.c
+++ b/kernel/events/uprobes.c
@@ -99,7 +99,7 @@ struct xol_area {
wait_queue_head_t wq; /* if all slots are busy */
atomic_t slot_count; /* number of in-use slots */
unsigned long *bitmap; /* 0 = free slot */
- struct page *page;
+ struct page *pages[2];
/*
* We keep the vma's vm_start rather than a pointer to the vma
@@ -1142,7 +1142,7 @@ static int xol_add_vma(struct mm_struct *mm, struct xol_area *area)
}
ret = install_special_mapping(mm, area->vaddr, PAGE_SIZE,
- VM_EXEC|VM_MAYEXEC|VM_DONTCOPY|VM_IO, &area->page);
+ VM_EXEC|VM_MAYEXEC|VM_DONTCOPY|VM_IO, area->pages);
if (ret)
goto fail;
@@ -1168,8 +1168,8 @@ static struct xol_area *__create_xol_area(unsigned long vaddr)
if (!area->bitmap)
goto free_area;
- area->page = alloc_page(GFP_HIGHUSER);
- if (!area->page)
+ area->pages[0] = alloc_page(GFP_HIGHUSER);
+ if (!area->pages[0])
goto free_bitmap;
area->vaddr = vaddr;
@@ -1177,12 +1177,12 @@ static struct xol_area *__create_xol_area(unsigned long vaddr)
/* Reserve the 1st slot for get_trampoline_vaddr() */
set_bit(0, area->bitmap);
atomic_set(&area->slot_count, 1);
- copy_to_page(area->page, 0, &insn, UPROBE_SWBP_INSN_SIZE);
+ copy_to_page(area->pages[0], 0, &insn, UPROBE_SWBP_INSN_SIZE);
if (!xol_add_vma(mm, area))
return area;
- __free_page(area->page);
+ __free_page(area->pages[0]);
free_bitmap:
kfree(area->bitmap);
free_area:
@@ -1220,7 +1220,7 @@ void uprobe_clear_state(struct mm_struct *mm)
if (!area)
return;
- put_page(area->page);
+ put_page(area->pages[0]);
kfree(area->bitmap);
kfree(area);
}
@@ -1289,7 +1289,7 @@ static unsigned long xol_get_insn_slot(struct uprobe *uprobe)
if (unlikely(!xol_vaddr))
return 0;
- arch_uprobe_copy_ixol(area->page, xol_vaddr,
+ arch_uprobe_copy_ixol(area->pages[0], xol_vaddr,
&uprobe->arch.ixol, sizeof(uprobe->arch.ixol));
return xol_vaddr;
--
1.5.5.1
^ permalink raw reply related [flat|nested] 13+ messages in thread* Re: [PATCH 1/3] uprobes: fix the usage of install_special_mapping()
2015-07-09 21:44 ` [PATCH 1/3] uprobes: fix the usage of install_special_mapping() Oleg Nesterov
@ 2015-07-09 21:49 ` Andy Lutomirski
2015-07-09 22:02 ` Oleg Nesterov
0 siblings, 1 reply; 13+ messages in thread
From: Andy Lutomirski @ 2015-07-09 21:49 UTC (permalink / raw)
To: Oleg Nesterov
Cc: Ingo Molnar, Srikar Dronamraju, Kirill A. Shutemov,
linux-kernel@vger.kernel.org
On Thu, Jul 9, 2015 at 2:44 PM, Oleg Nesterov <oleg@redhat.com> wrote:
> install_special_mapping(pages) expects that "pages" is the zero-
> terminated array while xol_add_vma() passes &area->page, this means
> that special_mapping_fault() can wrongly use the next member in
> xol_area (vaddr) as "struct page *".
>
> Fortunately, this area is not expandable so pgoff != 0 isn't possible
> (modulo bugs in special_mapping_vmops), but still this does not look
> good.
>
I fell for that awhile back, too, causing a bizarre HPET bug.
What zeroes pages[1]?
--Andy
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH 1/3] uprobes: fix the usage of install_special_mapping()
2015-07-09 21:49 ` Andy Lutomirski
@ 2015-07-09 22:02 ` Oleg Nesterov
2015-07-09 22:12 ` Andy Lutomirski
0 siblings, 1 reply; 13+ messages in thread
From: Oleg Nesterov @ 2015-07-09 22:02 UTC (permalink / raw)
To: Andy Lutomirski
Cc: Ingo Molnar, Srikar Dronamraju, Kirill A. Shutemov,
linux-kernel@vger.kernel.org
On 07/09, Andy Lutomirski wrote:
>
> On Thu, Jul 9, 2015 at 2:44 PM, Oleg Nesterov <oleg@redhat.com> wrote:
> > install_special_mapping(pages) expects that "pages" is the zero-
> > terminated array while xol_add_vma() passes &area->page, this means
> > that special_mapping_fault() can wrongly use the next member in
> > xol_area (vaddr) as "struct page *".
> >
> > Fortunately, this area is not expandable so pgoff != 0 isn't possible
> > (modulo bugs in special_mapping_vmops), but still this does not look
> > good.
> >
>
> I fell for that awhile back, too, causing a bizarre HPET bug.
I guess you mean no_pages[] = {NULL} in map_vdso() ?
uprobes differs, I think pgoff != 0 is not actually possible (assuming
we fix special_mapping_fault). But this doesn't matter, this is wrong
anyway.
> What zeroes pages[1]?
Heh ;) Thanks. I'll send v2.
Oleg.
^ permalink raw reply [flat|nested] 13+ messages in thread* Re: [PATCH 1/3] uprobes: fix the usage of install_special_mapping()
2015-07-09 22:02 ` Oleg Nesterov
@ 2015-07-09 22:12 ` Andy Lutomirski
0 siblings, 0 replies; 13+ messages in thread
From: Andy Lutomirski @ 2015-07-09 22:12 UTC (permalink / raw)
To: Oleg Nesterov
Cc: Ingo Molnar, Srikar Dronamraju, Kirill A. Shutemov,
linux-kernel@vger.kernel.org
On Thu, Jul 9, 2015 at 3:02 PM, Oleg Nesterov <oleg@redhat.com> wrote:
> On 07/09, Andy Lutomirski wrote:
>>
>> On Thu, Jul 9, 2015 at 2:44 PM, Oleg Nesterov <oleg@redhat.com> wrote:
>> > install_special_mapping(pages) expects that "pages" is the zero-
>> > terminated array while xol_add_vma() passes &area->page, this means
>> > that special_mapping_fault() can wrongly use the next member in
>> > xol_area (vaddr) as "struct page *".
>> >
>> > Fortunately, this area is not expandable so pgoff != 0 isn't possible
>> > (modulo bugs in special_mapping_vmops), but still this does not look
>> > good.
>> >
>>
>> I fell for that awhile back, too, causing a bizarre HPET bug.
>
> I guess you mean no_pages[] = {NULL} in map_vdso() ?
Yes.
--Andy
^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH 2/3] uprobes: use vm_special_mapping to name the xol vma
2015-07-09 21:44 uprobes: minor fixes + name the xol vma Oleg Nesterov
2015-07-09 21:44 ` [PATCH 1/3] uprobes: fix the usage of install_special_mapping() Oleg Nesterov
@ 2015-07-09 21:44 ` Oleg Nesterov
2015-07-09 21:50 ` Andy Lutomirski
2015-07-09 21:44 ` [PATCH 3/3] uprobes: fix the waitqueue_active() check in xol_free_insn_slot() Oleg Nesterov
2015-07-09 22:25 ` [PATCH v2 0/3] uprobes: minor fixes + name the xol vma Oleg Nesterov
3 siblings, 1 reply; 13+ messages in thread
From: Oleg Nesterov @ 2015-07-09 21:44 UTC (permalink / raw)
To: Ingo Molnar, Srikar Dronamraju
Cc: Andy Lutomirski, Kirill A. Shutemov, linux-kernel
Change xol_add_vma() to use _install_special_mapping(), this way
we can name the vma installed by uprobes. Currently it looks like
private anonymous mapping, this is confusing and complicates the
debugging. With this change /proc/$pid/maps reports "[uprobes]".
Signed-off-by: Oleg Nesterov <oleg@redhat.com>
---
kernel/events/uprobes.c | 30 ++++++++++++++++++++----------
1 files changed, 20 insertions(+), 10 deletions(-)
diff --git a/kernel/events/uprobes.c b/kernel/events/uprobes.c
index bd35bee..6a9c5e0 100644
--- a/kernel/events/uprobes.c
+++ b/kernel/events/uprobes.c
@@ -96,17 +96,18 @@ struct uprobe {
* allocated.
*/
struct xol_area {
- wait_queue_head_t wq; /* if all slots are busy */
- atomic_t slot_count; /* number of in-use slots */
- unsigned long *bitmap; /* 0 = free slot */
- struct page *pages[2];
+ wait_queue_head_t wq; /* if all slots are busy */
+ atomic_t slot_count; /* number of in-use slots */
+ unsigned long *bitmap; /* 0 = free slot */
+ struct vm_special_mapping xol_mapping;
+ struct page *pages[2];
/*
* We keep the vma's vm_start rather than a pointer to the vma
* itself. The probed process or a naughty kernel module could make
* the vma go away, and we must handle that reasonably gracefully.
*/
- unsigned long vaddr; /* Page(s) of instruction slots */
+ unsigned long vaddr; /* Page(s) of instruction slots */
};
/*
@@ -1125,11 +1126,14 @@ void uprobe_munmap(struct vm_area_struct *vma, unsigned long start, unsigned lon
/* Slot allocation for XOL */
static int xol_add_vma(struct mm_struct *mm, struct xol_area *area)
{
- int ret = -EALREADY;
+ struct vm_area_struct *vma;
+ int ret;
down_write(&mm->mmap_sem);
- if (mm->uprobes_state.xol_area)
+ if (mm->uprobes_state.xol_area) {
+ ret = -EALREADY;
goto fail;
+ }
if (!area->vaddr) {
/* Try to map as high as possible, this is only a hint. */
@@ -1141,11 +1145,15 @@ static int xol_add_vma(struct mm_struct *mm, struct xol_area *area)
}
}
- ret = install_special_mapping(mm, area->vaddr, PAGE_SIZE,
- VM_EXEC|VM_MAYEXEC|VM_DONTCOPY|VM_IO, area->pages);
- if (ret)
+ vma = _install_special_mapping(mm, area->vaddr, PAGE_SIZE,
+ VM_EXEC|VM_MAYEXEC|VM_DONTCOPY|VM_IO,
+ &area->xol_mapping);
+ if (IS_ERR(vma)) {
+ ret = PTR_ERR(vma);
goto fail;
+ }
+ ret = 0;
smp_wmb(); /* pairs with get_xol_area() */
mm->uprobes_state.xol_area = area;
fail:
@@ -1168,6 +1176,8 @@ static struct xol_area *__create_xol_area(unsigned long vaddr)
if (!area->bitmap)
goto free_area;
+ area->xol_mapping.name = "[uprobes]";
+ area->xol_mapping.pages = area->pages;
area->pages[0] = alloc_page(GFP_HIGHUSER);
if (!area->pages[0])
goto free_bitmap;
--
1.5.5.1
^ permalink raw reply related [flat|nested] 13+ messages in thread* Re: [PATCH 2/3] uprobes: use vm_special_mapping to name the xol vma
2015-07-09 21:44 ` [PATCH 2/3] uprobes: use vm_special_mapping to name the xol vma Oleg Nesterov
@ 2015-07-09 21:50 ` Andy Lutomirski
2015-07-09 22:03 ` Oleg Nesterov
0 siblings, 1 reply; 13+ messages in thread
From: Andy Lutomirski @ 2015-07-09 21:50 UTC (permalink / raw)
To: Oleg Nesterov
Cc: Ingo Molnar, Srikar Dronamraju, Kirill A. Shutemov,
linux-kernel@vger.kernel.org
On Thu, Jul 9, 2015 at 2:44 PM, Oleg Nesterov <oleg@redhat.com> wrote:
> Change xol_add_vma() to use _install_special_mapping(), this way
> we can name the vma installed by uprobes. Currently it looks like
> private anonymous mapping, this is confusing and complicates the
> debugging. With this change /proc/$pid/maps reports "[uprobes]".
I think this will cause core dumps to include it as a side effect. Is
that okay?
--Andy
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH 2/3] uprobes: use vm_special_mapping to name the xol vma
2015-07-09 21:50 ` Andy Lutomirski
@ 2015-07-09 22:03 ` Oleg Nesterov
0 siblings, 0 replies; 13+ messages in thread
From: Oleg Nesterov @ 2015-07-09 22:03 UTC (permalink / raw)
To: Andy Lutomirski
Cc: Ingo Molnar, Srikar Dronamraju, Kirill A. Shutemov,
linux-kernel@vger.kernel.org
On 07/09, Andy Lutomirski wrote:
>
> On Thu, Jul 9, 2015 at 2:44 PM, Oleg Nesterov <oleg@redhat.com> wrote:
> > Change xol_add_vma() to use _install_special_mapping(), this way
> > we can name the vma installed by uprobes. Currently it looks like
> > private anonymous mapping, this is confusing and complicates the
> > debugging. With this change /proc/$pid/maps reports "[uprobes]".
>
> I think this will cause core dumps to include it as a side effect. Is
> that okay?
Yes, I even mentioned this in 0/3... I'll move thhis note into the
changelog in v2.
Thanks!
Oleg.
^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH 3/3] uprobes: fix the waitqueue_active() check in xol_free_insn_slot()
2015-07-09 21:44 uprobes: minor fixes + name the xol vma Oleg Nesterov
2015-07-09 21:44 ` [PATCH 1/3] uprobes: fix the usage of install_special_mapping() Oleg Nesterov
2015-07-09 21:44 ` [PATCH 2/3] uprobes: use vm_special_mapping to name the xol vma Oleg Nesterov
@ 2015-07-09 21:44 ` Oleg Nesterov
2015-07-09 22:25 ` [PATCH v2 0/3] uprobes: minor fixes + name the xol vma Oleg Nesterov
3 siblings, 0 replies; 13+ messages in thread
From: Oleg Nesterov @ 2015-07-09 21:44 UTC (permalink / raw)
To: Ingo Molnar, Srikar Dronamraju
Cc: Andy Lutomirski, Kirill A. Shutemov, linux-kernel
The xol_free_insn_slot()->waitqueue_active() check is buggy. We need
mb() after we set the conditon for wait_event(), or xol_take_insn_slot()
can miss the wakeup.
Signed-off-by: Oleg Nesterov <oleg@redhat.com>
---
kernel/events/uprobes.c | 1 +
1 files changed, 1 insertions(+), 0 deletions(-)
diff --git a/kernel/events/uprobes.c b/kernel/events/uprobes.c
index 6a9c5e0..9a4f9df 100644
--- a/kernel/events/uprobes.c
+++ b/kernel/events/uprobes.c
@@ -1336,6 +1336,7 @@ static void xol_free_insn_slot(struct task_struct *tsk)
clear_bit(slot_nr, area->bitmap);
atomic_dec(&area->slot_count);
+ smp_mb__after_atomic(); /* pairs with prepare_to_wait() */
if (waitqueue_active(&area->wq))
wake_up(&area->wq);
--
1.5.5.1
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH v2 0/3] uprobes: minor fixes + name the xol vma
2015-07-09 21:44 uprobes: minor fixes + name the xol vma Oleg Nesterov
` (2 preceding siblings ...)
2015-07-09 21:44 ` [PATCH 3/3] uprobes: fix the waitqueue_active() check in xol_free_insn_slot() Oleg Nesterov
@ 2015-07-09 22:25 ` Oleg Nesterov
2015-07-09 22:25 ` [PATCH v2 1/3] uprobes: fix the usage of install_special_mapping() Oleg Nesterov
` (2 more replies)
3 siblings, 3 replies; 13+ messages in thread
From: Oleg Nesterov @ 2015-07-09 22:25 UTC (permalink / raw)
To: Ingo Molnar, Srikar Dronamraju
Cc: Andy Lutomirski, Kirill A. Shutemov, linux-kernel
On 07/09, Oleg Nesterov wrote:
>
> Hello,
>
> The bugs are theoretical, but still should be fixed imo. And it
> would be nice to name the special vma installed by uprobes. As a
> side effect this vma will be core-dump'ed, I think this is good.
>
> This doesn't depend on the pending longjmp fixes.
v2:
1/3 - initialize pages[1] (thanks Andy!)
2/3 - update the changelog
Oleg.
kernel/events/uprobes.c | 44 ++++++++++++++++++++++++++++----------------
1 files changed, 28 insertions(+), 16 deletions(-)
^ permalink raw reply [flat|nested] 13+ messages in thread* [PATCH v2 1/3] uprobes: fix the usage of install_special_mapping()
2015-07-09 22:25 ` [PATCH v2 0/3] uprobes: minor fixes + name the xol vma Oleg Nesterov
@ 2015-07-09 22:25 ` Oleg Nesterov
2015-07-09 22:25 ` [PATCH v2 2/3] uprobes: use vm_special_mapping to name the xol vma Oleg Nesterov
2015-07-09 22:25 ` [PATCH v2 3/3] uprobes: fix the waitqueue_active() check in xol_free_insn_slot() Oleg Nesterov
2 siblings, 0 replies; 13+ messages in thread
From: Oleg Nesterov @ 2015-07-09 22:25 UTC (permalink / raw)
To: Ingo Molnar, Srikar Dronamraju
Cc: Andy Lutomirski, Kirill A. Shutemov, linux-kernel
install_special_mapping(pages) expects that "pages" is the zero-
terminated array while xol_add_vma() passes &area->page, this means
that special_mapping_fault() can wrongly use the next member in
xol_area (vaddr) as "struct page *".
Fortunately, this area is not expandable so pgoff != 0 isn't possible
(modulo bugs in special_mapping_vmops), but still this does not look
good.
Signed-off-by: Oleg Nesterov <oleg@redhat.com>
---
kernel/events/uprobes.c | 17 +++++++++--------
1 files changed, 9 insertions(+), 8 deletions(-)
diff --git a/kernel/events/uprobes.c b/kernel/events/uprobes.c
index 0f370ef..4b8ac5f 100644
--- a/kernel/events/uprobes.c
+++ b/kernel/events/uprobes.c
@@ -99,7 +99,7 @@ struct xol_area {
wait_queue_head_t wq; /* if all slots are busy */
atomic_t slot_count; /* number of in-use slots */
unsigned long *bitmap; /* 0 = free slot */
- struct page *page;
+ struct page *pages[2];
/*
* We keep the vma's vm_start rather than a pointer to the vma
@@ -1142,7 +1142,7 @@ static int xol_add_vma(struct mm_struct *mm, struct xol_area *area)
}
ret = install_special_mapping(mm, area->vaddr, PAGE_SIZE,
- VM_EXEC|VM_MAYEXEC|VM_DONTCOPY|VM_IO, &area->page);
+ VM_EXEC|VM_MAYEXEC|VM_DONTCOPY|VM_IO, area->pages);
if (ret)
goto fail;
@@ -1168,21 +1168,22 @@ static struct xol_area *__create_xol_area(unsigned long vaddr)
if (!area->bitmap)
goto free_area;
- area->page = alloc_page(GFP_HIGHUSER);
- if (!area->page)
+ area->pages[0] = alloc_page(GFP_HIGHUSER);
+ if (!area->pages[0])
goto free_bitmap;
+ area->pages[1] = NULL;
area->vaddr = vaddr;
init_waitqueue_head(&area->wq);
/* Reserve the 1st slot for get_trampoline_vaddr() */
set_bit(0, area->bitmap);
atomic_set(&area->slot_count, 1);
- copy_to_page(area->page, 0, &insn, UPROBE_SWBP_INSN_SIZE);
+ copy_to_page(area->pages[0], 0, &insn, UPROBE_SWBP_INSN_SIZE);
if (!xol_add_vma(mm, area))
return area;
- __free_page(area->page);
+ __free_page(area->pages[0]);
free_bitmap:
kfree(area->bitmap);
free_area:
@@ -1220,7 +1221,7 @@ void uprobe_clear_state(struct mm_struct *mm)
if (!area)
return;
- put_page(area->page);
+ put_page(area->pages[0]);
kfree(area->bitmap);
kfree(area);
}
@@ -1289,7 +1290,7 @@ static unsigned long xol_get_insn_slot(struct uprobe *uprobe)
if (unlikely(!xol_vaddr))
return 0;
- arch_uprobe_copy_ixol(area->page, xol_vaddr,
+ arch_uprobe_copy_ixol(area->pages[0], xol_vaddr,
&uprobe->arch.ixol, sizeof(uprobe->arch.ixol));
return xol_vaddr;
--
1.5.5.1
^ permalink raw reply related [flat|nested] 13+ messages in thread* [PATCH v2 2/3] uprobes: use vm_special_mapping to name the xol vma
2015-07-09 22:25 ` [PATCH v2 0/3] uprobes: minor fixes + name the xol vma Oleg Nesterov
2015-07-09 22:25 ` [PATCH v2 1/3] uprobes: fix the usage of install_special_mapping() Oleg Nesterov
@ 2015-07-09 22:25 ` Oleg Nesterov
2015-07-09 22:25 ` [PATCH v2 3/3] uprobes: fix the waitqueue_active() check in xol_free_insn_slot() Oleg Nesterov
2 siblings, 0 replies; 13+ messages in thread
From: Oleg Nesterov @ 2015-07-09 22:25 UTC (permalink / raw)
To: Ingo Molnar, Srikar Dronamraju
Cc: Andy Lutomirski, Kirill A. Shutemov, linux-kernel
Change xol_add_vma() to use _install_special_mapping(), this way
we can name the vma installed by uprobes. Currently it looks like
private anonymous mapping, this is confusing and complicates the
debugging. With this change /proc/$pid/maps reports "[uprobes]".
As a side effect this will cause core dumps to include xol vma and
I think this is good; this can help to debug the problem if the app
crashed because it was probed.
Signed-off-by: Oleg Nesterov <oleg@redhat.com>
---
kernel/events/uprobes.c | 30 ++++++++++++++++++++----------
1 files changed, 20 insertions(+), 10 deletions(-)
diff --git a/kernel/events/uprobes.c b/kernel/events/uprobes.c
index 4b8ac5f..2d5b7bd 100644
--- a/kernel/events/uprobes.c
+++ b/kernel/events/uprobes.c
@@ -96,17 +96,18 @@ struct uprobe {
* allocated.
*/
struct xol_area {
- wait_queue_head_t wq; /* if all slots are busy */
- atomic_t slot_count; /* number of in-use slots */
- unsigned long *bitmap; /* 0 = free slot */
- struct page *pages[2];
+ wait_queue_head_t wq; /* if all slots are busy */
+ atomic_t slot_count; /* number of in-use slots */
+ unsigned long *bitmap; /* 0 = free slot */
+ struct vm_special_mapping xol_mapping;
+ struct page *pages[2];
/*
* We keep the vma's vm_start rather than a pointer to the vma
* itself. The probed process or a naughty kernel module could make
* the vma go away, and we must handle that reasonably gracefully.
*/
- unsigned long vaddr; /* Page(s) of instruction slots */
+ unsigned long vaddr; /* Page(s) of instruction slots */
};
/*
@@ -1125,11 +1126,14 @@ void uprobe_munmap(struct vm_area_struct *vma, unsigned long start, unsigned lon
/* Slot allocation for XOL */
static int xol_add_vma(struct mm_struct *mm, struct xol_area *area)
{
- int ret = -EALREADY;
+ struct vm_area_struct *vma;
+ int ret;
down_write(&mm->mmap_sem);
- if (mm->uprobes_state.xol_area)
+ if (mm->uprobes_state.xol_area) {
+ ret = -EALREADY;
goto fail;
+ }
if (!area->vaddr) {
/* Try to map as high as possible, this is only a hint. */
@@ -1141,11 +1145,15 @@ static int xol_add_vma(struct mm_struct *mm, struct xol_area *area)
}
}
- ret = install_special_mapping(mm, area->vaddr, PAGE_SIZE,
- VM_EXEC|VM_MAYEXEC|VM_DONTCOPY|VM_IO, area->pages);
- if (ret)
+ vma = _install_special_mapping(mm, area->vaddr, PAGE_SIZE,
+ VM_EXEC|VM_MAYEXEC|VM_DONTCOPY|VM_IO,
+ &area->xol_mapping);
+ if (IS_ERR(vma)) {
+ ret = PTR_ERR(vma);
goto fail;
+ }
+ ret = 0;
smp_wmb(); /* pairs with get_xol_area() */
mm->uprobes_state.xol_area = area;
fail:
@@ -1168,6 +1176,8 @@ static struct xol_area *__create_xol_area(unsigned long vaddr)
if (!area->bitmap)
goto free_area;
+ area->xol_mapping.name = "[uprobes]";
+ area->xol_mapping.pages = area->pages;
area->pages[0] = alloc_page(GFP_HIGHUSER);
if (!area->pages[0])
goto free_bitmap;
--
1.5.5.1
^ permalink raw reply related [flat|nested] 13+ messages in thread* [PATCH v2 3/3] uprobes: fix the waitqueue_active() check in xol_free_insn_slot()
2015-07-09 22:25 ` [PATCH v2 0/3] uprobes: minor fixes + name the xol vma Oleg Nesterov
2015-07-09 22:25 ` [PATCH v2 1/3] uprobes: fix the usage of install_special_mapping() Oleg Nesterov
2015-07-09 22:25 ` [PATCH v2 2/3] uprobes: use vm_special_mapping to name the xol vma Oleg Nesterov
@ 2015-07-09 22:25 ` Oleg Nesterov
2 siblings, 0 replies; 13+ messages in thread
From: Oleg Nesterov @ 2015-07-09 22:25 UTC (permalink / raw)
To: Ingo Molnar, Srikar Dronamraju
Cc: Andy Lutomirski, Kirill A. Shutemov, linux-kernel
The xol_free_insn_slot()->waitqueue_active() check is buggy. We need
mb() after we set the conditon for wait_event(), or xol_take_insn_slot()
can miss the wakeup.
Signed-off-by: Oleg Nesterov <oleg@redhat.com>
---
kernel/events/uprobes.c | 1 +
1 files changed, 1 insertions(+), 0 deletions(-)
diff --git a/kernel/events/uprobes.c b/kernel/events/uprobes.c
index 2d5b7bd..4e5e979 100644
--- a/kernel/events/uprobes.c
+++ b/kernel/events/uprobes.c
@@ -1337,6 +1337,7 @@ static void xol_free_insn_slot(struct task_struct *tsk)
clear_bit(slot_nr, area->bitmap);
atomic_dec(&area->slot_count);
+ smp_mb__after_atomic(); /* pairs with prepare_to_wait() */
if (waitqueue_active(&area->wq))
wake_up(&area->wq);
--
1.5.5.1
^ permalink raw reply related [flat|nested] 13+ messages in thread