]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
3.10-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 6 Nov 2015 06:28:35 +0000 (22:28 -0800)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 6 Nov 2015 06:28:35 +0000 (22:28 -0800)
added patches:
dm-btree-fix-leak-of-bufio-backed-block-in-btree_split_beneath-error-path.patch
dm-btree-remove-fix-a-bug-when-rebalancing-nodes-after-removal.patch
module-fix-locking-in-symbol_put_addr.patch
xen-blkfront-check-for-null-drvdata-in-blkback_changed-xenbusstateclosing.patch
xhci-handle-no-ping-response-error-properly.patch

queue-3.10/dm-btree-fix-leak-of-bufio-backed-block-in-btree_split_beneath-error-path.patch [new file with mode: 0644]
queue-3.10/dm-btree-remove-fix-a-bug-when-rebalancing-nodes-after-removal.patch [new file with mode: 0644]
queue-3.10/module-fix-locking-in-symbol_put_addr.patch [new file with mode: 0644]
queue-3.10/series
queue-3.10/xen-blkfront-check-for-null-drvdata-in-blkback_changed-xenbusstateclosing.patch [new file with mode: 0644]
queue-3.10/xhci-handle-no-ping-response-error-properly.patch [new file with mode: 0644]

diff --git a/queue-3.10/dm-btree-fix-leak-of-bufio-backed-block-in-btree_split_beneath-error-path.patch b/queue-3.10/dm-btree-fix-leak-of-bufio-backed-block-in-btree_split_beneath-error-path.patch
new file mode 100644 (file)
index 0000000..6c0fae4
--- /dev/null
@@ -0,0 +1,36 @@
+From 4dcb8b57df3593dcb20481d9d6cf79d1dc1534be Mon Sep 17 00:00:00 2001
+From: Mike Snitzer <snitzer@redhat.com>
+Date: Thu, 22 Oct 2015 10:56:40 -0400
+Subject: dm btree: fix leak of bufio-backed block in btree_split_beneath error path
+
+From: Mike Snitzer <snitzer@redhat.com>
+
+commit 4dcb8b57df3593dcb20481d9d6cf79d1dc1534be upstream.
+
+btree_split_beneath()'s error path had an outstanding FIXME that speaks
+directly to the potential for _not_ cleaning up a previously allocated
+bufio-backed block.
+
+Fix this by releasing the previously allocated bufio block using
+unlock_block().
+
+Reported-by: Mikulas Patocka <mpatocka@redhat.com>
+Signed-off-by: Mike Snitzer <snitzer@redhat.com>
+Acked-by: Joe Thornber <thornber@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/md/persistent-data/dm-btree.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/md/persistent-data/dm-btree.c
++++ b/drivers/md/persistent-data/dm-btree.c
+@@ -507,7 +507,7 @@ static int btree_split_beneath(struct sh
+       r = new_block(s->info, &right);
+       if (r < 0) {
+-              /* FIXME: put left */
++              unlock_block(s->info, left);
+               return r;
+       }
diff --git a/queue-3.10/dm-btree-remove-fix-a-bug-when-rebalancing-nodes-after-removal.patch b/queue-3.10/dm-btree-remove-fix-a-bug-when-rebalancing-nodes-after-removal.patch
new file mode 100644 (file)
index 0000000..51a9656
--- /dev/null
@@ -0,0 +1,76 @@
+From 2871c69e025e8bc507651d5a9cf81a8a7da9d24b Mon Sep 17 00:00:00 2001
+From: Joe Thornber <ejt@redhat.com>
+Date: Wed, 21 Oct 2015 18:36:49 +0100
+Subject: dm btree remove: fix a bug when rebalancing nodes after removal
+
+From: Joe Thornber <ejt@redhat.com>
+
+commit 2871c69e025e8bc507651d5a9cf81a8a7da9d24b upstream.
+
+Commit 4c7e309340ff ("dm btree remove: fix bug in redistribute3") wasn't
+a complete fix for redistribute3().
+
+The redistribute3 function takes 3 btree nodes and shares out the entries
+evenly between them.  If the three nodes in total contained
+(MAX_ENTRIES * 3) - 1 entries between them then this was erroneously getting
+rebalanced as (MAX_ENTRIES - 1) on the left and right, and (MAX_ENTRIES + 1) in
+the center.
+
+Fix this issue by being more careful about calculating the target number
+of entries for the left and right nodes.
+
+Unit tested in userspace using this program:
+https://github.com/jthornber/redistribute3-test/blob/master/redistribute3_t.c
+
+Signed-off-by: Joe Thornber <ejt@redhat.com>
+Signed-off-by: Mike Snitzer <snitzer@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/md/persistent-data/dm-btree-remove.c |   17 +++++++++++------
+ 1 file changed, 11 insertions(+), 6 deletions(-)
+
+--- a/drivers/md/persistent-data/dm-btree-remove.c
++++ b/drivers/md/persistent-data/dm-btree-remove.c
+@@ -301,11 +301,16 @@ static void redistribute3(struct dm_btre
+ {
+       int s;
+       uint32_t max_entries = le32_to_cpu(left->header.max_entries);
+-      unsigned target = (nr_left + nr_center + nr_right) / 3;
+-      BUG_ON(target > max_entries);
++      unsigned total = nr_left + nr_center + nr_right;
++      unsigned target_right = total / 3;
++      unsigned remainder = (target_right * 3) != total;
++      unsigned target_left = target_right + remainder;
++
++      BUG_ON(target_left > max_entries);
++      BUG_ON(target_right > max_entries);
+       if (nr_left < nr_right) {
+-              s = nr_left - target;
++              s = nr_left - target_left;
+               if (s < 0 && nr_center < -s) {
+                       /* not enough in central node */
+@@ -316,10 +321,10 @@ static void redistribute3(struct dm_btre
+               } else
+                       shift(left, center, s);
+-              shift(center, right, target - nr_right);
++              shift(center, right, target_right - nr_right);
+       } else {
+-              s = target - nr_right;
++              s = target_right - nr_right;
+               if (s > 0 && nr_center < s) {
+                       /* not enough in central node */
+                       shift(center, right, nr_center);
+@@ -329,7 +334,7 @@ static void redistribute3(struct dm_btre
+               } else
+                       shift(center, right, s);
+-              shift(left, center, nr_left - target);
++              shift(left, center, nr_left - target_left);
+       }
+       *key_ptr(parent, c->index) = center->keys[0];
diff --git a/queue-3.10/module-fix-locking-in-symbol_put_addr.patch b/queue-3.10/module-fix-locking-in-symbol_put_addr.patch
new file mode 100644 (file)
index 0000000..5bc86da
--- /dev/null
@@ -0,0 +1,63 @@
+From 275d7d44d802ef271a42dc87ac091a495ba72fc5 Mon Sep 17 00:00:00 2001
+From: Peter Zijlstra <peterz@infradead.org>
+Date: Thu, 20 Aug 2015 10:34:59 +0930
+Subject: module: Fix locking in symbol_put_addr()
+
+From: Peter Zijlstra <peterz@infradead.org>
+
+commit 275d7d44d802ef271a42dc87ac091a495ba72fc5 upstream.
+
+Poma (on the way to another bug) reported an assertion triggering:
+
+  [<ffffffff81150529>] module_assert_mutex_or_preempt+0x49/0x90
+  [<ffffffff81150822>] __module_address+0x32/0x150
+  [<ffffffff81150956>] __module_text_address+0x16/0x70
+  [<ffffffff81150f19>] symbol_put_addr+0x29/0x40
+  [<ffffffffa04b77ad>] dvb_frontend_detach+0x7d/0x90 [dvb_core]
+
+Laura Abbott <labbott@redhat.com> produced a patch which lead us to
+inspect symbol_put_addr(). This function has a comment claiming it
+doesn't need to disable preemption around the module lookup
+because it holds a reference to the module it wants to find, which
+therefore cannot go away.
+
+This is wrong (and a false optimization too, preempt_disable() is really
+rather cheap, and I doubt any of this is on uber critical paths,
+otherwise it would've retained a pointer to the actual module anyway and
+avoided the second lookup).
+
+While its true that the module cannot go away while we hold a reference
+on it, the data structure we do the lookup in very much _CAN_ change
+while we do the lookup. Therefore fix the comment and add the
+required preempt_disable().
+
+Reported-by: poma <pomidorabelisima@gmail.com>
+Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
+Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
+Fixes: a6e6abd575fc ("module: remove module_text_address()")
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ kernel/module.c |    8 ++++++--
+ 1 file changed, 6 insertions(+), 2 deletions(-)
+
+--- a/kernel/module.c
++++ b/kernel/module.c
+@@ -942,11 +942,15 @@ void symbol_put_addr(void *addr)
+       if (core_kernel_text(a))
+               return;
+-      /* module_text_address is safe here: we're supposed to have reference
+-       * to module from symbol_get, so it can't go away. */
++      /*
++       * Even though we hold a reference on the module; we still need to
++       * disable preemption in order to safely traverse the data structure.
++       */
++      preempt_disable();
+       modaddr = __module_text_address(a);
+       BUG_ON(!modaddr);
+       module_put(modaddr);
++      preempt_enable();
+ }
+ EXPORT_SYMBOL_GPL(symbol_put_addr);
index fd3e04e795d6f03bc3850b90ba70b949dfc63e18..7161d053025e3ccde8d2ea4d91de6ed7b9d9f6a7 100644 (file)
@@ -11,3 +11,8 @@ rbd-require-stable-pages-if-message-data-crcs-are-enabled.patch
 rbd-don-t-leak-parent_spec-in-rbd_dev_probe_parent.patch
 rbd-prevent-kernel-stack-blow-up-on-rbd-map.patch
 revert-arm64-unwind-fix-pc-calculation.patch
+dm-btree-remove-fix-a-bug-when-rebalancing-nodes-after-removal.patch
+dm-btree-fix-leak-of-bufio-backed-block-in-btree_split_beneath-error-path.patch
+xhci-handle-no-ping-response-error-properly.patch
+xen-blkfront-check-for-null-drvdata-in-blkback_changed-xenbusstateclosing.patch
+module-fix-locking-in-symbol_put_addr.patch
diff --git a/queue-3.10/xen-blkfront-check-for-null-drvdata-in-blkback_changed-xenbusstateclosing.patch b/queue-3.10/xen-blkfront-check-for-null-drvdata-in-blkback_changed-xenbusstateclosing.patch
new file mode 100644 (file)
index 0000000..aba811e
--- /dev/null
@@ -0,0 +1,35 @@
+From a54c8f0f2d7df525ff997e2afe71866a1a013064 Mon Sep 17 00:00:00 2001
+From: Cathy Avery <cathy.avery@oracle.com>
+Date: Fri, 2 Oct 2015 09:35:01 -0400
+Subject: xen-blkfront: check for null drvdata in blkback_changed (XenbusStateClosing)
+
+From: Cathy Avery <cathy.avery@oracle.com>
+
+commit a54c8f0f2d7df525ff997e2afe71866a1a013064 upstream.
+
+xen-blkfront will crash if the check to talk_to_blkback()
+in blkback_changed()(XenbusStateInitWait) returns an error.
+The driver data is freed and info is set to NULL. Later during
+the close process via talk_to_blkback's call to xenbus_dev_fatal()
+the null pointer is passed to and dereference in blkfront_closing.
+
+Signed-off-by: Cathy Avery <cathy.avery@oracle.com>
+Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/block/xen-blkfront.c |    3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/drivers/block/xen-blkfront.c
++++ b/drivers/block/xen-blkfront.c
+@@ -1590,7 +1590,8 @@ static void blkback_changed(struct xenbu
+                       break;
+               /* Missed the backend's Closing state -- fallthrough */
+       case XenbusStateClosing:
+-              blkfront_closing(info);
++              if (info)
++                      blkfront_closing(info);
+               break;
+       }
+ }
diff --git a/queue-3.10/xhci-handle-no-ping-response-error-properly.patch b/queue-3.10/xhci-handle-no-ping-response-error-properly.patch
new file mode 100644 (file)
index 0000000..f8c5493
--- /dev/null
@@ -0,0 +1,76 @@
+From 3b4739b8951d650becbcd855d7d6f18ac98a9a85 Mon Sep 17 00:00:00 2001
+From: Mathias Nyman <mathias.nyman@linux.intel.com>
+Date: Mon, 12 Oct 2015 11:30:12 +0300
+Subject: xhci: handle no ping response error properly
+
+From: Mathias Nyman <mathias.nyman@linux.intel.com>
+
+commit 3b4739b8951d650becbcd855d7d6f18ac98a9a85 upstream.
+
+If a host fails to wake up a isochronous SuperSpeed device from U1/U2
+in time for a isoch transfer it will generate a "No ping response error"
+Host will then move to the next transfer descriptor.
+
+Handle this case in the same way as missed service errors, tag the
+current TD as skipped and handle it on the next transfer event.
+
+Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/host/xhci-ring.c |   20 +++++++++++++++-----
+ 1 file changed, 15 insertions(+), 5 deletions(-)
+
+--- a/drivers/usb/host/xhci-ring.c
++++ b/drivers/usb/host/xhci-ring.c
+@@ -2348,6 +2348,7 @@ static int handle_tx_event(struct xhci_h
+       u32 trb_comp_code;
+       int ret = 0;
+       int td_num = 0;
++      bool handling_skipped_tds = false;
+       slot_id = TRB_TO_SLOT_ID(le32_to_cpu(event->flags));
+       xdev = xhci->devs[slot_id];
+@@ -2481,6 +2482,10 @@ static int handle_tx_event(struct xhci_h
+               ep->skip = true;
+               xhci_dbg(xhci, "Miss service interval error, set skip flag\n");
+               goto cleanup;
++      case COMP_PING_ERR:
++              ep->skip = true;
++              xhci_dbg(xhci, "No Ping response error, Skip one Isoc TD\n");
++              goto cleanup;
+       default:
+               if (xhci_is_vendor_info_code(xhci, trb_comp_code)) {
+                       status = 0;
+@@ -2612,13 +2617,18 @@ static int handle_tx_event(struct xhci_h
+                                                ep, &status);
+ cleanup:
++
++
++              handling_skipped_tds = ep->skip &&
++                      trb_comp_code != COMP_MISSED_INT &&
++                      trb_comp_code != COMP_PING_ERR;
++
+               /*
+-               * Do not update event ring dequeue pointer if ep->skip is set.
+-               * Will roll back to continue process missed tds.
++               * Do not update event ring dequeue pointer if we're in a loop
++               * processing missed tds.
+                */
+-              if (trb_comp_code == COMP_MISSED_INT || !ep->skip) {
++              if (!handling_skipped_tds)
+                       inc_deq(xhci, xhci->event_ring);
+-              }
+               if (ret) {
+                       urb = td->urb;
+@@ -2662,7 +2672,7 @@ cleanup:
+        * Process them as short transfer until reach the td pointed by
+        * the event.
+        */
+-      } while (ep->skip && trb_comp_code != COMP_MISSED_INT);
++      } while (handling_skipped_tds);
+       return 0;
+ }