linux/arch
Huang Ying cb9f753a37 mm: fix races between swapoff and flush dcache
Thanks to commit 4b3ef9daa4 ("mm/swap: split swap cache into 64MB
trunks"), after swapoff the address_space associated with the swap
device will be freed.  So page_mapping() users which may touch the
address_space need some kind of mechanism to prevent the address_space
from being freed during accessing.

The dcache flushing functions (flush_dcache_page(), etc) in architecture
specific code may access the address_space of swap device for anonymous
pages in swap cache via page_mapping() function.  But in some cases
there are no mechanisms to prevent the swap device from being swapoff,
for example,

  CPU1					CPU2
  __get_user_pages()			swapoff()
    flush_dcache_page()
      mapping = page_mapping()
        ...				  exit_swap_address_space()
        ...				    kvfree(spaces)
        mapping_mapped(mapping)

The address space may be accessed after being freed.

But from cachetlb.txt and Russell King, flush_dcache_page() only care
about file cache pages, for anonymous pages, flush_anon_page() should be
used.  The implementation of flush_dcache_page() in all architectures
follows this too.  They will check whether page_mapping() is NULL and
whether mapping_mapped() is true to determine whether to flush the
dcache immediately.  And they will use interval tree (mapping->i_mmap)
to find all user space mappings.  While mapping_mapped() and
mapping->i_mmap isn't used by anonymous pages in swap cache at all.

So, to fix the race between swapoff and flush dcache, __page_mapping()
is add to return the address_space for file cache pages and NULL
otherwise.  All page_mapping() invoking in flush dcache functions are
replaced with page_mapping_file().

[akpm@linux-foundation.org: simplify page_mapping_file(), per Mike]
Link: http://lkml.kernel.org/r/20180305083634.15174-1-ying.huang@intel.com
Signed-off-by: "Huang, Ying" <ying.huang@intel.com>
Reviewed-by: Andrew Morton <akpm@linux-foundation.org>
Cc: Minchan Kim <minchan@kernel.org>
Cc: Michal Hocko <mhocko@suse.com>
Cc: Johannes Weiner <hannes@cmpxchg.org>
Cc: Mel Gorman <mgorman@techsingularity.net>
Cc: Dave Hansen <dave.hansen@intel.com>
Cc: Chen Liqin <liqin.linux@gmail.com>
Cc: Russell King <linux@armlinux.org.uk>
Cc: Yoshinori Sato <ysato@users.sourceforge.jp>
Cc: "James E.J. Bottomley" <jejb@parisc-linux.org>
Cc: Guan Xuetao <gxt@mprc.pku.edu.cn>
Cc: "David S. Miller" <davem@davemloft.net>
Cc: Chris Zankel <chris@zankel.net>
Cc: Vineet Gupta <vgupta@synopsys.com>
Cc: Ley Foon Tan <lftan@altera.com>
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: Andi Kleen <ak@linux.intel.com>
Cc: Mike Rapoport <rppt@linux.vnet.ibm.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2018-04-05 21:36:26 -07:00
..
alpha Merge branch 'syscalls-next' of git://git.kernel.org/pub/scm/linux/kernel/git/brodo/linux 2018-04-02 21:22:12 -07:00
arc mm: fix races between swapoff and flush dcache 2018-04-05 21:36:26 -07:00
arm mm: fix races between swapoff and flush dcache 2018-04-05 21:36:26 -07:00
arm64 Merge branch 'linus' of git://git.kernel.org/pub/scm/linux/kernel/git/herbert/crypto-2.6 2018-04-04 17:11:08 -07:00
c6x The core framework has a handful of patches this time around, mostly due 2018-02-01 16:56:07 -08:00
h8300 h8300: remove extraneous __BIG_ENDIAN definition 2018-03-22 17:07:01 -07:00
hexagon The core framework has a handful of patches this time around, mostly due 2018-02-01 16:56:07 -08:00
ia64 mm: add ksys_mmap_pgoff() helper; remove in-kernel calls to sys_mmap_pgoff() 2018-04-02 20:16:11 +02:00
m68k Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next 2018-04-03 14:04:18 -07:00
microblaze Merge branch 'syscalls-next' of git://git.kernel.org/pub/scm/linux/kernel/git/brodo/linux 2018-04-02 21:22:12 -07:00
mips mm: fix races between swapoff and flush dcache 2018-04-05 21:36:26 -07:00
nds32 nds32: To use the generic dump_stack() 2018-03-16 15:45:23 +08:00
nios2 mm: fix races between swapoff and flush dcache 2018-04-05 21:36:26 -07:00
openrisc Merge branch 'irq-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip 2018-04-04 15:19:26 -07:00
parisc mm: fix races between swapoff and flush dcache 2018-04-05 21:36:26 -07:00
powerpc mm, powerpc: use vma_kernel_pagesize() in vma_mmu_pagesize() 2018-04-05 21:36:26 -07:00
riscv RISC-V changes for 4.17 2018-04-04 16:43:47 -07:00
s390 mm: add ksys_readahead() helper; remove in-kernel calls to sys_readahead() 2018-04-02 20:16:12 +02:00
sh mm: fix races between swapoff and flush dcache 2018-04-05 21:36:26 -07:00
sparc mm: fix races between swapoff and flush dcache 2018-04-05 21:36:26 -07:00
um mm: add ksys_mmap_pgoff() helper; remove in-kernel calls to sys_mmap_pgoff() 2018-04-02 20:16:11 +02:00
unicore32 mm: fix races between swapoff and flush dcache 2018-04-05 21:36:26 -07:00
x86 x86/mm/memory_hotplug: determine block size based on the end of boot memory 2018-04-05 21:36:25 -07:00
xtensa mm: fix races between swapoff and flush dcache 2018-04-05 21:36:26 -07:00
.gitignore
Kconfig kbuild: remove incremental linking option 2018-03-26 02:01:19 +09:00