diff options
author | Srikar Dronamraju <srikar@linux.vnet.ibm.com> | 2012-02-22 04:16:02 -0500 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2012-02-22 05:26:09 -0500 |
commit | 3ff54efdfaace9e9b2b7c1959a865be6b91de96c (patch) | |
tree | 6218c7b40bd80704d059d5f3fa434974e675b070 /kernel/events | |
parent | 96379f60075c75b261328aa7830ef8aa158247ac (diff) |
uprobes/core: Move insn to arch specific structure
Few cleanups suggested by Ingo Molnar.
- Rename struct uprobe_arch_info to struct arch_uprobe.
- Move insn from struct uprobe to struct arch_uprobe.
- Make arch specific uprobe functions to accept struct arch_uprobe
instead of struct uprobe.
- Move struct uprobe to kernel/uprobes.c from include/linux/uprobes.h
Signed-off-by: Srikar Dronamraju <srikar@linux.vnet.ibm.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Oleg Nesterov <oleg@redhat.com>
Cc: Christoph Hellwig <hch@infradead.org>
Cc: Steven Rostedt <rostedt@goodmis.org>
Cc: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Cc: Anton Arapov <anton@redhat.com>
Cc: Ananth N Mavinakayanahalli <ananth@in.ibm.com>
Cc: Jim Keniston <jkenisto@linux.vnet.ibm.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Josh Stone <jistone@redhat.com>
Link: http://lkml.kernel.org/r/20120222091602.15880.40249.sendpatchset@srdronam.in.ibm.com
[ Made various small improvements ]
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'kernel/events')
-rw-r--r-- | kernel/events/uprobes.c | 38 |
1 files changed, 26 insertions, 12 deletions
diff --git a/kernel/events/uprobes.c b/kernel/events/uprobes.c index ee496ad95db3..13f1b5909af4 100644 --- a/kernel/events/uprobes.c +++ b/kernel/events/uprobes.c | |||
@@ -65,6 +65,18 @@ struct vma_info { | |||
65 | loff_t vaddr; | 65 | loff_t vaddr; |
66 | }; | 66 | }; |
67 | 67 | ||
68 | struct uprobe { | ||
69 | struct rb_node rb_node; /* node in the rb tree */ | ||
70 | atomic_t ref; | ||
71 | struct rw_semaphore consumer_rwsem; | ||
72 | struct list_head pending_list; | ||
73 | struct uprobe_consumer *consumers; | ||
74 | struct inode *inode; /* Also hold a ref to inode */ | ||
75 | loff_t offset; | ||
76 | int flags; | ||
77 | struct arch_uprobe arch; | ||
78 | }; | ||
79 | |||
68 | /* | 80 | /* |
69 | * valid_vma: Verify if the specified vma is an executable vma | 81 | * valid_vma: Verify if the specified vma is an executable vma |
70 | * Relax restrictions while unregistering: vm_flags might have | 82 | * Relax restrictions while unregistering: vm_flags might have |
@@ -180,7 +192,7 @@ bool __weak is_bkpt_insn(uprobe_opcode_t *insn) | |||
180 | /* | 192 | /* |
181 | * write_opcode - write the opcode at a given virtual address. | 193 | * write_opcode - write the opcode at a given virtual address. |
182 | * @mm: the probed process address space. | 194 | * @mm: the probed process address space. |
183 | * @uprobe: the breakpointing information. | 195 | * @arch_uprobe: the breakpointing information. |
184 | * @vaddr: the virtual address to store the opcode. | 196 | * @vaddr: the virtual address to store the opcode. |
185 | * @opcode: opcode to be written at @vaddr. | 197 | * @opcode: opcode to be written at @vaddr. |
186 | * | 198 | * |
@@ -190,13 +202,14 @@ bool __weak is_bkpt_insn(uprobe_opcode_t *insn) | |||
190 | * For mm @mm, write the opcode at @vaddr. | 202 | * For mm @mm, write the opcode at @vaddr. |
191 | * Return 0 (success) or a negative errno. | 203 | * Return 0 (success) or a negative errno. |
192 | */ | 204 | */ |
193 | static int write_opcode(struct mm_struct *mm, struct uprobe *uprobe, | 205 | static int write_opcode(struct mm_struct *mm, struct arch_uprobe *auprobe, |
194 | unsigned long vaddr, uprobe_opcode_t opcode) | 206 | unsigned long vaddr, uprobe_opcode_t opcode) |
195 | { | 207 | { |
196 | struct page *old_page, *new_page; | 208 | struct page *old_page, *new_page; |
197 | struct address_space *mapping; | 209 | struct address_space *mapping; |
198 | void *vaddr_old, *vaddr_new; | 210 | void *vaddr_old, *vaddr_new; |
199 | struct vm_area_struct *vma; | 211 | struct vm_area_struct *vma; |
212 | struct uprobe *uprobe; | ||
200 | loff_t addr; | 213 | loff_t addr; |
201 | int ret; | 214 | int ret; |
202 | 215 | ||
@@ -216,6 +229,7 @@ static int write_opcode(struct mm_struct *mm, struct uprobe *uprobe, | |||
216 | if (!valid_vma(vma, is_bkpt_insn(&opcode))) | 229 | if (!valid_vma(vma, is_bkpt_insn(&opcode))) |
217 | goto put_out; | 230 | goto put_out; |
218 | 231 | ||
232 | uprobe = container_of(auprobe, struct uprobe, arch); | ||
219 | mapping = uprobe->inode->i_mapping; | 233 | mapping = uprobe->inode->i_mapping; |
220 | if (mapping != vma->vm_file->f_mapping) | 234 | if (mapping != vma->vm_file->f_mapping) |
221 | goto put_out; | 235 | goto put_out; |
@@ -326,7 +340,7 @@ static int is_bkpt_at_addr(struct mm_struct *mm, unsigned long vaddr) | |||
326 | * For mm @mm, store the breakpoint instruction at @vaddr. | 340 | * For mm @mm, store the breakpoint instruction at @vaddr. |
327 | * Return 0 (success) or a negative errno. | 341 | * Return 0 (success) or a negative errno. |
328 | */ | 342 | */ |
329 | int __weak set_bkpt(struct mm_struct *mm, struct uprobe *uprobe, unsigned long vaddr) | 343 | int __weak set_bkpt(struct mm_struct *mm, struct arch_uprobe *auprobe, unsigned long vaddr) |
330 | { | 344 | { |
331 | int result; | 345 | int result; |
332 | 346 | ||
@@ -337,7 +351,7 @@ int __weak set_bkpt(struct mm_struct *mm, struct uprobe *uprobe, unsigned long v | |||
337 | if (result) | 351 | if (result) |
338 | return result; | 352 | return result; |
339 | 353 | ||
340 | return write_opcode(mm, uprobe, vaddr, UPROBES_BKPT_INSN); | 354 | return write_opcode(mm, auprobe, vaddr, UPROBES_BKPT_INSN); |
341 | } | 355 | } |
342 | 356 | ||
343 | /** | 357 | /** |
@@ -351,7 +365,7 @@ int __weak set_bkpt(struct mm_struct *mm, struct uprobe *uprobe, unsigned long v | |||
351 | * Return 0 (success) or a negative errno. | 365 | * Return 0 (success) or a negative errno. |
352 | */ | 366 | */ |
353 | int __weak | 367 | int __weak |
354 | set_orig_insn(struct mm_struct *mm, struct uprobe *uprobe, unsigned long vaddr, bool verify) | 368 | set_orig_insn(struct mm_struct *mm, struct arch_uprobe *auprobe, unsigned long vaddr, bool verify) |
355 | { | 369 | { |
356 | if (verify) { | 370 | if (verify) { |
357 | int result; | 371 | int result; |
@@ -363,7 +377,7 @@ set_orig_insn(struct mm_struct *mm, struct uprobe *uprobe, unsigned long vaddr, | |||
363 | if (result != 1) | 377 | if (result != 1) |
364 | return result; | 378 | return result; |
365 | } | 379 | } |
366 | return write_opcode(mm, uprobe, vaddr, *(uprobe_opcode_t *)uprobe->insn); | 380 | return write_opcode(mm, auprobe, vaddr, *(uprobe_opcode_t *)auprobe->insn); |
367 | } | 381 | } |
368 | 382 | ||
369 | static int match_uprobe(struct uprobe *l, struct uprobe *r) | 383 | static int match_uprobe(struct uprobe *l, struct uprobe *r) |
@@ -593,13 +607,13 @@ static int copy_insn(struct uprobe *uprobe, struct vm_area_struct *vma, unsigned | |||
593 | 607 | ||
594 | /* Instruction at the page-boundary; copy bytes in second page */ | 608 | /* Instruction at the page-boundary; copy bytes in second page */ |
595 | if (nbytes < bytes) { | 609 | if (nbytes < bytes) { |
596 | if (__copy_insn(mapping, vma, uprobe->insn + nbytes, | 610 | if (__copy_insn(mapping, vma, uprobe->arch.insn + nbytes, |
597 | bytes - nbytes, uprobe->offset + nbytes)) | 611 | bytes - nbytes, uprobe->offset + nbytes)) |
598 | return -ENOMEM; | 612 | return -ENOMEM; |
599 | 613 | ||
600 | bytes = nbytes; | 614 | bytes = nbytes; |
601 | } | 615 | } |
602 | return __copy_insn(mapping, vma, uprobe->insn, bytes, uprobe->offset); | 616 | return __copy_insn(mapping, vma, uprobe->arch.insn, bytes, uprobe->offset); |
603 | } | 617 | } |
604 | 618 | ||
605 | static int install_breakpoint(struct mm_struct *mm, struct uprobe *uprobe, | 619 | static int install_breakpoint(struct mm_struct *mm, struct uprobe *uprobe, |
@@ -625,23 +639,23 @@ static int install_breakpoint(struct mm_struct *mm, struct uprobe *uprobe, | |||
625 | if (ret) | 639 | if (ret) |
626 | return ret; | 640 | return ret; |
627 | 641 | ||
628 | if (is_bkpt_insn((uprobe_opcode_t *)uprobe->insn)) | 642 | if (is_bkpt_insn((uprobe_opcode_t *)uprobe->arch.insn)) |
629 | return -EEXIST; | 643 | return -EEXIST; |
630 | 644 | ||
631 | ret = arch_uprobes_analyze_insn(mm, uprobe); | 645 | ret = arch_uprobes_analyze_insn(mm, &uprobe->arch); |
632 | if (ret) | 646 | if (ret) |
633 | return ret; | 647 | return ret; |
634 | 648 | ||
635 | uprobe->flags |= UPROBES_COPY_INSN; | 649 | uprobe->flags |= UPROBES_COPY_INSN; |
636 | } | 650 | } |
637 | ret = set_bkpt(mm, uprobe, addr); | 651 | ret = set_bkpt(mm, &uprobe->arch, addr); |
638 | 652 | ||
639 | return ret; | 653 | return ret; |
640 | } | 654 | } |
641 | 655 | ||
642 | static void remove_breakpoint(struct mm_struct *mm, struct uprobe *uprobe, loff_t vaddr) | 656 | static void remove_breakpoint(struct mm_struct *mm, struct uprobe *uprobe, loff_t vaddr) |
643 | { | 657 | { |
644 | set_orig_insn(mm, uprobe, (unsigned long)vaddr, true); | 658 | set_orig_insn(mm, &uprobe->arch, (unsigned long)vaddr, true); |
645 | } | 659 | } |
646 | 660 | ||
647 | static void delete_uprobe(struct uprobe *uprobe) | 661 | static void delete_uprobe(struct uprobe *uprobe) |