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.

kernel/events/uprobes: pass VMA to set_swbp(), set_orig_insn() and uprobe_write_opcode()

We already have the VMA, no need to look it up using
get_user_page_vma_remote(). We can now switch to get_user_pages_remote().

Link: https://lkml.kernel.org/r/20250321113713.204682-3-david@redhat.com
Signed-off-by: David Hildenbrand <david@redhat.com>
Acked-by: Oleg Nesterov <oleg@redhat.com>
Acked-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Andrii Nakryiko <andrii.nakryiko@gmail.com>
Cc: Arnaldo Carvalho de Melo <acme@kernel.org>
Cc: Ian Rogers <irogers@google.com>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Jiri Olsa <olsajiri@gmail.com>
Cc: Kan Liang <kan.liang@linux.intel.com>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: "Masami Hiramatsu (Google)" <mhiramat@kernel.org>
Cc: Matthew Wilcox (Oracle) <willy@infradead.org>
Cc: Namhyung kim <namhyung@kernel.org>
Cc: Russel King <linux@armlinux.org.uk>
Cc: tongtiangen <tongtiangen@huawei.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>

authored by

David Hildenbrand and committed by
Andrew Morton
8a557742 b56e6446

+22 -21
+2 -2
arch/arm/probes/uprobes/core.c
··· 26 26 (UPROBE_SWBP_ARM_INSN & 0x0fffffff); 27 27 } 28 28 29 - int set_swbp(struct arch_uprobe *auprobe, struct mm_struct *mm, 29 + int set_swbp(struct arch_uprobe *auprobe, struct vm_area_struct *vma, 30 30 unsigned long vaddr) 31 31 { 32 - return uprobe_write_opcode(auprobe, mm, vaddr, 32 + return uprobe_write_opcode(auprobe, vma, vaddr, 33 33 __opcode_to_mem_arm(auprobe->bpinsn)); 34 34 } 35 35
+3 -3
include/linux/uprobes.h
··· 188 188 }; 189 189 190 190 extern void __init uprobes_init(void); 191 - extern int set_swbp(struct arch_uprobe *aup, struct mm_struct *mm, unsigned long vaddr); 192 - extern int set_orig_insn(struct arch_uprobe *aup, struct mm_struct *mm, unsigned long vaddr); 191 + extern int set_swbp(struct arch_uprobe *aup, struct vm_area_struct *vma, unsigned long vaddr); 192 + extern int set_orig_insn(struct arch_uprobe *aup, struct vm_area_struct *vma, unsigned long vaddr); 193 193 extern bool is_swbp_insn(uprobe_opcode_t *insn); 194 194 extern bool is_trap_insn(uprobe_opcode_t *insn); 195 195 extern unsigned long uprobe_get_swbp_addr(struct pt_regs *regs); 196 196 extern unsigned long uprobe_get_trap_addr(struct pt_regs *regs); 197 - extern int uprobe_write_opcode(struct arch_uprobe *auprobe, struct mm_struct *mm, unsigned long vaddr, uprobe_opcode_t); 197 + extern int uprobe_write_opcode(struct arch_uprobe *auprobe, struct vm_area_struct *vma, unsigned long vaddr, uprobe_opcode_t); 198 198 extern struct uprobe *uprobe_register(struct inode *inode, loff_t offset, loff_t ref_ctr_offset, struct uprobe_consumer *uc); 199 199 extern int uprobe_apply(struct uprobe *uprobe, struct uprobe_consumer *uc, bool); 200 200 extern void uprobe_unregister_nosync(struct uprobe *uprobe, struct uprobe_consumer *uc);
+17 -16
kernel/events/uprobes.c
··· 474 474 * 475 475 * uprobe_write_opcode - write the opcode at a given virtual address. 476 476 * @auprobe: arch specific probepoint information. 477 - * @mm: the probed process address space. 477 + * @vma: the probed virtual memory area. 478 478 * @vaddr: the virtual address to store the opcode. 479 479 * @opcode: opcode to be written at @vaddr. 480 480 * 481 481 * Called with mm->mmap_lock held for read or write. 482 482 * Return 0 (success) or a negative errno. 483 483 */ 484 - int uprobe_write_opcode(struct arch_uprobe *auprobe, struct mm_struct *mm, 485 - unsigned long vaddr, uprobe_opcode_t opcode) 484 + int uprobe_write_opcode(struct arch_uprobe *auprobe, struct vm_area_struct *vma, 485 + unsigned long vaddr, uprobe_opcode_t opcode) 486 486 { 487 + struct mm_struct *mm = vma->vm_mm; 487 488 struct uprobe *uprobe; 488 489 struct page *old_page, *new_page; 489 - struct vm_area_struct *vma; 490 490 int ret, is_register, ref_ctr_updated = 0; 491 491 bool orig_page_huge = false; 492 492 unsigned int gup_flags = FOLL_FORCE; ··· 498 498 if (is_register) 499 499 gup_flags |= FOLL_SPLIT_PMD; 500 500 /* Read the page with vaddr into memory */ 501 - old_page = get_user_page_vma_remote(mm, vaddr, gup_flags, &vma); 502 - if (IS_ERR(old_page)) 503 - return PTR_ERR(old_page); 501 + ret = get_user_pages_remote(mm, vaddr, 1, gup_flags, &old_page, NULL); 502 + if (ret != 1) 503 + return ret; 504 504 505 505 ret = verify_opcode(old_page, vaddr, &opcode); 506 506 if (ret <= 0) ··· 590 590 /** 591 591 * set_swbp - store breakpoint at a given address. 592 592 * @auprobe: arch specific probepoint information. 593 - * @mm: the probed process address space. 593 + * @vma: the probed virtual memory area. 594 594 * @vaddr: the virtual address to insert the opcode. 595 595 * 596 596 * For mm @mm, store the breakpoint instruction at @vaddr. 597 597 * Return 0 (success) or a negative errno. 598 598 */ 599 - int __weak set_swbp(struct arch_uprobe *auprobe, struct mm_struct *mm, unsigned long vaddr) 599 + int __weak set_swbp(struct arch_uprobe *auprobe, struct vm_area_struct *vma, 600 + unsigned long vaddr) 600 601 { 601 - return uprobe_write_opcode(auprobe, mm, vaddr, UPROBE_SWBP_INSN); 602 + return uprobe_write_opcode(auprobe, vma, vaddr, UPROBE_SWBP_INSN); 602 603 } 603 604 604 605 /** 605 606 * set_orig_insn - Restore the original instruction. 606 - * @mm: the probed process address space. 607 + * @vma: the probed virtual memory area. 607 608 * @auprobe: arch specific probepoint information. 608 609 * @vaddr: the virtual address to insert the opcode. 609 610 * 610 611 * For mm @mm, restore the original opcode (opcode) at @vaddr. 611 612 * Return 0 (success) or a negative errno. 612 613 */ 613 - int __weak 614 - set_orig_insn(struct arch_uprobe *auprobe, struct mm_struct *mm, unsigned long vaddr) 614 + int __weak set_orig_insn(struct arch_uprobe *auprobe, 615 + struct vm_area_struct *vma, unsigned long vaddr) 615 616 { 616 - return uprobe_write_opcode(auprobe, mm, vaddr, 617 + return uprobe_write_opcode(auprobe, vma, vaddr, 617 618 *(uprobe_opcode_t *)&auprobe->insn); 618 619 } 619 620 ··· 1154 1153 if (first_uprobe) 1155 1154 set_bit(MMF_HAS_UPROBES, &mm->flags); 1156 1155 1157 - ret = set_swbp(&uprobe->arch, mm, vaddr); 1156 + ret = set_swbp(&uprobe->arch, vma, vaddr); 1158 1157 if (!ret) 1159 1158 clear_bit(MMF_RECALC_UPROBES, &mm->flags); 1160 1159 else if (first_uprobe) ··· 1169 1168 struct mm_struct *mm = vma->vm_mm; 1170 1169 1171 1170 set_bit(MMF_RECALC_UPROBES, &mm->flags); 1172 - return set_orig_insn(&uprobe->arch, mm, vaddr); 1171 + return set_orig_insn(&uprobe->arch, vma, vaddr); 1173 1172 } 1174 1173 1175 1174 struct map_info {