linux/arch/arm/mm
Russell King 2725898fc9 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>
2009-10-05 15:42:16 +01:00
..
abort-ev4.S
abort-ev4t.S
abort-ev5t.S
abort-ev5tj.S
abort-ev6.S Add core support for ARMv6/v7 big-endian 2009-05-30 14:00:18 +01:00
abort-ev7.S [ARM] 5227/1: Add the ENDPROC declarations to the .S files 2008-09-01 12:06:34 +01:00
abort-lv4t.S [ARM] nommu: abort handler fixup for !CPU_CP15_MMU cores. 2006-09-28 20:15:46 +01:00
abort-macro.S
abort-nommu.S [ARM] 5227/1: Add the ENDPROC declarations to the .S files 2008-09-01 12:06:34 +01:00
alignment.c Thumb-2: Implement the unified arch/arm/mm support 2009-07-24 12:32:56 +01:00
cache-fa.S ARM: Add support for FA526 v2 2009-03-25 13:10:01 +02:00
cache-feroceon-l2.c [ARM] Kirkwood: small L2 code cleanup 2009-03-28 22:39:30 -04:00
cache-l2x0.c [ARM] Convert asm/io.h to linux/io.h 2008-09-06 12:10:45 +01:00
cache-v3.S [ARM] Remove unnecessary mach/hardware.h includes in arch/arm/mm 2008-11-28 23:20:39 +00:00
cache-v4.S [ARM] Remove unnecessary mach/hardware.h includes in arch/arm/mm 2008-11-28 23:20:39 +00:00
cache-v4wb.S Remove obsolete #include <linux/config.h> 2006-06-30 19:25:36 +02:00
cache-v4wt.S [ARM] Remove unnecessary mach/hardware.h includes in arch/arm/mm 2008-11-28 23:20:39 +00:00
cache-v6.S [ARM] 5488/1: ARM errata: Invalidation of the Instruction Cache operation can fail 2009-04-30 20:12:47 +01:00
cache-v7.S Thumb-2: Implement the unified arch/arm/mm support 2009-07-24 12:32:56 +01:00
cache-xsc3l2.c [ARM] xsc3: add highmem support to L2 cache handling code 2009-03-15 21:01:21 -04:00
context.c cpumask: use mm_cpumask() wrapper: arm 2009-09-24 09:34:49 +09:30
copypage-fa.c ARM: Add support for FA526 v2 2009-03-25 13:10:01 +02:00
copypage-feroceon.c ARM: Flush user mapping on VIVT processors when copying a page 2009-10-05 15:42:16 +01:00
copypage-v3.c ARM: Pass VMA to copy_user_highpage() implementations 2009-10-05 15:17:45 +01:00
copypage-v4mc.c ARM: Pass VMA to copy_user_highpage() implementations 2009-10-05 15:17:45 +01:00
copypage-v4wb.c ARM: Flush user mapping on VIVT processors when copying a page 2009-10-05 15:42:16 +01:00
copypage-v4wt.c ARM: Pass VMA to copy_user_highpage() implementations 2009-10-05 15:17:45 +01:00
copypage-v6.c ARM: Pass VMA to copy_user_highpage() implementations 2009-10-05 15:17:45 +01:00
copypage-xsc3.c ARM: Flush user mapping on VIVT processors when copying a page 2009-10-05 15:42:16 +01:00
copypage-xscale.c ARM: Pass VMA to copy_user_highpage() implementations 2009-10-05 15:17:45 +01:00
discontig.c mm: move bootmem descriptors definition to a single place 2008-07-24 10:47:14 -07:00
dma-mapping.c nommu: Add noMMU support to the DMA API 2009-07-24 12:35:02 +01:00
extable.c [ARM] Convert asm/uaccess.h to linux/uaccess.h 2008-09-06 11:35:55 +01:00
fault-armv.c [ARM] 5366/1: fix shared memory coherency with VIVT L1 + L2 caches 2009-01-28 16:55:00 +00:00
fault.c ARM: 5728/1: Proper prefetch abort handling on ARMv6 and ARMv7 2009-10-02 22:34:32 +01:00
fault.h [ARM] do_bad_area() always takes current and current->active_mm 2006-09-27 16:13:48 +01:00
flush.c cpumask: use mm_cpumask() wrapper: arm 2009-09-24 09:34:49 +09:30
highmem.c ARM: 5691/1: fix cache aliasing issues between kmap() and kmap_atomic() with highmem 2009-09-04 19:20:07 +01:00
init.c Merge branch 'origin' into for-linus 2009-09-24 21:22:33 +01:00
iomap.c [ARM] Convert asm/io.h to linux/io.h 2008-09-06 12:10:45 +01:00
ioremap.c omap iommu: simple virtual address space management 2009-05-19 08:23:49 +03:00
Kconfig ARM: 5727/1: Pass IFSR register to do_PrefetchAbort() 2009-10-02 22:34:32 +01:00
Makefile ARM: 5727/1: Pass IFSR register to do_PrefetchAbort() 2009-10-02 22:34:32 +01:00
mm.h [ARM] fixmap support 2009-03-15 21:01:20 -04:00
mmap.c ARM: 5740/1: fix valid_phys_addr_range() range check 2009-10-02 22:32:34 +01:00
mmu.c ARM: Don't allow highmem on SMP platforms without h/w TLB ops broadcast 2009-09-28 18:06:20 +01:00
nommu.c nommu: Include asm/setup.h in arch/arm/mm/nommu.c 2009-07-24 12:35:03 +01:00
pabort-legacy.S ARM: 5727/1: Pass IFSR register to do_PrefetchAbort() 2009-10-02 22:34:32 +01:00
pabort-v6.S ARM: 5727/1: Pass IFSR register to do_PrefetchAbort() 2009-10-02 22:34:32 +01:00
pabort-v7.S ARM: 5727/1: Pass IFSR register to do_PrefetchAbort() 2009-10-02 22:34:32 +01:00
pgd.c [ARM] remove memzero() 2008-11-27 12:37:59 +00:00
proc-arm6_7.S ARM: 5727/1: Pass IFSR register to do_PrefetchAbort() 2009-10-02 22:34:32 +01:00
proc-arm7tdmi.S ARM: 5727/1: Pass IFSR register to do_PrefetchAbort() 2009-10-02 22:34:32 +01:00
proc-arm9tdmi.S ARM: 5727/1: Pass IFSR register to do_PrefetchAbort() 2009-10-02 22:34:32 +01:00
proc-arm720.S ARM: 5727/1: Pass IFSR register to do_PrefetchAbort() 2009-10-02 22:34:32 +01:00
proc-arm740.S ARM: 5727/1: Pass IFSR register to do_PrefetchAbort() 2009-10-02 22:34:32 +01:00
proc-arm920.S ARM: 5727/1: Pass IFSR register to do_PrefetchAbort() 2009-10-02 22:34:32 +01:00
proc-arm922.S ARM: 5727/1: Pass IFSR register to do_PrefetchAbort() 2009-10-02 22:34:32 +01:00
proc-arm925.S ARM: 5727/1: Pass IFSR register to do_PrefetchAbort() 2009-10-02 22:34:32 +01:00
proc-arm926.S ARM: 5727/1: Pass IFSR register to do_PrefetchAbort() 2009-10-02 22:34:32 +01:00
proc-arm940.S ARM: 5727/1: Pass IFSR register to do_PrefetchAbort() 2009-10-02 22:34:32 +01:00
proc-arm946.S ARM: 5727/1: Pass IFSR register to do_PrefetchAbort() 2009-10-02 22:34:32 +01:00
proc-arm1020.S ARM: 5727/1: Pass IFSR register to do_PrefetchAbort() 2009-10-02 22:34:32 +01:00
proc-arm1020e.S ARM: 5727/1: Pass IFSR register to do_PrefetchAbort() 2009-10-02 22:34:32 +01:00
proc-arm1022.S ARM: 5727/1: Pass IFSR register to do_PrefetchAbort() 2009-10-02 22:34:32 +01:00
proc-arm1026.S ARM: 5727/1: Pass IFSR register to do_PrefetchAbort() 2009-10-02 22:34:32 +01:00
proc-fa526.S ARM: 5727/1: Pass IFSR register to do_PrefetchAbort() 2009-10-02 22:34:32 +01:00
proc-feroceon.S ARM: 5727/1: Pass IFSR register to do_PrefetchAbort() 2009-10-02 22:34:32 +01:00
proc-macros.S Merge branch 'devel-stable' into devel 2009-09-12 12:02:26 +01:00
proc-mohawk.S ARM: 5727/1: Pass IFSR register to do_PrefetchAbort() 2009-10-02 22:34:32 +01:00
proc-sa110.S ARM: 5727/1: Pass IFSR register to do_PrefetchAbort() 2009-10-02 22:34:32 +01:00
proc-sa1100.S ARM: 5727/1: Pass IFSR register to do_PrefetchAbort() 2009-10-02 22:34:32 +01:00
proc-syms.c [ARM] export __cpu_flush_dcache_page 2009-07-05 15:25:00 +01:00
proc-v6.S ARM: 5727/1: Pass IFSR register to do_PrefetchAbort() 2009-10-02 22:34:32 +01:00
proc-v7.S ARM: 5727/1: Pass IFSR register to do_PrefetchAbort() 2009-10-02 22:34:32 +01:00
proc-xsc3.S ARM: 5727/1: Pass IFSR register to do_PrefetchAbort() 2009-10-02 22:34:32 +01:00
proc-xscale.S ARM: 5727/1: Pass IFSR register to do_PrefetchAbort() 2009-10-02 22:34:32 +01:00
tlb-fa.S ARM: Add support for FA526 v2 2009-03-25 13:10:01 +02:00
tlb-v3.S
tlb-v4.S
tlb-v4wb.S
tlb-v4wbi.S
tlb-v6.S arm: Use __INIT macro instead of .text.init. 2009-04-27 19:51:58 -07:00
tlb-v7.S Check whether the TLB operations need broadcasting on SMP systems 2009-05-30 14:00:14 +01:00