lkml.org 
[lkml]   [2011]   [Oct]   [5]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    /
    Date
    From
    SubjectRe: [PATCH v5 3.1.0-rc4-tip 5/26] Uprobes: copy of the original instruction.
    * Oleg Nesterov <oleg@redhat.com> [2011-10-03 18:29:05]:

    > On 09/20, Srikar Dronamraju wrote:
    > >
    > > +static int __copy_insn(struct address_space *mapping,
    > > + struct vm_area_struct *vma, char *insn,
    > > + unsigned long nbytes, unsigned long offset)
    > > +{
    > > + struct file *filp = vma->vm_file;
    > > + struct page *page;
    > > + void *vaddr;
    > > + unsigned long off1;
    > > + unsigned long idx;
    > > +
    > > + if (!filp)
    > > + return -EINVAL;
    > > +
    > > + idx = (unsigned long) (offset >> PAGE_CACHE_SHIFT);
    > > + off1 = offset &= ~PAGE_MASK;
    > > +
    > > + /*
    > > + * Ensure that the page that has the original instruction is
    > > + * populated and in page-cache.
    > > + */
    >
    > Hmm. But how we can ensure?


    >
    > > + page_cache_sync_readahead(mapping, &filp->f_ra, filp, idx, 1);
    >
    > This schedules the i/o,
    >
    > > + page = grab_cache_page(mapping, idx);
    >
    > This finds/locks the page in the page-cache,
    >
    > > + if (!page)
    > > + return -ENOMEM;
    > > +
    > > + vaddr = kmap_atomic(page);
    > > + memcpy(insn, vaddr + off1, nbytes);
    >
    > What if this page is not PageUptodate() ?

    Since we do a synchronous read ahead, I thought the page would be
    populated and upto date.

    would these two lines after grab_cache_page help?

    if (!PageUptodate(page))
    mapping->a_ops->readpage(filp, page);


    >
    > Somehow this assumes that the i/o was already completed, I don't
    > understand this.
    >
    > But I am starting to think I simply do not understand this change.
    > To the point, I do not underestand why do we need copy_insn() at all.
    > We are going to replace this page, can't we save/analyze ->insn later
    > when we copy the content of the old page? Most probably I missed
    > something simple...
    >
    >
    > > +static struct task_struct *get_mm_owner(struct mm_struct *mm)
    > > +{
    > > + struct task_struct *tsk;
    > > +
    > > + rcu_read_lock();
    > > + tsk = rcu_dereference(mm->owner);
    > > + if (tsk)
    > > + get_task_struct(tsk);
    > > + rcu_read_unlock();
    > > + return tsk;
    > > +}
    >
    > Hmm. Do we really need task_struct?
    >
    > > -static int install_breakpoint(struct mm_struct *mm, struct uprobe *uprobe)
    > > +static int install_breakpoint(struct mm_struct *mm, struct uprobe *uprobe,
    > > + struct vm_area_struct *vma, loff_t vaddr)
    > > {
    > > - /* Placeholder: Yet to be implemented */
    > > + struct task_struct *tsk;
    > > + unsigned long addr;
    > > + int ret = -EINVAL;
    > > +
    > > if (!uprobe->consumers)
    > > return 0;
    > >
    > > - atomic_inc(&mm->mm_uprobes_count);
    > > - return 0;
    > > + tsk = get_mm_owner(mm);
    > > + if (!tsk) /* task is probably exiting; bail-out */
    > > + return -ESRCH;
    > > +
    > > + if (vaddr > TASK_SIZE_OF(tsk))
    > > + goto put_return;
    >
    > But this should not be possible, no? How it can map this vaddr above
    > TASK_SIZE ?
    >
    > get_user_pages(tsk => NULL) is fine. Why else do we need mm->owner ?

    >
    > Probably used by the next patches... Say, is_32bit_app(tsk). This
    > can use mm->context.ia32_compat (hopefully will be replaced with
    > MMF_COMPAT).
    >

    We used the tsk struct for checking if the application was 32 bit and
    for calling get_user_pages. Since we can pass NULL to get_user_pages and
    since we can use mm->context.ia32_compat or MMF_COMPAT, I will remove
    get_mm_owner, that way we dont need to be dependent on CONFIG_MM_OWNER.

    --
    Thanks and Regards
    Srikar


    \
     
     \ /
      Last update: 2011-10-05 13:13    [W:0.032 / U:0.208 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site