[PATCH v2] ARM: uprobes need icache flush after xol write

Victor Kamensky victor.kamensky at linaro.org
Wed Apr 9 12:13:56 PDT 2014


On 9 April 2014 11:45, Oleg Nesterov <oleg at redhat.com> wrote:
> Victor, sorry, I can't even read this thread now, will try to reply
> tomorrow... But at first glance,

Sure, np. Will wait for you to free up.

> On 04/08, Victor Kamensky wrote:
>>
>> Because on ARM cache flush function need kernel address
>
> ...
>
>> --- a/kernel/events/uprobes.c
>> +++ b/kernel/events/uprobes.c
>> @@ -1287,6 +1287,7 @@ static unsigned long xol_get_insn_slot(struct uprobe *uprobe)
>>  {
>>       struct xol_area *area;
>>       unsigned long xol_vaddr;
>> +     void *xol_page_kaddr;
>>
>>       area = get_xol_area();
>>       if (!area)
>> @@ -1296,14 +1297,22 @@ static unsigned long xol_get_insn_slot(struct uprobe *uprobe)
>>       if (unlikely(!xol_vaddr))
>>               return 0;
>>
>> -     /* Initialize the slot */
>> -     copy_to_page(area->page, xol_vaddr,
>> -                     &uprobe->arch.ixol, sizeof(uprobe->arch.ixol));
>>       /*
>> -      * We probably need flush_icache_user_range() but it needs vma.
>> -      * This should work on supported architectures too.
>> +      * We don't use copy_to_page here because we need kernel page
>> +      * addr to invalidate caches correctly
>>        */
>> -     flush_dcache_page(area->page);
>> +     xol_page_kaddr = kmap_atomic(area->page);
>> +
>> +     /* Initialize the slot */
>> +     memcpy(xol_page_kaddr + (xol_vaddr & ~PAGE_MASK),
>> +            &uprobe->arch.ixol,
>> +            sizeof(uprobe->arch.ixol));
>> +
>> +     arch_uprobe_flush_xol_access(area->page, xol_vaddr,
>> +                                  xol_page_kaddr + (xol_vaddr & ~PAGE_MASK),
>> +                                  sizeof(uprobe->arch.ixol));
>> +
>> +     kunmap_atomic(xol_page_kaddr);
>>
>>       return xol_vaddr;
>>  }
>> @@ -1346,6 +1355,18 @@ static void xol_free_insn_slot(struct task_struct *tsk)
>>       }
>>  }
>>
>> +void __weak arch_uprobe_flush_xol_access(struct page *page, unsigned long vaddr,
>> +                                      void *kaddr, unsigned long len)
>> +{
>> +     /*
>> +      * We probably need flush_icache_user_range() but it needs vma.
>> +      * This should work on most of architectures by default. If
>> +      * architecture needs to do something different it can define
>> +      * its own version of the function.
>> +      */
>> +     flush_dcache_page(page);
>> +}
>
> In this case I'd suggest to move this kmap/memcpy horror into arch_ helper.
> IOW, something like below.
>
> If arm needs the kernel address we are writing to, let it do kmap/etc in
> its implementation.

Fair enough. Can do that, as well as address Dave's comment about
checkpatch.

But before I do that let's reach some conclusion wrt latest Russell's
remarks about copy_{to,from}_user_page usage in uprobes. It is bigger
question covering more than ARM issue and possibly having bigger
implication on uprobes design. I have some comments/thoughts about
it, but since I am not uprobes maintainer, will wait for you to address
it first.

Thanks,
Victor

> Oleg.
>
>
> --- x/kernel/events/uprobes.c
> +++ x/kernel/events/uprobes.c
> @@ -1291,18 +1291,16 @@ static unsigned long xol_get_insn_slot(s
>         if (unlikely(!xol_vaddr))
>                 return 0;
>
> -       /* Initialize the slot */
> -       copy_to_page(area->page, xol_vaddr,
> -                       &uprobe->arch.ixol, sizeof(uprobe->arch.ixol));
> -       /*
> -        * We probably need flush_icache_user_range() but it needs vma.
> -        * This should work on supported architectures too.
> -        */
> -       flush_dcache_page(area->page);
> -
> +       arch_uprobe_xxx(area->page, xol_vaddr, ...);
>         return xol_vaddr;
>  }
>
> +void __weak arch_uprobe_xxx(page, xol_vaddr, ...)
> +{
> +       copy_to_page(page, xol_vaddr, ...)
> +       flush_dcache_page(page);
> +}
> +
>  /*
>   * xol_free_insn_slot - If slot was earlier allocated by
>   * @xol_get_insn_slot(), make the slot available for
>



More information about the linux-arm-kernel mailing list