]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
3.7-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 25 Feb 2013 17:41:59 +0000 (09:41 -0800)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 25 Feb 2013 17:41:59 +0000 (09:41 -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
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-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

queue-3.7/b43-increase-number-of-rx-dma-slots.patch [new file with mode: 0644]
queue-3.7/driver-core-treat-unregistered-bus_types-as-having-no-devices.patch [new file with mode: 0644]
queue-3.7/mmu_notifier_unregister-null-pointer-deref-and-multiple-release-callouts.patch [new file with mode: 0644]
queue-3.7/rtlwifi-rtl8192cu-add-new-usb-id.patch [new file with mode: 0644]
queue-3.7/rtlwifi-usb-allocate-urb-control-message-setup_packet-and-data-buffer-separately.patch [new file with mode: 0644]
queue-3.7/series
queue-3.7/tty-vt-fix-character-insertion-overflow.patch [new file with mode: 0644]
queue-3.7/xen-close-evtchn-port-if-binding-to-irq-fails.patch [new file with mode: 0644]
queue-3.7/xen-send-spinlock-ipi-to-all-waiters.patch [new file with mode: 0644]
queue-3.7/zram-fix-deadlock-bug-in-partial-read-write.patch [new file with mode: 0644]

diff --git a/queue-3.7/b43-increase-number-of-rx-dma-slots.patch b/queue-3.7/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.7/driver-core-treat-unregistered-bus_types-as-having-no-devices.patch b/queue-3.7/driver-core-treat-unregistered-bus_types-as-having-no-devices.patch
new file mode 100644 (file)
index 0000000..2d786d2
--- /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
+@@ -293,7 +293,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,
+@@ -327,7 +327,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.7/mmu_notifier_unregister-null-pointer-deref-and-multiple-release-callouts.patch b/queue-3.7/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.7/rtlwifi-rtl8192cu-add-new-usb-id.patch b/queue-3.7/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.7/rtlwifi-usb-allocate-urb-control-message-setup_packet-and-data-buffer-separately.patch b/queue-3.7/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 c9ef1ba79d72b89432a213b1397a3230e2b1ec13..4adfa5b74d44e7872b30bb27f331a7a92c25147b 100644 (file)
@@ -18,3 +18,12 @@ 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-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
+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.7/tty-vt-fix-character-insertion-overflow.patch b/queue-3.7/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.7/xen-close-evtchn-port-if-binding-to-irq-fails.patch b/queue-3.7/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.7/xen-send-spinlock-ipi-to-all-waiters.patch b/queue-3.7/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.7/zram-fix-deadlock-bug-in-partial-read-write.patch b/queue-3.7/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;