]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
3.11-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 30 Oct 2013 22:40:14 +0000 (15:40 -0700)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 30 Oct 2013 22:40:14 +0000 (15:40 -0700)
added patches:
alsa-hda-fix-inverted-internal-mic-not-indicated-on-some-machines.patch
alsa-us122l-fix-pcm_usb_stream-mmapping-regression.patch
arm-7851-1-check-for-number-of-arguments-in-syscall_get-set_arguments.patch
arm-integrator-deactivate-timer0-on-the-integrator-cp.patch
dm-snapshot-fix-data-corruption.patch
ext-fix-double-put-in-tmpfile.patch
fs-buffer-move-allocation-failure-loop-into-the-allocator.patch
gpio-lynxpoint-check-if-the-interrupt-is-enabled-in-irq-handler.patch
i2c-ismt-initialize-dma-buffer.patch
mm-fix-bug-in-__split_huge_page_pmd.patch
mm-migration-do-not-lose-soft-dirty-bit-if-page-is-in-migration-state.patch
mm-zswap-bugfix-memory-leak-when-re-swapon.patch
w1-call-request_module-with-w1-master-mutex-unlocked.patch
wireless-cw1200-acquire-hwbus-lock-around-cw1200_irq_handler-call.patch
wireless-radiotap-fix-parsing-buffer-overrun.patch
writeback-fix-negative-bdi-max-pause.patch

17 files changed:
queue-3.11/alsa-hda-fix-inverted-internal-mic-not-indicated-on-some-machines.patch [new file with mode: 0644]
queue-3.11/alsa-us122l-fix-pcm_usb_stream-mmapping-regression.patch [new file with mode: 0644]
queue-3.11/arm-7851-1-check-for-number-of-arguments-in-syscall_get-set_arguments.patch [new file with mode: 0644]
queue-3.11/arm-integrator-deactivate-timer0-on-the-integrator-cp.patch [new file with mode: 0644]
queue-3.11/dm-snapshot-fix-data-corruption.patch [new file with mode: 0644]
queue-3.11/ext-fix-double-put-in-tmpfile.patch [new file with mode: 0644]
queue-3.11/fs-buffer-move-allocation-failure-loop-into-the-allocator.patch [new file with mode: 0644]
queue-3.11/gpio-lynxpoint-check-if-the-interrupt-is-enabled-in-irq-handler.patch [new file with mode: 0644]
queue-3.11/i2c-ismt-initialize-dma-buffer.patch [new file with mode: 0644]
queue-3.11/mm-fix-bug-in-__split_huge_page_pmd.patch [new file with mode: 0644]
queue-3.11/mm-migration-do-not-lose-soft-dirty-bit-if-page-is-in-migration-state.patch [new file with mode: 0644]
queue-3.11/mm-zswap-bugfix-memory-leak-when-re-swapon.patch [new file with mode: 0644]
queue-3.11/series
queue-3.11/w1-call-request_module-with-w1-master-mutex-unlocked.patch [new file with mode: 0644]
queue-3.11/wireless-cw1200-acquire-hwbus-lock-around-cw1200_irq_handler-call.patch [new file with mode: 0644]
queue-3.11/wireless-radiotap-fix-parsing-buffer-overrun.patch [new file with mode: 0644]
queue-3.11/writeback-fix-negative-bdi-max-pause.patch [new file with mode: 0644]

diff --git a/queue-3.11/alsa-hda-fix-inverted-internal-mic-not-indicated-on-some-machines.patch b/queue-3.11/alsa-hda-fix-inverted-internal-mic-not-indicated-on-some-machines.patch
new file mode 100644 (file)
index 0000000..4d1836e
--- /dev/null
@@ -0,0 +1,42 @@
+From ccb041571b73888785ef7828a276e380125891a4 Mon Sep 17 00:00:00 2001
+From: David Henningsson <david.henningsson@canonical.com>
+Date: Mon, 14 Oct 2013 10:16:22 +0200
+Subject: ALSA: hda - Fix inverted internal mic not indicated on some machines
+
+From: David Henningsson <david.henningsson@canonical.com>
+
+commit ccb041571b73888785ef7828a276e380125891a4 upstream.
+
+The create_bind_cap_vol_ctl does not create any control indicating
+that an inverted dmic is present. Therefore, create multiple
+capture volumes in this scenario, so we always have some indication
+that the internal mic is inverted.
+
+This happens on the Lenovo Ideapad U310 as well as the Lenovo Yoga 13
+(both are based on the CX20590 codec), but the fix is generic and
+could be needed for other codecs/machines too.
+
+Thanks to Szymon Acedański for the pointer and a draft patch.
+
+BugLink: https://bugs.launchpad.net/bugs/1239392
+BugLink: https://bugs.launchpad.net/bugs/1227491
+Reported-by: Szymon Acedański <accek@mimuw.edu.pl>
+Signed-off-by: David Henningsson <david.henningsson@canonical.com>
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ sound/pci/hda/hda_generic.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/sound/pci/hda/hda_generic.c
++++ b/sound/pci/hda/hda_generic.c
+@@ -3505,7 +3505,7 @@ static int create_capture_mixers(struct
+               if (!multi)
+                       err = create_single_cap_vol_ctl(codec, n, vol, sw,
+                                                       inv_dmic);
+-              else if (!multi_cap_vol)
++              else if (!multi_cap_vol && !inv_dmic)
+                       err = create_bind_cap_vol_ctl(codec, n, vol, sw);
+               else
+                       err = create_multi_cap_vol_ctl(codec);
diff --git a/queue-3.11/alsa-us122l-fix-pcm_usb_stream-mmapping-regression.patch b/queue-3.11/alsa-us122l-fix-pcm_usb_stream-mmapping-regression.patch
new file mode 100644 (file)
index 0000000..52a15c7
--- /dev/null
@@ -0,0 +1,40 @@
+From ac536a848a1643e4b87e8fbd376a63091afc2ccc Mon Sep 17 00:00:00 2001
+From: Takashi Iwai <tiwai@suse.de>
+Date: Mon, 14 Oct 2013 16:02:15 +0200
+Subject: ALSA: us122l: Fix pcm_usb_stream mmapping regression
+
+From: Takashi Iwai <tiwai@suse.de>
+
+commit ac536a848a1643e4b87e8fbd376a63091afc2ccc upstream.
+
+The pcm_usb_stream plugin requires the mremap explicitly for the read
+buffer, as it expands itself once after reading the required size.
+But the commit [314e51b9: mm: kill vma flag VM_RESERVED and
+mm->reserved_vm counter] converted blindly to a combination of
+VM_DONTEXPAND | VM_DONTDUMP like other normal drivers, and this
+resulted in the failure of mremap().
+
+For fixing this regression, we need to remove VM_DONTEXPAND for the
+read-buffer mmap.
+
+Reported-and-tested-by: James Miller <jamesstewartmiller@gmail.com>
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ sound/usb/usx2y/us122l.c |    4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+--- a/sound/usb/usx2y/us122l.c
++++ b/sound/usb/usx2y/us122l.c
+@@ -262,7 +262,9 @@ static int usb_stream_hwdep_mmap(struct
+       }
+       area->vm_ops = &usb_stream_hwdep_vm_ops;
+-      area->vm_flags |= VM_DONTEXPAND | VM_DONTDUMP;
++      area->vm_flags |= VM_DONTDUMP;
++      if (!read)
++              area->vm_flags |= VM_DONTEXPAND;
+       area->vm_private_data = us122l;
+       atomic_inc(&us122l->mmap_count);
+ out:
diff --git a/queue-3.11/arm-7851-1-check-for-number-of-arguments-in-syscall_get-set_arguments.patch b/queue-3.11/arm-7851-1-check-for-number-of-arguments-in-syscall_get-set_arguments.patch
new file mode 100644 (file)
index 0000000..4b33389
--- /dev/null
@@ -0,0 +1,53 @@
+From 3c1532df5c1b54b5f6246cdef94eeb73a39fe43a Mon Sep 17 00:00:00 2001
+From: AKASHI Takahiro <takahiro.akashi@linaro.org>
+Date: Wed, 9 Oct 2013 15:58:29 +0100
+Subject: ARM: 7851/1: check for number of arguments in syscall_get/set_arguments()
+
+From: AKASHI Takahiro <takahiro.akashi@linaro.org>
+
+commit 3c1532df5c1b54b5f6246cdef94eeb73a39fe43a upstream.
+
+In ftrace_syscall_enter(),
+    syscall_get_arguments(..., 0, n, ...)
+        if (i == 0) { <handle ORIG_r0> ...; n--;}
+        memcpy(..., n * sizeof(args[0]));
+If 'number of arguments(n)' is zero and 'argument index(i)' is also zero in
+syscall_get_arguments(), none of arguments should be copied by memcpy().
+Otherwise 'n--' can be a big positive number and unexpected amount of data
+will be copied. Tracing system calls which take no argument, say sync(void),
+may hit this case and eventually make the system corrupted.
+This patch fixes the issue both in syscall_get_arguments() and
+syscall_set_arguments().
+
+Acked-by: Will Deacon <will.deacon@arm.com>
+Signed-off-by: AKASHI Takahiro <takahiro.akashi@linaro.org>
+Signed-off-by: Will Deacon <will.deacon@arm.com>
+Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/arm/include/asm/syscall.h |    6 ++++++
+ 1 file changed, 6 insertions(+)
+
+--- a/arch/arm/include/asm/syscall.h
++++ b/arch/arm/include/asm/syscall.h
+@@ -57,6 +57,9 @@ static inline void syscall_get_arguments
+                                        unsigned int i, unsigned int n,
+                                        unsigned long *args)
+ {
++      if (n == 0)
++              return;
++
+       if (i + n > SYSCALL_MAX_ARGS) {
+               unsigned long *args_bad = args + SYSCALL_MAX_ARGS - i;
+               unsigned int n_bad = n + i - SYSCALL_MAX_ARGS;
+@@ -81,6 +84,9 @@ static inline void syscall_set_arguments
+                                        unsigned int i, unsigned int n,
+                                        const unsigned long *args)
+ {
++      if (n == 0)
++              return;
++
+       if (i + n > SYSCALL_MAX_ARGS) {
+               pr_warning("%s called with max args %d, handling only %d\n",
+                          __func__, i + n, SYSCALL_MAX_ARGS);
diff --git a/queue-3.11/arm-integrator-deactivate-timer0-on-the-integrator-cp.patch b/queue-3.11/arm-integrator-deactivate-timer0-on-the-integrator-cp.patch
new file mode 100644 (file)
index 0000000..f7005ae
--- /dev/null
@@ -0,0 +1,78 @@
+From 29114fd7db2fc82a34da8340d29b8fa413e03dca Mon Sep 17 00:00:00 2001
+From: Linus Walleij <linus.walleij@linaro.org>
+Date: Mon, 7 Oct 2013 15:19:53 +0200
+Subject: ARM: integrator: deactivate timer0 on the Integrator/CP
+
+From: Linus Walleij <linus.walleij@linaro.org>
+
+commit 29114fd7db2fc82a34da8340d29b8fa413e03dca upstream.
+
+This fixes a long-standing Integrator/CP regression from
+commit 870e2928cf3368ca9b06bc925d0027b0a56bcd8e
+"ARM: integrator-cp: convert use CLKSRC_OF for timer init"
+
+When this code was introduced, the both aliases pointing the
+system to use timer1 as primary (clocksource) and timer2
+as secondary (clockevent) was ignored, and the system would
+simply use the first two timers found as clocksource and
+clockevent.
+
+However this made the system timeline accelerate by a
+factor x25, as it turns out that the way the clocking
+actually works (totally undocumented and found after some
+trial-and-error) is that timer0 runs @ 25MHz and timer1
+and timer2 runs @ 1MHz. Presumably this divider setting
+is a boot-on default and configurable albeit the way to
+configure it is not documented.
+
+So as a quick fix to the problem, let's mark timer0 as
+disabled, so the code will chose timer1 and timer2 as it
+used to.
+
+This also deletes the two aliases for the primary and
+secondary timer as they have been superceded by the
+auto-selection
+
+Cc: Rob Herring <rob.herring@calxeda.com>
+Cc: Russell King <linux@arm.linux.org.uk>
+Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
+Signed-off-by: Olof Johansson <olof@lixom.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/arm/boot/dts/integratorcp.dts |    9 ++++-----
+ 1 file changed, 4 insertions(+), 5 deletions(-)
+
+--- a/arch/arm/boot/dts/integratorcp.dts
++++ b/arch/arm/boot/dts/integratorcp.dts
+@@ -9,11 +9,6 @@
+       model = "ARM Integrator/CP";
+       compatible = "arm,integrator-cp";
+-      aliases {
+-              arm,timer-primary = &timer2;
+-              arm,timer-secondary = &timer1;
+-      };
+-
+       chosen {
+               bootargs = "root=/dev/ram0 console=ttyAMA0,38400n8 earlyprintk";
+       };
+@@ -24,14 +19,18 @@
+       };
+       timer0: timer@13000000 {
++              /* TIMER0 runs @ 25MHz */
+               compatible = "arm,integrator-cp-timer";
++              status = "disabled";
+       };
+       timer1: timer@13000100 {
++              /* TIMER1 runs @ 1MHz */
+               compatible = "arm,integrator-cp-timer";
+       };
+       timer2: timer@13000200 {
++              /* TIMER2 runs @ 1MHz */
+               compatible = "arm,integrator-cp-timer";
+       };
diff --git a/queue-3.11/dm-snapshot-fix-data-corruption.patch b/queue-3.11/dm-snapshot-fix-data-corruption.patch
new file mode 100644 (file)
index 0000000..113824c
--- /dev/null
@@ -0,0 +1,88 @@
+From e9c6a182649f4259db704ae15a91ac820e63b0ca Mon Sep 17 00:00:00 2001
+From: Mikulas Patocka <mpatocka@redhat.com>
+Date: Wed, 16 Oct 2013 03:17:47 +0100
+Subject: dm snapshot: fix data corruption
+
+From: Mikulas Patocka <mpatocka@redhat.com>
+
+commit e9c6a182649f4259db704ae15a91ac820e63b0ca upstream.
+
+This patch fixes a particular type of data corruption that has been
+encountered when loading a snapshot's metadata from disk.
+
+When we allocate a new chunk in persistent_prepare, we increment
+ps->next_free and we make sure that it doesn't point to a metadata area
+by further incrementing it if necessary.
+
+When we load metadata from disk on device activation, ps->next_free is
+positioned after the last used data chunk. However, if this last used
+data chunk is followed by a metadata area, ps->next_free is positioned
+erroneously to the metadata area. A newly-allocated chunk is placed at
+the same location as the metadata area, resulting in data or metadata
+corruption.
+
+This patch changes the code so that ps->next_free skips the metadata
+area when metadata are loaded in function read_exceptions.
+
+The patch also moves a piece of code from persistent_prepare_exception
+to a separate function skip_metadata to avoid code duplication.
+
+CVE-2013-4299
+
+Signed-off-by: Mikulas Patocka <mpatocka@redhat.com>
+Cc: Mike Snitzer <snitzer@redhat.com>
+Signed-off-by: Alasdair G Kergon <agk@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/md/dm-snap-persistent.c |   18 ++++++++++++------
+ 1 file changed, 12 insertions(+), 6 deletions(-)
+
+--- a/drivers/md/dm-snap-persistent.c
++++ b/drivers/md/dm-snap-persistent.c
+@@ -269,6 +269,14 @@ static chunk_t area_location(struct psto
+       return NUM_SNAPSHOT_HDR_CHUNKS + ((ps->exceptions_per_area + 1) * area);
+ }
++static void skip_metadata(struct pstore *ps)
++{
++      uint32_t stride = ps->exceptions_per_area + 1;
++      chunk_t next_free = ps->next_free;
++      if (sector_div(next_free, stride) == NUM_SNAPSHOT_HDR_CHUNKS)
++              ps->next_free++;
++}
++
+ /*
+  * Read or write a metadata area.  Remembering to skip the first
+  * chunk which holds the header.
+@@ -502,6 +510,8 @@ static int read_exceptions(struct pstore
+       ps->current_area--;
++      skip_metadata(ps);
++
+       return 0;
+ }
+@@ -616,8 +626,6 @@ static int persistent_prepare_exception(
+                                       struct dm_exception *e)
+ {
+       struct pstore *ps = get_info(store);
+-      uint32_t stride;
+-      chunk_t next_free;
+       sector_t size = get_dev_size(dm_snap_cow(store->snap)->bdev);
+       /* Is there enough room ? */
+@@ -630,10 +638,8 @@ static int persistent_prepare_exception(
+        * Move onto the next free pending, making sure to take
+        * into account the location of the metadata chunks.
+        */
+-      stride = (ps->exceptions_per_area + 1);
+-      next_free = ++ps->next_free;
+-      if (sector_div(next_free, stride) == 1)
+-              ps->next_free++;
++      ps->next_free++;
++      skip_metadata(ps);
+       atomic_inc(&ps->pending_count);
+       return 0;
diff --git a/queue-3.11/ext-fix-double-put-in-tmpfile.patch b/queue-3.11/ext-fix-double-put-in-tmpfile.patch
new file mode 100644 (file)
index 0000000..f0e6bd4
--- /dev/null
@@ -0,0 +1,66 @@
+From 43ae9e3fc70ca0057ae0a24ef5eedff05e3fae06 Mon Sep 17 00:00:00 2001
+From: Miklos Szeredi <mszeredi@suse.cz>
+Date: Thu, 10 Oct 2013 16:48:19 +0200
+Subject: ext[34]: fix double put in tmpfile
+
+From: Miklos Szeredi <mszeredi@suse.cz>
+
+commit 43ae9e3fc70ca0057ae0a24ef5eedff05e3fae06 upstream.
+
+d_tmpfile() already swallowed the inode ref.
+
+Signed-off-by: Miklos Szeredi <mszeredi@suse.cz>
+Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/ext3/namei.c |    5 ++---
+ fs/ext4/namei.c |    5 ++---
+ 2 files changed, 4 insertions(+), 6 deletions(-)
+
+--- a/fs/ext3/namei.c
++++ b/fs/ext3/namei.c
+@@ -1783,7 +1783,7 @@ retry:
+               d_tmpfile(dentry, inode);
+               err = ext3_orphan_add(handle, inode);
+               if (err)
+-                      goto err_drop_inode;
++                      goto err_unlock_inode;
+               mark_inode_dirty(inode);
+               unlock_new_inode(inode);
+       }
+@@ -1791,10 +1791,9 @@ retry:
+       if (err == -ENOSPC && ext3_should_retry_alloc(dir->i_sb, &retries))
+               goto retry;
+       return err;
+-err_drop_inode:
++err_unlock_inode:
+       ext3_journal_stop(handle);
+       unlock_new_inode(inode);
+-      iput(inode);
+       return err;
+ }
+--- a/fs/ext4/namei.c
++++ b/fs/ext4/namei.c
+@@ -2319,7 +2319,7 @@ retry:
+               d_tmpfile(dentry, inode);
+               err = ext4_orphan_add(handle, inode);
+               if (err)
+-                      goto err_drop_inode;
++                      goto err_unlock_inode;
+               mark_inode_dirty(inode);
+               unlock_new_inode(inode);
+       }
+@@ -2328,10 +2328,9 @@ retry:
+       if (err == -ENOSPC && ext4_should_retry_alloc(dir->i_sb, &retries))
+               goto retry;
+       return err;
+-err_drop_inode:
++err_unlock_inode:
+       ext4_journal_stop(handle);
+       unlock_new_inode(inode);
+-      iput(inode);
+       return err;
+ }
diff --git a/queue-3.11/fs-buffer-move-allocation-failure-loop-into-the-allocator.patch b/queue-3.11/fs-buffer-move-allocation-failure-loop-into-the-allocator.patch
new file mode 100644 (file)
index 0000000..099d2ba
--- /dev/null
@@ -0,0 +1,75 @@
+From 84235de394d9775bfaa7fa9762a59d91fef0c1fc Mon Sep 17 00:00:00 2001
+From: Johannes Weiner <hannes@cmpxchg.org>
+Date: Wed, 16 Oct 2013 13:47:00 -0700
+Subject: fs: buffer: move allocation failure loop into the allocator
+
+From: Johannes Weiner <hannes@cmpxchg.org>
+
+commit 84235de394d9775bfaa7fa9762a59d91fef0c1fc upstream.
+
+Buffer allocation has a very crude indefinite loop around waking the
+flusher threads and performing global NOFS direct reclaim because it can
+not handle allocation failures.
+
+The most immediate problem with this is that the allocation may fail due
+to a memory cgroup limit, where flushers + direct reclaim might not make
+any progress towards resolving the situation at all.  Because unlike the
+global case, a memory cgroup may not have any cache at all, only
+anonymous pages but no swap.  This situation will lead to a reclaim
+livelock with insane IO from waking the flushers and thrashing unrelated
+filesystem cache in a tight loop.
+
+Use __GFP_NOFAIL allocations for buffers for now.  This makes sure that
+any looping happens in the page allocator, which knows how to
+orchestrate kswapd, direct reclaim, and the flushers sensibly.  It also
+allows memory cgroups to detect allocations that can't handle failure
+and will allow them to ultimately bypass the limit if reclaim can not
+make progress.
+
+Reported-by: azurIt <azurit@pobox.sk>
+Signed-off-by: Johannes Weiner <hannes@cmpxchg.org>
+Cc: Michal Hocko <mhocko@suse.cz>
+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>
+
+---
+ fs/buffer.c     |   14 ++++++++++++--
+ mm/memcontrol.c |    2 ++
+ 2 files changed, 14 insertions(+), 2 deletions(-)
+
+--- a/fs/buffer.c
++++ b/fs/buffer.c
+@@ -1005,9 +1005,19 @@ grow_dev_page(struct block_device *bdev,
+       struct buffer_head *bh;
+       sector_t end_block;
+       int ret = 0;            /* Will call free_more_memory() */
++      gfp_t gfp_mask;
+-      page = find_or_create_page(inode->i_mapping, index,
+-              (mapping_gfp_mask(inode->i_mapping) & ~__GFP_FS)|__GFP_MOVABLE);
++      gfp_mask = mapping_gfp_mask(inode->i_mapping) & ~__GFP_FS;
++      gfp_mask |= __GFP_MOVABLE;
++      /*
++       * XXX: __getblk_slow() can not really deal with failure and
++       * will endlessly loop on improvised global reclaim.  Prefer
++       * looping in the allocator rather than here, at least that
++       * code knows what it's doing.
++       */
++      gfp_mask |= __GFP_NOFAIL;
++
++      page = find_or_create_page(inode->i_mapping, index, gfp_mask);
+       if (!page)
+               return ret;
+--- a/mm/memcontrol.c
++++ b/mm/memcontrol.c
+@@ -2772,6 +2772,8 @@ done:
+       return 0;
+ nomem:
+       *ptr = NULL;
++      if (gfp_mask & __GFP_NOFAIL)
++              return 0;
+       return -ENOMEM;
+ bypass:
+       *ptr = root_mem_cgroup;
diff --git a/queue-3.11/gpio-lynxpoint-check-if-the-interrupt-is-enabled-in-irq-handler.patch b/queue-3.11/gpio-lynxpoint-check-if-the-interrupt-is-enabled-in-irq-handler.patch
new file mode 100644 (file)
index 0000000..7c64635
--- /dev/null
@@ -0,0 +1,44 @@
+From 03d152d5582abc8a1c19cb107164c3724bbd4be4 Mon Sep 17 00:00:00 2001
+From: Mika Westerberg <mika.westerberg@linux.intel.com>
+Date: Tue, 1 Oct 2013 17:35:43 +0300
+Subject: gpio/lynxpoint: check if the interrupt is enabled in IRQ handler
+
+From: Mika Westerberg <mika.westerberg@linux.intel.com>
+
+commit 03d152d5582abc8a1c19cb107164c3724bbd4be4 upstream.
+
+Checking LP_INT_STAT is not enough in the interrupt handler because its
+contents get updated regardless of whether the pin has interrupt enabled or
+not. This causes the driver to loop forever for GPIOs that are pulled up.
+
+Fix this by checking the interrupt enable bit for the pin as well.
+
+Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
+Acked-by: Mathias Nyman <mathias.nyman@linux.intel.com>
+Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/gpio/gpio-lynxpoint.c |    5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+--- a/drivers/gpio/gpio-lynxpoint.c
++++ b/drivers/gpio/gpio-lynxpoint.c
+@@ -248,14 +248,15 @@ static void lp_gpio_irq_handler(unsigned
+       struct lp_gpio *lg = irq_data_get_irq_handler_data(data);
+       struct irq_chip *chip = irq_data_get_irq_chip(data);
+       u32 base, pin, mask;
+-      unsigned long reg, pending;
++      unsigned long reg, ena, pending;
+       unsigned virq;
+       /* check from GPIO controller which pin triggered the interrupt */
+       for (base = 0; base < lg->chip.ngpio; base += 32) {
+               reg = lp_gpio_reg(&lg->chip, base, LP_INT_STAT);
++              ena = lp_gpio_reg(&lg->chip, base, LP_INT_ENABLE);
+-              while ((pending = inl(reg))) {
++              while ((pending = (inl(reg) & inl(ena)))) {
+                       pin = __ffs(pending);
+                       mask = BIT(pin);
+                       /* Clear before handling so we don't lose an edge */
diff --git a/queue-3.11/i2c-ismt-initialize-dma-buffer.patch b/queue-3.11/i2c-ismt-initialize-dma-buffer.patch
new file mode 100644 (file)
index 0000000..7b9b921
--- /dev/null
@@ -0,0 +1,34 @@
+From bf4169100c909667ede6af67668b3ecce6928343 Mon Sep 17 00:00:00 2001
+From: James Ralston <james.d.ralston@intel.com>
+Date: Tue, 24 Sep 2013 16:47:55 -0700
+Subject: i2c: ismt: initialize DMA buffer
+
+From: James Ralston <james.d.ralston@intel.com>
+
+commit bf4169100c909667ede6af67668b3ecce6928343 upstream.
+
+This patch adds code to initialize the DMA buffer to compensate for
+possible hardware data corruption.
+
+Signed-off-by: James Ralston <james.d.ralston@intel.com>
+[wsa: changed to use 'sizeof']
+Signed-off-by: Wolfram Sang <wsa@the-dreams.de>
+Cc: Jean Delvare <jdelvare@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/i2c/busses/i2c-ismt.c |    3 +++
+ 1 file changed, 3 insertions(+)
+
+--- a/drivers/i2c/busses/i2c-ismt.c
++++ b/drivers/i2c/busses/i2c-ismt.c
+@@ -393,6 +393,9 @@ static int ismt_access(struct i2c_adapte
+       desc = &priv->hw[priv->head];
++      /* Initialize the DMA buffer */
++      memset(priv->dma_buffer, 0, sizeof(priv->dma_buffer));
++
+       /* Initialize the descriptor */
+       memset(desc, 0, sizeof(struct ismt_desc));
+       desc->tgtaddr_rw = ISMT_DESC_ADDR_RW(addr, read_write);
diff --git a/queue-3.11/mm-fix-bug-in-__split_huge_page_pmd.patch b/queue-3.11/mm-fix-bug-in-__split_huge_page_pmd.patch
new file mode 100644 (file)
index 0000000..fed2469
--- /dev/null
@@ -0,0 +1,57 @@
+From 750e8165f5e87b6a142be953640eabb13a9d350a Mon Sep 17 00:00:00 2001
+From: Hugh Dickins <hughd@google.com>
+Date: Wed, 16 Oct 2013 13:47:08 -0700
+Subject: mm: fix BUG in __split_huge_page_pmd
+
+From: Hugh Dickins <hughd@google.com>
+
+commit 750e8165f5e87b6a142be953640eabb13a9d350a upstream.
+
+Occasionally we hit the BUG_ON(pmd_trans_huge(*pmd)) at the end of
+__split_huge_page_pmd(): seen when doing madvise(,,MADV_DONTNEED).
+
+It's invalid: we don't always have down_write of mmap_sem there: a racing
+do_huge_pmd_wp_page() might have copied-on-write to another huge page
+before our split_huge_page() got the anon_vma lock.
+
+Forget the BUG_ON, just go back and try again if this happens.
+
+Signed-off-by: Hugh Dickins <hughd@google.com>
+Acked-by: Kirill A. Shutemov <kirill.shutemov@linux.intel.com>
+Cc: Andrea Arcangeli <aarcange@redhat.com>
+Cc: Naoya Horiguchi <n-horiguchi@ah.jp.nec.com>
+Cc: David Rientjes <rientjes@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/huge_memory.c |   10 +++++++++-
+ 1 file changed, 9 insertions(+), 1 deletion(-)
+
+--- a/mm/huge_memory.c
++++ b/mm/huge_memory.c
+@@ -2709,6 +2709,7 @@ void __split_huge_page_pmd(struct vm_are
+       mmun_start = haddr;
+       mmun_end   = haddr + HPAGE_PMD_SIZE;
++again:
+       mmu_notifier_invalidate_range_start(mm, mmun_start, mmun_end);
+       spin_lock(&mm->page_table_lock);
+       if (unlikely(!pmd_trans_huge(*pmd))) {
+@@ -2731,7 +2732,14 @@ void __split_huge_page_pmd(struct vm_are
+       split_huge_page(page);
+       put_page(page);
+-      BUG_ON(pmd_trans_huge(*pmd));
++
++      /*
++       * We don't always have down_write of mmap_sem here: a racing
++       * do_huge_pmd_wp_page() might have copied-on-write to another
++       * huge page before our split_huge_page() got the anon_vma lock.
++       */
++      if (unlikely(pmd_trans_huge(*pmd)))
++              goto again;
+ }
+ void split_huge_page_pmd_mm(struct mm_struct *mm, unsigned long address,
diff --git a/queue-3.11/mm-migration-do-not-lose-soft-dirty-bit-if-page-is-in-migration-state.patch b/queue-3.11/mm-migration-do-not-lose-soft-dirty-bit-if-page-is-in-migration-state.patch
new file mode 100644 (file)
index 0000000..01131c8
--- /dev/null
@@ -0,0 +1,80 @@
+From c3d16e16522fe3fe8759735850a0676da18f4b1d Mon Sep 17 00:00:00 2001
+From: Cyrill Gorcunov <gorcunov@gmail.com>
+Date: Wed, 16 Oct 2013 13:46:51 -0700
+Subject: mm: migration: do not lose soft dirty bit if page is in migration state
+
+From: Cyrill Gorcunov <gorcunov@gmail.com>
+
+commit c3d16e16522fe3fe8759735850a0676da18f4b1d upstream.
+
+If page migration is turned on in config and the page is migrating, we
+may lose the soft dirty bit.  If fork and mprotect are called on
+migrating pages (once migration is complete) pages do not obtain the
+soft dirty bit in the correspond pte entries.  Fix it adding an
+appropriate test on swap entries.
+
+Signed-off-by: Cyrill Gorcunov <gorcunov@openvz.org>
+Cc: Pavel Emelyanov <xemul@parallels.com>
+Cc: Andy Lutomirski <luto@amacapital.net>
+Cc: Matt Mackall <mpm@selenic.com>
+Cc: Xiao Guangrong <xiaoguangrong@linux.vnet.ibm.com>
+Cc: Marcelo Tosatti <mtosatti@redhat.com>
+Cc: KOSAKI Motohiro <kosaki.motohiro@gmail.com>
+Cc: Stephen Rothwell <sfr@canb.auug.org.au>
+Cc: Peter Zijlstra <peterz@infradead.org>
+Cc: "Aneesh Kumar K.V" <aneesh.kumar@linux.vnet.ibm.com>
+Cc: Naoya Horiguchi <n-horiguchi@ah.jp.nec.com>
+Cc: Mel Gorman <mel@csn.ul.ie>
+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/memory.c   |    2 ++
+ mm/migrate.c  |    2 ++
+ mm/mprotect.c |    7 +++++--
+ 3 files changed, 9 insertions(+), 2 deletions(-)
+
+--- a/mm/memory.c
++++ b/mm/memory.c
+@@ -861,6 +861,8 @@ copy_one_pte(struct mm_struct *dst_mm, s
+                                        */
+                                       make_migration_entry_read(&entry);
+                                       pte = swp_entry_to_pte(entry);
++                                      if (pte_swp_soft_dirty(*src_pte))
++                                              pte = pte_swp_mksoft_dirty(pte);
+                                       set_pte_at(src_mm, addr, src_pte, pte);
+                               }
+                       }
+--- a/mm/migrate.c
++++ b/mm/migrate.c
+@@ -157,6 +157,8 @@ static int remove_migration_pte(struct p
+       get_page(new);
+       pte = pte_mkold(mk_pte(new, vma->vm_page_prot));
++      if (pte_swp_soft_dirty(*ptep))
++              pte = pte_mksoft_dirty(pte);
+       if (is_write_migration_entry(entry))
+               pte = pte_mkwrite(pte);
+ #ifdef CONFIG_HUGETLB_PAGE
+--- a/mm/mprotect.c
++++ b/mm/mprotect.c
+@@ -94,13 +94,16 @@ static unsigned long change_pte_range(st
+                       swp_entry_t entry = pte_to_swp_entry(oldpte);
+                       if (is_write_migration_entry(entry)) {
++                              pte_t newpte;
+                               /*
+                                * A protection check is difficult so
+                                * just be safe and disable write
+                                */
+                               make_migration_entry_read(&entry);
+-                              set_pte_at(mm, addr, pte,
+-                                      swp_entry_to_pte(entry));
++                              newpte = swp_entry_to_pte(entry);
++                              if (pte_swp_soft_dirty(oldpte))
++                                      newpte = pte_swp_mksoft_dirty(newpte);
++                              set_pte_at(mm, addr, pte, newpte);
+                       }
+                       pages++;
+               }
diff --git a/queue-3.11/mm-zswap-bugfix-memory-leak-when-re-swapon.patch b/queue-3.11/mm-zswap-bugfix-memory-leak-when-re-swapon.patch
new file mode 100644 (file)
index 0000000..299ea36
--- /dev/null
@@ -0,0 +1,66 @@
+From aa9bca05a467c61dcea4142b2877d5392de5bdce Mon Sep 17 00:00:00 2001
+From: Weijie Yang <weijie.yang@samsung.com>
+Date: Wed, 16 Oct 2013 13:46:54 -0700
+Subject: mm/zswap: bugfix: memory leak when re-swapon
+
+From: Weijie Yang <weijie.yang@samsung.com>
+
+commit aa9bca05a467c61dcea4142b2877d5392de5bdce upstream.
+
+zswap_tree is not freed when swapoff, and it got re-kmalloced in swapon,
+so a memory leak occurs.
+
+Free the memory of zswap_tree in zswap_frontswap_invalidate_area().
+
+Signed-off-by: Weijie Yang <weijie.yang@samsung.com>
+Reviewed-by: Bob Liu <bob.liu@oracle.com>
+Cc: Minchan Kim <minchan@kernel.org>
+Reviewed-by: Minchan Kim <minchan@kernel.org>
+From: Weijie Yang <weijie.yang@samsung.com>
+Subject: mm/zswap: bugfix: memory leak when invalidate and reclaim occur concurrently
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+Consider the following scenario:
+thread 0: reclaim entry x (get refcount, but not call zswap_get_swap_cache_page)
+thread 1: call zswap_frontswap_invalidate_page to invalidate entry x.
+       finished, entry x and its zbud is not freed as its refcount != 0
+       now, the swap_map[x] = 0
+thread 0: now call zswap_get_swap_cache_page
+       swapcache_prepare return -ENOENT because entry x is not used any more
+       zswap_get_swap_cache_page return ZSWAP_SWAPCACHE_NOMEM
+       zswap_writeback_entry do nothing except put refcount
+Now, the memory of zswap_entry x and its zpage leak.
+
+Modify:
+ - check the refcount in fail path, free memory if it is not referenced.
+
+ - use ZSWAP_SWAPCACHE_FAIL instead of ZSWAP_SWAPCACHE_NOMEM as the fail path
+   can be not only caused by nomem but also by invalidate.
+
+[akpm@linux-foundation.org: coding-style fixes]
+Signed-off-by: Weijie Yang <weijie.yang@samsung.com>
+Reviewed-by: Bob Liu <bob.liu@oracle.com>
+Cc: Minchan Kim <minchan@kernel.org>
+Cc: <stable@vger.kernel.org>
+Acked-by: Seth Jennings <sjenning@linux.vnet.ibm.com>
+
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+
+---
+ mm/zswap.c |    4 ++++
+ 1 file changed, 4 insertions(+)
+
+--- a/mm/zswap.c
++++ b/mm/zswap.c
+@@ -816,6 +816,10 @@ static void zswap_frontswap_invalidate_a
+       }
+       tree->rbroot = RB_ROOT;
+       spin_unlock(&tree->lock);
++
++      zbud_destroy_pool(tree->pool);
++      kfree(tree);
++      zswap_trees[type] = NULL;
+ }
+ static struct zbud_ops zswap_zbud_ops = {
index e4dd0ae7410718051b84a6112f15e1a877bab8c7..c0fc69d347106ce0c13a02215bc367616eb7967c 100644 (file)
@@ -45,3 +45,20 @@ ipv6-fill-rt6i_gateway-with-nexthop-address.patch
 netfilter-nf_conntrack-fix-rt6i_gateway-checks-for-h.323-helper.patch
 ipv6-probe-routes-asynchronous-in-rt6_probe.patch
 davinci_emac.c-fix-iff_allmulti-setup.patch
+arm-7851-1-check-for-number-of-arguments-in-syscall_get-set_arguments.patch
+arm-integrator-deactivate-timer0-on-the-integrator-cp.patch
+ext-fix-double-put-in-tmpfile.patch
+gpio-lynxpoint-check-if-the-interrupt-is-enabled-in-irq-handler.patch
+dm-snapshot-fix-data-corruption.patch
+i2c-ismt-initialize-dma-buffer.patch
+mm-migration-do-not-lose-soft-dirty-bit-if-page-is-in-migration-state.patch
+mm-zswap-bugfix-memory-leak-when-re-swapon.patch
+mm-fix-bug-in-__split_huge_page_pmd.patch
+alsa-us122l-fix-pcm_usb_stream-mmapping-regression.patch
+alsa-hda-fix-inverted-internal-mic-not-indicated-on-some-machines.patch
+writeback-fix-negative-bdi-max-pause.patch
+w1-call-request_module-with-w1-master-mutex-unlocked.patch
+wireless-radiotap-fix-parsing-buffer-overrun.patch
+wireless-cw1200-acquire-hwbus-lock-around-cw1200_irq_handler-call.patch
+fs-buffer-move-allocation-failure-loop-into-the-allocator.patch
+
diff --git a/queue-3.11/w1-call-request_module-with-w1-master-mutex-unlocked.patch b/queue-3.11/w1-call-request_module-with-w1-master-mutex-unlocked.patch
new file mode 100644 (file)
index 0000000..878db2e
--- /dev/null
@@ -0,0 +1,35 @@
+From bc04d76d6942068f75c10790072280b847ec6f1f Mon Sep 17 00:00:00 2001
+From: Hans-Frieder Vogt <hfvogt@gmx.net>
+Date: Sun, 6 Oct 2013 21:13:40 +0200
+Subject: w1 - call request_module with w1 master mutex unlocked
+
+From: Hans-Frieder Vogt <hfvogt@gmx.net>
+
+commit bc04d76d6942068f75c10790072280b847ec6f1f upstream.
+
+request_module for w1 slave modules needs to be called with the w1
+master mutex unlocked. Because w1_attach_slave_device gets always(?)
+called with mutex locked, we need to temporarily unlock the w1 master
+mutex for the loading of the w1 slave module.
+
+Signed-off by: Hans-Frieder Vogt <hfvogt@gmx.net>
+Acked-by: Evgeniy Polyakov <zbr@ioremap.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/w1/w1.c |    3 +++
+ 1 file changed, 3 insertions(+)
+
+--- a/drivers/w1/w1.c
++++ b/drivers/w1/w1.c
+@@ -680,7 +680,10 @@ static int w1_attach_slave_device(struct
+       atomic_set(&sl->refcnt, 0);
+       init_completion(&sl->released);
++      /* slave modules need to be loaded in a context with unlocked mutex */
++      mutex_unlock(&dev->mutex);
+       request_module("w1-family-0x%0x", rn->family);
++      mutex_lock(&dev->mutex);
+       spin_lock(&w1_flock);
+       f = w1_family_registered(rn->family);
diff --git a/queue-3.11/wireless-cw1200-acquire-hwbus-lock-around-cw1200_irq_handler-call.patch b/queue-3.11/wireless-cw1200-acquire-hwbus-lock-around-cw1200_irq_handler-call.patch
new file mode 100644 (file)
index 0000000..c85906c
--- /dev/null
@@ -0,0 +1,35 @@
+From 4978705d26149a629b9f50ff221caed6f1ae3048 Mon Sep 17 00:00:00 2001
+From: Solomon Peachy <pizza@shaftnet.org>
+Date: Wed, 9 Oct 2013 12:15:11 -0400
+Subject: wireless: cw1200: acquire hwbus lock around cw1200_irq_handler() call.
+
+From: Solomon Peachy <pizza@shaftnet.org>
+
+commit 4978705d26149a629b9f50ff221caed6f1ae3048 upstream.
+
+This fixes "lost interrupt" problems that occurred on SPI-based systems.
+cw1200_irq_handler() expects the hwbus to be locked, but on the
+SPI-path, that lock wasn't taken (unlike in the SDIO-path, where the
+generic SDIO-code takes care of acquiring the lock).
+
+Signed-off-by: David Mosberger <davidm@egauge.net>
+Signed-off-by: Solomon Peachy <pizza@shaftnet.org>
+Signed-off-by: John W. Linville <linville@tuxdriver.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/net/wireless/cw1200/cw1200_spi.c |    2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/drivers/net/wireless/cw1200/cw1200_spi.c
++++ b/drivers/net/wireless/cw1200/cw1200_spi.c
+@@ -237,7 +237,9 @@ static irqreturn_t cw1200_spi_irq_handle
+       struct hwbus_priv *self = dev_id;
+       if (self->core) {
++              cw1200_spi_lock(self);
+               cw1200_irq_handler(self->core);
++              cw1200_spi_unlock(self);
+               return IRQ_HANDLED;
+       } else {
+               return IRQ_NONE;
diff --git a/queue-3.11/wireless-radiotap-fix-parsing-buffer-overrun.patch b/queue-3.11/wireless-radiotap-fix-parsing-buffer-overrun.patch
new file mode 100644 (file)
index 0000000..fce15b8
--- /dev/null
@@ -0,0 +1,54 @@
+From f5563318ff1bde15b10e736e97ffce13be08bc1a Mon Sep 17 00:00:00 2001
+From: Johannes Berg <johannes.berg@intel.com>
+Date: Fri, 11 Oct 2013 14:47:05 +0200
+Subject: wireless: radiotap: fix parsing buffer overrun
+
+From: Johannes Berg <johannes.berg@intel.com>
+
+commit f5563318ff1bde15b10e736e97ffce13be08bc1a upstream.
+
+When parsing an invalid radiotap header, the parser can overrun
+the buffer that is passed in because it doesn't correctly check
+ 1) the minimum radiotap header size
+ 2) the space for extended bitmaps
+
+The first issue doesn't affect any in-kernel user as they all
+check the minimum size before calling the radiotap function.
+The second issue could potentially affect the kernel if an skb
+is passed in that consists only of the radiotap header with a
+lot of extended bitmaps that extend past the SKB. In that case
+a read-only buffer overrun by at most 4 bytes is possible.
+
+Fix this by adding the appropriate checks to the parser.
+
+Reported-by: Evan Huus <eapache@gmail.com>
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ net/wireless/radiotap.c |    7 ++++++-
+ 1 file changed, 6 insertions(+), 1 deletion(-)
+
+--- a/net/wireless/radiotap.c
++++ b/net/wireless/radiotap.c
+@@ -97,6 +97,10 @@ int ieee80211_radiotap_iterator_init(
+       struct ieee80211_radiotap_header *radiotap_header,
+       int max_length, const struct ieee80211_radiotap_vendor_namespaces *vns)
+ {
++      /* check the radiotap header can actually be present */
++      if (max_length < sizeof(struct ieee80211_radiotap_header))
++              return -EINVAL;
++
+       /* Linux only supports version 0 radiotap format */
+       if (radiotap_header->it_version)
+               return -EINVAL;
+@@ -131,7 +135,8 @@ int ieee80211_radiotap_iterator_init(
+                        */
+                       if ((unsigned long)iterator->_arg -
+-                          (unsigned long)iterator->_rtheader >
++                          (unsigned long)iterator->_rtheader +
++                          sizeof(uint32_t) >
+                           (unsigned long)iterator->_max_length)
+                               return -EINVAL;
+               }
diff --git a/queue-3.11/writeback-fix-negative-bdi-max-pause.patch b/queue-3.11/writeback-fix-negative-bdi-max-pause.patch
new file mode 100644 (file)
index 0000000..104fcfe
--- /dev/null
@@ -0,0 +1,93 @@
+From e3b6c655b91e01a1dade056cfa358581b47a5351 Mon Sep 17 00:00:00 2001
+From: Fengguang Wu <fengguang.wu@intel.com>
+Date: Wed, 16 Oct 2013 13:47:03 -0700
+Subject: writeback: fix negative bdi max pause
+
+From: Fengguang Wu <fengguang.wu@intel.com>
+
+commit e3b6c655b91e01a1dade056cfa358581b47a5351 upstream.
+
+Toralf runs trinity on UML/i386.  After some time it hangs and the last
+message line is
+
+       BUG: soft lockup - CPU#0 stuck for 22s! [trinity-child0:1521]
+
+It's found that pages_dirtied becomes very large.  More than 1000000000
+pages in this case:
+
+       period = HZ * pages_dirtied / task_ratelimit;
+       BUG_ON(pages_dirtied > 2000000000);
+       BUG_ON(pages_dirtied > 1000000000);      <---------
+
+UML debug printf shows that we got negative pause here:
+
+       ick: pause : -984
+       ick: pages_dirtied : 0
+       ick: task_ratelimit: 0
+
+        pause:
+       +       if (pause < 0)  {
+       +               extern int printf(char *, ...);
+       +               printf("ick : pause : %li\n", pause);
+       +               printf("ick: pages_dirtied : %lu\n", pages_dirtied);
+       +               printf("ick: task_ratelimit: %lu\n", task_ratelimit);
+       +               BUG_ON(1);
+       +       }
+               trace_balance_dirty_pages(bdi,
+
+Since pause is bounded by [min_pause, max_pause] where min_pause is also
+bounded by max_pause.  It's suspected and demonstrated that the
+max_pause calculation goes wrong:
+
+       ick: pause : -717
+       ick: min_pause : -177
+       ick: max_pause : -717
+       ick: pages_dirtied : 14
+       ick: task_ratelimit: 0
+
+The problem lies in the two "long = unsigned long" assignments in
+bdi_max_pause() which might go negative if the highest bit is 1, and the
+min_t(long, ...) check failed to protect it falling under 0.  Fix all of
+them by using "unsigned long" throughout the function.
+
+Signed-off-by: Fengguang Wu <fengguang.wu@intel.com>
+Reported-by: Toralf Förster <toralf.foerster@gmx.de>
+Tested-by: Toralf Förster <toralf.foerster@gmx.de>
+Reviewed-by: Jan Kara <jack@suse.cz>
+Cc: Richard Weinberger <richard@nod.at>
+Cc: Geert Uytterhoeven <geert@linux-m68k.org>
+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/page-writeback.c |   10 +++++-----
+ 1 file changed, 5 insertions(+), 5 deletions(-)
+
+--- a/mm/page-writeback.c
++++ b/mm/page-writeback.c
+@@ -1104,11 +1104,11 @@ static unsigned long dirty_poll_interval
+       return 1;
+ }
+-static long bdi_max_pause(struct backing_dev_info *bdi,
+-                        unsigned long bdi_dirty)
++static unsigned long bdi_max_pause(struct backing_dev_info *bdi,
++                                 unsigned long bdi_dirty)
+ {
+-      long bw = bdi->avg_write_bandwidth;
+-      long t;
++      unsigned long bw = bdi->avg_write_bandwidth;
++      unsigned long t;
+       /*
+        * Limit pause time for small memory systems. If sleeping for too long
+@@ -1120,7 +1120,7 @@ static long bdi_max_pause(struct backing
+       t = bdi_dirty / (1 + bw / roundup_pow_of_two(1 + HZ / 8));
+       t++;
+-      return min_t(long, t, MAX_PAUSE);
++      return min_t(unsigned long, t, MAX_PAUSE);
+ }
+ static long bdi_min_pause(struct backing_dev_info *bdi,