MIPS: Fix race condition in lazy cache flushing.
authorLars Persson <lars.persson@axis.com>
Thu, 26 Feb 2015 13:16:03 +0000 (14:16 +0100)
committerWilly Tarreau <w@1wt.eu>
Fri, 18 Sep 2015 11:52:06 +0000 (13:52 +0200)
commit353bd7db1b1f48c32ca1cfde03f80e666839cec2
tree49f1b534e4ea48a381b0af914ba0ba5666f59664
parent93f44614486be7d8eb4864b51f4808fc945b69f6
MIPS: Fix race condition in lazy cache flushing.

commit 4d46a67a3eb827ccf1125959936fd51ba318dabc upstream.

The lazy cache flushing implemented in the MIPS kernel suffers from a
race condition that is exposed by do_set_pte() in mm/memory.c.

A pre-condition is a file-system that writes to the page from the CPU
in its readpage method and then calls flush_dcache_page(). One example
is ubifs. Another pre-condition is that the dcache flush is postponed
in __flush_dcache_page().

Upon a page fault for an executable mapping not existing in the
page-cache, the following will happen:
1. Write to the page
2. flush_dcache_page
3. flush_icache_page
4. set_pte_at
5. update_mmu_cache (commits the flush of a dcache-dirty page)

Between steps 4 and 5 another thread can hit the same page and it will
encounter a valid pte. Because the data still is in the L1 dcache the CPU
will fetch stale data from L2 into the icache and execute garbage.

This fix moves the commit of the cache flush to step 3 to close the
race window. It also reduces the amount of flushes on non-executable
mappings because we never enter __flush_dcache_page() for non-aliasing
CPUs.

Regressions can occur in drivers that mistakenly relies on the
flush_dcache_page() in get_user_pages() for DMA operations.

[ralf@linux-mips.org: Folded in patch 9346 to fix highmem issue.]

Signed-off-by: Lars Persson <larper@axis.com>
Cc: linux-mips@linux-mips.org
Cc: paul.burton@imgtec.com
Cc: linux-kernel@vger.kernel.org
Patchwork: https://patchwork.linux-mips.org/patch/9346/
Patchwork: https://patchwork.linux-mips.org/patch/9738/
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
(cherry picked from commit 6bde6a3df0b4c8680d51c987d446b0ff2d6df0a6)

Signed-off-by: Willy Tarreau <w@1wt.eu>
arch/mips/include/asm/cacheflush.h
arch/mips/mm/cache.c