--- /dev/null
+From willy@infradead.org Wed Feb 23 18:42:46 2022
+From: "Matthew Wilcox (Oracle)" <willy@infradead.org>
+Date: Wed, 23 Feb 2022 15:59:18 +0000
+Subject: mm/filemap: Fix handling of THPs in generic_file_buffered_read()
+To: stable@vger.kernel.org, linux-mm@kvack.org, linux-kernel@vger.kernel.org, kirill.shutemov@linux.intel.com, Song Liu <songliubraving@fb.com>
+Cc: "Matthew Wilcox (Oracle)" <willy@infradead.org>, Adam Majer <amajer@suse.com>, Dirk Mueller <dmueller@suse.com>, Takashi Iwai <tiwai@suse.de>, Vlastimil Babka <vbabka@suse.cz>
+Message-ID: <20220223155918.927140-1-willy@infradead.org>
+
+From: "Matthew Wilcox (Oracle)" <willy@infradead.org>
+
+When a THP is present in the page cache, we can return it several times,
+leading to userspace seeing the same data repeatedly if doing a read()
+that crosses a 64-page boundary. This is probably not a security issue
+(since the data all comes from the same file), but it can be interpreted
+as a transient data corruption issue. Fortunately, it is very rare as
+it can only occur when CONFIG_READ_ONLY_THP_FOR_FS is enabled, and it can
+only happen to executables. We don't often call read() on executables.
+
+This bug is fixed differently in v5.17 by commit 6b24ca4a1a8d
+("mm: Use multi-index entries in the page cache"). That commit is
+unsuitable for backporting, so fix this in the clearest way. It
+sacrifices a little performance for clarity, but this should never
+be a performance path in these kernel versions.
+
+Fixes: cbd59c48ae2b ("mm/filemap: use head pages in generic_file_buffered_read")
+Cc: stable@vger.kernel.org # v5.15, v5.16
+Link: https://lore.kernel.org/r/df3b5d1c-a36b-2c73-3e27-99e74983de3a@suse.cz/
+Analyzed-by: Adam Majer <amajer@suse.com>
+Analyzed-by: Dirk Mueller <dmueller@suse.com>
+Bisected-by: Takashi Iwai <tiwai@suse.de>
+Reported-by: Vlastimil Babka <vbabka@suse.cz>
+Tested-by: Vlastimil Babka <vbabka@suse.cz>
+Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ mm/filemap.c | 8 ++++++--
+ 1 file changed, 6 insertions(+), 2 deletions(-)
+
+--- a/mm/filemap.c
++++ b/mm/filemap.c
+@@ -2354,8 +2354,12 @@ static void filemap_get_read_batch(struc
+ break;
+ if (PageReadahead(head))
+ break;
+- xas.xa_index = head->index + thp_nr_pages(head) - 1;
+- xas.xa_offset = (xas.xa_index >> xas.xa_shift) & XA_CHUNK_MASK;
++ if (PageHead(head)) {
++ xas_set(&xas, head->index + thp_nr_pages(head));
++ /* Handle wrap correctly */
++ if (xas.xa_index - 1 >= max)
++ break;
++ }
+ continue;
+ put_page:
+ put_page(head);