]> git.karo-electronics.de Git - karo-tx-linux.git/commit
uprobes: Install and remove breakpoints.
authorSrikar Dronamraju <srikar@linux.vnet.ibm.com>
Wed, 7 Dec 2011 10:15:47 +0000 (15:45 +0530)
committerSrikar Dronamraju <srikar@linux.vnet.ibm.com>
Sun, 18 Dec 2011 06:22:57 +0000 (11:52 +0530)
commit70b8389289038e2963eba6581be428cff40c988c
treeeeb63048842ca9f893687051d39898a70229be67
parent18fe9f4383d259a902a4c7019d3bf37c2e9757e5
uprobes: Install and remove breakpoints.

Uprobes are maintained in an rb-tree indexed by inode and offset (the
offset here is from the start of the mapping). For a unique (inode,
offset) tuple, there can be atmost one uprobe in the rb-tree.

Since the (inode, offset) tuple identifies a unique uprobe, more
than one user may be interested in the same uprobe. Provides the
ability to hook multiple 'consumers' for the same uprobe.

Each consumer defines a handler and a filter (optional). The
'handler' is run every time the uprobe is hit, if it matches the
'filter' criteria.

The first consumer of a uprobe causes the breakpoint to be inserted
at the specified address and subsequent consumers are appended to
this list.  On subsequent probes, the consumer gets appended to the
existing list of consumers. The breakpoint is removed when the last
consumer unregisters. All other unregisterations, the consumer is
removed from the list of consumers.

Given a inode, we get a list of mm's that have mapped the inode. Do
the actual registration if mm maps the page where a probe needs to
be inserted/removed.

We use a temporary list to walk thro the vmas that map the inode.
- The number of maps that map the inode, is not known before we walk
  the rmap and keeps changing.
- extending vm_area_struct wasnt recommended.
- There can be more than one maps of the inode in the same mm.

Hook mmap to keep an eye on text vmas that are of interest to
uprobes.  When a vma of interest is mapped, insert the breakpoint at
the right address.

Uprobe works by replacing the instruction at the address defined by
(inode, offset) with the arch specific breakpoint instruction. Save a
copy of the original instruction at the uprobed address.

This is needed for:
a. executing the instruction out-of-line (xol).
b. instruction analysis for any subsequent fixups.
c. restoring the instruction back when the uprobe is unregistered.

We insert or delete a breakpoint instruction, and this breakpoint
instructions is assumed to be the smallest instruction available on
the platform. For fixed size instruction platforms this is trivially
true, for variable size instruction platforms the breakpoint
instruction is typically the smallest (often a single byte).

Writing the instruction is done by COWing the page and changing the
instruction during the copy, this even though most platforms allow
atomic writes of the breakpoint instruction. This also mirrors the
behaviour of a ptrace() memory write to a PRIVATE file map.

The core worker is derived from ksm's replace_page() logic.

In essence, similar to ksm:
a. allocate a new page and copy over contents of the page that has the
   uprobed vaddr
b. modify the copy and insert the breakpoint at the required address
c. switch the original page with the copy containing the breakpoint
d. flush page tables.

replace_page is being replicated here because of some minor changes
in the type of pages and also because Hugh Dickins had plans to
improve replace_page for ksm specific work.

Instruction analysis on x86 is based on instruction decoder and
determines if an instruction can be probed and determines the
necessary fixups after singlestep.  Instruction analysis is done at
probe insertion time so that we avoid having to repeat the same
analysis every time a probe is hit.

A lot of code here is due to the improvement/suggestions/inputs from
Peter.

Signed-off-by: Jim Keniston <jkenisto@us.ibm.com>
Signed-off-by: Srikar Dronamraju <srikar@linux.vnet.ibm.com>
arch/Kconfig
arch/x86/Kconfig
arch/x86/include/asm/uprobes.h [new file with mode: 0644]
arch/x86/kernel/Makefile
arch/x86/kernel/uprobes.c [new file with mode: 0644]
include/linux/uprobes.h [new file with mode: 0644]
kernel/Makefile
kernel/uprobes.c [new file with mode: 0644]
mm/mmap.c