diff options
author | Stan Cox <scox@redhat.com> | 2009-09-16 21:05:00 -0400 |
---|---|---|
committer | Stan Cox <scox@redhat.com> | 2009-09-16 21:05:00 -0400 |
commit | 6846cfc8a5cdb24fccb19037b27a180d2300ee09 (patch) | |
tree | 9dbcddce5f4410d96b98ec5beb757e74c901e74c /runtime/access_process_vm.h | |
parent | 9f7d5236c8fb1fd84636656416e1dad531e9586d (diff) | |
download | systemtap-steved-6846cfc8a5cdb24fccb19037b27a180d2300ee09.tar.gz systemtap-steved-6846cfc8a5cdb24fccb19037b27a180d2300ee09.tar.xz systemtap-steved-6846cfc8a5cdb24fccb19037b27a180d2300ee09.zip |
* sdt.h (STAP_SEMAPHORE): New. Add guard to utrace probe points.
* itrace.h (__access_process_vm): Moved from here...
* runtime/access_process_vm.h: New. ...to here.
* translate.cxx (translate_pass): Include access_process_vm.h
* session.h (sdt_semaphore_addr): New.
* tapsets.cxx (sdt_query::record_semaphore): New. Record sdt_semaphore_addr.
(uprobe_derived_probe_group::emit_module_decls): Allow for uprobe guard variable to be set and unset.
(uprobe_derived_probe_group::emit_module_decls): Likewise.
(uprobe_derived_probe_group::emit_module_exit): Likewise.
* tapset-utrace.cxx (utrace_derived_probe_group::emit_probe_decl): Likewise.
(utrace_derived_probe_group::emit_module_decls): Likewise.
(utrace_derived_probe_group::emit_module_exit): Likewise.
Diffstat (limited to 'runtime/access_process_vm.h')
-rw-r--r-- | runtime/access_process_vm.h | 54 |
1 files changed, 54 insertions, 0 deletions
diff --git a/runtime/access_process_vm.h b/runtime/access_process_vm.h new file mode 100644 index 00000000..70489d48 --- /dev/null +++ b/runtime/access_process_vm.h @@ -0,0 +1,54 @@ +/* + * The kernel's access_process_vm is not exported in kernel.org kernels, although + * some distros export it on some architectures. To workaround this inconsistency, + * we copied and pasted it here. Fortunately, everything it calls is exported. + */ +#include <linux/pagemap.h> +#include <asm/cacheflush.h> +static int __access_process_vm(struct task_struct *tsk, unsigned long addr, void *buf, int len, int write) +{ + struct mm_struct *mm; + struct vm_area_struct *vma; + struct page *page; + void *old_buf = buf; + + mm = get_task_mm(tsk); + if (!mm) + return 0; + + down_read(&mm->mmap_sem); + /* ignore errors, just check how much was sucessfully transfered */ + while (len) { + int bytes, ret, offset; + void *maddr; + + ret = get_user_pages(tsk, mm, addr, 1, + write, 1, &page, &vma); + if (ret <= 0) + break; + + bytes = len; + offset = addr & (PAGE_SIZE-1); + if (bytes > PAGE_SIZE-offset) + bytes = PAGE_SIZE-offset; + + maddr = kmap(page); + if (write) { + copy_to_user_page(vma, page, addr, + maddr + offset, buf, bytes); + set_page_dirty_lock(page); + } else { + copy_from_user_page(vma, page, addr, + buf, maddr + offset, bytes); + } + kunmap(page); + page_cache_release(page); + len -= bytes; + buf += bytes; + addr += bytes; + } + up_read(&mm->mmap_sem); + mmput(mm); + + return buf - old_buf; +} |