diff --git a/mm/util.c b/mm/util.c
index 988d11e6c17c..ec8739ab0cc3 100644
--- a/mm/util.c
+++ b/mm/util.c
@@ -685,8 +685,24 @@ EXPORT_SYMBOL(page_mapping);
  */
 struct address_space *page_mapping_file(struct page *page)
 {
-	if (unlikely(PageSwapCache(page)))
+	if (unlikely(PageSwapCache(page))) {
+		/*
+		 * This might be a shmem page that is in a sense a file that
+		 * can be mapped multiple times in different processes at
+		 * possibly different virtual addresses (fork + mremap). So
+		 * return the shmem mapping that will allow any arch code to
+		 * find all mappings of the page.
+		 *
+		 * Note that even if page is not anonymous then the page might
+		 * have a NULL page->mapping field if it is being truncated,
+		 * but then it is fine as each pte poiting to the page will be
+		 * remove and cache flushing should be handled properly by that
+		 * part of the code.
+		 */
+		if (!PageAnon(page))
+			return page->mapping;
 		return NULL;
+	}
 	return page_mapping(page);
 }
 
