Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

uprobes: Remove breakpoint in unapply_uprobe under mmap_write_lock

Currently unapply_uprobe takes mmap_read_lock, but it might call
remove_breakpoint which eventually changes user pages.

Current code writes either breakpoint or original instruction, so it can
go away with read lock as explained in here [1]. But with the upcoming
change that writes multiple instructions on the probed address we need
to ensure that any update to mm's pages is exclusive.

[1] https://lore.kernel.org/all/20240710140045.GA1084@redhat.com/

Signed-off-by: Jiri Olsa <jolsa@kernel.org>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Acked-by: Andrii Nakryiko <andrii@kernel.org>
Acked-by: Masami Hiramatsu (Google) <mhiramat@kernel.org>
Acked-by: Oleg Nesterov <oleg@redhat.com>
Link: https://lore.kernel.org/r/20250720112133.244369-2-jolsa@kernel.org

authored by

Jiri Olsa and committed by
Peter Zijlstra
7769cb17 448f97fb

+3 -3
+3 -3
kernel/events/uprobes.c
··· 482 482 * @opcode_vaddr: the virtual address to store the opcode. 483 483 * @opcode: opcode to be written at @opcode_vaddr. 484 484 * 485 - * Called with mm->mmap_lock held for read or write. 485 + * Called with mm->mmap_lock held for write. 486 486 * Return 0 (success) or a negative errno. 487 487 */ 488 488 int uprobe_write_opcode(struct arch_uprobe *auprobe, struct vm_area_struct *vma, ··· 1463 1463 struct vm_area_struct *vma; 1464 1464 int err = 0; 1465 1465 1466 - mmap_read_lock(mm); 1466 + mmap_write_lock(mm); 1467 1467 for_each_vma(vmi, vma) { 1468 1468 unsigned long vaddr; 1469 1469 loff_t offset; ··· 1480 1480 vaddr = offset_to_vaddr(vma, uprobe->offset); 1481 1481 err |= remove_breakpoint(uprobe, vma, vaddr); 1482 1482 } 1483 - mmap_read_unlock(mm); 1483 + mmap_write_unlock(mm); 1484 1484 1485 1485 return err; 1486 1486 }