diff options
author | Russell King <rmk+kernel@arm.linux.org.uk> | 2009-10-05 15:34:22 +0100 |
---|---|---|
committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2009-10-05 15:42:16 +0100 |
commit | 2725898fc9bb2121ac0fb1b5e4faf4fc09014729 (patch) | |
tree | f2397446518cdfd8dc42a1d3808ed77005f427cc /drivers/video | |
parent | f00a75c094c340c4e7435665816c3273c870e849 (diff) |
ARM: Flush user mapping on VIVT processors when copying a page
Steven Walter <stevenrwalter@gmail.com> writes:
> I've been tracking down an instance of userspace data corruption,
> and I believe I have found a window during fork where data can be
> lost. The corruption is occurring on an ARMv5 system with VIVT
> caches. Here's the scenario in question. Thread A is forking,
> Thread B is running in userspace:
>
> Thread A: flush_cache_mm() (dup_mmap)
> Thread B: writes to a page in the above mm
> Thread A: pte_wrprotect() the above page (copy_one_pte)
> Thread B: writes to the same page again
>
> During thread B's second write, he'll take a fault and enter the
> do_wp_page() case. We'll end up calling copy_page(), which notably
> uses the kernel virtual addresses for the old and new pages. This
> means that the new page does not necessarily have the data from the
> first write. Now there are two conflicting copies of the same
> cache-line in dcache. If the userspace cache-line flushes before
> the kernel cache-line, we lose the changes made during the first
> write. do_wp_page does call flush_dcache_page on the newly-copied
> page, but there's still a window where the CPU could flush the
> userspace cache-line before then.
Resolve this by flushing the user mapping before copying the page
on processors with a writeback VIVT cache.
Note: this does have a performance impact, and so needs further
consideration before being merged - can we optimize out some of
the cache flushes if, eg, we know that the page isn't yet mapped?
Thread: <e06498070903061426o5875ad13hc6328aa0d3f08ed7@mail.gmail.com>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Diffstat (limited to 'drivers/video')
0 files changed, 0 insertions, 0 deletions