mirror of
https://github.com/torvalds/linux.git
synced 2026-06-02 11:33:28 +02:00
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>
This commit is contained in:
parent
b56e644665
commit
8a5577428e
|
|
@ -26,10 +26,10 @@ bool is_swbp_insn(uprobe_opcode_t *insn)
|
|||
(UPROBE_SWBP_ARM_INSN & 0x0fffffff);
|
||||
}
|
||||
|
||||
int set_swbp(struct arch_uprobe *auprobe, struct mm_struct *mm,
|
||||
int set_swbp(struct arch_uprobe *auprobe, struct vm_area_struct *vma,
|
||||
unsigned long vaddr)
|
||||
{
|
||||
return uprobe_write_opcode(auprobe, mm, vaddr,
|
||||
return uprobe_write_opcode(auprobe, vma, vaddr,
|
||||
__opcode_to_mem_arm(auprobe->bpinsn));
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -188,13 +188,13 @@ struct uprobes_state {
|
|||
};
|
||||
|
||||
extern void __init uprobes_init(void);
|
||||
extern int set_swbp(struct arch_uprobe *aup, struct mm_struct *mm, unsigned long vaddr);
|
||||
extern int set_orig_insn(struct arch_uprobe *aup, struct mm_struct *mm, unsigned long vaddr);
|
||||
extern int set_swbp(struct arch_uprobe *aup, struct vm_area_struct *vma, unsigned long vaddr);
|
||||
extern int set_orig_insn(struct arch_uprobe *aup, struct vm_area_struct *vma, unsigned long vaddr);
|
||||
extern bool is_swbp_insn(uprobe_opcode_t *insn);
|
||||
extern bool is_trap_insn(uprobe_opcode_t *insn);
|
||||
extern unsigned long uprobe_get_swbp_addr(struct pt_regs *regs);
|
||||
extern unsigned long uprobe_get_trap_addr(struct pt_regs *regs);
|
||||
extern int uprobe_write_opcode(struct arch_uprobe *auprobe, struct mm_struct *mm, unsigned long vaddr, uprobe_opcode_t);
|
||||
extern int uprobe_write_opcode(struct arch_uprobe *auprobe, struct vm_area_struct *vma, unsigned long vaddr, uprobe_opcode_t);
|
||||
extern struct uprobe *uprobe_register(struct inode *inode, loff_t offset, loff_t ref_ctr_offset, struct uprobe_consumer *uc);
|
||||
extern int uprobe_apply(struct uprobe *uprobe, struct uprobe_consumer *uc, bool);
|
||||
extern void uprobe_unregister_nosync(struct uprobe *uprobe, struct uprobe_consumer *uc);
|
||||
|
|
|
|||
|
|
@ -474,19 +474,19 @@ static int update_ref_ctr(struct uprobe *uprobe, struct mm_struct *mm,
|
|||
*
|
||||
* uprobe_write_opcode - write the opcode at a given virtual address.
|
||||
* @auprobe: arch specific probepoint information.
|
||||
* @mm: the probed process address space.
|
||||
* @vma: the probed virtual memory area.
|
||||
* @vaddr: the virtual address to store the opcode.
|
||||
* @opcode: opcode to be written at @vaddr.
|
||||
*
|
||||
* Called with mm->mmap_lock held for read or write.
|
||||
* Return 0 (success) or a negative errno.
|
||||
*/
|
||||
int uprobe_write_opcode(struct arch_uprobe *auprobe, struct mm_struct *mm,
|
||||
unsigned long vaddr, uprobe_opcode_t opcode)
|
||||
int uprobe_write_opcode(struct arch_uprobe *auprobe, struct vm_area_struct *vma,
|
||||
unsigned long vaddr, uprobe_opcode_t opcode)
|
||||
{
|
||||
struct mm_struct *mm = vma->vm_mm;
|
||||
struct uprobe *uprobe;
|
||||
struct page *old_page, *new_page;
|
||||
struct vm_area_struct *vma;
|
||||
int ret, is_register, ref_ctr_updated = 0;
|
||||
bool orig_page_huge = false;
|
||||
unsigned int gup_flags = FOLL_FORCE;
|
||||
|
|
@ -498,9 +498,9 @@ int uprobe_write_opcode(struct arch_uprobe *auprobe, struct mm_struct *mm,
|
|||
if (is_register)
|
||||
gup_flags |= FOLL_SPLIT_PMD;
|
||||
/* Read the page with vaddr into memory */
|
||||
old_page = get_user_page_vma_remote(mm, vaddr, gup_flags, &vma);
|
||||
if (IS_ERR(old_page))
|
||||
return PTR_ERR(old_page);
|
||||
ret = get_user_pages_remote(mm, vaddr, 1, gup_flags, &old_page, NULL);
|
||||
if (ret != 1)
|
||||
return ret;
|
||||
|
||||
ret = verify_opcode(old_page, vaddr, &opcode);
|
||||
if (ret <= 0)
|
||||
|
|
@ -590,30 +590,31 @@ int uprobe_write_opcode(struct arch_uprobe *auprobe, struct mm_struct *mm,
|
|||
/**
|
||||
* set_swbp - store breakpoint at a given address.
|
||||
* @auprobe: arch specific probepoint information.
|
||||
* @mm: the probed process address space.
|
||||
* @vma: the probed virtual memory area.
|
||||
* @vaddr: the virtual address to insert the opcode.
|
||||
*
|
||||
* For mm @mm, store the breakpoint instruction at @vaddr.
|
||||
* Return 0 (success) or a negative errno.
|
||||
*/
|
||||
int __weak set_swbp(struct arch_uprobe *auprobe, struct mm_struct *mm, unsigned long vaddr)
|
||||
int __weak set_swbp(struct arch_uprobe *auprobe, struct vm_area_struct *vma,
|
||||
unsigned long vaddr)
|
||||
{
|
||||
return uprobe_write_opcode(auprobe, mm, vaddr, UPROBE_SWBP_INSN);
|
||||
return uprobe_write_opcode(auprobe, vma, vaddr, UPROBE_SWBP_INSN);
|
||||
}
|
||||
|
||||
/**
|
||||
* set_orig_insn - Restore the original instruction.
|
||||
* @mm: the probed process address space.
|
||||
* @vma: the probed virtual memory area.
|
||||
* @auprobe: arch specific probepoint information.
|
||||
* @vaddr: the virtual address to insert the opcode.
|
||||
*
|
||||
* For mm @mm, restore the original opcode (opcode) at @vaddr.
|
||||
* Return 0 (success) or a negative errno.
|
||||
*/
|
||||
int __weak
|
||||
set_orig_insn(struct arch_uprobe *auprobe, struct mm_struct *mm, unsigned long vaddr)
|
||||
int __weak set_orig_insn(struct arch_uprobe *auprobe,
|
||||
struct vm_area_struct *vma, unsigned long vaddr)
|
||||
{
|
||||
return uprobe_write_opcode(auprobe, mm, vaddr,
|
||||
return uprobe_write_opcode(auprobe, vma, vaddr,
|
||||
*(uprobe_opcode_t *)&auprobe->insn);
|
||||
}
|
||||
|
||||
|
|
@ -1153,7 +1154,7 @@ static int install_breakpoint(struct uprobe *uprobe, struct vm_area_struct *vma,
|
|||
if (first_uprobe)
|
||||
set_bit(MMF_HAS_UPROBES, &mm->flags);
|
||||
|
||||
ret = set_swbp(&uprobe->arch, mm, vaddr);
|
||||
ret = set_swbp(&uprobe->arch, vma, vaddr);
|
||||
if (!ret)
|
||||
clear_bit(MMF_RECALC_UPROBES, &mm->flags);
|
||||
else if (first_uprobe)
|
||||
|
|
@ -1168,7 +1169,7 @@ static int remove_breakpoint(struct uprobe *uprobe, struct vm_area_struct *vma,
|
|||
struct mm_struct *mm = vma->vm_mm;
|
||||
|
||||
set_bit(MMF_RECALC_UPROBES, &mm->flags);
|
||||
return set_orig_insn(&uprobe->arch, mm, vaddr);
|
||||
return set_orig_insn(&uprobe->arch, vma, vaddr);
|
||||
}
|
||||
|
||||
struct map_info {
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user