This is the mail archive of the systemtap@sourceware.org mailing list for the systemtap project.
Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
---|---|---|
Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |
Other format: | [Raw text] |
Hi, As I mentioned in my previous post today, besides the need for updating runtime/itrace.c to use the new utrace interface, I found another problem when trying to use the itrace probe point on ppc64 -- I got an "unknown symbol" error for 'access_process_vm' when systemtap tried to insert the generated kernel module. Turns out that on the ppc64 kernel for Fedora, this symbol isn't exported. :-( I've gotten around this by simply pasting the access_process_vm code into runtime/itrace.c and renaming it to avoid a clash when using on Fedora/x86_64 (where this kernel function *is* exported). The attached patch shows this change. Is this an acceptable way to handle this problem? Or does someone have a better idea? Thanks. -Maynard
diff -paur systemtap-orig/runtime/itrace.c systemtap-fixes/runtime/itrace.c --- systemtap-orig/runtime/itrace.c 2009-03-02 23:32:51.000000000 -0500 +++ systemtap-fixes/runtime/itrace.c 2009-03-02 23:35:43.000000000 -0500 @@ -63,6 +63,61 @@ static struct itrace_info *create_itrace struct task_struct *tsk, u32 step_flag, struct stap_itrace_probe *itrace_probe); +/* + * 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; +} + static u32 usr_itrace_report_quiesce(enum utrace_resume_action action, struct utrace_attached_engine *engine, struct task_struct *tsk, @@ -325,7 +380,7 @@ static void insert_atomic_ss_breakpoint cur_instr = get_instr(bpt->addr, "insert_atomic_ss_breakpoint"); if (cur_instr != BPT_TRAP) { bpt->instr = cur_instr; - WARN_ON(access_process_vm(tsk, bpt->addr, &bp_instr, INSTR_SZ, 1) != + WARN_ON(__access_process_vm(tsk, bpt->addr, &bp_instr, INSTR_SZ, 1) != INSTR_SZ); } } @@ -333,7 +388,7 @@ static void insert_atomic_ss_breakpoint static void remove_atomic_ss_breakpoint (struct task_struct *tsk, struct bpt_info *bpt) { - WARN_ON(access_process_vm(tsk, bpt->addr, &bpt->instr, INSTR_SZ, 1) != + WARN_ON(__access_process_vm(tsk, bpt->addr, &bpt->instr, INSTR_SZ, 1) != INSTR_SZ); }
Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
---|---|---|
Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |