]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
3.0-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 6 Feb 2012 19:17:11 +0000 (11:17 -0800)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 6 Feb 2012 19:17:11 +0000 (11:17 -0800)
added patches:
at_hdmac-bugfix-for-enabling-channel-irq.patch
drm-nouveau-gem-fix-fence_sync-race-oops.patch
drm-radeon-kms-disable-output-polling-when-suspended.patch
drm-radeon-set-desktop_height-register-to-the-framebuffer-not-mode-height.patch
mm-compaction-check-pfn_valid-when-entering-a-new-max_order_nr_pages-block-during-isolation-for-migration.patch
mm-filemap_xip.c-fix-race-condition-in-xip_file_fault.patch

queue-3.0/at_hdmac-bugfix-for-enabling-channel-irq.patch [new file with mode: 0644]
queue-3.0/drm-nouveau-gem-fix-fence_sync-race-oops.patch [new file with mode: 0644]
queue-3.0/drm-radeon-kms-disable-output-polling-when-suspended.patch [new file with mode: 0644]
queue-3.0/drm-radeon-set-desktop_height-register-to-the-framebuffer-not-mode-height.patch [new file with mode: 0644]
queue-3.0/mm-compaction-check-pfn_valid-when-entering-a-new-max_order_nr_pages-block-during-isolation-for-migration.patch [new file with mode: 0644]
queue-3.0/mm-filemap_xip.c-fix-race-condition-in-xip_file_fault.patch [new file with mode: 0644]
queue-3.0/series

diff --git a/queue-3.0/at_hdmac-bugfix-for-enabling-channel-irq.patch b/queue-3.0/at_hdmac-bugfix-for-enabling-channel-irq.patch
new file mode 100644 (file)
index 0000000..755bf36
--- /dev/null
@@ -0,0 +1,88 @@
+From bda3a47c886664e86ee14eb79e9072b9e341f575 Mon Sep 17 00:00:00 2001
+From: Nikolaus Voss <n.voss@weinmann.de>
+Date: Tue, 17 Jan 2012 10:28:33 +0100
+Subject: at_hdmac: bugfix for enabling channel irq
+
+From: Nikolaus Voss <n.voss@weinmann.de>
+
+commit bda3a47c886664e86ee14eb79e9072b9e341f575 upstream.
+
+commit 463894705e4089d0ff69e7d877312d496ac70e5b deleted redundant
+chan_id and chancnt initialization in dma drivers as this is done
+in dma_async_device_register().
+
+However, atc_enable_irq() relied on chan_id set before registering
+the device, what left only channel 0 functional for this driver.
+
+This patch introduces atc_enable/disable_chan_irq() as a variant
+of atc_enable/disable_irq() with the channel as explicit argument.
+
+Signed-off-by: Nikolaus Voss <n.voss@weinmann.de>
+Signed-off-by: Nicolas Ferre <nicolas.ferre@atmel.com>
+Signed-off-by: Vinod Koul <vinod.koul@linux.intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/dma/at_hdmac.c      |    4 ++--
+ drivers/dma/at_hdmac_regs.h |   17 ++++++++---------
+ 2 files changed, 10 insertions(+), 11 deletions(-)
+
+--- a/drivers/dma/at_hdmac.c
++++ b/drivers/dma/at_hdmac.c
+@@ -1279,7 +1279,7 @@ static int __init at_dma_probe(struct pl
+               tasklet_init(&atchan->tasklet, atc_tasklet,
+                               (unsigned long)atchan);
+-              atc_enable_irq(atchan);
++              atc_enable_chan_irq(atdma, i);
+       }
+       /* set base routines */
+@@ -1348,7 +1348,7 @@ static int __exit at_dma_remove(struct p
+               struct at_dma_chan      *atchan = to_at_dma_chan(chan);
+               /* Disable interrupts */
+-              atc_disable_irq(atchan);
++              atc_disable_chan_irq(atdma, chan->chan_id);
+               tasklet_disable(&atchan->tasklet);
+               tasklet_kill(&atchan->tasklet);
+--- a/drivers/dma/at_hdmac_regs.h
++++ b/drivers/dma/at_hdmac_regs.h
+@@ -319,28 +319,27 @@ static void atc_dump_lli(struct at_dma_c
+ }
+-static void atc_setup_irq(struct at_dma_chan *atchan, int on)
++static void atc_setup_irq(struct at_dma *atdma, int chan_id, int on)
+ {
+-      struct at_dma   *atdma = to_at_dma(atchan->chan_common.device);
+-      u32             ebci;
++      u32 ebci;
+       /* enable interrupts on buffer transfer completion & error */
+-      ebci =    AT_DMA_BTC(atchan->chan_common.chan_id)
+-              | AT_DMA_ERR(atchan->chan_common.chan_id);
++      ebci =    AT_DMA_BTC(chan_id)
++              | AT_DMA_ERR(chan_id);
+       if (on)
+               dma_writel(atdma, EBCIER, ebci);
+       else
+               dma_writel(atdma, EBCIDR, ebci);
+ }
+-static inline void atc_enable_irq(struct at_dma_chan *atchan)
++static void atc_enable_chan_irq(struct at_dma *atdma, int chan_id)
+ {
+-      atc_setup_irq(atchan, 1);
++      atc_setup_irq(atdma, chan_id, 1);
+ }
+-static inline void atc_disable_irq(struct at_dma_chan *atchan)
++static void atc_disable_chan_irq(struct at_dma *atdma, int chan_id)
+ {
+-      atc_setup_irq(atchan, 0);
++      atc_setup_irq(atdma, chan_id, 0);
+ }
diff --git a/queue-3.0/drm-nouveau-gem-fix-fence_sync-race-oops.patch b/queue-3.0/drm-nouveau-gem-fix-fence_sync-race-oops.patch
new file mode 100644 (file)
index 0000000..eee66e0
--- /dev/null
@@ -0,0 +1,106 @@
+From 525895ba388c949aa906f26e3ec5cb1ab041f56b Mon Sep 17 00:00:00 2001
+From: Ben Skeggs <bskeggs@redhat.com>
+Date: Tue, 10 Jan 2012 10:18:28 +1000
+Subject: drm/nouveau/gem: fix fence_sync race / oops
+
+From: Ben Skeggs <bskeggs@redhat.com>
+
+commit 525895ba388c949aa906f26e3ec5cb1ab041f56b upstream.
+
+Due to a race it was possible for a fence to be destroyed while another
+thread was trying to synchronise with it.  If this happened in the fallback
+non-semaphore path, it lead to the following oops due to fence->channel
+being NULL.
+
+BUG: unable to handle kernel NULL pointer dereference at   (null)
+IP: [<fa9632ce>] nouveau_fence_update+0xe/0xe0 [nouveau]
+*pde = a649c067
+SMP
+Modules linked in: fuse nouveau(O) ttm(O) drm_kms_helper(O) drm(O) mxm_wmi video wmi netconsole configfs lockd bnep bluetooth rfkill ip6t_REJECT nf_conntrack_ipv6 nf_defrag_ipv6 nf_conntrack_ipv4 nf_defrag_ipv4 xt_state nf_conntrack ip6table_filter ip6_tables snd_hda_codec_realtek snd_hda_intel snd_hda_cobinfmt_misc uinput ata_generic pata_acpi pata_aet2c_algo_bit i2c_core [last unloaded: wmi]
+
+Pid: 2255, comm: gnome-shell Tainted: G           O 3.2.0-0.rc5.git0.1.fc17.i686 #1 System manufacturer System Product Name/M2A-VM
+EIP: 0060:[<fa9632ce>] EFLAGS: 00010296 CPU: 1
+EIP is at nouveau_fence_update+0xe/0xe0 [nouveau]
+EAX: 00000000 EBX: ddfc6dd0 ECX: dd111580 EDX: 00000000
+ESI: 00003e80 EDI: dd111580 EBP: dd121d00 ESP: dd121ce8
+ DS: 007b ES: 007b FS: 00d8 GS: 00e0 SS: 0068
+Process gnome-shell (pid: 2255, ti=dd120000 task=dd111580 task.ti=dd120000)
+Stack:
+ 7dc86c76 00000000 00003e80 ddfc6dd0 00003e80 dd111580 dd121d0c fa96371f
+ 00000000 dd121d3c fa963773 dd111580 01000246 000ec53d 00000000 ddfc6dd0
+ 00001f40 00000000 ddfc6dd0 00000010 dc7df840 dd121d6c fa9639a0 00000000
+Call Trace:
+ [<fa96371f>] __nouveau_fence_signalled+0x1f/0x30 [nouveau]
+ [<fa963773>] __nouveau_fence_wait+0x43/0xd0 [nouveau]
+ [<fa9639a0>] nouveau_fence_sync+0x1a0/0x1c0 [nouveau]
+ [<fa964046>] validate_list+0x176/0x300 [nouveau]
+ [<f7d9c9c0>] ? ttm_bo_mem_put+0x30/0x30 [ttm]
+ [<fa964b8a>] nouveau_gem_ioctl_pushbuf+0x48a/0xfd0 [nouveau]
+ [<c0406481>] ? die+0x31/0x80
+ [<f7c93d98>] drm_ioctl+0x388/0x490 [drm]
+ [<c0406481>] ? die+0x31/0x80
+ [<fa964700>] ? nouveau_gem_ioctl_new+0x150/0x150 [nouveau]
+ [<c0635c7b>] ? file_has_perm+0xcb/0xe0
+ [<f7c93a10>] ? drm_copy_field+0x80/0x80 [drm]
+ [<c0564f56>] do_vfs_ioctl+0x86/0x5b0
+ [<c0406481>] ? die+0x31/0x80
+ [<c0635f22>] ? selinux_file_ioctl+0x62/0x130
+ [<c0554f30>] ? fget_light+0x30/0x340
+ [<c05654ef>] sys_ioctl+0x6f/0x80
+ [<c099e3a4>] syscall_call+0x7/0xb
+ [<c0406481>] ? die+0x31/0x80
+ [<c0406481>] ? die+0x31/0x80
+
+Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/gpu/drm/nouveau/nouveau_gem.c |   23 +++++++++++++++++++++--
+ 1 file changed, 21 insertions(+), 2 deletions(-)
+
+--- a/drivers/gpu/drm/nouveau/nouveau_gem.c
++++ b/drivers/gpu/drm/nouveau/nouveau_gem.c
+@@ -315,6 +315,25 @@ retry:
+ }
+ static int
++validate_sync(struct nouveau_channel *chan, struct nouveau_bo *nvbo)
++{
++      struct nouveau_fence *fence = NULL;
++      int ret = 0;
++
++      spin_lock(&nvbo->bo.bdev->fence_lock);
++      if (nvbo->bo.sync_obj)
++              fence = nouveau_fence_ref(nvbo->bo.sync_obj);
++      spin_unlock(&nvbo->bo.bdev->fence_lock);
++
++      if (fence) {
++              ret = nouveau_fence_sync(fence, chan);
++              nouveau_fence_unref(&fence);
++      }
++
++      return ret;
++}
++
++static int
+ validate_list(struct nouveau_channel *chan, struct list_head *list,
+             struct drm_nouveau_gem_pushbuf_bo *pbbo, uint64_t user_pbbo_ptr)
+ {
+@@ -327,7 +346,7 @@ validate_list(struct nouveau_channel *ch
+       list_for_each_entry(nvbo, list, entry) {
+               struct drm_nouveau_gem_pushbuf_bo *b = &pbbo[nvbo->pbbo_index];
+-              ret = nouveau_fence_sync(nvbo->bo.sync_obj, chan);
++              ret = validate_sync(chan, nvbo);
+               if (unlikely(ret)) {
+                       NV_ERROR(dev, "fail pre-validate sync\n");
+                       return ret;
+@@ -350,7 +369,7 @@ validate_list(struct nouveau_channel *ch
+                       return ret;
+               }
+-              ret = nouveau_fence_sync(nvbo->bo.sync_obj, chan);
++              ret = validate_sync(chan, nvbo);
+               if (unlikely(ret)) {
+                       NV_ERROR(dev, "fail post-validate sync\n");
+                       return ret;
diff --git a/queue-3.0/drm-radeon-kms-disable-output-polling-when-suspended.patch b/queue-3.0/drm-radeon-kms-disable-output-polling-when-suspended.patch
new file mode 100644 (file)
index 0000000..3378bc2
--- /dev/null
@@ -0,0 +1,42 @@
+From 86698c20f71d488b32c49ed4687fb3cf8a88a5ca Mon Sep 17 00:00:00 2001
+From: Seth Forshee <seth.forshee@canonical.com>
+Date: Tue, 31 Jan 2012 19:06:25 -0600
+Subject: drm/radeon/kms: disable output polling when suspended
+
+From: Seth Forshee <seth.forshee@canonical.com>
+
+commit 86698c20f71d488b32c49ed4687fb3cf8a88a5ca upstream.
+
+Polling the outputs when the device is suspended can result in erroneous
+status updates. Disable output polling during suspend to prevent this
+from happening.
+
+Signed-off-by: Seth Forshee <seth.forshee@canonical.com>
+Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Dave Airlie <airlied@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/gpu/drm/radeon/radeon_device.c |    4 ++++
+ 1 file changed, 4 insertions(+)
+
+--- a/drivers/gpu/drm/radeon/radeon_device.c
++++ b/drivers/gpu/drm/radeon/radeon_device.c
+@@ -857,6 +857,8 @@ int radeon_suspend_kms(struct drm_device
+       if (dev->switch_power_state == DRM_SWITCH_POWER_OFF)
+               return 0;
++      drm_kms_helper_poll_disable(dev);
++
+       /* turn off display hw */
+       list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
+               drm_helper_connector_dpms(connector, DRM_MODE_DPMS_OFF);
+@@ -943,6 +945,8 @@ int radeon_resume_kms(struct drm_device
+       list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
+               drm_helper_connector_dpms(connector, DRM_MODE_DPMS_ON);
+       }
++
++      drm_kms_helper_poll_enable(dev);
+       return 0;
+ }
diff --git a/queue-3.0/drm-radeon-set-desktop_height-register-to-the-framebuffer-not-mode-height.patch b/queue-3.0/drm-radeon-set-desktop_height-register-to-the-framebuffer-not-mode-height.patch
new file mode 100644 (file)
index 0000000..979c4a4
--- /dev/null
@@ -0,0 +1,52 @@
+From 1b61925061660009f5b8047f93c5297e04541273 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Michel=20D=C3=A4nzer?= <michel.daenzer@amd.com>
+Date: Wed, 1 Feb 2012 12:09:55 +0100
+Subject: drm/radeon: Set DESKTOP_HEIGHT register to the framebuffer (not mode) height.
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: =?UTF-8?q?Michel=20D=C3=A4nzer?= <michel.daenzer@amd.com>
+
+commit 1b61925061660009f5b8047f93c5297e04541273 upstream.
+
+The value of this register is transferred to the V_COUNTER register at the
+beginning of vertical blank. V_COUNTER is the reference for VLINE waits and
+goes from VIEWPORT_Y_START to VIEWPORT_Y_START+VIEWPORT_HEIGHT during scanout,
+so if VIEWPORT_Y_START is not 0, V_COUNTER actually went backwards at the
+beginning of vertical blank, and VLINE waits excluding the whole scanout area
+could never finish (possibly only if VIEWPORT_Y_START is larger than the length
+of vertical blank in scanlines). Setting DESKTOP_HEIGHT to the framebuffer
+height should prevent this for any kind of VLINE wait.
+
+Fixes https://bugs.freedesktop.org/show_bug.cgi?id=45329 .
+
+Signed-off-by: Michel Dänzer <michel.daenzer@amd.com>
+Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Dave Airlie <airlied@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/gpu/drm/radeon/atombios_crtc.c |    4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/drivers/gpu/drm/radeon/atombios_crtc.c
++++ b/drivers/gpu/drm/radeon/atombios_crtc.c
+@@ -1173,7 +1173,7 @@ static int dce4_crtc_do_set_base(struct
+       WREG32(EVERGREEN_GRPH_ENABLE + radeon_crtc->crtc_offset, 1);
+       WREG32(EVERGREEN_DESKTOP_HEIGHT + radeon_crtc->crtc_offset,
+-             crtc->mode.vdisplay);
++             target_fb->height);
+       x &= ~3;
+       y &= ~1;
+       WREG32(EVERGREEN_VIEWPORT_START + radeon_crtc->crtc_offset,
+@@ -1342,7 +1342,7 @@ static int avivo_crtc_do_set_base(struct
+       WREG32(AVIVO_D1GRPH_ENABLE + radeon_crtc->crtc_offset, 1);
+       WREG32(AVIVO_D1MODE_DESKTOP_HEIGHT + radeon_crtc->crtc_offset,
+-             crtc->mode.vdisplay);
++             target_fb->height);
+       x &= ~3;
+       y &= ~1;
+       WREG32(AVIVO_D1MODE_VIEWPORT_START + radeon_crtc->crtc_offset,
diff --git a/queue-3.0/mm-compaction-check-pfn_valid-when-entering-a-new-max_order_nr_pages-block-during-isolation-for-migration.patch b/queue-3.0/mm-compaction-check-pfn_valid-when-entering-a-new-max_order_nr_pages-block-during-isolation-for-migration.patch
new file mode 100644 (file)
index 0000000..a02037f
--- /dev/null
@@ -0,0 +1,108 @@
+From 0bf380bc70ecba68cb4d74dc656cc2fa8c4d801a Mon Sep 17 00:00:00 2001
+From: Mel Gorman <mgorman@suse.de>
+Date: Fri, 3 Feb 2012 15:37:18 -0800
+Subject: mm: compaction: check pfn_valid when entering a new MAX_ORDER_NR_PAGES block during isolation for migration
+
+From: Mel Gorman <mgorman@suse.de>
+
+commit 0bf380bc70ecba68cb4d74dc656cc2fa8c4d801a upstream.
+
+When isolating for migration, migration starts at the start of a zone
+which is not necessarily pageblock aligned.  Further, it stops isolating
+when COMPACT_CLUSTER_MAX pages are isolated so migrate_pfn is generally
+not aligned.  This allows isolate_migratepages() to call pfn_to_page() on
+an invalid PFN which can result in a crash.  This was originally reported
+against a 3.0-based kernel with the following trace in a crash dump.
+
+PID: 9902   TASK: d47aecd0  CPU: 0   COMMAND: "memcg_process_s"
+ #0 [d72d3ad0] crash_kexec at c028cfdb
+ #1 [d72d3b24] oops_end at c05c5322
+ #2 [d72d3b38] __bad_area_nosemaphore at c0227e60
+ #3 [d72d3bec] bad_area at c0227fb6
+ #4 [d72d3c00] do_page_fault at c05c72ec
+ #5 [d72d3c80] error_code (via page_fault) at c05c47a4
+    EAX: 00000000  EBX: 000c0000  ECX: 00000001  EDX: 00000807  EBP: 000c0000
+    DS:  007b      ESI: 00000001  ES:  007b      EDI: f3000a80  GS:  6f50
+    CS:  0060      EIP: c030b15a  ERR: ffffffff  EFLAGS: 00010002
+ #6 [d72d3cb4] isolate_migratepages at c030b15a
+ #7 [d72d3d14] zone_watermark_ok at c02d26cb
+ #8 [d72d3d2c] compact_zone at c030b8de
+ #9 [d72d3d68] compact_zone_order at c030bba1
+#10 [d72d3db4] try_to_compact_pages at c030bc84
+#11 [d72d3ddc] __alloc_pages_direct_compact at c02d61e7
+#12 [d72d3e08] __alloc_pages_slowpath at c02d66c7
+#13 [d72d3e78] __alloc_pages_nodemask at c02d6a97
+#14 [d72d3eb8] alloc_pages_vma at c030a845
+#15 [d72d3ed4] do_huge_pmd_anonymous_page at c03178eb
+#16 [d72d3f00] handle_mm_fault at c02f36c6
+#17 [d72d3f30] do_page_fault at c05c70ed
+#18 [d72d3fb0] error_code (via page_fault) at c05c47a4
+    EAX: b71ff000  EBX: 00000001  ECX: 00001600  EDX: 00000431
+    DS:  007b      ESI: 08048950  ES:  007b      EDI: bfaa3788
+    SS:  007b      ESP: bfaa36e0  EBP: bfaa3828  GS:  6f50
+    CS:  0073      EIP: 080487c8  ERR: ffffffff  EFLAGS: 00010202
+
+It was also reported by Herbert van den Bergh against 3.1-based kernel
+with the following snippet from the console log.
+
+BUG: unable to handle kernel paging request at 01c00008
+IP: [<c0522399>] isolate_migratepages+0x119/0x390
+*pdpt = 000000002f7ce001 *pde = 0000000000000000
+
+It is expected that it also affects 3.2.x and current mainline.
+
+The problem is that pfn_valid is only called on the first PFN being
+checked and that PFN is not necessarily aligned.  Lets say we have a case
+like this
+
+H = MAX_ORDER_NR_PAGES boundary
+| = pageblock boundary
+m = cc->migrate_pfn
+f = cc->free_pfn
+o = memory hole
+
+H------|------H------|----m-Hoooooo|ooooooH-f----|------H
+
+The migrate_pfn is just below a memory hole and the free scanner is beyond
+the hole.  When isolate_migratepages started, it scans from migrate_pfn to
+migrate_pfn+pageblock_nr_pages which is now in a memory hole.  It checks
+pfn_valid() on the first PFN but then scans into the hole where there are
+not necessarily valid struct pages.
+
+This patch ensures that isolate_migratepages calls pfn_valid when
+necessary.
+
+Reported-by: Herbert van den Bergh <herbert.van.den.bergh@oracle.com>
+Tested-by: Herbert van den Bergh <herbert.van.den.bergh@oracle.com>
+Signed-off-by: Mel Gorman <mgorman@suse.de>
+Acked-by: Michal Nazarewicz <mina86@mina86.com>
+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/compaction.c |   13 +++++++++++++
+ 1 file changed, 13 insertions(+)
+
+--- a/mm/compaction.c
++++ b/mm/compaction.c
+@@ -320,6 +320,19 @@ static isolate_migrate_t isolate_migrate
+               } else if (!locked)
+                       spin_lock_irq(&zone->lru_lock);
++              /*
++               * migrate_pfn does not necessarily start aligned to a
++               * pageblock. Ensure that pfn_valid is called when moving
++               * into a new MAX_ORDER_NR_PAGES range in case of large
++               * memory holes within the zone
++               */
++              if ((low_pfn & (MAX_ORDER_NR_PAGES - 1)) == 0) {
++                      if (!pfn_valid(low_pfn)) {
++                              low_pfn += MAX_ORDER_NR_PAGES - 1;
++                              continue;
++                      }
++              }
++
+               if (!pfn_valid_within(low_pfn))
+                       continue;
+               nr_scanned++;
diff --git a/queue-3.0/mm-filemap_xip.c-fix-race-condition-in-xip_file_fault.patch b/queue-3.0/mm-filemap_xip.c-fix-race-condition-in-xip_file_fault.patch
new file mode 100644 (file)
index 0000000..1c543ab
--- /dev/null
@@ -0,0 +1,55 @@
+From 99f02ef1f18631eb0a4e0ea0a3d56878dbcb4b90 Mon Sep 17 00:00:00 2001
+From: Carsten Otte <carsteno@de.ibm.com>
+Date: Fri, 3 Feb 2012 15:37:14 -0800
+Subject: mm/filemap_xip.c: fix race condition in xip_file_fault()
+
+From: Carsten Otte <carsteno@de.ibm.com>
+
+commit 99f02ef1f18631eb0a4e0ea0a3d56878dbcb4b90 upstream.
+
+Fix a race condition that shows in conjunction with xip_file_fault() when
+two threads of the same user process fault on the same memory page.
+
+In this case, the race winner will install the page table entry and the
+unlucky loser will cause an oops: xip_file_fault calls vm_insert_pfn (via
+vm_insert_mixed) which drops out at this check:
+
+       retval = -EBUSY;
+       if (!pte_none(*pte))
+               goto out_unlock;
+
+The resulting -EBUSY return value will trigger a BUG_ON() in
+xip_file_fault.
+
+This fix simply considers the fault as fixed in this case, because the
+race winner has successfully installed the pte.
+
+[akpm@linux-foundation.org: use conventional (and consistent) comment layout]
+Reported-by: David Sadler <dsadler@us.ibm.com>
+Signed-off-by: Carsten Otte <cotte@de.ibm.com>
+Reported-by: Louis Alex Eisner <leisner@cs.ucsd.edu>
+Cc: Hugh Dickins <hughd@google.com>
+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/filemap_xip.c |    7 ++++++-
+ 1 file changed, 6 insertions(+), 1 deletion(-)
+
+--- a/mm/filemap_xip.c
++++ b/mm/filemap_xip.c
+@@ -263,7 +263,12 @@ found:
+                                                       xip_pfn);
+               if (err == -ENOMEM)
+                       return VM_FAULT_OOM;
+-              BUG_ON(err);
++              /*
++               * err == -EBUSY is fine, we've raced against another thread
++               * that faulted-in the same page
++               */
++              if (err != -EBUSY)
++                      BUG_ON(err);
+               return VM_FAULT_NOPAGE;
+       } else {
+               int err, ret = VM_FAULT_OOM;
index b84822bc1e15bd68cf7570dad9870107d140bdd5..2b4d2fb89ab8ff4f09fda3b0db165638356160bd 100644 (file)
@@ -14,3 +14,9 @@ firewire-ohci-add-reset-packet-quirk-for-sb-audigy.patch
 firewire-ohci-disable-msi-on-ricoh-controllers.patch
 ib-mlx4-pass-smp-vendor-specific-attribute-mads-to-firmware.patch
 kprobes-fix-a-memory-leak-in-function-pre_handler_kretprobe.patch
+at_hdmac-bugfix-for-enabling-channel-irq.patch
+mm-filemap_xip.c-fix-race-condition-in-xip_file_fault.patch
+mm-compaction-check-pfn_valid-when-entering-a-new-max_order_nr_pages-block-during-isolation-for-migration.patch
+drm-radeon-set-desktop_height-register-to-the-framebuffer-not-mode-height.patch
+drm-nouveau-gem-fix-fence_sync-race-oops.patch
+drm-radeon-kms-disable-output-polling-when-suspended.patch