> 
> One of Vlastimil's comments made me go dig back in to the uprobes
> code's use of get_user_pages().  I decided to change both of them
> to be "foreign" accesses.
> 
> This also fixes the nommu breakage that Vlastimil noted last time.
> 
> Srikar, I'd appreciate if you can have a look at the uprobes.c
> modifications, especially the comment.  I don't think this will
> change any behavior, but I want to make sure the comment is
> accurate.
> 
> ---
> 
> From: Dave Hansen <dave.han...@linux.intel.com>
> 
> For protection keys, we need to understand whether protections
> should be enforced in software or not.  In general, we enforce
> protections when working on our own task, but not when on others.
> We call these "current" and "foreign" operations.
> 
> This patch introduces a new get_user_pages() variant:
> 
>       get_user_pages_foreign()
> 
> We modify the vanilla get_user_pages() so it can no longer be
> used on mm/tasks other than 'current/current->mm', which is by
> far the most common way it is called.  Using it makes a few of
> the call sites look a bit nicer.
> 
> In other words, get_user_pages_foreign() is a replacement for
> when get_user_pages() is called on non-current tsk/mm.
> 
> This also switches get_user_pages_(un)locked() over to be like
> get_user_pages() and not take a tsk/mm.  There is no
> get_user_pages_foreign_(un)locked().  If someone wants that
> behavior they just have to use "__" variant and pass in
> FOLL_FOREIGN explicitly.
> 
> The uprobes is_trap_at_addr() location holds mmap_sem and
> calls get_user_pages(current->mm) on an instruction address.  This
> makes it a pretty unique gup caller.  Being an instruction access
> and also really originating from the kernel (vs. the app), I opted
> to consider this a 'foreign' access where protection keys will not
> be enforced.
> 

Changes for uprobes.c looks good to me.
Acked-by: Srikar Dronamraju <sri...@linux.vnet.ibm.com>

> Signed-off-by: Dave Hansen <dave.han...@linux.intel.com>
> Cc: Andrew Morton <a...@linux-foundation.org>
> Cc: Kirill A. Shutemov <kirill.shute...@linux.intel.com>
> Cc: Andrea Arcangeli <aarca...@redhat.com>
> Cc: Naoya Horiguchi <n-horigu...@ah.jp.nec.com>
> Cc: Srikar Dronamraju <sri...@linux.vnet.ibm.com>
> Cc: vba...@suse.cz
> Cc: j...@suse.cz

> diff -puN kernel/events/uprobes.c~get_current_user_pages 
> kernel/events/uprobes.c
> --- a/kernel/events/uprobes.c~get_current_user_pages  2016-01-22 
> 08:43:42.602473969 -0800
> +++ b/kernel/events/uprobes.c 2016-01-22 09:36:14.203845894 -0800
> @@ -299,7 +299,7 @@ int uprobe_write_opcode(struct mm_struct
> 
>  retry:
>       /* Read the page with vaddr into memory */
> -     ret = get_user_pages(NULL, mm, vaddr, 1, 0, 1, &old_page, &vma);
> +     ret = get_user_pages_foreign(NULL, mm, vaddr, 1, 0, 1, &old_page, &vma);
>       if (ret <= 0)
>               return ret;
> 
> @@ -1700,7 +1700,13 @@ static int is_trap_at_addr(struct mm_str
>       if (likely(result == 0))
>               goto out;
> 
> -     result = get_user_pages(NULL, mm, vaddr, 1, 0, 1, &page, NULL);
> +     /*
> +      * The NULL 'tsk' here ensures that any faults that occur here
> +      * will not be accounted to the task.  'mm' *is* current->mm,
> +      * but we treat this as a 'foreign' access since it is
> +      * essentially a kernel access to the memory.
> +      */
> +     result = get_user_pages_foreign(NULL, mm, vaddr, 1, 0, 1, &page, NULL);
>       if (result < 0)
>               return result;
> 

-- 
Thanks and Regards
Srikar Dronamraju

Reply via email to