aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristian Borntraeger <borntraeger@de.ibm.com>2018-07-13 19:58:52 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2018-07-14 14:11:09 -0400
commitbce73e4842390f7b7309c8e253e139db71288ac3 (patch)
treeac9b8bf5f1ac4fa8d53d6cbfe731de70a2416344
parent3951dbf232e8500bef27f77437fd5d04b67cc6d1 (diff)
mm: do not drop unused pages when userfaultd is running
KVM guests on s390 can notify the host of unused pages. This can result in pte_unused callbacks to be true for KVM guest memory. If a page is unused (checked with pte_unused) we might drop this page instead of paging it. This can have side-effects on userfaultd, when the page in question was already migrated: The next access of that page will trigger a fault and a user fault instead of faulting in a new and empty zero page. As QEMU does not expect a userfault on an already migrated page this migration will fail. The most straightforward solution is to ignore the pte_unused hint if a userfault context is active for this VMA. Link: http://lkml.kernel.org/r/20180703171854.63981-1-borntraeger@de.ibm.com Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com> Cc: Martin Schwidefsky <schwidefsky@de.ibm.com> Cc: Andrea Arcangeli <aarcange@redhat.com> Cc: Mike Rapoport <rppt@linux.vnet.ibm.com> Cc: Janosch Frank <frankja@linux.ibm.com> Cc: David Hildenbrand <david@redhat.com> Cc: Cornelia Huck <cohuck@redhat.com> Cc: <stable@vger.kernel.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r--mm/rmap.c8
1 files changed, 7 insertions, 1 deletions
diff --git a/mm/rmap.c b/mm/rmap.c
index 6db729dc4c50..eb477809a5c0 100644
--- a/mm/rmap.c
+++ b/mm/rmap.c
@@ -64,6 +64,7 @@
64#include <linux/backing-dev.h> 64#include <linux/backing-dev.h>
65#include <linux/page_idle.h> 65#include <linux/page_idle.h>
66#include <linux/memremap.h> 66#include <linux/memremap.h>
67#include <linux/userfaultfd_k.h>
67 68
68#include <asm/tlbflush.h> 69#include <asm/tlbflush.h>
69 70
@@ -1481,11 +1482,16 @@ static bool try_to_unmap_one(struct page *page, struct vm_area_struct *vma,
1481 set_pte_at(mm, address, pvmw.pte, pteval); 1482 set_pte_at(mm, address, pvmw.pte, pteval);
1482 } 1483 }
1483 1484
1484 } else if (pte_unused(pteval)) { 1485 } else if (pte_unused(pteval) && !userfaultfd_armed(vma)) {
1485 /* 1486 /*
1486 * The guest indicated that the page content is of no 1487 * The guest indicated that the page content is of no
1487 * interest anymore. Simply discard the pte, vmscan 1488 * interest anymore. Simply discard the pte, vmscan
1488 * will take care of the rest. 1489 * will take care of the rest.
1490 * A future reference will then fault in a new zero
1491 * page. When userfaultfd is active, we must not drop
1492 * this page though, as its main user (postcopy
1493 * migration) will not expect userfaults on already
1494 * copied pages.
1489 */ 1495 */
1490 dec_mm_counter(mm, mm_counter(page)); 1496 dec_mm_counter(mm, mm_counter(page));
1491 /* We have to invalidate as we cleared the pte */ 1497 /* We have to invalidate as we cleared the pte */