]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
another patch
authorGreg Kroah-Hartman <gregkh@suse.de>
Mon, 23 Jun 2008 22:53:23 +0000 (15:53 -0700)
committerGreg Kroah-Hartman <gregkh@suse.de>
Mon, 23 Jun 2008 22:53:23 +0000 (15:53 -0700)
review-2.6.25/fix-zero_page-breakage-with-vmware.patch [new file with mode: 0644]
review-2.6.25/series

diff --git a/review-2.6.25/fix-zero_page-breakage-with-vmware.patch b/review-2.6.25/fix-zero_page-breakage-with-vmware.patch
new file mode 100644 (file)
index 0000000..984e852
--- /dev/null
@@ -0,0 +1,78 @@
+From 672ca28e300c17bf8d792a2a7a8631193e580c74 Mon Sep 17 00:00:00 2001
+From: Linus Torvalds <torvalds@linux-foundation.org>
+Date: Mon, 23 Jun 2008 11:21:37 -0700
+Subject: Fix ZERO_PAGE breakage with vmware
+
+From: Linus Torvalds <torvalds@linux-foundation.org>
+
+commit 672ca28e300c17bf8d792a2a7a8631193e580c74 upstream
+
+Commit 89f5b7da2a6bad2e84670422ab8192382a5aeb9f ("Reinstate ZERO_PAGE
+optimization in 'get_user_pages()' and fix XIP") broke vmware, as
+reported by Jeff Chua:
+
+  "This broke vmware 6.0.4.
+   Jun 22 14:53:03.845: vmx| NOT_IMPLEMENTED
+   /build/mts/release/bora-93057/bora/vmx/main/vmmonPosix.c:774"
+
+and the reason seems to be that there's an old bug in how we handle do
+FOLL_ANON on VM_SHARED areas in get_user_pages(), but since it only
+triggered if the whole page table was missing, nobody had apparently hit
+it before.
+
+The recent changes to 'follow_page()' made the FOLL_ANON logic trigger
+not just for whole missing page tables, but for individual pages as
+well, and exposed this problem.
+
+This fixes it by making the test for when FOLL_ANON is used more
+careful, and also makes the code easier to read and understand by moving
+the logic to a separate inline function.
+
+Reported-and-tested-by: Jeff Chua <jeff.chua.linux@gmail.com>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ mm/memory.c |   24 +++++++++++++++++++++---
+ 1 file changed, 21 insertions(+), 3 deletions(-)
+
+--- a/mm/memory.c
++++ b/mm/memory.c
+@@ -989,6 +989,26 @@ no_page_table:
+       return page;
+ }
++/* Can we do the FOLL_ANON optimization? */
++static inline int use_zero_page(struct vm_area_struct *vma)
++{
++      /*
++       * We don't want to optimize FOLL_ANON for make_pages_present()
++       * when it tries to page in a VM_LOCKED region. As to VM_SHARED,
++       * we want to get the page from the page tables to make sure
++       * that we serialize and update with any other user of that
++       * mapping.
++       */
++      if (vma->vm_flags & (VM_LOCKED | VM_SHARED))
++              return 0;
++      /*
++       * And if we have a fault or a nopfn routine, it's not an
++       * anonymous region.
++       */
++      return !vma->vm_ops ||
++              (!vma->vm_ops->fault && !vma->vm_ops->nopfn);
++}
++
+ int get_user_pages(struct task_struct *tsk, struct mm_struct *mm,
+               unsigned long start, int len, int write, int force,
+               struct page **pages, struct vm_area_struct **vmas)
+@@ -1063,9 +1083,7 @@ int get_user_pages(struct task_struct *t
+               foll_flags = FOLL_TOUCH;
+               if (pages)
+                       foll_flags |= FOLL_GET;
+-              if (!write && !(vma->vm_flags & VM_LOCKED) &&
+-                  (!vma->vm_ops || (!vma->vm_ops->nopage &&
+-                                      !vma->vm_ops->fault)))
++              if (!write && use_zero_page(vma))
+                       foll_flags |= FOLL_ANON;
+               do {
index 5af6371618322560330cabb7850e190d7f7e197c..43cf2b9ddc2ce545a74410055550ec7dc5293e48 100644 (file)
@@ -7,3 +7,4 @@ add-return-value-to-reserve_bootmem_node.patch
 watchdog-hpwdt-fix-use-of-inline-assembly.patch
 hwmon-fix-function-range_to_reg.patch
 patch-hwmon-initialize-max_duty_at_overheat-before-use.patch
+fix-zero_page-breakage-with-vmware.patch