I don't think I can review, I forgot everything, but I'll try to read this
series when I have time to (try to) understand what it does...
On 06/24, Andrii Nakryiko wrote:
>
> Given unapply_uprobe() can call remove_breakpoint() which eventually
> calls uprobe_write_opcode(), which can modify a set of memory pages and
> expects mm->mmap_lock held for write, it needs to have writer lock.
>
> Fix this by switching to mmap_write_lock()/mmap_write_unlock().
>
> Fixes: da1816b1caec ("uprobes: Teach handler_chain() to filter out the probed
> task")
> Signed-off-by: Andrii Nakryiko <[email protected]>
> ---
> kernel/events/uprobes.c | 4 ++--
> 1 file changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/kernel/events/uprobes.c b/kernel/events/uprobes.c
> index 197fbe4663b5..e896eeecb091 100644
> --- a/kernel/events/uprobes.c
> +++ b/kernel/events/uprobes.c
> @@ -1235,7 +1235,7 @@ static int unapply_uprobe(struct uprobe *uprobe, struct
> mm_struct *mm)
> struct vm_area_struct *vma;
> int err = 0;
>
> - mmap_read_lock(mm);
> + mmap_write_lock(mm);
Can you explain what exactly is wrong?
FOLL_FORCE/etc is fine under mmap_read_lock(), __replace_page() seems too...
I recall that initially uprobes.c always took mmap_sem for reading, then
register_for_each_vma() was changed by 77fc4af1b59d12 but there was other
reasons for this change...
Again, I don't understand this code today, quite possibly I missed something,
I am just trying to understand.
Well, it seems there is another reason for this change... Currently 2
unapply_uprobe()'s can race with each other if they try to update the same
page. But in this case we can rely on -EAGAIN from __replace_page() ?
Oleg.