From: dave.long@linaro.org (David Long)
To: linux-arm-kernel@lists.infradead.org
Subject: [RFC PATCH] ARM: uprobes need icache flush after xol write
Date: Tue, 08 Apr 2014 09:05:49 -0400 [thread overview]
Message-ID: <5343F42D.5090205@linaro.org> (raw)
In-Reply-To: <20140408114619.GE16119@n2100.arm.linux.org.uk>
On 04/08/14 07:46, Russell King - ARM Linux wrote:
> On Tue, Apr 08, 2014 at 09:24:50AM +0100, Dave Martin wrote:
>> You're right that something is needed.
>>
>> Would flush_icache_range() not be the correct thing to call here?
>>
>> Sync'ing the I and D sides for a whole page seems excessive to
>> install a probe.
>>
>> I believe __cpuc_coherent_kern_range() is not intended as an API,
>> and should only be used in special situations in arch-specific code.
>> It's the correct operation, but arm provides flush_icache_range as a
>> wrapper to call.
>>
>> flush_icache_range() is documented, with the correct effect, in
>> Documentation/cachetlb.txt, so I believe that all arches should
>> provide it, even if it's a no-op.
>
> The real question is, what is this code in xol_get_insn_slot() trying
> to do?
>
> 1. area->page is an anonymous page - it was allocated by
> alloc_page(GFP_HIGHUSER). This makes use of flush_dcache_page()
> questionable at best.
>
> 2. xol_get_insn_slot() appears to want to copy instructions into this
> page via the kernel mapping such that they're visible to userspace.
>
> So, the first thing that we need to do is to push the written data out to
> a point where the instruction stream can see it. Then we need to ensure
> that the instruction stream can see the new instructions.
>
> Practically for ARM, that means pushing it out of the D-cache and then
> making sure that there are no I-cache lines associated with the new
> instructions.
>
> With VIVT instruction caches (yes, we still have them on ARMv7), we have
> to flush the I-cache lines associated with the userspace addresses -
> flushing the I-cache lines for the kernel mapping doesn't do anything for
> the stale lines in the userspace mapping.
>
> copy_to_page() kmap_atomic()'s the page - this doesn't take account of
> VIPT aliasing caches, and so the writes may be in an alias of the user
> page. Plus, when the page is kunmap_atomic()'d, there's no guarantee that
> the written lines will be flushed out.
>
> copy_from_page() suffers from a similar problem, though its saving grace
> is that the user mapping is execute-only (iow, read+execute only) so
> should never end up with any dirty cache lines associated with it.
>
> flush_dcache_page() will ensure that the D-cache lines are flushed out on
> ARM (even though it's only defined to have an effect for page cache pages)
> but it does nothing for the I-cache. So, although it seems to partially
> work, it's definitely the wrong interface here.
>
> However... the normal way we do this (for example, in the case of ptrace)
> is via copy_to_user_page() / copy_from_user_page(), and we have some
> pretty complex handling via those functions to deal with writing to the
> page and having the affected thread running on a different CPU to the
> one we wrote the new instructions. I'd recommend that uprobes looks at
> trying to re-use some of this infrastructure rather than re-inventing
> this wheel.
>
Conincentally I ran into this same problem last weekend while testing my
future thumb extensions to the uprobes code. I too tried a couple
cache-flushing changes, and found most any change fixed the problem and
the past intermittent systemtap failures I had seen (although I was
unsure how much of that was due to happy side-effects from any
particular flush operation). I found flush_icache_user_range() but I
was scratching my head on how to use it instead of a heavy-weight flush
as the uprobes code deliberately does not hang onto a copy of the user
vma pointer. I tried a patch storing the mm struct pointer in the
uprobes xol struct and looking up the vma info using it and the user
virtual address, but I'm not sure that's any better than just hanging
onto the vma pointer.
I also would not necessarily have assumed the kernel dcache flush was
still needed, but I now see how this makes sense. Thanks for the
explanation Russell, it answered several questions I had.
Unfortunately copy_to_user_page() also needs a pointer to a vma struct
so, while it presumably provides the model to follow, it can't simply be
dropped in.
Victor, do you want to own the action of coming up with a patch? If not
I'm OK with taking this forward, although I suspect both of us will need
help testing for anything other than ARM.
-dl
next prev parent reply other threads:[~2014-04-08 13:05 UTC|newest]
Thread overview: 17+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-04-08 3:04 [RFC PATCH] ARM: uprobes need icache flush after xol write Victor Kamensky
2014-04-08 3:04 ` Victor Kamensky
2014-04-08 8:24 ` Dave Martin
2014-04-08 11:46 ` Russell King - ARM Linux
2014-04-08 13:05 ` David Long [this message]
2014-04-08 13:30 ` Russell King - ARM Linux
2014-04-08 14:09 ` Victor Kamensky
2014-04-08 15:35 ` Victor Kamensky
2014-04-08 16:19 ` Russell King - ARM Linux
2014-04-08 16:29 ` David Long
2014-04-08 18:39 ` Victor Kamensky
2014-04-08 15:27 ` Oleg Nesterov
2014-04-08 15:41 ` Russell King - ARM Linux
2014-04-09 16:18 ` Russell King - ARM Linux
2014-04-09 16:38 ` Russell King - ARM Linux
2014-04-09 18:24 ` Oleg Nesterov
2014-04-08 14:15 ` Victor Kamensky
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=5343F42D.5090205@linaro.org \
--to=dave.long@linaro.org \
--cc=linux-arm-kernel@lists.infradead.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).