| From 1de13ee59225dfc98d483f8cce7d83f97c0b31de Mon Sep 17 00:00:00 2001 |
| From: Ralph Campbell <rcampbell@nvidia.com> |
| Date: Tue, 13 Aug 2019 15:37:11 -0700 |
| Subject: mm/hmm: fix bad subpage pointer in try_to_unmap_one |
| MIME-Version: 1.0 |
| Content-Type: text/plain; charset=UTF-8 |
| Content-Transfer-Encoding: 8bit |
| |
| From: Ralph Campbell <rcampbell@nvidia.com> |
| |
| commit 1de13ee59225dfc98d483f8cce7d83f97c0b31de upstream. |
| |
| When migrating an anonymous private page to a ZONE_DEVICE private page, |
| the source page->mapping and page->index fields are copied to the |
| destination ZONE_DEVICE struct page and the page_mapcount() is |
| increased. This is so rmap_walk() can be used to unmap and migrate the |
| page back to system memory. |
| |
| However, try_to_unmap_one() computes the subpage pointer from a swap pte |
| which computes an invalid page pointer and a kernel panic results such |
| as: |
| |
| BUG: unable to handle page fault for address: ffffea1fffffffc8 |
| |
| Currently, only single pages can be migrated to device private memory so |
| no subpage computation is needed and it can be set to "page". |
| |
| [rcampbell@nvidia.com: add comment] |
| Link: http://lkml.kernel.org/r/20190724232700.23327-4-rcampbell@nvidia.com |
| Link: http://lkml.kernel.org/r/20190719192955.30462-4-rcampbell@nvidia.com |
| Fixes: a5430dda8a3a1c ("mm/migrate: support un-addressable ZONE_DEVICE page in migration") |
| Signed-off-by: Ralph Campbell <rcampbell@nvidia.com> |
| Cc: "Jérôme Glisse" <jglisse@redhat.com> |
| Cc: "Kirill A. Shutemov" <kirill.shutemov@linux.intel.com> |
| Cc: Mike Kravetz <mike.kravetz@oracle.com> |
| Cc: Christoph Hellwig <hch@lst.de> |
| Cc: Jason Gunthorpe <jgg@mellanox.com> |
| Cc: John Hubbard <jhubbard@nvidia.com> |
| Cc: Andrea Arcangeli <aarcange@redhat.com> |
| Cc: Andrey Ryabinin <aryabinin@virtuozzo.com> |
| Cc: Christoph Lameter <cl@linux.com> |
| Cc: Dan Williams <dan.j.williams@intel.com> |
| Cc: Dave Hansen <dave.hansen@linux.intel.com> |
| Cc: Ira Weiny <ira.weiny@intel.com> |
| Cc: Jan Kara <jack@suse.cz> |
| Cc: Lai Jiangshan <jiangshanlai@gmail.com> |
| Cc: Logan Gunthorpe <logang@deltatee.com> |
| Cc: Martin Schwidefsky <schwidefsky@de.ibm.com> |
| Cc: Matthew Wilcox <willy@infradead.org> |
| Cc: Mel Gorman <mgorman@techsingularity.net> |
| Cc: Michal Hocko <mhocko@suse.com> |
| Cc: Pekka Enberg <penberg@kernel.org> |
| Cc: Randy Dunlap <rdunlap@infradead.org> |
| Cc: Vlastimil Babka <vbabka@suse.cz> |
| Cc: <stable@vger.kernel.org> |
| Signed-off-by: Andrew Morton <akpm@linux-foundation.org> |
| Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| |
| --- |
| mm/rmap.c | 8 ++++++++ |
| 1 file changed, 8 insertions(+) |
| |
| --- a/mm/rmap.c |
| +++ b/mm/rmap.c |
| @@ -1467,7 +1467,15 @@ static bool try_to_unmap_one(struct page |
| /* |
| * No need to invalidate here it will synchronize on |
| * against the special swap migration pte. |
| + * |
| + * The assignment to subpage above was computed from a |
| + * swap PTE which results in an invalid pointer. |
| + * Since only PAGE_SIZE pages can currently be |
| + * migrated, just set it to page. This will need to be |
| + * changed when hugepage migrations to device private |
| + * memory are supported. |
| */ |
| + subpage = page; |
| goto discard; |
| } |
| |