]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
3.8-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 25 Feb 2013 17:39:58 +0000 (09:39 -0800)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 25 Feb 2013 17:39:58 +0000 (09:39 -0800)
added patches:
b43-increase-number-of-rx-dma-slots.patch
driver-core-treat-unregistered-bus_types-as-having-no-devices.patch
mmu_notifier_unregister-null-pointer-deref-and-multiple-release-callouts.patch
pps-add-pps_lookup_dev-function.patch
pps-fix-a-use-after-free-bug-when-unregistering-a-source.patch
pps-use-pps_lookup_dev-to-reduce-ldisc-coupling.patch
rtlwifi-rtl8192cu-add-new-usb-id.patch
rtlwifi-rtl8192cu-fix-null-dereference-bug-when-using-new_id.patch
rtlwifi-usb-allocate-urb-control-message-setup_packet-and-data-buffer-separately.patch
tty-vt-fix-character-insertion-overflow.patch
xen-close-evtchn-port-if-binding-to-irq-fails.patch
xen-send-spinlock-ipi-to-all-waiters.patch
zram-fix-deadlock-bug-in-partial-read-write.patch

14 files changed:
queue-3.8/b43-increase-number-of-rx-dma-slots.patch [new file with mode: 0644]
queue-3.8/driver-core-treat-unregistered-bus_types-as-having-no-devices.patch [new file with mode: 0644]
queue-3.8/mmu_notifier_unregister-null-pointer-deref-and-multiple-release-callouts.patch [new file with mode: 0644]
queue-3.8/pps-add-pps_lookup_dev-function.patch [new file with mode: 0644]
queue-3.8/pps-fix-a-use-after-free-bug-when-unregistering-a-source.patch [new file with mode: 0644]
queue-3.8/pps-use-pps_lookup_dev-to-reduce-ldisc-coupling.patch [new file with mode: 0644]
queue-3.8/rtlwifi-rtl8192cu-add-new-usb-id.patch [new file with mode: 0644]
queue-3.8/rtlwifi-rtl8192cu-fix-null-dereference-bug-when-using-new_id.patch [new file with mode: 0644]
queue-3.8/rtlwifi-usb-allocate-urb-control-message-setup_packet-and-data-buffer-separately.patch [new file with mode: 0644]
queue-3.8/series
queue-3.8/tty-vt-fix-character-insertion-overflow.patch [new file with mode: 0644]
queue-3.8/xen-close-evtchn-port-if-binding-to-irq-fails.patch [new file with mode: 0644]
queue-3.8/xen-send-spinlock-ipi-to-all-waiters.patch [new file with mode: 0644]
queue-3.8/zram-fix-deadlock-bug-in-partial-read-write.patch [new file with mode: 0644]

diff --git a/queue-3.8/b43-increase-number-of-rx-dma-slots.patch b/queue-3.8/b43-increase-number-of-rx-dma-slots.patch
new file mode 100644 (file)
index 0000000..8300fc8
--- /dev/null
@@ -0,0 +1,37 @@
+From ccae0e50c16a7f7adb029c169147400d1ce9f703 Mon Sep 17 00:00:00 2001
+From: Larry Finger <Larry.Finger@lwfinger.net>
+Date: Sun, 17 Feb 2013 17:01:20 +0000
+Subject: b43: Increase number of RX DMA slots
+
+From: Larry Finger <Larry.Finger@lwfinger.net>
+
+commit ccae0e50c16a7f7adb029c169147400d1ce9f703 upstream.
+
+Bastian Bittorf reported that some of the silent freezes on a Linksys WRT54G
+were due to overflow of the RX DMA ring buffer, which was created with 64
+slots. That finding reminded me that I was seeing similar crashed on a netbook,
+which also has a relatively slow processor. After increasing the number of
+slots to 128, runs on the netbook that previously failed now worked; however,
+I found that 109 slots had been used in one test. For that reason, the number
+of slots is being increased to 256.
+
+Signed-off-by: Larry Finger <Larry.Finger@lwfinger.net>
+Cc: Bastian Bittorf <bittorf@bluebottle.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/net/wireless/b43/dma.h |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/net/wireless/b43/dma.h
++++ b/drivers/net/wireless/b43/dma.h
+@@ -169,7 +169,7 @@ struct b43_dmadesc_generic {
+ /* DMA engine tuning knobs */
+ #define B43_TXRING_SLOTS              256
+-#define B43_RXRING_SLOTS              64
++#define B43_RXRING_SLOTS              256
+ #define B43_DMA0_RX_FW598_BUFSIZE     (B43_DMA0_RX_FW598_FO + IEEE80211_MAX_FRAME_LEN)
+ #define B43_DMA0_RX_FW351_BUFSIZE     (B43_DMA0_RX_FW351_FO + IEEE80211_MAX_FRAME_LEN)
diff --git a/queue-3.8/driver-core-treat-unregistered-bus_types-as-having-no-devices.patch b/queue-3.8/driver-core-treat-unregistered-bus_types-as-having-no-devices.patch
new file mode 100644 (file)
index 0000000..4de81b3
--- /dev/null
@@ -0,0 +1,57 @@
+From 4fa3e78be7e985ca814ce2aa0c09cbee404efcf7 Mon Sep 17 00:00:00 2001
+From: Bjorn Helgaas <bhelgaas@google.com>
+Date: Tue, 29 Jan 2013 16:44:27 -0700
+Subject: Driver core: treat unregistered bus_types as having no devices
+
+From: Bjorn Helgaas <bhelgaas@google.com>
+
+commit 4fa3e78be7e985ca814ce2aa0c09cbee404efcf7 upstream.
+
+A bus_type has a list of devices (klist_devices), but the list and the
+subsys_private structure that contains it are not initialized until the
+bus_type is registered with bus_register().
+
+The panic/reboot path has fixups that look up devices in pci_bus_type.  If
+we panic before registering pci_bus_type, the bus_type exists but the list
+does not, so mach_reboot_fixups() trips over a null pointer and panics
+again:
+
+    mach_reboot_fixups
+      pci_get_device
+        ..
+          bus_find_device(&pci_bus_type, ...)
+            bus->p is NULL
+
+Joonsoo reported a problem when panicking before PCI was initialized.
+I think this patch should be sufficient to replace the patch he posted
+here: https://lkml.org/lkml/2012/12/28/75 ("[PATCH] x86, reboot: skip
+reboot_fixups in early boot phase")
+
+Reported-by: Joonsoo Kim <js1304@gmail.com>
+Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/base/bus.c |    4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/drivers/base/bus.c
++++ b/drivers/base/bus.c
+@@ -290,7 +290,7 @@ int bus_for_each_dev(struct bus_type *bu
+       struct device *dev;
+       int error = 0;
+-      if (!bus)
++      if (!bus || !bus->p)
+               return -EINVAL;
+       klist_iter_init_node(&bus->p->klist_devices, &i,
+@@ -324,7 +324,7 @@ struct device *bus_find_device(struct bu
+       struct klist_iter i;
+       struct device *dev;
+-      if (!bus)
++      if (!bus || !bus->p)
+               return NULL;
+       klist_iter_init_node(&bus->p->klist_devices, &i,
diff --git a/queue-3.8/mmu_notifier_unregister-null-pointer-deref-and-multiple-release-callouts.patch b/queue-3.8/mmu_notifier_unregister-null-pointer-deref-and-multiple-release-callouts.patch
new file mode 100644 (file)
index 0000000..05d3c72
--- /dev/null
@@ -0,0 +1,180 @@
+From 751efd8610d3d7d67b7bdf7f62646edea7365dd7 Mon Sep 17 00:00:00 2001
+From: Robin Holt <holt@sgi.com>
+Date: Fri, 22 Feb 2013 16:35:34 -0800
+Subject: mmu_notifier_unregister NULL Pointer deref and multiple ->release() callouts
+
+From: Robin Holt <holt@sgi.com>
+
+commit 751efd8610d3d7d67b7bdf7f62646edea7365dd7 upstream.
+
+There is a race condition between mmu_notifier_unregister() and
+__mmu_notifier_release().
+
+Assume two tasks, one calling mmu_notifier_unregister() as a result of a
+filp_close() ->flush() callout (task A), and the other calling
+mmu_notifier_release() from an mmput() (task B).
+
+                A                               B
+t1                                              srcu_read_lock()
+t2              if (!hlist_unhashed())
+t3                                              srcu_read_unlock()
+t4              srcu_read_lock()
+t5                                              hlist_del_init_rcu()
+t6                                              synchronize_srcu()
+t7              srcu_read_unlock()
+t8              hlist_del_rcu()  <--- NULL pointer deref.
+
+Additionally, the list traversal in __mmu_notifier_release() is not
+protected by the by the mmu_notifier_mm->hlist_lock which can result in
+callouts to the ->release() notifier from both mmu_notifier_unregister()
+and __mmu_notifier_release().
+
+-stable suggestions:
+
+The stable trees prior to 3.7.y need commits 21a92735f660 and
+70400303ce0c cherry-picked in that order prior to cherry-picking this
+commit.  The 3.7.y tree already has those two commits.
+
+Signed-off-by: Robin Holt <holt@sgi.com>
+Cc: Andrea Arcangeli <aarcange@redhat.com>
+Cc: Wanpeng Li <liwanp@linux.vnet.ibm.com>
+Cc: Xiao Guangrong <xiaoguangrong@linux.vnet.ibm.com>
+Cc: Avi Kivity <avi@redhat.com>
+Cc: Hugh Dickins <hughd@google.com>
+Cc: Marcelo Tosatti <mtosatti@redhat.com>
+Cc: Sagi Grimberg <sagig@mellanox.co.il>
+Cc: Haggai Eran <haggaie@mellanox.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/mmu_notifier.c |   82 +++++++++++++++++++++++++++---------------------------
+ 1 file changed, 42 insertions(+), 40 deletions(-)
+
+--- a/mm/mmu_notifier.c
++++ b/mm/mmu_notifier.c
+@@ -37,49 +37,51 @@ static struct srcu_struct srcu;
+ void __mmu_notifier_release(struct mm_struct *mm)
+ {
+       struct mmu_notifier *mn;
+-      struct hlist_node *n;
+       int id;
+       /*
+-       * SRCU here will block mmu_notifier_unregister until
+-       * ->release returns.
++       * srcu_read_lock() here will block synchronize_srcu() in
++       * mmu_notifier_unregister() until all registered
++       * ->release() callouts this function makes have
++       * returned.
+        */
+       id = srcu_read_lock(&srcu);
+-      hlist_for_each_entry_rcu(mn, n, &mm->mmu_notifier_mm->list, hlist)
+-              /*
+-               * if ->release runs before mmu_notifier_unregister it
+-               * must be handled as it's the only way for the driver
+-               * to flush all existing sptes and stop the driver
+-               * from establishing any more sptes before all the
+-               * pages in the mm are freed.
+-               */
+-              if (mn->ops->release)
+-                      mn->ops->release(mn, mm);
+-      srcu_read_unlock(&srcu, id);
+-
+       spin_lock(&mm->mmu_notifier_mm->lock);
+       while (unlikely(!hlist_empty(&mm->mmu_notifier_mm->list))) {
+               mn = hlist_entry(mm->mmu_notifier_mm->list.first,
+                                struct mmu_notifier,
+                                hlist);
++
+               /*
+-               * We arrived before mmu_notifier_unregister so
+-               * mmu_notifier_unregister will do nothing other than
+-               * to wait ->release to finish and
+-               * mmu_notifier_unregister to return.
++               * Unlink.  This will prevent mmu_notifier_unregister()
++               * from also making the ->release() callout.
+                */
+               hlist_del_init_rcu(&mn->hlist);
++              spin_unlock(&mm->mmu_notifier_mm->lock);
++
++              /*
++               * Clear sptes. (see 'release' description in mmu_notifier.h)
++               */
++              if (mn->ops->release)
++                      mn->ops->release(mn, mm);
++
++              spin_lock(&mm->mmu_notifier_mm->lock);
+       }
+       spin_unlock(&mm->mmu_notifier_mm->lock);
+       /*
+-       * synchronize_srcu here prevents mmu_notifier_release to
+-       * return to exit_mmap (which would proceed freeing all pages
+-       * in the mm) until the ->release method returns, if it was
+-       * invoked by mmu_notifier_unregister.
+-       *
+-       * The mmu_notifier_mm can't go away from under us because one
+-       * mm_count is hold by exit_mmap.
++       * All callouts to ->release() which we have done are complete.
++       * Allow synchronize_srcu() in mmu_notifier_unregister() to complete
++       */
++      srcu_read_unlock(&srcu, id);
++
++      /*
++       * mmu_notifier_unregister() may have unlinked a notifier and may
++       * still be calling out to it.  Additionally, other notifiers
++       * may have been active via vmtruncate() et. al. Block here
++       * to ensure that all notifier callouts for this mm have been
++       * completed and the sptes are really cleaned up before returning
++       * to exit_mmap().
+        */
+       synchronize_srcu(&srcu);
+ }
+@@ -294,31 +296,31 @@ void mmu_notifier_unregister(struct mmu_
+ {
+       BUG_ON(atomic_read(&mm->mm_count) <= 0);
++      spin_lock(&mm->mmu_notifier_mm->lock);
+       if (!hlist_unhashed(&mn->hlist)) {
+-              /*
+-               * SRCU here will force exit_mmap to wait ->release to finish
+-               * before freeing the pages.
+-               */
+               int id;
+-              id = srcu_read_lock(&srcu);
+               /*
+-               * exit_mmap will block in mmu_notifier_release to
+-               * guarantee ->release is called before freeing the
+-               * pages.
++               * Ensure we synchronize up with __mmu_notifier_release().
+                */
++              id = srcu_read_lock(&srcu);
++
++              hlist_del_rcu(&mn->hlist);
++              spin_unlock(&mm->mmu_notifier_mm->lock);
++
+               if (mn->ops->release)
+                       mn->ops->release(mn, mm);
+-              srcu_read_unlock(&srcu, id);
+-              spin_lock(&mm->mmu_notifier_mm->lock);
+-              hlist_del_rcu(&mn->hlist);
++              /*
++               * Allow __mmu_notifier_release() to complete.
++               */
++              srcu_read_unlock(&srcu, id);
++      } else
+               spin_unlock(&mm->mmu_notifier_mm->lock);
+-      }
+       /*
+-       * Wait any running method to finish, of course including
+-       * ->release if it was run by mmu_notifier_relase instead of us.
++       * Wait for any running method to finish, including ->release() if it
++       * was run by __mmu_notifier_release() instead of us.
+        */
+       synchronize_srcu(&srcu);
diff --git a/queue-3.8/pps-add-pps_lookup_dev-function.patch b/queue-3.8/pps-add-pps_lookup_dev-function.patch
new file mode 100644 (file)
index 0000000..ae4e033
--- /dev/null
@@ -0,0 +1,125 @@
+From 513b032c98b4b9414aa4e9b4a315cb1bf0380101 Mon Sep 17 00:00:00 2001
+From: George Spelvin <linux@horizon.com>
+Date: Sun, 10 Feb 2013 04:08:32 -0500
+Subject: pps: Add pps_lookup_dev() function
+
+From: George Spelvin <linux@horizon.com>
+
+commit 513b032c98b4b9414aa4e9b4a315cb1bf0380101 upstream.
+
+The PPS serial line discipline wants to attach a PPS device to a tty
+without changing the tty code to add a struct pps_device * pointer.
+
+Since the number of PPS devices in a typical system is generally very low
+(n=1 is by far the most common), it's practical to search the entire list
+of allocated pps devices.  (We capture the timestamp before the lookup,
+so the timing isn't affected.)
+
+It is a bit ugly that this function, which is part of the in-kernel
+PPS API, has to be in pps.c as opposed to kapi,c, but that's not
+something that affects users.
+
+Signed-off-by: George Spelvin <linux@horizon.com>
+Acked-by: Rodolfo Giometti <giometti@enneenne.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/pps/pps.c          |   33 +++++++++++++++++++++++++++++++++
+ include/linux/pps_kernel.h |   17 ++++++++++++++---
+ 2 files changed, 47 insertions(+), 3 deletions(-)
+
+--- a/drivers/pps/pps.c
++++ b/drivers/pps/pps.c
+@@ -352,11 +352,44 @@ free_idr:
+ void pps_unregister_cdev(struct pps_device *pps)
+ {
++      pps->lookup_cookie = NULL;
+       device_destroy(pps_class, pps->dev->devt);
+       cdev_del(&pps->cdev);
+ }
+ /*
++ * Look up a pps device by magic cookie.
++ * The cookie is usually a pointer to some enclosing device, but this
++ * code doesn't care; you should never be dereferencing it.
++ *
++ * This is a bit of a kludge that is currently used only by the PPS
++ * serial line discipline.  It may need to be tweaked when a second user
++ * is found.
++ *
++ * There is no function interface for setting the lookup_cookie field.
++ * It's initialized to NULL when the pps device is created, and if a
++ * client wants to use it, just fill it in afterward.
++ *
++ * The cookie is automatically set to NULL in pps_unregister_source()
++ * so that it will not be used again, even if the pps device cannot
++ * be removed from the idr due to pending references holding the minor
++ * number in use.
++ */
++struct pps_device *pps_lookup_dev(void const *cookie)
++{
++      struct pps_device *pps;
++      unsigned id;
++
++      rcu_read_lock();
++      idr_for_each_entry(&pps_idr, pps, id)
++              if (cookie == pps->lookup_cookie)
++                      break;
++      rcu_read_unlock();
++      return pps;
++}
++EXPORT_SYMBOL(pps_lookup_dev);
++
++/*
+  * Module stuff
+  */
+--- a/include/linux/pps_kernel.h
++++ b/include/linux/pps_kernel.h
+@@ -43,7 +43,7 @@ struct pps_source_info {
+                       int event, void *data); /* PPS echo function */
+       struct module *owner;
+-      struct device *dev;
++      struct device *dev;             /* Parent device for device_create */
+ };
+ struct pps_event_time {
+@@ -69,6 +69,7 @@ struct pps_device {
+       wait_queue_head_t queue;                /* PPS event queue */
+       unsigned int id;                        /* PPS source unique ID */
++      void const *lookup_cookie;              /* pps_lookup_dev only */
+       struct cdev cdev;
+       struct device *dev;
+       struct fasync_struct *async_queue;      /* fasync method */
+@@ -82,16 +83,26 @@ struct pps_device {
+ extern struct device_attribute pps_attrs[];
+ /*
++ * Internal functions.
++ *
++ * These are not actually part of the exported API, but this is a
++ * convenient header file to put them in.
++ */
++
++extern int pps_register_cdev(struct pps_device *pps);
++extern void pps_unregister_cdev(struct pps_device *pps);
++
++/*
+  * Exported functions
+  */
+ extern struct pps_device *pps_register_source(
+               struct pps_source_info *info, int default_params);
+ extern void pps_unregister_source(struct pps_device *pps);
+-extern int pps_register_cdev(struct pps_device *pps);
+-extern void pps_unregister_cdev(struct pps_device *pps);
+ extern void pps_event(struct pps_device *pps,
+               struct pps_event_time *ts, int event, void *data);
++/* Look up a pps device by magic cookie */
++struct pps_device *pps_lookup_dev(void const *cookie);
+ static inline void timespec_to_pps_ktime(struct pps_ktime *kt,
+               struct timespec ts)
diff --git a/queue-3.8/pps-fix-a-use-after-free-bug-when-unregistering-a-source.patch b/queue-3.8/pps-fix-a-use-after-free-bug-when-unregistering-a-source.patch
new file mode 100644 (file)
index 0000000..95baae1
--- /dev/null
@@ -0,0 +1,80 @@
+From d953e0e837e65ecc1ddaa4f9560f7925878a0de6 Mon Sep 17 00:00:00 2001
+From: George Spelvin <linux@horizon.com>
+Date: Tue, 12 Feb 2013 02:27:20 -0500
+Subject: pps: Fix a use-after free bug when unregistering a source.
+
+From: George Spelvin <linux@horizon.com>
+
+commit d953e0e837e65ecc1ddaa4f9560f7925878a0de6 upstream.
+
+Remove the cdev from the system (with cdev_del) *before* deallocating it
+(in pps_device_destruct, called via kobject_put from device_destroy).
+
+Also prevent deallocating a device with open file handles.
+
+A better long-term fix is probably to remove the cdev from the pps_device
+entirely, and instead have all devices reference one global cdev.  Then
+the deallocation ordering becomes simpler.
+
+But that's more complex and invasive change, so we leave that
+for later.
+
+Signed-off-by: George Spelvin <linux@horizon.com>
+Acked-by: Rodolfo Giometti <giometti@enneenne.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/pps/pps.c |   14 ++++++++++----
+ 1 file changed, 10 insertions(+), 4 deletions(-)
+
+--- a/drivers/pps/pps.c
++++ b/drivers/pps/pps.c
+@@ -247,12 +247,15 @@ static int pps_cdev_open(struct inode *i
+       struct pps_device *pps = container_of(inode->i_cdev,
+                                               struct pps_device, cdev);
+       file->private_data = pps;
+-
++      kobject_get(&pps->dev->kobj);
+       return 0;
+ }
+ static int pps_cdev_release(struct inode *inode, struct file *file)
+ {
++      struct pps_device *pps = container_of(inode->i_cdev,
++                                              struct pps_device, cdev);
++      kobject_put(&pps->dev->kobj);
+       return 0;
+ }
+@@ -274,8 +277,10 @@ static void pps_device_destruct(struct d
+ {
+       struct pps_device *pps = dev_get_drvdata(dev);
+-      /* release id here to protect others from using it while it's
+-       * still in use */
++      cdev_del(&pps->cdev);
++
++      /* Now we can release the ID for re-use */
++      pr_debug("deallocating pps%d\n", pps->id);
+       mutex_lock(&pps_idr_lock);
+       idr_remove(&pps_idr, pps->id);
+       mutex_unlock(&pps_idr_lock);
+@@ -332,6 +337,7 @@ int pps_register_cdev(struct pps_device
+               goto del_cdev;
+       }
++      /* Override the release function with our own */
+       pps->dev->release = pps_device_destruct;
+       pr_debug("source %s got cdev (%d:%d)\n", pps->info.name,
+@@ -352,9 +358,9 @@ free_idr:
+ void pps_unregister_cdev(struct pps_device *pps)
+ {
++      pr_debug("unregistering pps%d\n", pps->id);
+       pps->lookup_cookie = NULL;
+       device_destroy(pps_class, pps->dev->devt);
+-      cdev_del(&pps->cdev);
+ }
+ /*
diff --git a/queue-3.8/pps-use-pps_lookup_dev-to-reduce-ldisc-coupling.patch b/queue-3.8/pps-use-pps_lookup_dev-to-reduce-ldisc-coupling.patch
new file mode 100644 (file)
index 0000000..7aeabad
--- /dev/null
@@ -0,0 +1,69 @@
+From 03a7ffe4e542310838bac70ef85acc17536b6d7c Mon Sep 17 00:00:00 2001
+From: George Spelvin <linux@horizon.com>
+Date: Sun, 10 Feb 2013 04:41:56 -0500
+Subject: pps: Use pps_lookup_dev to reduce ldisc coupling
+
+From: George Spelvin <linux@horizon.com>
+
+commit 03a7ffe4e542310838bac70ef85acc17536b6d7c upstream.
+
+Now that N_TTY uses tty->disc_data for its private data,
+'subclass' ldiscs cannot use ->disc_data for their own private data.
+(This is a regression is v3.8-rc1)
+
+Use pps_lookup_dev to associate the tty with the pps source instead.
+
+This fixes a crashing regression in 3.8-rc1.
+
+Signed-off-by: George Spelvin <linux@horizon.com>
+Acked-by: Rodolfo Giometti <giometti@enneenne.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/pps/clients/pps-ldisc.c |   10 ++++------
+ 1 file changed, 4 insertions(+), 6 deletions(-)
+
+--- a/drivers/pps/clients/pps-ldisc.c
++++ b/drivers/pps/clients/pps-ldisc.c
+@@ -31,7 +31,7 @@
+ static void pps_tty_dcd_change(struct tty_struct *tty, unsigned int status,
+                               struct pps_event_time *ts)
+ {
+-      struct pps_device *pps = (struct pps_device *)tty->disc_data;
++      struct pps_device *pps = pps_lookup_dev(tty);
+       BUG_ON(pps == NULL);
+@@ -67,9 +67,9 @@ static int pps_tty_open(struct tty_struc
+               pr_err("cannot register PPS source \"%s\"\n", info.path);
+               return -ENOMEM;
+       }
+-      tty->disc_data = pps;
++      pps->lookup_cookie = tty;
+-      /* Should open N_TTY ldisc too */
++      /* Now open the base class N_TTY ldisc */
+       ret = alias_n_tty_open(tty);
+       if (ret < 0) {
+               pr_err("cannot open tty ldisc \"%s\"\n", info.path);
+@@ -81,7 +81,6 @@ static int pps_tty_open(struct tty_struc
+       return 0;
+ err_unregister:
+-      tty->disc_data = NULL;
+       pps_unregister_source(pps);
+       return ret;
+ }
+@@ -90,11 +89,10 @@ static void (*alias_n_tty_close)(struct
+ static void pps_tty_close(struct tty_struct *tty)
+ {
+-      struct pps_device *pps = (struct pps_device *)tty->disc_data;
++      struct pps_device *pps = pps_lookup_dev(tty);
+       alias_n_tty_close(tty);
+-      tty->disc_data = NULL;
+       dev_info(pps->dev, "removed\n");
+       pps_unregister_source(pps);
+ }
diff --git a/queue-3.8/rtlwifi-rtl8192cu-add-new-usb-id.patch b/queue-3.8/rtlwifi-rtl8192cu-add-new-usb-id.patch
new file mode 100644 (file)
index 0000000..2037705
--- /dev/null
@@ -0,0 +1,30 @@
+From 8708aac79e4572ba673d7a21e94ddca9f3abb7fc Mon Sep 17 00:00:00 2001
+From: Larry Finger <Larry.Finger@lwfinger.net>
+Date: Fri, 8 Feb 2013 12:28:18 -0600
+Subject: rtlwifi: rtl8192cu: Add new USB ID
+
+From: Larry Finger <Larry.Finger@lwfinger.net>
+
+commit 8708aac79e4572ba673d7a21e94ddca9f3abb7fc upstream.
+
+A new model of the RTL8188CUS has appeared.
+
+Reported-and-tested-by: Thomas Rosenkrantz <tom.rosary@googlemail.com>
+Signed-off-by: Larry Finger <Larry.Finger@lwfinger.net>
+Signed-off-by: John W. Linville <linville@tuxdriver.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/net/wireless/rtlwifi/rtl8192cu/sw.c |    1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c
++++ b/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c
+@@ -285,6 +285,7 @@ static struct usb_device_id rtl8192c_usb
+       {RTL_USB_DEVICE(USB_VENDER_ID_REALTEK, 0x817f, rtl92cu_hal_cfg)},
+       /* RTL8188CUS-VL */
+       {RTL_USB_DEVICE(USB_VENDER_ID_REALTEK, 0x818a, rtl92cu_hal_cfg)},
++      {RTL_USB_DEVICE(USB_VENDER_ID_REALTEK, 0x819a, rtl92cu_hal_cfg)},
+       /* 8188 Combo for BC4 */
+       {RTL_USB_DEVICE(USB_VENDER_ID_REALTEK, 0x8754, rtl92cu_hal_cfg)},
diff --git a/queue-3.8/rtlwifi-rtl8192cu-fix-null-dereference-bug-when-using-new_id.patch b/queue-3.8/rtlwifi-rtl8192cu-fix-null-dereference-bug-when-using-new_id.patch
new file mode 100644 (file)
index 0000000..d63b600
--- /dev/null
@@ -0,0 +1,76 @@
+From 957f4aca5fa0db69635271bc4621cc0b65b2d590 Mon Sep 17 00:00:00 2001
+From: Larry Finger <Larry.Finger@lwfinger.net>
+Date: Wed, 6 Feb 2013 12:54:17 -0600
+Subject: rtlwifi: rtl8192cu: Fix NULL dereference BUG when using new_id
+
+From: Larry Finger <Larry.Finger@lwfinger.net>
+
+commit 957f4aca5fa0db69635271bc4621cc0b65b2d590 upstream.
+
+When the new_id entry in /sysfs is used for a foreign USB device, rtlwifi
+BUGS with a NULL pointer dereference because the per-driver configuration
+data is not available. The probe function has been restructured as
+suggested by Ben Hutchings <bhutchings@solarflare.com>.
+
+Signed-off-by: Larry Finger <Larry.Finger@lwfinger.net>
+Signed-off-by: John W. Linville <linville@tuxdriver.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/net/wireless/rtlwifi/rtl8192cu/sw.c |    8 +++++++-
+ drivers/net/wireless/rtlwifi/usb.c          |    5 +++--
+ drivers/net/wireless/rtlwifi/usb.h          |    3 ++-
+ 3 files changed, 12 insertions(+), 4 deletions(-)
+
+--- a/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c
++++ b/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c
+@@ -363,9 +363,15 @@ static struct usb_device_id rtl8192c_usb
+ MODULE_DEVICE_TABLE(usb, rtl8192c_usb_ids);
++static int rtl8192cu_probe(struct usb_interface *intf,
++                         const struct usb_device_id *id)
++{
++      return rtl_usb_probe(intf, id, &rtl92cu_hal_cfg);
++}
++
+ static struct usb_driver rtl8192cu_driver = {
+       .name = "rtl8192cu",
+-      .probe = rtl_usb_probe,
++      .probe = rtl8192cu_probe,
+       .disconnect = rtl_usb_disconnect,
+       .id_table = rtl8192c_usb_ids,
+--- a/drivers/net/wireless/rtlwifi/usb.c
++++ b/drivers/net/wireless/rtlwifi/usb.c
+@@ -941,7 +941,8 @@ static struct rtl_intf_ops rtl_usb_ops =
+ };
+ int rtl_usb_probe(struct usb_interface *intf,
+-                      const struct usb_device_id *id)
++                const struct usb_device_id *id,
++                struct rtl_hal_cfg *rtl_hal_cfg)
+ {
+       int err;
+       struct ieee80211_hw *hw = NULL;
+@@ -976,7 +977,7 @@ int rtl_usb_probe(struct usb_interface *
+       usb_set_intfdata(intf, hw);
+       /* init cfg & intf_ops */
+       rtlpriv->rtlhal.interface = INTF_USB;
+-      rtlpriv->cfg = (struct rtl_hal_cfg *)(id->driver_info);
++      rtlpriv->cfg = rtl_hal_cfg;
+       rtlpriv->intf_ops = &rtl_usb_ops;
+       rtl_dbgp_flag_init(hw);
+       /* Init IO handler */
+--- a/drivers/net/wireless/rtlwifi/usb.h
++++ b/drivers/net/wireless/rtlwifi/usb.h
+@@ -157,7 +157,8 @@ struct rtl_usb_priv {
+ int rtl_usb_probe(struct usb_interface *intf,
+-                          const struct usb_device_id *id);
++                const struct usb_device_id *id,
++                struct rtl_hal_cfg *rtl92cu_hal_cfg);
+ void rtl_usb_disconnect(struct usb_interface *intf);
+ int rtl_usb_suspend(struct usb_interface *pusb_intf, pm_message_t message);
+ int rtl_usb_resume(struct usb_interface *pusb_intf);
diff --git a/queue-3.8/rtlwifi-usb-allocate-urb-control-message-setup_packet-and-data-buffer-separately.patch b/queue-3.8/rtlwifi-usb-allocate-urb-control-message-setup_packet-and-data-buffer-separately.patch
new file mode 100644 (file)
index 0000000..72b63c9
--- /dev/null
@@ -0,0 +1,113 @@
+From bc6b89237acb3dee6af6e64e51a18255fef89cc2 Mon Sep 17 00:00:00 2001
+From: Jussi Kivilinna <jussi.kivilinna@mbnet.fi>
+Date: Mon, 18 Feb 2013 10:29:30 +0200
+Subject: rtlwifi: usb: allocate URB control message setup_packet and data buffer separately
+
+From: Jussi Kivilinna <jussi.kivilinna@mbnet.fi>
+
+commit bc6b89237acb3dee6af6e64e51a18255fef89cc2 upstream.
+
+rtlwifi allocates both setup_packet and data buffer of control message urb,
+using shared kmalloc in _usbctrl_vendorreq_async_write. Structure used for
+allocating is:
+       struct {
+               u8 data[254];
+               struct usb_ctrlrequest dr;
+       };
+
+Because 'struct usb_ctrlrequest' is __packed, setup packet is unaligned and
+DMA mapping of both 'data' and 'dr' confuses ARM/sunxi, leading to memory
+corruptions and freezes.
+
+Patch changes setup packet to be allocated separately.
+
+[v2]:
+ - Use WARN_ON_ONCE instead of WARN_ON
+
+Signed-off-by: Jussi Kivilinna <jussi.kivilinna@mbnet.fi>
+Signed-off-by: John W. Linville <linville@tuxdriver.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/net/wireless/rtlwifi/usb.c |   44 +++++++++++++++++++++++--------------
+ 1 file changed, 28 insertions(+), 16 deletions(-)
+
+--- a/drivers/net/wireless/rtlwifi/usb.c
++++ b/drivers/net/wireless/rtlwifi/usb.c
+@@ -42,8 +42,12 @@
+ static void usbctrl_async_callback(struct urb *urb)
+ {
+-      if (urb)
+-              kfree(urb->context);
++      if (urb) {
++              /* free dr */
++              kfree(urb->setup_packet);
++              /* free databuf */
++              kfree(urb->transfer_buffer);
++      }
+ }
+ static int _usbctrl_vendorreq_async_write(struct usb_device *udev, u8 request,
+@@ -55,39 +59,47 @@ static int _usbctrl_vendorreq_async_writ
+       u8 reqtype;
+       struct usb_ctrlrequest *dr;
+       struct urb *urb;
+-      struct rtl819x_async_write_data {
+-              u8 data[REALTEK_USB_VENQT_MAX_BUF_SIZE];
+-              struct usb_ctrlrequest dr;
+-      } *buf;
++      const u16 databuf_maxlen = REALTEK_USB_VENQT_MAX_BUF_SIZE;
++      u8 *databuf;
++
++      if (WARN_ON_ONCE(len > databuf_maxlen))
++              len = databuf_maxlen;
+       pipe = usb_sndctrlpipe(udev, 0); /* write_out */
+       reqtype =  REALTEK_USB_VENQT_WRITE;
+-      buf = kmalloc(sizeof(*buf), GFP_ATOMIC);
+-      if (!buf)
++      dr = kmalloc(sizeof(*dr), GFP_ATOMIC);
++      if (!dr)
+               return -ENOMEM;
++      databuf = kmalloc(databuf_maxlen, GFP_ATOMIC);
++      if (!databuf) {
++              kfree(dr);
++              return -ENOMEM;
++      }
++
+       urb = usb_alloc_urb(0, GFP_ATOMIC);
+       if (!urb) {
+-              kfree(buf);
++              kfree(databuf);
++              kfree(dr);
+               return -ENOMEM;
+       }
+-      dr = &buf->dr;
+-
+       dr->bRequestType = reqtype;
+       dr->bRequest = request;
+       dr->wValue = cpu_to_le16(value);
+       dr->wIndex = cpu_to_le16(index);
+       dr->wLength = cpu_to_le16(len);
+       /* data are already in little-endian order */
+-      memcpy(buf, pdata, len);
++      memcpy(databuf, pdata, len);
+       usb_fill_control_urb(urb, udev, pipe,
+-                           (unsigned char *)dr, buf, len,
+-                           usbctrl_async_callback, buf);
++                           (unsigned char *)dr, databuf, len,
++                           usbctrl_async_callback, NULL);
+       rc = usb_submit_urb(urb, GFP_ATOMIC);
+-      if (rc < 0)
+-              kfree(buf);
++      if (rc < 0) {
++              kfree(databuf);
++              kfree(dr);
++      }
+       usb_free_urb(urb);
+       return rc;
+ }
index b2772513b1597eb2c5fa42db65c6e40b9db01a5b..4cd591083cb92f92902b0af18d5ba9879bda6a26 100644 (file)
@@ -17,3 +17,16 @@ tty-set_termios-set_termiox-should-not-return-eintr.patch
 usb-serial-fix-null-pointer-dereferences-on-disconnect.patch
 serial-imx-fix-recursive-locking-bug.patch
 serial_core-fix-type-definition-for-port_brcm_trumanage.patch
+b43-increase-number-of-rx-dma-slots.patch
+rtlwifi-rtl8192cu-fix-null-dereference-bug-when-using-new_id.patch
+rtlwifi-rtl8192cu-add-new-usb-id.patch
+rtlwifi-usb-allocate-urb-control-message-setup_packet-and-data-buffer-separately.patch
+tty-vt-fix-character-insertion-overflow.patch
+xen-send-spinlock-ipi-to-all-waiters.patch
+xen-close-evtchn-port-if-binding-to-irq-fails.patch
+pps-add-pps_lookup_dev-function.patch
+pps-use-pps_lookup_dev-to-reduce-ldisc-coupling.patch
+pps-fix-a-use-after-free-bug-when-unregistering-a-source.patch
+zram-fix-deadlock-bug-in-partial-read-write.patch
+driver-core-treat-unregistered-bus_types-as-having-no-devices.patch
+mmu_notifier_unregister-null-pointer-deref-and-multiple-release-callouts.patch
diff --git a/queue-3.8/tty-vt-fix-character-insertion-overflow.patch b/queue-3.8/tty-vt-fix-character-insertion-overflow.patch
new file mode 100644 (file)
index 0000000..4831118
--- /dev/null
@@ -0,0 +1,53 @@
+From a883b70d8e0a88278c0a1f80753b4dc99962b541 Mon Sep 17 00:00:00 2001
+From: Nicolas Pitre <nicolas.pitre@linaro.org>
+Date: Sun, 24 Feb 2013 20:06:09 -0500
+Subject: tty vt: fix character insertion overflow
+
+From: Nicolas Pitre <nicolas.pitre@linaro.org>
+
+commit a883b70d8e0a88278c0a1f80753b4dc99962b541 upstream.
+
+Commit 81732c3b2fed ("tty vt: Fix line garbage in virtual console on
+command line edition") broke insert_char() in multiple ways.  Then
+commit b1a925f44a3a ("tty vt: Fix a regression in command line edition")
+partially fixed it.  However, the buffer being moved is still too large
+and overflowing beyond the end of the current line, corrupting existing
+characters on the next line.
+
+Example test case:
+
+echo -e "abc\nde\x1b[A\x1b[4h \x1b[4l\x1b[B"
+
+Expected result:
+
+ab c
+de
+
+Current result:
+
+ab c
+ e
+
+Needless to say that this is very annoying when inserting words in the
+middle of paragraphs with certain text editors.
+
+Signed-off-by: Nicolas Pitre <nico@linaro.org>
+Acked-by: Jean-François Moine <moinejf@free.fr>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/tty/vt/vt.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/tty/vt/vt.c
++++ b/drivers/tty/vt/vt.c
+@@ -539,7 +539,7 @@ static void insert_char(struct vc_data *
+ {
+       unsigned short *p = (unsigned short *) vc->vc_pos;
+-      scr_memmovew(p + nr, p, (vc->vc_cols - vc->vc_x) * 2);
++      scr_memmovew(p + nr, p, (vc->vc_cols - vc->vc_x - nr) * 2);
+       scr_memsetw(p, vc->vc_video_erase_char, nr * 2);
+       vc->vc_need_wrap = 0;
+       if (DO_UPDATE(vc))
diff --git a/queue-3.8/xen-close-evtchn-port-if-binding-to-irq-fails.patch b/queue-3.8/xen-close-evtchn-port-if-binding-to-irq-fails.patch
new file mode 100644 (file)
index 0000000..c74e73f
--- /dev/null
@@ -0,0 +1,43 @@
+From e7e44e444876478d50630f57b0c31d29f6725020 Mon Sep 17 00:00:00 2001
+From: Wei Liu <wei.liu2@citrix.com>
+Date: Mon, 18 Feb 2013 14:57:58 +0000
+Subject: xen: close evtchn port if binding to irq fails
+
+From: Wei Liu <wei.liu2@citrix.com>
+
+commit e7e44e444876478d50630f57b0c31d29f6725020 upstream.
+
+Signed-off-by: Wei Liu <wei.liu2@citrix.com>
+Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/xen/evtchn.c |   10 ++++++++++
+ 1 file changed, 10 insertions(+)
+
+--- a/drivers/xen/evtchn.c
++++ b/drivers/xen/evtchn.c
+@@ -269,6 +269,14 @@ static int evtchn_bind_to_user(struct pe
+                                      u->name, (void *)(unsigned long)port);
+       if (rc >= 0)
+               rc = evtchn_make_refcounted(port);
++      else {
++              /* bind failed, should close the port now */
++              struct evtchn_close close;
++              close.port = port;
++              if (HYPERVISOR_event_channel_op(EVTCHNOP_close, &close) != 0)
++                      BUG();
++              set_port_user(port, NULL);
++      }
+       return rc;
+ }
+@@ -277,6 +285,8 @@ static void evtchn_unbind_from_user(stru
+ {
+       int irq = irq_from_evtchn(port);
++      BUG_ON(irq < 0);
++
+       unbind_from_irqhandler(irq, (void *)(unsigned long)port);
+       set_port_user(port, NULL);
diff --git a/queue-3.8/xen-send-spinlock-ipi-to-all-waiters.patch b/queue-3.8/xen-send-spinlock-ipi-to-all-waiters.patch
new file mode 100644 (file)
index 0000000..d4c724b
--- /dev/null
@@ -0,0 +1,63 @@
+From 76eaca031f0af2bb303e405986f637811956a422 Mon Sep 17 00:00:00 2001
+From: Stefan Bader <stefan.bader@canonical.com>
+Date: Fri, 15 Feb 2013 09:48:52 +0100
+Subject: xen: Send spinlock IPI to all waiters
+
+From: Stefan Bader <stefan.bader@canonical.com>
+
+commit 76eaca031f0af2bb303e405986f637811956a422 upstream.
+
+There is a loophole between Xen's current implementation of
+pv-spinlocks and the scheduler. This was triggerable through
+a testcase until v3.6 changed the TLB flushing code. The
+problem potentially is still there just not observable in the
+same way.
+
+What could happen was (is):
+
+1. CPU n tries to schedule task x away and goes into a slow
+   wait for the runq lock of CPU n-# (must be one with a lower
+   number).
+2. CPU n-#, while processing softirqs, tries to balance domains
+   and goes into a slow wait for its own runq lock (for updating
+   some records). Since this is a spin_lock_irqsave in softirq
+   context, interrupts will be re-enabled for the duration of
+   the poll_irq hypercall used by Xen.
+3. Before the runq lock of CPU n-# is unlocked, CPU n-1 receives
+   an interrupt (e.g. endio) and when processing the interrupt,
+   tries to wake up task x. But that is in schedule and still
+   on_cpu, so try_to_wake_up goes into a tight loop.
+4. The runq lock of CPU n-# gets unlocked, but the message only
+   gets sent to the first waiter, which is CPU n-# and that is
+   busily stuck.
+5. CPU n-# never returns from the nested interruption to take and
+   release the lock because the scheduler uses a busy wait.
+   And CPU n never finishes the task migration because the unlock
+   notification only went to CPU n-#.
+
+To avoid this and since the unlocking code has no real sense of
+which waiter is best suited to grab the lock, just send the IPI
+to all of them. This causes the waiters to return from the hyper-
+call (those not interrupted at least) and do active spinlocking.
+
+BugLink: http://bugs.launchpad.net/bugs/1011792
+
+Acked-by: Jan Beulich <JBeulich@suse.com>
+Signed-off-by: Stefan Bader <stefan.bader@canonical.com>
+Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/x86/xen/spinlock.c |    1 -
+ 1 file changed, 1 deletion(-)
+
+--- a/arch/x86/xen/spinlock.c
++++ b/arch/x86/xen/spinlock.c
+@@ -328,7 +328,6 @@ static noinline void xen_spin_unlock_slo
+               if (per_cpu(lock_spinners, cpu) == xl) {
+                       ADD_STATS(released_slow_kicked, 1);
+                       xen_send_IPI_one(cpu, XEN_SPIN_UNLOCK_VECTOR);
+-                      break;
+               }
+       }
+ }
diff --git a/queue-3.8/zram-fix-deadlock-bug-in-partial-read-write.patch b/queue-3.8/zram-fix-deadlock-bug-in-partial-read-write.patch
new file mode 100644 (file)
index 0000000..38774a4
--- /dev/null
@@ -0,0 +1,63 @@
+From 7e5a5104c6af709a8d97d5f4711e7c917761d464 Mon Sep 17 00:00:00 2001
+From: Minchan Kim <minchan@kernel.org>
+Date: Wed, 30 Jan 2013 11:41:39 +0900
+Subject: zram: Fix deadlock bug in partial read/write
+
+From: Minchan Kim <minchan@kernel.org>
+
+commit 7e5a5104c6af709a8d97d5f4711e7c917761d464 upstream.
+
+Now zram allocates new page with GFP_KERNEL in zram I/O path
+if IO is partial. Unfortunately, It may cause deadlock with
+reclaim path like below.
+
+write_page from fs
+fs_lock
+allocation(GFP_KERNEL)
+reclaim
+pageout
+                               write_page from fs
+                               fs_lock <-- deadlock
+
+This patch fixes it by using GFP_NOIO.  In read path, we
+reorganize code flow so that kmap_atomic is called after the
+GFP_NOIO allocation.
+
+Acked-by: Jerome Marchand <jmarchand@redhat.com>
+Acked-by: Nitin Gupta <ngupta@vflare.org>
+[ penberg@kernel.org: don't use GFP_ATOMIC ]
+Signed-off-by: Pekka Enberg <penberg@kernel.org>
+Signed-off-by: Minchan Kim <minchan@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/staging/zram/zram_drv.c |    9 +++++----
+ 1 file changed, 5 insertions(+), 4 deletions(-)
+
+--- a/drivers/staging/zram/zram_drv.c
++++ b/drivers/staging/zram/zram_drv.c
+@@ -228,11 +228,12 @@ static int zram_bvec_read(struct zram *z
+               return 0;
+       }
+-      user_mem = kmap_atomic(page);
+       if (is_partial_io(bvec))
+               /* Use  a temporary buffer to decompress the page */
+-              uncmem = kmalloc(PAGE_SIZE, GFP_KERNEL);
+-      else
++              uncmem = kmalloc(PAGE_SIZE, GFP_NOIO);
++
++      user_mem = kmap_atomic(page);
++      if (!is_partial_io(bvec))
+               uncmem = user_mem;
+       if (!uncmem) {
+@@ -279,7 +280,7 @@ static int zram_bvec_write(struct zram *
+                * This is a partial IO. We need to read the full page
+                * before to write the changes.
+                */
+-              uncmem = kmalloc(PAGE_SIZE, GFP_KERNEL);
++              uncmem = kmalloc(PAGE_SIZE, GFP_NOIO);
+               if (!uncmem) {
+                       pr_info("Error allocating temp memory!\n");
+                       ret = -ENOMEM;