--- /dev/null
+From zhenyuw@linux.intel.com Wed Sep 22 13:11:16 2010
+From: Zhenyu Wang <zhenyuw@linux.intel.com>
+Date: Sun, 19 Sep 2010 10:28:54 +0800
+Subject: agp/intel: fix dma mask bits on sandybridge
+To: stable@kernel.org
+Cc: tiwai@suse.de, chris@chris-wilson.co.uk
+Message-ID: <1284863335-15989-4-git-send-email-zhenyuw@linux.intel.com>
+
+From: Zhenyu Wang <zhenyuw@linux.intel.com>
+
+[This is backport patch from upstream 877fdacf.]
+
+Signed-off-by: Zhenyu Wang <zhenyuw@linux.intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/char/agp/intel-agp.c | 23 ++++++++++++++---------
+ 1 file changed, 14 insertions(+), 9 deletions(-)
+
+--- a/drivers/char/agp/intel-agp.c
++++ b/drivers/char/agp/intel-agp.c
+@@ -835,7 +835,7 @@ static const struct intel_driver_descrip
+ static int __devinit intel_gmch_probe(struct pci_dev *pdev,
+ struct agp_bridge_data *bridge)
+ {
+- int i;
++ int i, mask;
+ bridge->driver = NULL;
+
+ for (i = 0; intel_agp_chipsets[i].name != NULL; i++) {
+@@ -855,14 +855,19 @@ static int __devinit intel_gmch_probe(st
+
+ dev_info(&pdev->dev, "Intel %s Chipset\n", intel_agp_chipsets[i].name);
+
+- if (bridge->driver->mask_memory == intel_i965_mask_memory) {
+- if (pci_set_dma_mask(intel_private.pcidev, DMA_BIT_MASK(36)))
+- dev_err(&intel_private.pcidev->dev,
+- "set gfx device dma mask 36bit failed!\n");
+- else
+- pci_set_consistent_dma_mask(intel_private.pcidev,
+- DMA_BIT_MASK(36));
+- }
++ if (bridge->driver->mask_memory == intel_gen6_mask_memory)
++ mask = 40;
++ else if (bridge->driver->mask_memory == intel_i965_mask_memory)
++ mask = 36;
++ else
++ mask = 32;
++
++ if (pci_set_dma_mask(intel_private.pcidev, DMA_BIT_MASK(mask)))
++ dev_err(&intel_private.pcidev->dev,
++ "set gfx device dma mask %d-bit failed!\n", mask);
++ else
++ pci_set_consistent_dma_mask(intel_private.pcidev,
++ DMA_BIT_MASK(mask));
+
+ return 1;
+ }
--- /dev/null
+From zhenyuw@linux.intel.com Wed Sep 22 13:11:00 2010
+From: Zhenyu Wang <zhenyuw@linux.intel.com>
+Date: Sun, 19 Sep 2010 10:28:53 +0800
+Subject: agp/intel: fix physical address mask bits for sandybridge
+To: stable@kernel.org
+Cc: tiwai@suse.de, chris@chris-wilson.co.uk
+Message-ID: <1284863335-15989-3-git-send-email-zhenyuw@linux.intel.com>
+
+From: Zhenyu Wang <zhenyuw@linux.intel.com>
+
+[This is backport patch from upstream 8dfc2b14.]
+
+Signed-off-by: Zhenyu Wang <zhenyuw@linux.intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/char/agp/intel-gtt.c | 12 +++++++++++-
+ 1 file changed, 11 insertions(+), 1 deletion(-)
+
+--- a/drivers/char/agp/intel-gtt.c
++++ b/drivers/char/agp/intel-gtt.c
+@@ -1317,6 +1317,16 @@ static unsigned long intel_i965_mask_mem
+ return addr | bridge->driver->masks[type].mask;
+ }
+
++static unsigned long intel_gen6_mask_memory(struct agp_bridge_data *bridge,
++ dma_addr_t addr, int type)
++{
++ /* gen6 has bit11-4 for physical addr bit39-32 */
++ addr |= (addr >> 28) & 0xff0;
++
++ /* Type checking must be done elsewhere */
++ return addr | bridge->driver->masks[type].mask;
++}
++
+ static void intel_i965_get_gtt_range(int *gtt_offset, int *gtt_size)
+ {
+ u16 snb_gmch_ctl;
+@@ -1535,7 +1545,7 @@ static const struct agp_bridge_driver in
+ .configure = intel_i9xx_configure,
+ .fetch_size = intel_i9xx_fetch_size,
+ .cleanup = intel_i915_cleanup,
+- .mask_memory = intel_i965_mask_memory,
++ .mask_memory = intel_gen6_mask_memory,
+ .masks = intel_i810_masks,
+ .agp_enable = intel_i810_agp_enable,
+ .cache_flush = global_cache_flush,
--- /dev/null
+From zhenyuw@linux.intel.com Wed Sep 22 13:10:08 2010
+From: Zhenyu Wang <zhenyuw@linux.intel.com>
+Date: Sun, 19 Sep 2010 10:28:52 +0800
+Subject: intel_agp, drm/i915: Add all sandybridge graphics devices support
+To: stable@kernel.org
+Cc: tiwai@suse.de, chris@chris-wilson.co.uk
+Message-ID: <1284863335-15989-2-git-send-email-zhenyuw@linux.intel.com>
+
+From: Zhenyu Wang <zhenyuw@linux.intel.com>
+
+New pci ids for all sandybridge graphics versions on desktop/mobile/server.
+
+[This is backport patch from upstream commit 4fefe435 and 85540480.]
+
+Signed-off-by: Zhenyu Wang <zhenyuw@linux.intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+---
+ drivers/char/agp/intel-agp.c | 19 +++++++++++++++----
+ drivers/char/agp/intel-agp.h | 17 ++++++++++++-----
+ drivers/char/agp/intel-gtt.c | 37 +++++++++++++++++++++++++++++++++++--
+ drivers/gpu/drm/i915/i915_drv.c | 5 +++++
+ 4 files changed, 67 insertions(+), 11 deletions(-)
+
+--- a/drivers/char/agp/intel-agp.c
++++ b/drivers/char/agp/intel-agp.c
+@@ -815,10 +815,20 @@ static const struct intel_driver_descrip
+ "HD Graphics", NULL, &intel_i965_driver },
+ { PCI_DEVICE_ID_INTEL_IRONLAKE_MC2_HB, PCI_DEVICE_ID_INTEL_IRONLAKE_M_IG,
+ "HD Graphics", NULL, &intel_i965_driver },
+- { PCI_DEVICE_ID_INTEL_SANDYBRIDGE_HB, PCI_DEVICE_ID_INTEL_SANDYBRIDGE_IG,
+- "Sandybridge", NULL, &intel_i965_driver },
+- { PCI_DEVICE_ID_INTEL_SANDYBRIDGE_M_HB, PCI_DEVICE_ID_INTEL_SANDYBRIDGE_M_IG,
+- "Sandybridge", NULL, &intel_i965_driver },
++ { PCI_DEVICE_ID_INTEL_SANDYBRIDGE_HB, PCI_DEVICE_ID_INTEL_SANDYBRIDGE_GT1_IG,
++ "Sandybridge", NULL, &intel_gen6_driver },
++ { PCI_DEVICE_ID_INTEL_SANDYBRIDGE_HB, PCI_DEVICE_ID_INTEL_SANDYBRIDGE_GT2_IG,
++ "Sandybridge", NULL, &intel_gen6_driver },
++ { PCI_DEVICE_ID_INTEL_SANDYBRIDGE_HB, PCI_DEVICE_ID_INTEL_SANDYBRIDGE_GT2_PLUS_IG,
++ "Sandybridge", NULL, &intel_gen6_driver },
++ { PCI_DEVICE_ID_INTEL_SANDYBRIDGE_M_HB, PCI_DEVICE_ID_INTEL_SANDYBRIDGE_M_GT1_IG,
++ "Sandybridge", NULL, &intel_gen6_driver },
++ { PCI_DEVICE_ID_INTEL_SANDYBRIDGE_M_HB, PCI_DEVICE_ID_INTEL_SANDYBRIDGE_M_GT2_IG,
++ "Sandybridge", NULL, &intel_gen6_driver },
++ { PCI_DEVICE_ID_INTEL_SANDYBRIDGE_M_HB, PCI_DEVICE_ID_INTEL_SANDYBRIDGE_M_GT2_PLUS_IG,
++ "Sandybridge", NULL, &intel_gen6_driver },
++ { PCI_DEVICE_ID_INTEL_SANDYBRIDGE_S_HB, PCI_DEVICE_ID_INTEL_SANDYBRIDGE_S_IG,
++ "Sandybridge", NULL, &intel_gen6_driver },
+ { 0, 0, NULL, NULL, NULL }
+ };
+
+@@ -1036,6 +1046,7 @@ static struct pci_device_id agp_intel_pc
+ ID(PCI_DEVICE_ID_INTEL_IRONLAKE_MC2_HB),
+ ID(PCI_DEVICE_ID_INTEL_SANDYBRIDGE_HB),
+ ID(PCI_DEVICE_ID_INTEL_SANDYBRIDGE_M_HB),
++ ID(PCI_DEVICE_ID_INTEL_SANDYBRIDGE_S_HB),
+ { }
+ };
+
+--- a/drivers/char/agp/intel-agp.h
++++ b/drivers/char/agp/intel-agp.h
+@@ -194,10 +194,16 @@
+ #define PCI_DEVICE_ID_INTEL_IRONLAKE_MA_HB 0x0062
+ #define PCI_DEVICE_ID_INTEL_IRONLAKE_MC2_HB 0x006a
+ #define PCI_DEVICE_ID_INTEL_IRONLAKE_M_IG 0x0046
+-#define PCI_DEVICE_ID_INTEL_SANDYBRIDGE_HB 0x0100
+-#define PCI_DEVICE_ID_INTEL_SANDYBRIDGE_IG 0x0102
+-#define PCI_DEVICE_ID_INTEL_SANDYBRIDGE_M_HB 0x0104
+-#define PCI_DEVICE_ID_INTEL_SANDYBRIDGE_M_IG 0x0106
++#define PCI_DEVICE_ID_INTEL_SANDYBRIDGE_HB 0x0100 /* Desktop */
++#define PCI_DEVICE_ID_INTEL_SANDYBRIDGE_GT1_IG 0x0102
++#define PCI_DEVICE_ID_INTEL_SANDYBRIDGE_GT2_IG 0x0112
++#define PCI_DEVICE_ID_INTEL_SANDYBRIDGE_GT2_PLUS_IG 0x0122
++#define PCI_DEVICE_ID_INTEL_SANDYBRIDGE_M_HB 0x0104 /* Mobile */
++#define PCI_DEVICE_ID_INTEL_SANDYBRIDGE_M_GT1_IG 0x0106
++#define PCI_DEVICE_ID_INTEL_SANDYBRIDGE_M_GT2_IG 0x0116
++#define PCI_DEVICE_ID_INTEL_SANDYBRIDGE_M_GT2_PLUS_IG 0x0126
++#define PCI_DEVICE_ID_INTEL_SANDYBRIDGE_S_HB 0x0108 /* Server */
++#define PCI_DEVICE_ID_INTEL_SANDYBRIDGE_S_IG 0x010A
+
+ /* cover 915 and 945 variants */
+ #define IS_I915 (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_E7221_HB || \
+@@ -224,7 +230,8 @@
+ agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_PINEVIEW_HB)
+
+ #define IS_SNB (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_SANDYBRIDGE_HB || \
+- agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_SANDYBRIDGE_M_HB)
++ agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_SANDYBRIDGE_M_HB || \
++ agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_SANDYBRIDGE_S_HB)
+
+ #define IS_G4X (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_EAGLELAKE_HB || \
+ agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_Q45_HB || \
+--- a/drivers/char/agp/intel-gtt.c
++++ b/drivers/char/agp/intel-gtt.c
+@@ -585,8 +585,7 @@ static void intel_i830_init_gtt_entries(
+ gtt_entries = 0;
+ break;
+ }
+- } else if (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_SANDYBRIDGE_HB ||
+- agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_SANDYBRIDGE_M_HB) {
++ } else if (IS_SNB) {
+ /*
+ * SandyBridge has new memory control reg at 0x50.w
+ */
+@@ -1337,6 +1336,7 @@ static void intel_i965_get_gtt_range(int
+ break;
+ case PCI_DEVICE_ID_INTEL_SANDYBRIDGE_HB:
+ case PCI_DEVICE_ID_INTEL_SANDYBRIDGE_M_HB:
++ case PCI_DEVICE_ID_INTEL_SANDYBRIDGE_S_HB:
+ *gtt_offset = MB(2);
+
+ pci_read_config_word(intel_private.pcidev, SNB_GMCH_CTRL, &snb_gmch_ctl);
+@@ -1497,6 +1497,39 @@ static const struct agp_bridge_driver in
+ .owner = THIS_MODULE,
+ .aperture_sizes = intel_i830_sizes,
+ .size_type = FIXED_APER_SIZE,
++ .num_aperture_sizes = 4,
++ .needs_scratch_page = true,
++ .configure = intel_i9xx_configure,
++ .fetch_size = intel_i9xx_fetch_size,
++ .cleanup = intel_i915_cleanup,
++ .mask_memory = intel_i965_mask_memory,
++ .masks = intel_i810_masks,
++ .agp_enable = intel_i810_agp_enable,
++ .cache_flush = global_cache_flush,
++ .create_gatt_table = intel_i965_create_gatt_table,
++ .free_gatt_table = intel_i830_free_gatt_table,
++ .insert_memory = intel_i915_insert_entries,
++ .remove_memory = intel_i915_remove_entries,
++ .alloc_by_type = intel_i830_alloc_by_type,
++ .free_by_type = intel_i810_free_by_type,
++ .agp_alloc_page = agp_generic_alloc_page,
++ .agp_alloc_pages = agp_generic_alloc_pages,
++ .agp_destroy_page = agp_generic_destroy_page,
++ .agp_destroy_pages = agp_generic_destroy_pages,
++ .agp_type_to_mask_type = intel_i830_type_to_mask_type,
++ .chipset_flush = intel_i915_chipset_flush,
++#ifdef USE_PCI_DMA_API
++ .agp_map_page = intel_agp_map_page,
++ .agp_unmap_page = intel_agp_unmap_page,
++ .agp_map_memory = intel_agp_map_memory,
++ .agp_unmap_memory = intel_agp_unmap_memory,
++#endif
++};
++
++static const struct agp_bridge_driver intel_gen6_driver = {
++ .owner = THIS_MODULE,
++ .aperture_sizes = intel_i830_sizes,
++ .size_type = FIXED_APER_SIZE,
+ .num_aperture_sizes = 4,
+ .needs_scratch_page = true,
+ .configure = intel_i9xx_configure,
+--- a/drivers/gpu/drm/i915/i915_drv.c
++++ b/drivers/gpu/drm/i915/i915_drv.c
+@@ -180,7 +180,12 @@ static const struct pci_device_id pciidl
+ INTEL_VGA_DEVICE(0x0042, &intel_ironlake_d_info),
+ INTEL_VGA_DEVICE(0x0046, &intel_ironlake_m_info),
+ INTEL_VGA_DEVICE(0x0102, &intel_sandybridge_d_info),
++ INTEL_VGA_DEVICE(0x0112, &intel_sandybridge_d_info),
++ INTEL_VGA_DEVICE(0x0122, &intel_sandybridge_d_info),
+ INTEL_VGA_DEVICE(0x0106, &intel_sandybridge_m_info),
++ INTEL_VGA_DEVICE(0x0116, &intel_sandybridge_m_info),
++ INTEL_VGA_DEVICE(0x0126, &intel_sandybridge_m_info),
++ INTEL_VGA_DEVICE(0x010A, &intel_sandybridge_d_info),
+ {0, 0, 0}
+ };
+
--- /dev/null
+From 4969c1192d15afa3389e7ae3302096ff684ba655 Mon Sep 17 00:00:00 2001
+From: Andrea Arcangeli <aarcange@redhat.com>
+Date: Thu, 9 Sep 2010 16:37:52 -0700
+Subject: mm: fix swapin race condition
+
+From: Andrea Arcangeli <aarcange@redhat.com>
+
+commit 4969c1192d15afa3389e7ae3302096ff684ba655 upstream.
+
+The pte_same check is reliable only if the swap entry remains pinned (by
+the page lock on swapcache). We've also to ensure the swapcache isn't
+removed before we take the lock as try_to_free_swap won't care about the
+page pin.
+
+One of the possible impacts of this patch is that a KSM-shared page can
+point to the anon_vma of another process, which could exit before the page
+is freed.
+
+This can leave a page with a pointer to a recycled anon_vma object, or
+worse, a pointer to something that is no longer an anon_vma.
+
+[Backport to 2.6.35.5 (anon_vma instead of anon_vma->root in ksm.h) by Hugh]
+
+[riel@redhat.com: changelog help]
+Signed-off-by: Andrea Arcangeli <aarcange@redhat.com>
+Acked-by: Hugh Dickins <hughd@google.com>
+Reviewed-by: Rik van Riel <riel@redhat.com>
+Cc: <stable@kernel.org>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Hugh Dickins <hughd@google.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ include/linux/ksm.h | 20 +++++++++-----------
+ mm/ksm.c | 3 ---
+ mm/memory.c | 39 ++++++++++++++++++++++++++++++++++-----
+ 3 files changed, 43 insertions(+), 19 deletions(-)
+
+--- a/include/linux/ksm.h
++++ b/include/linux/ksm.h
+@@ -16,6 +16,9 @@
+ struct stable_node;
+ struct mem_cgroup;
+
++struct page *ksm_does_need_to_copy(struct page *page,
++ struct vm_area_struct *vma, unsigned long address);
++
+ #ifdef CONFIG_KSM
+ int ksm_madvise(struct vm_area_struct *vma, unsigned long start,
+ unsigned long end, int advice, unsigned long *vm_flags);
+@@ -70,19 +73,14 @@ static inline void set_page_stable_node(
+ * We'd like to make this conditional on vma->vm_flags & VM_MERGEABLE,
+ * but what if the vma was unmerged while the page was swapped out?
+ */
+-struct page *ksm_does_need_to_copy(struct page *page,
+- struct vm_area_struct *vma, unsigned long address);
+-static inline struct page *ksm_might_need_to_copy(struct page *page,
++static inline int ksm_might_need_to_copy(struct page *page,
+ struct vm_area_struct *vma, unsigned long address)
+ {
+ struct anon_vma *anon_vma = page_anon_vma(page);
+
+- if (!anon_vma ||
+- (anon_vma == vma->anon_vma &&
+- page->index == linear_page_index(vma, address)))
+- return page;
+-
+- return ksm_does_need_to_copy(page, vma, address);
++ return anon_vma &&
++ (anon_vma != vma->anon_vma ||
++ page->index != linear_page_index(vma, address));
+ }
+
+ int page_referenced_ksm(struct page *page,
+@@ -115,10 +113,10 @@ static inline int ksm_madvise(struct vm_
+ return 0;
+ }
+
+-static inline struct page *ksm_might_need_to_copy(struct page *page,
++static inline int ksm_might_need_to_copy(struct page *page,
+ struct vm_area_struct *vma, unsigned long address)
+ {
+- return page;
++ return 0;
+ }
+
+ static inline int page_referenced_ksm(struct page *page,
+--- a/mm/ksm.c
++++ b/mm/ksm.c
+@@ -1523,8 +1523,6 @@ struct page *ksm_does_need_to_copy(struc
+ {
+ struct page *new_page;
+
+- unlock_page(page); /* any racers will COW it, not modify it */
+-
+ new_page = alloc_page_vma(GFP_HIGHUSER_MOVABLE, vma, address);
+ if (new_page) {
+ copy_user_highpage(new_page, page, address, vma);
+@@ -1540,7 +1538,6 @@ struct page *ksm_does_need_to_copy(struc
+ add_page_to_unevictable_list(new_page);
+ }
+
+- page_cache_release(page);
+ return new_page;
+ }
+
+--- a/mm/memory.c
++++ b/mm/memory.c
+@@ -2626,7 +2626,7 @@ static int do_swap_page(struct mm_struct
+ unsigned int flags, pte_t orig_pte)
+ {
+ spinlock_t *ptl;
+- struct page *page;
++ struct page *page, *swapcache = NULL;
+ swp_entry_t entry;
+ pte_t pte;
+ struct mem_cgroup *ptr = NULL;
+@@ -2681,10 +2681,23 @@ static int do_swap_page(struct mm_struct
+ lock_page(page);
+ delayacct_clear_flag(DELAYACCT_PF_SWAPIN);
+
+- page = ksm_might_need_to_copy(page, vma, address);
+- if (!page) {
+- ret = VM_FAULT_OOM;
+- goto out;
++ /*
++ * Make sure try_to_free_swap didn't release the swapcache
++ * from under us. The page pin isn't enough to prevent that.
++ */
++ if (unlikely(!PageSwapCache(page)))
++ goto out_page;
++
++ if (ksm_might_need_to_copy(page, vma, address)) {
++ swapcache = page;
++ page = ksm_does_need_to_copy(page, vma, address);
++
++ if (unlikely(!page)) {
++ ret = VM_FAULT_OOM;
++ page = swapcache;
++ swapcache = NULL;
++ goto out_page;
++ }
+ }
+
+ if (mem_cgroup_try_charge_swapin(mm, page, GFP_KERNEL, &ptr)) {
+@@ -2735,6 +2748,18 @@ static int do_swap_page(struct mm_struct
+ if (vm_swap_full() || (vma->vm_flags & VM_LOCKED) || PageMlocked(page))
+ try_to_free_swap(page);
+ unlock_page(page);
++ if (swapcache) {
++ /*
++ * Hold the lock to avoid the swap entry to be reused
++ * until we take the PT lock for the pte_same() check
++ * (to avoid false positives from pte_same). For
++ * further safety release the lock after the swap_free
++ * so that the swap count won't change under a
++ * parallel locked swapcache.
++ */
++ unlock_page(swapcache);
++ page_cache_release(swapcache);
++ }
+
+ if (flags & FAULT_FLAG_WRITE) {
+ ret |= do_wp_page(mm, vma, address, page_table, pmd, ptl, pte);
+@@ -2756,6 +2781,10 @@ out_page:
+ unlock_page(page);
+ out_release:
+ page_cache_release(page);
++ if (swapcache) {
++ unlock_page(swapcache);
++ page_cache_release(swapcache);
++ }
+ return ret;
+ }
+
--- /dev/null
+From 31c4a3d3a0f84a5847665f8aa0552d188389f791 Mon Sep 17 00:00:00 2001
+From: Hugh Dickins <hughd@google.com>
+Date: Sun, 19 Sep 2010 19:40:22 -0700
+Subject: mm: further fix swapin race condition
+
+From: Hugh Dickins <hughd@google.com>
+
+commit 31c4a3d3a0f84a5847665f8aa0552d188389f791 upstream.
+
+Commit 4969c1192d15 ("mm: fix swapin race condition") is now agreed to
+be incomplete. There's a race, not very much less likely than the
+original race envisaged, in which it is further necessary to check that
+the swapcache page's swap has not changed.
+
+Here's the reasoning: cast in terms of reuse_swap_page(), but probably
+could be reformulated to rely on try_to_free_swap() instead, or on
+swapoff+swapon.
+
+A, faults into do_swap_page(): does page1 = lookup_swap_cache(swap1) and
+comes through the lock_page(page1).
+
+B, a racing thread of the same process, faults on the same address: does
+page1 = lookup_swap_cache(swap1) and now waits in lock_page(page1), but
+for whatever reason is unlucky not to get the lock any time soon.
+
+A carries on through do_swap_page(), a write fault, but cannot reuse the
+swap page1 (another reference to swap1). Unlocks the page1 (but B
+doesn't get it yet), does COW in do_wp_page(), page2 now in that pte.
+
+C, perhaps the parent of A+B, comes in and write faults the same swap
+page1 into its mm, reuse_swap_page() succeeds this time, swap1 is freed.
+
+kswapd comes in after some time (B still unlucky) and swaps out some
+pages from A+B and C: it allocates the original swap1 to page2 in A+B,
+and some other swap2 to the original page1 now in C. But does not
+immediately free page1 (actually it couldn't: B holds a reference),
+leaving it in swap cache for now.
+
+B at last gets the lock on page1, hooray! Is PageSwapCache(page1)? Yes.
+Is pte_same(*page_table, orig_pte)? Yes, because page2 has now been
+given the swap1 which page1 used to have. So B proceeds to insert page1
+into A+B's page_table, though its content now belongs to C, quite
+different from what A wrote there.
+
+B ought to have checked that page1's swap was still swap1.
+
+Signed-off-by: Hugh Dickins <hughd@google.com>
+Reviewed-by: Rik van Riel <riel@redhat.com>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ mm/memory.c | 8 +++++---
+ 1 file changed, 5 insertions(+), 3 deletions(-)
+
+--- a/mm/memory.c
++++ b/mm/memory.c
+@@ -2682,10 +2682,12 @@ static int do_swap_page(struct mm_struct
+ delayacct_clear_flag(DELAYACCT_PF_SWAPIN);
+
+ /*
+- * Make sure try_to_free_swap didn't release the swapcache
+- * from under us. The page pin isn't enough to prevent that.
++ * Make sure try_to_free_swap or reuse_swap_page or swapoff did not
++ * release the swapcache from under us. The page pin, and pte_same
++ * test below, are not enough to exclude that. Even if it is still
++ * swapcache, we need to check that the page's swap has not changed.
+ */
+- if (unlikely(!PageSwapCache(page)))
++ if (unlikely(!PageSwapCache(page) || page_private(page) != entry.val))
+ goto out_page;
+
+ if (ksm_might_need_to_copy(page, vma, address)) {
--- /dev/null
+From 339db11b219f36cf7da61b390992d95bb6b7ba2e Mon Sep 17 00:00:00 2001
+From: Dan Carpenter <error27@gmail.com>
+Date: Fri, 10 Sep 2010 01:56:16 +0000
+Subject: net/llc: make opt unsigned in llc_ui_setsockopt()
+
+From: Dan Carpenter <error27@gmail.com>
+
+commit 339db11b219f36cf7da61b390992d95bb6b7ba2e upstream.
+
+The members of struct llc_sock are unsigned so if we pass a negative
+value for "opt" it can cause a sign bug. Also it can cause an integer
+overflow when we multiply "opt * HZ".
+
+Signed-off-by: Dan Carpenter <error27@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ net/llc/af_llc.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/net/llc/af_llc.c
++++ b/net/llc/af_llc.c
+@@ -1024,7 +1024,8 @@ static int llc_ui_setsockopt(struct sock
+ {
+ struct sock *sk = sock->sk;
+ struct llc_sock *llc = llc_sk(sk);
+- int rc = -EINVAL, opt;
++ unsigned int opt;
++ int rc = -EINVAL;
+
+ lock_sock(sk);
+ if (unlikely(level != SOL_LLC || optlen != sizeof(int)))
drivers-net-cxgb3-cxgb3_main.c-prevent-reading-uninitialized-stack-memory.patch
drivers-net-eql.c-prevent-reading-uninitialized-stack-memory.patch
bonding-correctly-process-non-linear-skbs.patch
+staging-vt6655-fix-buffer-overflow.patch
+net-llc-make-opt-unsigned-in-llc_ui_setsockopt.patch
+mm-fix-swapin-race-condition.patch
+mm-further-fix-swapin-race-condition.patch
+virtio-console-prevent-userspace-from-submitting-null-buffers.patch
+virtio-console-fix-poll-blocking-even-though-there-is-data-to-read.patch
+intel_agp-drm-i915-add-all-sandybridge-graphics-devices-support.patch
+agp-intel-fix-physical-address-mask-bits-for-sandybridge.patch
+agp-intel-fix-dma-mask-bits-on-sandybridge.patch
--- /dev/null
+From dd173abfead903c7df54e977535973f3312cd307 Mon Sep 17 00:00:00 2001
+From: Dan Carpenter <error27@gmail.com>
+Date: Mon, 6 Sep 2010 14:32:30 +0200
+Subject: Staging: vt6655: fix buffer overflow
+
+From: Dan Carpenter <error27@gmail.com>
+
+commit dd173abfead903c7df54e977535973f3312cd307 upstream.
+
+"param->u.wpa_associate.wpa_ie_len" comes from the user. We should
+check it so that the copy_from_user() doesn't overflow the buffer.
+
+Also further down in the function, we assume that if
+"param->u.wpa_associate.wpa_ie_len" is set then "abyWPAIE[0]" is
+initialized. To make that work, I changed the test here to say that if
+"wpa_ie_len" is set then "wpa_ie" has to be a valid pointer or we return
+-EINVAL.
+
+Oddly, we only use the first element of the abyWPAIE[] array. So I
+suspect there may be some other issues in this function.
+
+Signed-off-by: Dan Carpenter <error27@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/staging/vt6655/wpactl.c | 11 ++++++++---
+ 1 file changed, 8 insertions(+), 3 deletions(-)
+
+--- a/drivers/staging/vt6655/wpactl.c
++++ b/drivers/staging/vt6655/wpactl.c
+@@ -766,9 +766,14 @@ static int wpa_set_associate(PSDevice pD
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "wpa_ie_len = %d\n", param->u.wpa_associate.wpa_ie_len);
+
+
+- if (param->u.wpa_associate.wpa_ie &&
+- copy_from_user(&abyWPAIE[0], param->u.wpa_associate.wpa_ie, param->u.wpa_associate.wpa_ie_len))
+- return -EINVAL;
++ if (param->u.wpa_associate.wpa_ie_len) {
++ if (!param->u.wpa_associate.wpa_ie)
++ return -EINVAL;
++ if (param->u.wpa_associate.wpa_ie_len > sizeof(abyWPAIE))
++ return -EINVAL;
++ if (copy_from_user(&abyWPAIE[0], param->u.wpa_associate.wpa_ie, param->u.wpa_associate.wpa_ie_len))
++ return -EFAULT;
++ }
+
+ if (param->u.wpa_associate.mode == 1)
+ pMgmt->eConfigMode = WMAC_CONFIG_IBSS_STA;
--- /dev/null
+From 6df7aadcd9290807c464675098b5dd2dc9da5075 Mon Sep 17 00:00:00 2001
+From: Hans de Goede <hdegoede@redhat.com>
+Date: Thu, 16 Sep 2010 14:43:08 +0530
+Subject: virtio: console: Fix poll blocking even though there is data to read
+
+From: Hans de Goede <hdegoede@redhat.com>
+
+commit 6df7aadcd9290807c464675098b5dd2dc9da5075 upstream.
+
+I found this while working on a Linux agent for spice, the symptom I was
+seeing was select blocking on the spice vdagent virtio serial port even
+though there were messages queued up there.
+
+virtio_console's port_fops_poll checks port->inbuf != NULL to determine
+if read won't block. However if an application reads enough bytes from
+inbuf through port_fops_read, to empty the current port->inbuf,
+port->inbuf will be NULL even though there may be buffers left in the
+virtqueue.
+
+This causes poll() to block even though there is data to be read,
+this patch fixes this by using will_read_block(port) instead of the
+port->inbuf != NULL check.
+
+Signed-off-By: Hans de Goede <hdegoede@redhat.com>
+Signed-off-by: Amit Shah <amit.shah@redhat.com>
+Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/char/virtio_console.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/char/virtio_console.c
++++ b/drivers/char/virtio_console.c
+@@ -646,7 +646,7 @@ static unsigned int port_fops_poll(struc
+ poll_wait(filp, &port->waitqueue, wait);
+
+ ret = 0;
+- if (port->inbuf)
++ if (!will_read_block(port))
+ ret |= POLLIN | POLLRDNORM;
+ if (!will_write_block(port))
+ ret |= POLLOUT;
--- /dev/null
+From 65745422a898741ee0e7068ef06624ab06e8aefa Mon Sep 17 00:00:00 2001
+From: Amit Shah <amit.shah@redhat.com>
+Date: Tue, 14 Sep 2010 13:26:16 +0530
+Subject: virtio: console: Prevent userspace from submitting NULL buffers
+
+From: Amit Shah <amit.shah@redhat.com>
+
+commit 65745422a898741ee0e7068ef06624ab06e8aefa upstream.
+
+A userspace could submit a buffer with 0 length to be written to the
+host. Prevent such a situation.
+
+This was not needed previously, but recent changes in the way write()
+works exposed this condition to trigger a virtqueue event to the host,
+causing a NULL buffer to be sent across.
+
+Signed-off-by: Amit Shah <amit.shah@redhat.com>
+Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/char/virtio_console.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+--- a/drivers/char/virtio_console.c
++++ b/drivers/char/virtio_console.c
+@@ -596,6 +596,10 @@ static ssize_t port_fops_write(struct fi
+ ssize_t ret;
+ bool nonblock;
+
++ /* Userspace could be out to fool us */
++ if (!count)
++ return 0;
++
+ port = filp->private_data;
+
+ nonblock = filp->f_flags & O_NONBLOCK;