rpms/kernel/devel linux-2.6.29-pat-change-is_linear_pfn_mapping-to-not-use-vm_pgoff.patch, NONE, 1.1 linux-2.6.29-pat-pci-change-prot-for-inherit.patch, NONE, 1.1 kernel.spec, 1.1487, 1.1488 linux-2.6.29-pat-fixes.patch, 1.1, 1.2

Chuck Ebbert cebbert at fedoraproject.org
Mon Mar 30 22:16:42 UTC 2009


Author: cebbert

Update of /cvs/pkgs/rpms/kernel/devel
In directory cvs1.fedora.phx.redhat.com:/tmp/cvs-serv3175

Modified Files:
	kernel.spec linux-2.6.29-pat-fixes.patch 
Added Files:
	linux-2.6.29-pat-change-is_linear_pfn_mapping-to-not-use-vm_pgoff.patch 
	linux-2.6.29-pat-pci-change-prot-for-inherit.patch 
Log Message:
Separate PAT fixes that are headed for -stable from our out-of-tree ones.

linux-2.6.29-pat-change-is_linear_pfn_mapping-to-not-use-vm_pgoff.patch:

--- NEW FILE linux-2.6.29-pat-change-is_linear_pfn_mapping-to-not-use-vm_pgoff.patch ---
From: Pallipadi, Venkatesh <venkatesh.pallipadi at intel.com>
Date: Fri, 13 Mar 2009 00:45:27 +0000 (-0700)
Subject: VM, x86, PAT: Change is_linear_pfn_mapping to not use vm_pgoff
X-Git-Url: http://git.kernel.org/?p=linux%2Fkernel%2Fgit%2Ftorvalds%2Flinux-2.6.git;a=commitdiff_plain;h=4bb9c5c02153dfc89a6c73a6f32091413805ad7d

VM, x86, PAT: Change is_linear_pfn_mapping to not use vm_pgoff

Impact: fix false positive PAT warnings - also fix VirtalBox hang

Use of vma->vm_pgoff to identify the pfnmaps that are fully
mapped at mmap time is broken. vm_pgoff is set by generic mmap
code even for cases where drivers are setting up the mappings
at the fault time.

The problem was originally reported here:

 http://marc.info/?l=linux-kernel&m=123383810628583&w=2

Change is_linear_pfn_mapping logic to overload VM_INSERTPAGE
flag along with VM_PFNMAP to mean full PFNMAP setup at mmap
time.

Problem also tracked at:

 http://bugzilla.kernel.org/show_bug.cgi?id=12800

Reported-by: Thomas Hellstrom <thellstrom at vmware.com>
Tested-by: Frans Pop <elendil at planet.nl>
Signed-off-by: Venkatesh Pallipadi <venkatesh.pallipadi at intel.com>
Signed-off-by: Suresh Siddha <suresh.b.siddha>@intel.com>
Cc: Nick Piggin <npiggin at suse.de>
Cc: "ebiederm at xmission.com" <ebiederm at xmission.com>
Cc: <stable at kernel.org> # only for 2.6.29.1, not .28
LKML-Reference: <20090313004527.GA7176 at linux-os.sc.intel.com>
Signed-off-by: Ingo Molnar <mingo at elte.hu>
---

diff --git a/arch/x86/mm/pat.c b/arch/x86/mm/pat.c
index e0ab173..21bc1f7 100644
--- a/arch/x86/mm/pat.c
+++ b/arch/x86/mm/pat.c
@@ -641,10 +641,11 @@ static int reserve_pfn_range(u64 paddr, unsigned long size, pgprot_t *vma_prot,
 	is_ram = pat_pagerange_is_ram(paddr, paddr + size);
 
 	/*
-	 * reserve_pfn_range() doesn't support RAM pages.
+	 * reserve_pfn_range() doesn't support RAM pages. Maintain the current
+	 * behavior with RAM pages by returning success.
 	 */
 	if (is_ram != 0)
-		return -EINVAL;
+		return 0;
 
 	ret = reserve_memtype(paddr, paddr + size, want_flags, &flags);
 	if (ret)
diff --git a/include/linux/mm.h b/include/linux/mm.h
index 065cdf8..3daa05f 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -98,7 +98,7 @@ extern unsigned int kobjsize(const void *objp);
 #define VM_HUGETLB	0x00400000	/* Huge TLB Page VM */
 #define VM_NONLINEAR	0x00800000	/* Is non-linear (remap_file_pages) */
 #define VM_MAPPED_COPY	0x01000000	/* T if mapped copy of data (nommu mmap) */
-#define VM_INSERTPAGE	0x02000000	/* The vma has had "vm_insert_page()" done on it */
+#define VM_INSERTPAGE	0x02000000	/* The vma has had "vm_insert_page()" done on it. Refer note in VM_PFNMAP_AT_MMAP below */
 #define VM_ALWAYSDUMP	0x04000000	/* Always include in core dumps */
 
 #define VM_CAN_NONLINEAR 0x08000000	/* Has ->fault & does nonlinear pages */
@@ -127,6 +127,17 @@ extern unsigned int kobjsize(const void *objp);
 #define VM_SPECIAL (VM_IO | VM_DONTEXPAND | VM_RESERVED | VM_PFNMAP)
 
 /*
+ * pfnmap vmas that are fully mapped at mmap time (not mapped on fault).
+ * Used by x86 PAT to identify such PFNMAP mappings and optimize their handling.
+ * Note VM_INSERTPAGE flag is overloaded here. i.e,
+ * VM_INSERTPAGE && !VM_PFNMAP implies
+ *     The vma has had "vm_insert_page()" done on it
+ * VM_INSERTPAGE && VM_PFNMAP implies
+ *     The vma is PFNMAP with full mapping at mmap time
+ */
+#define VM_PFNMAP_AT_MMAP (VM_INSERTPAGE | VM_PFNMAP)
+
+/*
  * mapping from the currently active vm_flags protection bits (the
  * low four bits) to a page protection mask..
  */
@@ -145,7 +156,7 @@ extern pgprot_t protection_map[16];
  */
 static inline int is_linear_pfn_mapping(struct vm_area_struct *vma)
 {
-	return ((vma->vm_flags & VM_PFNMAP) && vma->vm_pgoff);
+	return ((vma->vm_flags & VM_PFNMAP_AT_MMAP) == VM_PFNMAP_AT_MMAP);
 }
 
 static inline int is_pfn_mapping(struct vm_area_struct *vma)
diff --git a/mm/memory.c b/mm/memory.c
index baa999e..d7df5ba 100644
--- a/mm/memory.c
+++ b/mm/memory.c
@@ -1665,9 +1665,10 @@ int remap_pfn_range(struct vm_area_struct *vma, unsigned long addr,
 	 * behaviour that some programs depend on. We mark the "original"
 	 * un-COW'ed pages by matching them up with "vma->vm_pgoff".
 	 */
-	if (addr == vma->vm_start && end == vma->vm_end)
+	if (addr == vma->vm_start && end == vma->vm_end) {
 		vma->vm_pgoff = pfn;
-	else if (is_cow_mapping(vma->vm_flags))
+		vma->vm_flags |= VM_PFNMAP_AT_MMAP;
+	} else if (is_cow_mapping(vma->vm_flags))
 		return -EINVAL;
 
 	vma->vm_flags |= VM_IO | VM_RESERVED | VM_PFNMAP;
@@ -1679,6 +1680,7 @@ int remap_pfn_range(struct vm_area_struct *vma, unsigned long addr,
 		 * needed from higher level routine calling unmap_vmas
 		 */
 		vma->vm_flags &= ~(VM_IO | VM_RESERVED | VM_PFNMAP);
+		vma->vm_flags &= ~VM_PFNMAP_AT_MMAP;
 		return -EINVAL;
 	}
 

linux-2.6.29-pat-pci-change-prot-for-inherit.patch:

--- NEW FILE linux-2.6.29-pat-pci-change-prot-for-inherit.patch ---
From: Pallipadi, Venkatesh <venkatesh.pallipadi at intel.com>
Date: Mon, 23 Mar 2009 19:07:20 +0000 (-0700)
Subject: x86, PAT, PCI: Change vma prot in pci_mmap to reflect inherited prot
X-Git-Url: http://git.kernel.org/?p=linux%2Fkernel%2Fgit%2Ftorvalds%2Flinux-2.6.git;a=commitdiff_plain;h=9cdec049389ce2c324fd1ec508a71528a27d4a07

x86, PAT, PCI: Change vma prot in pci_mmap to reflect inherited prot

While looking at the issue in the thread:

  http://marc.info/?l=dri-devel&m=123606627824556&w=2

noticed a bug in pci PAT code and memory type setting.

PCI mmap code did not set the proper protection in vma, when it
inherited protection in reserve_memtype. This bug only affects
the case where there exists a WC mapping before X does an mmap
with /proc or /sys pci interface. This will cause X userlevel
mmap from /proc or /sysfs to fail on fork.

Reported-by: Kevin Winchester <kjwinchester at gmail.com>
Signed-off-by: Venkatesh Pallipadi <venkatesh.pallipadi at intel.com>
Signed-off-by: Suresh Siddha <suresh.b.siddha at intel.com>
Cc: Jesse Barnes <jbarnes at virtuousgeek.org>
Cc: Dave Airlie <airlied at redhat.com>
Cc: <stable at kernel.org>
LKML-Reference: <20090323190720.GA16831 at linux-os.sc.intel.com>
Signed-off-by: Ingo Molnar <mingo at elte.hu>
---

diff --git a/arch/x86/pci/i386.c b/arch/x86/pci/i386.c
index 5ead808..f234a37 100644
--- a/arch/x86/pci/i386.c
+++ b/arch/x86/pci/i386.c
@@ -319,6 +319,9 @@ int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma,
 			return -EINVAL;
 		}
 		flags = new_flags;
+		vma->vm_page_prot = __pgprot(
+			(pgprot_val(vma->vm_page_prot) & ~_PAGE_CACHE_MASK) |
+			flags);
 	}
 
 	if (((vma->vm_pgoff < max_low_pfn_mapped) ||


Index: kernel.spec
===================================================================
RCS file: /cvs/pkgs/rpms/kernel/devel/kernel.spec,v
retrieving revision 1.1487
retrieving revision 1.1488
diff -u -r1.1487 -r1.1488
--- kernel.spec	30 Mar 2009 19:26:07 -0000	1.1487
+++ kernel.spec	30 Mar 2009 22:16:11 -0000	1.1488
@@ -704,6 +704,8 @@
 Patch9200: linux-2.6-net-xfrm-fix-spin-unlock.patch
 
 # http://bugs.freedesktop.org/show_bug.cgi?id=20803
+Patch9208: linux-2.6.29-pat-change-is_linear_pfn_mapping-to-not-use-vm_pgoff.patch
+Patch9209: linux-2.6.29-pat-pci-change-prot-for-inherit.patch
 Patch9210: linux-2.6.29-pat-fixes.patch
 
 %endif
@@ -1269,6 +1271,8 @@
 
 ApplyPatch linux-2.6-net-xfrm-fix-spin-unlock.patch
 
+ApplyPatch linux-2.6.29-pat-change-is_linear_pfn_mapping-to-not-use-vm_pgoff.patch
+ApplyPatch linux-2.6.29-pat-pci-change-prot-for-inherit.patch
 ApplyPatch linux-2.6.29-pat-fixes.patch
 
 # END OF PATCH APPLICATIONS
@@ -1854,6 +1858,9 @@
 # and build.
 
 %changelog
+* Mon Mar 30 2009 Chuck Ebbert <cebbert at redhat.com>
+- Separate PAT fixes that are headed for -stable from our out-of-tree ones.
+
 * Mon Mar 30 2009 Dave Jones <davej at redhat.com>
 - Make io schedulers selectable at boot time again. (#492817)
 

linux-2.6.29-pat-fixes.patch:

Index: linux-2.6.29-pat-fixes.patch
===================================================================
RCS file: /cvs/pkgs/rpms/kernel/devel/linux-2.6.29-pat-fixes.patch,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- linux-2.6.29-pat-fixes.patch	30 Mar 2009 15:08:54 -0000	1.1
+++ linux-2.6.29-pat-fixes.patch	30 Mar 2009 22:16:12 -0000	1.2
@@ -9,18 +9,20 @@
 Stolen from http://bugs.freedesktop.org/attachment.cgi?id=24172
 with minor fixes.
 
----
- arch/x86/mm/pat.c   |   50 ++++++++++++++++++++++++++++++++++++++------------
- arch/x86/pci/i386.c |    3 +++
- include/linux/mm.h  |   15 +++++++++++++--
- mm/memory.c         |    6 ++++--
- 4 files changed, 58 insertions(+), 16 deletions(-)
 
-diff --git a/arch/x86/mm/pat.c b/arch/x86/mm/pat.c
-index e0ab173..026247e 100644
---- a/arch/x86/mm/pat.c
+cebbert: removed the two patches that are upstream and made them separate:
+	linux-2.6.29-pat-pci-change-prot-for-inherit.patch
+	linux-2.6.29-pat-change-is_linear_pfn_mapping-to-not-use-vm_pgoff.patch
+
+  leaving these two patches from the tarball:
+	pat_pfntrack_debug_3.patch
+	PAT_do_not_use_vm_pgoff_to_track.patch
+
+---
+diff -u b/arch/x86/mm/pat.c b/arch/x86/mm/pat.c
+--- b/arch/x86/mm/pat.c
 +++ b/arch/x86/mm/pat.c
-@@ -365,11 +365,14 @@ int reserve_memtype(u64 start, u64 end, unsigned long req_type,
+@@ -365,11 +365,14 @@
  		*new_type = actual_type;
  
  	is_range_ram = pat_pagerange_is_ram(start, end);
@@ -37,20 +39,15 @@
  
  	new  = kmalloc(sizeof(struct memtype), GFP_KERNEL);
  	if (!new)
-@@ -641,14 +644,21 @@ static int reserve_pfn_range(u64 paddr, unsigned long size, pgprot_t *vma_prot,
- 	is_ram = pat_pagerange_is_ram(paddr, paddr + size);
- 
- 	/*
--	 * reserve_pfn_range() doesn't support RAM pages.
-+	 * reserve_pfn_range() doesn't support RAM pages. Maintain the current
-+	 * behavior with RAM pages by returning success.
+@@ -644,12 +647,18 @@
+ 	 * reserve_pfn_range() doesn't support RAM pages. Maintain the current
+ 	 * behavior with RAM pages by returning success.
  	 */
 -	if (is_ram != 0)
--		return -EINVAL;
 +	if (is_ram != 0) {
 +		printk(KERN_WARNING "reserve_pfn_range: is_ram is %d for 0x%llx!\n",
 +			is_ram, paddr);
-+		return 0;
+ 		return 0;
 +	}
  
  	ret = reserve_memtype(paddr, paddr + size, want_flags, &flags);
@@ -63,7 +60,7 @@
  
  	if (flags != want_flags) {
  		if (strict_prot || !is_new_memtype_allowed(want_flags, flags)) {
-@@ -739,7 +749,12 @@ int track_pfn_vma_copy(struct vm_area_struct *vma)
+@@ -740,7 +749,12 @@
  			return -EINVAL;
  		}
  		pgprot = __pgprot(prot);
@@ -77,7 +74,7 @@
  	}
  
  	/* reserve entire vma page by page, using pfn and prot from pte */
-@@ -749,8 +764,11 @@ int track_pfn_vma_copy(struct vm_area_struct *vma)
+@@ -750,8 +764,11 @@
  
  		pgprot = __pgprot(prot);
  		retval = reserve_pfn_range(paddr, PAGE_SIZE, &pgprot, 1);
@@ -90,7 +87,7 @@
  	}
  	return 0;
  
-@@ -795,8 +813,13 @@ int track_pfn_vma_new(struct vm_area_struct *vma, pgprot_t *prot,
+@@ -796,8 +813,13 @@
  
  	if (is_linear_pfn_mapping(vma)) {
  		/* reserve the whole chunk starting from vm_pgoff */
@@ -106,7 +103,7 @@
  	}
  
  	/* reserve page by page using pfn and size */
-@@ -804,8 +827,11 @@ int track_pfn_vma_new(struct vm_area_struct *vma, pgprot_t *prot,
+@@ -805,8 +827,11 @@
  	for (i = 0; i < size; i += PAGE_SIZE) {
  		paddr = base_paddr + i;
  		retval = reserve_pfn_range(paddr, PAGE_SIZE, prot, 0);
@@ -119,7 +116,7 @@
  	}
  	return 0;
  
-@@ -816,7 +842,7 @@ cleanup_ret:
+@@ -817,7 +842,7 @@
  		free_pfn_range(paddr, PAGE_SIZE);
  	}
  
@@ -128,85 +125,3 @@
  }
  
  /*
-diff --git a/arch/x86/pci/i386.c b/arch/x86/pci/i386.c
-index 5ead808..f234a37 100644
---- a/arch/x86/pci/i386.c
-+++ b/arch/x86/pci/i386.c
-@@ -319,6 +319,9 @@ int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma,
- 			return -EINVAL;
- 		}
- 		flags = new_flags;
-+		vma->vm_page_prot = __pgprot(
-+			(pgprot_val(vma->vm_page_prot) & ~_PAGE_CACHE_MASK) |
-+			flags);
- 	}
- 
- 	if (((vma->vm_pgoff < max_low_pfn_mapped) ||
-diff --git a/include/linux/mm.h b/include/linux/mm.h
-index 065cdf8..3daa05f 100644
---- a/include/linux/mm.h
-+++ b/include/linux/mm.h
-@@ -98,7 +98,7 @@ extern unsigned int kobjsize(const void *objp);
- #define VM_HUGETLB	0x00400000	/* Huge TLB Page VM */
- #define VM_NONLINEAR	0x00800000	/* Is non-linear (remap_file_pages) */
- #define VM_MAPPED_COPY	0x01000000	/* T if mapped copy of data (nommu mmap) */
--#define VM_INSERTPAGE	0x02000000	/* The vma has had "vm_insert_page()" done on it */
-+#define VM_INSERTPAGE	0x02000000	/* The vma has had "vm_insert_page()" done on it. Refer note in VM_PFNMAP_AT_MMAP below */
- #define VM_ALWAYSDUMP	0x04000000	/* Always include in core dumps */
- 
- #define VM_CAN_NONLINEAR 0x08000000	/* Has ->fault & does nonlinear pages */
-@@ -127,6 +127,17 @@ extern unsigned int kobjsize(const void *objp);
- #define VM_SPECIAL (VM_IO | VM_DONTEXPAND | VM_RESERVED | VM_PFNMAP)
- 
- /*
-+ * pfnmap vmas that are fully mapped at mmap time (not mapped on fault).
-+ * Used by x86 PAT to identify such PFNMAP mappings and optimize their handling.
-+ * Note VM_INSERTPAGE flag is overloaded here. i.e,
-+ * VM_INSERTPAGE && !VM_PFNMAP implies
-+ *     The vma has had "vm_insert_page()" done on it
-+ * VM_INSERTPAGE && VM_PFNMAP implies
-+ *     The vma is PFNMAP with full mapping at mmap time
-+ */
-+#define VM_PFNMAP_AT_MMAP (VM_INSERTPAGE | VM_PFNMAP)
-+
-+/*
-  * mapping from the currently active vm_flags protection bits (the
-  * low four bits) to a page protection mask..
-  */
-@@ -145,7 +156,7 @@ extern pgprot_t protection_map[16];
-  */
- static inline int is_linear_pfn_mapping(struct vm_area_struct *vma)
- {
--	return ((vma->vm_flags & VM_PFNMAP) && vma->vm_pgoff);
-+	return ((vma->vm_flags & VM_PFNMAP_AT_MMAP) == VM_PFNMAP_AT_MMAP);
- }
- 
- static inline int is_pfn_mapping(struct vm_area_struct *vma)
-diff --git a/mm/memory.c b/mm/memory.c
-index baa999e..d7df5ba 100644
---- a/mm/memory.c
-+++ b/mm/memory.c
-@@ -1665,9 +1665,10 @@ int remap_pfn_range(struct vm_area_struct *vma, unsigned long addr,
- 	 * behaviour that some programs depend on. We mark the "original"
- 	 * un-COW'ed pages by matching them up with "vma->vm_pgoff".
- 	 */
--	if (addr == vma->vm_start && end == vma->vm_end)
-+	if (addr == vma->vm_start && end == vma->vm_end) {
- 		vma->vm_pgoff = pfn;
--	else if (is_cow_mapping(vma->vm_flags))
-+		vma->vm_flags |= VM_PFNMAP_AT_MMAP;
-+	} else if (is_cow_mapping(vma->vm_flags))
- 		return -EINVAL;
- 
- 	vma->vm_flags |= VM_IO | VM_RESERVED | VM_PFNMAP;
-@@ -1679,6 +1680,7 @@ int remap_pfn_range(struct vm_area_struct *vma, unsigned long addr,
- 		 * needed from higher level routine calling unmap_vmas
- 		 */
- 		vma->vm_flags &= ~(VM_IO | VM_RESERVED | VM_PFNMAP);
-+		vma->vm_flags &= ~VM_PFNMAP_AT_MMAP;
- 		return -EINVAL;
- 	}
- 
--- 
-1.6.2
-




More information about the fedora-extras-commits mailing list