]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
3.4-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 14 Jan 2013 18:54:00 +0000 (10:54 -0800)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 14 Jan 2013 18:54:00 +0000 (10:54 -0800)
added patches:
dm-ioctl-prevent-unsafe-change-to-dm_ioctl-data_size.patch
dm-persistent-data-rename-node-to-btree_node.patch
rdma-nes-fix-for-crash-when-registering-zero-length-mr-for-cq.patch
rdma-nes-fix-for-terminate-timer-crash.patch
ring-buffer-fix-race-between-integrity-check-and-readers.patch

queue-3.4/dm-ioctl-prevent-unsafe-change-to-dm_ioctl-data_size.patch [new file with mode: 0644]
queue-3.4/dm-persistent-data-rename-node-to-btree_node.patch [new file with mode: 0644]
queue-3.4/rdma-nes-fix-for-crash-when-registering-zero-length-mr-for-cq.patch [new file with mode: 0644]
queue-3.4/rdma-nes-fix-for-terminate-timer-crash.patch [new file with mode: 0644]
queue-3.4/ring-buffer-fix-race-between-integrity-check-and-readers.patch [new file with mode: 0644]
queue-3.4/series

diff --git a/queue-3.4/dm-ioctl-prevent-unsafe-change-to-dm_ioctl-data_size.patch b/queue-3.4/dm-ioctl-prevent-unsafe-change-to-dm_ioctl-data_size.patch
new file mode 100644 (file)
index 0000000..098a28f
--- /dev/null
@@ -0,0 +1,62 @@
+From e910d7ebecd1aac43125944a8641b6cb1a0dfabe Mon Sep 17 00:00:00 2001
+From: Alasdair G Kergon <agk@redhat.com>
+Date: Fri, 21 Dec 2012 20:23:30 +0000
+Subject: dm ioctl: prevent unsafe change to dm_ioctl data_size
+
+From: Alasdair G Kergon <agk@redhat.com>
+
+commit e910d7ebecd1aac43125944a8641b6cb1a0dfabe upstream.
+
+Abort dm ioctl processing if userspace changes the data_size parameter
+after we validated it but before we finished copying the data buffer
+from userspace.
+
+The dm ioctl parameters are processed in the following sequence:
+ 1. ctl_ioctl() calls copy_params();
+ 2. copy_params() makes a first copy of the fixed-sized portion of the
+    userspace parameters into the local variable "tmp";
+ 3. copy_params() then validates tmp.data_size and allocates a new
+    structure big enough to hold the complete data and copies the whole
+    userspace buffer there;
+ 4. ctl_ioctl() reads userspace data the second time and copies the whole
+    buffer into the pointer "param";
+ 5. ctl_ioctl() reads param->data_size without any validation and stores it
+    in the variable "input_param_size";
+ 6. "input_param_size" is further used as the authoritative size of the
+    kernel buffer.
+
+The problem is that userspace code could change the contents of user
+memory between steps 2 and 4.  In particular, the data_size parameter
+can be changed to an invalid value after the kernel has validated it.
+This lets userspace force the kernel to access invalid kernel memory.
+
+The fix is to ensure that the size has not changed at step 4.
+
+This patch shouldn't have a security impact because CAP_SYS_ADMIN is
+required to run this code, but it should be fixed anyway.
+
+Reported-by: Mikulas Patocka <mpatocka@redhat.com>
+Signed-off-by: Alasdair G Kergon <agk@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/md/dm-ioctl.c |    8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+--- a/drivers/md/dm-ioctl.c
++++ b/drivers/md/dm-ioctl.c
+@@ -1563,6 +1563,14 @@ static int copy_params(struct dm_ioctl _
+       if (copy_from_user(dmi, user, tmp.data_size))
+               goto bad;
++      /*
++       * Abort if something changed the ioctl data while it was being copied.
++       */
++      if (dmi->data_size != tmp.data_size) {
++              DMERR("rejecting ioctl: data size modified while processing parameters");
++              goto bad;
++      }
++
+       /* Wipe the user buffer so we do not return it to userspace */
+       if (secure_data && clear_user(user, tmp.data_size))
+               goto bad;
diff --git a/queue-3.4/dm-persistent-data-rename-node-to-btree_node.patch b/queue-3.4/dm-persistent-data-rename-node-to-btree_node.patch
new file mode 100644 (file)
index 0000000..427d577
--- /dev/null
@@ -0,0 +1,403 @@
+From 550929faf89e2e2cdb3e9945ea87d383989274cf Mon Sep 17 00:00:00 2001
+From: Mikulas Patocka <mpatocka@redhat.com>
+Date: Fri, 21 Dec 2012 20:23:30 +0000
+Subject: dm persistent data: rename node to btree_node
+
+From: Mikulas Patocka <mpatocka@redhat.com>
+
+commit 550929faf89e2e2cdb3e9945ea87d383989274cf upstream.
+
+This patch fixes a compilation failure on sparc32 by renaming struct node.
+
+struct node is already defined in include/linux/node.h. On sparc32, it
+happens to be included through other dependencies and persistent-data
+doesn't compile because of conflicting declarations.
+
+Signed-off-by: Mikulas Patocka <mpatocka@redhat.com>
+Signed-off-by: Alasdair G Kergon <agk@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/md/persistent-data/dm-btree-internal.h |   16 ++++----
+ drivers/md/persistent-data/dm-btree-remove.c   |   50 ++++++++++++-------------
+ drivers/md/persistent-data/dm-btree-spine.c    |    6 +--
+ drivers/md/persistent-data/dm-btree.c          |   22 +++++------
+ 4 files changed, 47 insertions(+), 47 deletions(-)
+
+--- a/drivers/md/persistent-data/dm-btree-internal.h
++++ b/drivers/md/persistent-data/dm-btree-internal.h
+@@ -36,13 +36,13 @@ struct node_header {
+       __le32 padding;
+ } __packed;
+-struct node {
++struct btree_node {
+       struct node_header header;
+       __le64 keys[0];
+ } __packed;
+-void inc_children(struct dm_transaction_manager *tm, struct node *n,
++void inc_children(struct dm_transaction_manager *tm, struct btree_node *n,
+                 struct dm_btree_value_type *vt);
+ int new_block(struct dm_btree_info *info, struct dm_block **result);
+@@ -64,7 +64,7 @@ struct ro_spine {
+ void init_ro_spine(struct ro_spine *s, struct dm_btree_info *info);
+ int exit_ro_spine(struct ro_spine *s);
+ int ro_step(struct ro_spine *s, dm_block_t new_child);
+-struct node *ro_node(struct ro_spine *s);
++struct btree_node *ro_node(struct ro_spine *s);
+ struct shadow_spine {
+       struct dm_btree_info *info;
+@@ -98,17 +98,17 @@ int shadow_root(struct shadow_spine *s);
+ /*
+  * Some inlines.
+  */
+-static inline __le64 *key_ptr(struct node *n, uint32_t index)
++static inline __le64 *key_ptr(struct btree_node *n, uint32_t index)
+ {
+       return n->keys + index;
+ }
+-static inline void *value_base(struct node *n)
++static inline void *value_base(struct btree_node *n)
+ {
+       return &n->keys[le32_to_cpu(n->header.max_entries)];
+ }
+-static inline void *value_ptr(struct node *n, uint32_t index)
++static inline void *value_ptr(struct btree_node *n, uint32_t index)
+ {
+       uint32_t value_size = le32_to_cpu(n->header.value_size);
+       return value_base(n) + (value_size * index);
+@@ -117,7 +117,7 @@ static inline void *value_ptr(struct nod
+ /*
+  * Assumes the values are suitably-aligned and converts to core format.
+  */
+-static inline uint64_t value64(struct node *n, uint32_t index)
++static inline uint64_t value64(struct btree_node *n, uint32_t index)
+ {
+       __le64 *values_le = value_base(n);
+@@ -127,7 +127,7 @@ static inline uint64_t value64(struct no
+ /*
+  * Searching for a key within a single node.
+  */
+-int lower_bound(struct node *n, uint64_t key);
++int lower_bound(struct btree_node *n, uint64_t key);
+ extern struct dm_block_validator btree_node_validator;
+--- a/drivers/md/persistent-data/dm-btree-remove.c
++++ b/drivers/md/persistent-data/dm-btree-remove.c
+@@ -53,7 +53,7 @@
+ /*
+  * Some little utilities for moving node data around.
+  */
+-static void node_shift(struct node *n, int shift)
++static void node_shift(struct btree_node *n, int shift)
+ {
+       uint32_t nr_entries = le32_to_cpu(n->header.nr_entries);
+       uint32_t value_size = le32_to_cpu(n->header.value_size);
+@@ -79,7 +79,7 @@ static void node_shift(struct node *n, i
+       }
+ }
+-static void node_copy(struct node *left, struct node *right, int shift)
++static void node_copy(struct btree_node *left, struct btree_node *right, int shift)
+ {
+       uint32_t nr_left = le32_to_cpu(left->header.nr_entries);
+       uint32_t value_size = le32_to_cpu(left->header.value_size);
+@@ -108,7 +108,7 @@ static void node_copy(struct node *left,
+ /*
+  * Delete a specific entry from a leaf node.
+  */
+-static void delete_at(struct node *n, unsigned index)
++static void delete_at(struct btree_node *n, unsigned index)
+ {
+       unsigned nr_entries = le32_to_cpu(n->header.nr_entries);
+       unsigned nr_to_copy = nr_entries - (index + 1);
+@@ -128,7 +128,7 @@ static void delete_at(struct node *n, un
+       n->header.nr_entries = cpu_to_le32(nr_entries - 1);
+ }
+-static unsigned merge_threshold(struct node *n)
++static unsigned merge_threshold(struct btree_node *n)
+ {
+       return le32_to_cpu(n->header.max_entries) / 3;
+ }
+@@ -136,7 +136,7 @@ static unsigned merge_threshold(struct n
+ struct child {
+       unsigned index;
+       struct dm_block *block;
+-      struct node *n;
++      struct btree_node *n;
+ };
+ static struct dm_btree_value_type le64_type = {
+@@ -147,7 +147,7 @@ static struct dm_btree_value_type le64_t
+       .equal = NULL
+ };
+-static int init_child(struct dm_btree_info *info, struct node *parent,
++static int init_child(struct dm_btree_info *info, struct btree_node *parent,
+                     unsigned index, struct child *result)
+ {
+       int r, inc;
+@@ -177,7 +177,7 @@ static int exit_child(struct dm_btree_in
+       return dm_tm_unlock(info->tm, c->block);
+ }
+-static void shift(struct node *left, struct node *right, int count)
++static void shift(struct btree_node *left, struct btree_node *right, int count)
+ {
+       uint32_t nr_left = le32_to_cpu(left->header.nr_entries);
+       uint32_t nr_right = le32_to_cpu(right->header.nr_entries);
+@@ -203,11 +203,11 @@ static void shift(struct node *left, str
+       right->header.nr_entries = cpu_to_le32(nr_right + count);
+ }
+-static void __rebalance2(struct dm_btree_info *info, struct node *parent,
++static void __rebalance2(struct dm_btree_info *info, struct btree_node *parent,
+                        struct child *l, struct child *r)
+ {
+-      struct node *left = l->n;
+-      struct node *right = r->n;
++      struct btree_node *left = l->n;
++      struct btree_node *right = r->n;
+       uint32_t nr_left = le32_to_cpu(left->header.nr_entries);
+       uint32_t nr_right = le32_to_cpu(right->header.nr_entries);
+       unsigned threshold = 2 * merge_threshold(left) + 1;
+@@ -239,7 +239,7 @@ static int rebalance2(struct shadow_spin
+                     unsigned left_index)
+ {
+       int r;
+-      struct node *parent;
++      struct btree_node *parent;
+       struct child left, right;
+       parent = dm_block_data(shadow_current(s));
+@@ -270,9 +270,9 @@ static int rebalance2(struct shadow_spin
+  * in right, then rebalance2.  This wastes some cpu, but I want something
+  * simple atm.
+  */
+-static void delete_center_node(struct dm_btree_info *info, struct node *parent,
++static void delete_center_node(struct dm_btree_info *info, struct btree_node *parent,
+                              struct child *l, struct child *c, struct child *r,
+-                             struct node *left, struct node *center, struct node *right,
++                             struct btree_node *left, struct btree_node *center, struct btree_node *right,
+                              uint32_t nr_left, uint32_t nr_center, uint32_t nr_right)
+ {
+       uint32_t max_entries = le32_to_cpu(left->header.max_entries);
+@@ -301,9 +301,9 @@ static void delete_center_node(struct dm
+ /*
+  * Redistributes entries among 3 sibling nodes.
+  */
+-static void redistribute3(struct dm_btree_info *info, struct node *parent,
++static void redistribute3(struct dm_btree_info *info, struct btree_node *parent,
+                         struct child *l, struct child *c, struct child *r,
+-                        struct node *left, struct node *center, struct node *right,
++                        struct btree_node *left, struct btree_node *center, struct btree_node *right,
+                         uint32_t nr_left, uint32_t nr_center, uint32_t nr_right)
+ {
+       int s;
+@@ -343,12 +343,12 @@ static void redistribute3(struct dm_btre
+       *key_ptr(parent, r->index) = right->keys[0];
+ }
+-static void __rebalance3(struct dm_btree_info *info, struct node *parent,
++static void __rebalance3(struct dm_btree_info *info, struct btree_node *parent,
+                        struct child *l, struct child *c, struct child *r)
+ {
+-      struct node *left = l->n;
+-      struct node *center = c->n;
+-      struct node *right = r->n;
++      struct btree_node *left = l->n;
++      struct btree_node *center = c->n;
++      struct btree_node *right = r->n;
+       uint32_t nr_left = le32_to_cpu(left->header.nr_entries);
+       uint32_t nr_center = le32_to_cpu(center->header.nr_entries);
+@@ -371,7 +371,7 @@ static int rebalance3(struct shadow_spin
+                     unsigned left_index)
+ {
+       int r;
+-      struct node *parent = dm_block_data(shadow_current(s));
++      struct btree_node *parent = dm_block_data(shadow_current(s));
+       struct child left, center, right;
+       /*
+@@ -421,7 +421,7 @@ static int get_nr_entries(struct dm_tran
+ {
+       int r;
+       struct dm_block *block;
+-      struct node *n;
++      struct btree_node *n;
+       r = dm_tm_read_lock(tm, b, &btree_node_validator, &block);
+       if (r)
+@@ -438,7 +438,7 @@ static int rebalance_children(struct sha
+ {
+       int i, r, has_left_sibling, has_right_sibling;
+       uint32_t child_entries;
+-      struct node *n;
++      struct btree_node *n;
+       n = dm_block_data(shadow_current(s));
+@@ -483,7 +483,7 @@ static int rebalance_children(struct sha
+       return r;
+ }
+-static int do_leaf(struct node *n, uint64_t key, unsigned *index)
++static int do_leaf(struct btree_node *n, uint64_t key, unsigned *index)
+ {
+       int i = lower_bound(n, key);
+@@ -506,7 +506,7 @@ static int remove_raw(struct shadow_spin
+                     uint64_t key, unsigned *index)
+ {
+       int i = *index, r;
+-      struct node *n;
++      struct btree_node *n;
+       for (;;) {
+               r = shadow_step(s, root, vt);
+@@ -556,7 +556,7 @@ int dm_btree_remove(struct dm_btree_info
+       unsigned level, last_level = info->levels - 1;
+       int index = 0, r = 0;
+       struct shadow_spine spine;
+-      struct node *n;
++      struct btree_node *n;
+       init_shadow_spine(&spine, info);
+       for (level = 0; level < info->levels; level++) {
+--- a/drivers/md/persistent-data/dm-btree-spine.c
++++ b/drivers/md/persistent-data/dm-btree-spine.c
+@@ -23,7 +23,7 @@ static void node_prepare_for_write(struc
+                                  struct dm_block *b,
+                                  size_t block_size)
+ {
+-      struct node *n = dm_block_data(b);
++      struct btree_node *n = dm_block_data(b);
+       struct node_header *h = &n->header;
+       h->blocknr = cpu_to_le64(dm_block_location(b));
+@@ -38,7 +38,7 @@ static int node_check(struct dm_block_va
+                     struct dm_block *b,
+                     size_t block_size)
+ {
+-      struct node *n = dm_block_data(b);
++      struct btree_node *n = dm_block_data(b);
+       struct node_header *h = &n->header;
+       size_t value_size;
+       __le32 csum_disk;
+@@ -164,7 +164,7 @@ int ro_step(struct ro_spine *s, dm_block
+       return r;
+ }
+-struct node *ro_node(struct ro_spine *s)
++struct btree_node *ro_node(struct ro_spine *s)
+ {
+       struct dm_block *block;
+--- a/drivers/md/persistent-data/dm-btree.c
++++ b/drivers/md/persistent-data/dm-btree.c
+@@ -38,7 +38,7 @@ static void array_insert(void *base, siz
+ /*----------------------------------------------------------------*/
+ /* makes the assumption that no two keys are the same. */
+-static int bsearch(struct node *n, uint64_t key, int want_hi)
++static int bsearch(struct btree_node *n, uint64_t key, int want_hi)
+ {
+       int lo = -1, hi = le32_to_cpu(n->header.nr_entries);
+@@ -58,12 +58,12 @@ static int bsearch(struct node *n, uint6
+       return want_hi ? hi : lo;
+ }
+-int lower_bound(struct node *n, uint64_t key)
++int lower_bound(struct btree_node *n, uint64_t key)
+ {
+       return bsearch(n, key, 0);
+ }
+-void inc_children(struct dm_transaction_manager *tm, struct node *n,
++void inc_children(struct dm_transaction_manager *tm, struct btree_node *n,
+                 struct dm_btree_value_type *vt)
+ {
+       unsigned i;
+@@ -77,7 +77,7 @@ void inc_children(struct dm_transaction_
+                       vt->inc(vt->context, value_ptr(n, i));
+ }
+-static int insert_at(size_t value_size, struct node *node, unsigned index,
++static int insert_at(size_t value_size, struct btree_node *node, unsigned index,
+                     uint64_t key, void *value)
+                     __dm_written_to_disk(value)
+ {
+@@ -122,7 +122,7 @@ int dm_btree_empty(struct dm_btree_info
+ {
+       int r;
+       struct dm_block *b;
+-      struct node *n;
++      struct btree_node *n;
+       size_t block_size;
+       uint32_t max_entries;
+@@ -154,7 +154,7 @@ EXPORT_SYMBOL_GPL(dm_btree_empty);
+ #define MAX_SPINE_DEPTH 64
+ struct frame {
+       struct dm_block *b;
+-      struct node *n;
++      struct btree_node *n;
+       unsigned level;
+       unsigned nr_children;
+       unsigned current_child;
+@@ -295,7 +295,7 @@ EXPORT_SYMBOL_GPL(dm_btree_del);
+ /*----------------------------------------------------------------*/
+ static int btree_lookup_raw(struct ro_spine *s, dm_block_t block, uint64_t key,
+-                          int (*search_fn)(struct node *, uint64_t),
++                          int (*search_fn)(struct btree_node *, uint64_t),
+                           uint64_t *result_key, void *v, size_t value_size)
+ {
+       int i, r;
+@@ -406,7 +406,7 @@ static int btree_split_sibling(struct sh
+       size_t size;
+       unsigned nr_left, nr_right;
+       struct dm_block *left, *right, *parent;
+-      struct node *ln, *rn, *pn;
++      struct btree_node *ln, *rn, *pn;
+       __le64 location;
+       left = shadow_current(s);
+@@ -491,7 +491,7 @@ static int btree_split_beneath(struct sh
+       size_t size;
+       unsigned nr_left, nr_right;
+       struct dm_block *left, *right, *new_parent;
+-      struct node *pn, *ln, *rn;
++      struct btree_node *pn, *ln, *rn;
+       __le64 val;
+       new_parent = shadow_current(s);
+@@ -576,7 +576,7 @@ static int btree_insert_raw(struct shado
+                           uint64_t key, unsigned *index)
+ {
+       int r, i = *index, top = 1;
+-      struct node *node;
++      struct btree_node *node;
+       for (;;) {
+               r = shadow_step(s, root, vt);
+@@ -643,7 +643,7 @@ static int insert(struct dm_btree_info *
+       unsigned level, index = -1, last_level = info->levels - 1;
+       dm_block_t block = root;
+       struct shadow_spine spine;
+-      struct node *n;
++      struct btree_node *n;
+       struct dm_btree_value_type le64_type;
+       le64_type.context = NULL;
diff --git a/queue-3.4/rdma-nes-fix-for-crash-when-registering-zero-length-mr-for-cq.patch b/queue-3.4/rdma-nes-fix-for-crash-when-registering-zero-length-mr-for-cq.patch
new file mode 100644 (file)
index 0000000..a050d6d
--- /dev/null
@@ -0,0 +1,32 @@
+From 7d9c199a55200c9b9fcad08e150470d02fb385be Mon Sep 17 00:00:00 2001
+From: Tatyana Nikolova <Tatyana.E.Nikolova@intel.com>
+Date: Thu, 6 Dec 2012 20:05:02 +0000
+Subject: RDMA/nes: Fix for crash when registering zero length MR for CQ
+
+From: Tatyana Nikolova <Tatyana.E.Nikolova@intel.com>
+
+commit 7d9c199a55200c9b9fcad08e150470d02fb385be upstream.
+
+Signed-off-by: Tatyana Nikolova <Tatyana.E.Nikolova@intel.com>
+Signed-off-by: Roland Dreier <roland@purestorage.com>
+Signed-off-by: CAI Qian <caiqian@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/infiniband/hw/nes/nes_verbs.c |    5 +++++
+ 1 file changed, 5 insertions(+)
+
+--- a/drivers/infiniband/hw/nes/nes_verbs.c
++++ b/drivers/infiniband/hw/nes/nes_verbs.c
+@@ -2559,6 +2559,11 @@ static struct ib_mr *nes_reg_user_mr(str
+                       return ibmr;
+               case IWNES_MEMREG_TYPE_QP:
+               case IWNES_MEMREG_TYPE_CQ:
++                      if (!region->length) {
++                              nes_debug(NES_DBG_MR, "Unable to register zero length region for CQ\n");
++                              ib_umem_release(region);
++                              return ERR_PTR(-EINVAL);
++                      }
+                       nespbl = kzalloc(sizeof(*nespbl), GFP_KERNEL);
+                       if (!nespbl) {
+                               nes_debug(NES_DBG_MR, "Unable to allocate PBL\n");
diff --git a/queue-3.4/rdma-nes-fix-for-terminate-timer-crash.patch b/queue-3.4/rdma-nes-fix-for-terminate-timer-crash.patch
new file mode 100644 (file)
index 0000000..351af10
--- /dev/null
@@ -0,0 +1,84 @@
+From 7bfcfa51c35cdd2d37e0d70fc11790642dd11fb3 Mon Sep 17 00:00:00 2001
+From: Tatyana Nikolova <Tatyana.E.Nikolova@intel.com>
+Date: Thu, 6 Dec 2012 19:58:27 +0000
+Subject: RDMA/nes: Fix for terminate timer crash
+
+From: Tatyana Nikolova <Tatyana.E.Nikolova@intel.com>
+
+commit 7bfcfa51c35cdd2d37e0d70fc11790642dd11fb3 upstream.
+
+The terminate timer needs to be initialized just once.
+
+Signed-off-by: Tatyana Nikolova <Tatyana.E.Nikolova@intel.com>
+Signed-off-by: Roland Dreier <roland@purestorage.com>
+Signed-off-by: CAI Qian <caiqian@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/infiniband/hw/nes/nes.h       |    1 +
+ drivers/infiniband/hw/nes/nes_hw.c    |    9 ++-------
+ drivers/infiniband/hw/nes/nes_verbs.c |    4 +++-
+ 3 files changed, 6 insertions(+), 8 deletions(-)
+
+--- a/drivers/infiniband/hw/nes/nes.h
++++ b/drivers/infiniband/hw/nes/nes.h
+@@ -524,6 +524,7 @@ void nes_iwarp_ce_handler(struct nes_dev
+ int nes_destroy_cqp(struct nes_device *);
+ int nes_nic_cm_xmit(struct sk_buff *, struct net_device *);
+ void nes_recheck_link_status(struct work_struct *work);
++void nes_terminate_timeout(unsigned long context);
+ /* nes_nic.c */
+ struct net_device *nes_netdev_init(struct nes_device *, void __iomem *);
+--- a/drivers/infiniband/hw/nes/nes_hw.c
++++ b/drivers/infiniband/hw/nes/nes_hw.c
+@@ -75,7 +75,6 @@ static void nes_process_iwarp_aeqe(struc
+ static void process_critical_error(struct nes_device *nesdev);
+ static void nes_process_mac_intr(struct nes_device *nesdev, u32 mac_number);
+ static unsigned int nes_reset_adapter_ne020(struct nes_device *nesdev, u8 *OneG_Mode);
+-static void nes_terminate_timeout(unsigned long context);
+ static void nes_terminate_start_timer(struct nes_qp *nesqp);
+ #ifdef CONFIG_INFINIBAND_NES_DEBUG
+@@ -3522,7 +3521,7 @@ static void nes_terminate_received(struc
+ }
+ /* Timeout routine in case terminate fails to complete */
+-static void nes_terminate_timeout(unsigned long context)
++void nes_terminate_timeout(unsigned long context)
+ {
+       struct nes_qp *nesqp = (struct nes_qp *)(unsigned long)context;
+@@ -3532,11 +3531,7 @@ static void nes_terminate_timeout(unsign
+ /* Set a timer in case hw cannot complete the terminate sequence */
+ static void nes_terminate_start_timer(struct nes_qp *nesqp)
+ {
+-      init_timer(&nesqp->terminate_timer);
+-      nesqp->terminate_timer.function = nes_terminate_timeout;
+-      nesqp->terminate_timer.expires = jiffies + HZ;
+-      nesqp->terminate_timer.data = (unsigned long)nesqp;
+-      add_timer(&nesqp->terminate_timer);
++      mod_timer(&nesqp->terminate_timer, (jiffies + HZ));
+ }
+ /**
+--- a/drivers/infiniband/hw/nes/nes_verbs.c
++++ b/drivers/infiniband/hw/nes/nes_verbs.c
+@@ -1404,6 +1404,9 @@ static struct ib_qp *nes_create_qp(struc
+       }
+       nesqp->sig_all = (init_attr->sq_sig_type == IB_SIGNAL_ALL_WR);
++      init_timer(&nesqp->terminate_timer);
++      nesqp->terminate_timer.function = nes_terminate_timeout;
++      nesqp->terminate_timer.data = (unsigned long)nesqp;
+       /* update the QP table */
+       nesdev->nesadapter->qp_table[nesqp->hwqp.qp_id-NES_FIRST_QPN] = nesqp;
+@@ -1413,7 +1416,6 @@ static struct ib_qp *nes_create_qp(struc
+       return &nesqp->ibqp;
+ }
+-
+ /**
+  * nes_clean_cq
+  */
diff --git a/queue-3.4/ring-buffer-fix-race-between-integrity-check-and-readers.patch b/queue-3.4/ring-buffer-fix-race-between-integrity-check-and-readers.patch
new file mode 100644 (file)
index 0000000..ffaae64
--- /dev/null
@@ -0,0 +1,65 @@
+From 9366c1ba13fbc41bdb57702e75ca4382f209c82f Mon Sep 17 00:00:00 2001
+From: Steven Rostedt <srostedt@redhat.com>
+Date: Thu, 29 Nov 2012 22:31:16 -0500
+Subject: ring-buffer: Fix race between integrity check and readers
+
+From: Steven Rostedt <srostedt@redhat.com>
+
+commit 9366c1ba13fbc41bdb57702e75ca4382f209c82f upstream.
+
+The function rb_check_pages() was added to make sure the ring buffer's
+pages were sane. This check is done when the ring buffer size is modified
+as well as when the iterator is released (closing the "trace" file),
+as that was considered a non fast path and a good place to do a sanity
+check.
+
+The problem is that the check does not have any locks around it.
+If one process were to read the trace file, and another were to read
+the raw binary file, the check could happen while the reader is reading
+the file.
+
+The issues with this is that the check requires to clear the HEAD page
+before doing the full check and it restores it afterward. But readers
+require the HEAD page to exist before it can read the buffer, otherwise
+it gives a nasty warning and disables the buffer.
+
+By adding the reader lock around the check, this keeps the race from
+happening.
+
+Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ kernel/trace/ring_buffer.c |    7 +++++--
+ 1 file changed, 5 insertions(+), 2 deletions(-)
+
+--- a/kernel/trace/ring_buffer.c
++++ b/kernel/trace/ring_buffer.c
+@@ -2708,7 +2708,7 @@ unsigned long ring_buffer_oldest_event_t
+       unsigned long flags;
+       struct ring_buffer_per_cpu *cpu_buffer;
+       struct buffer_page *bpage;
+-      unsigned long ret;
++      unsigned long ret = 0;
+       if (!cpumask_test_cpu(cpu, buffer->cpumask))
+               return 0;
+@@ -2723,7 +2723,8 @@ unsigned long ring_buffer_oldest_event_t
+               bpage = cpu_buffer->reader_page;
+       else
+               bpage = rb_set_head_page(cpu_buffer);
+-      ret = bpage->page->time_stamp;
++      if (bpage)
++              ret = bpage->page->time_stamp;
+       raw_spin_unlock_irqrestore(&cpu_buffer->reader_lock, flags);
+       return ret;
+@@ -3030,6 +3031,8 @@ rb_get_reader_page(struct ring_buffer_pe
+        * Splice the empty reader page into the list around the head.
+        */
+       reader = rb_set_head_page(cpu_buffer);
++      if (!reader)
++              goto out;
+       cpu_buffer->reader_page->list.next = rb_list_head(reader->list.next);
+       cpu_buffer->reader_page->list.prev = reader->list.prev;
index bbdb155a30957d312d0088c9c02b56902362885c..b90ab8acac2ffb0bafe4ee2837517d01a44647d8 100644 (file)
@@ -40,3 +40,8 @@ drm-radeon-add-wait_until-to-evergreen-vm-safe-reg-list.patch
 drm-radeon-properly-handle-ddc-probe-for-dp-bridges.patch
 drm-i915-make-the-panel-fitter-work-on-pipes-b-and-c-on-ivb.patch
 sunrpc-fix-validity-issues-with-rpc_pipefs-sb-s_fs_info.patch
+rdma-nes-fix-for-crash-when-registering-zero-length-mr-for-cq.patch
+rdma-nes-fix-for-terminate-timer-crash.patch
+ring-buffer-fix-race-between-integrity-check-and-readers.patch
+dm-persistent-data-rename-node-to-btree_node.patch
+dm-ioctl-prevent-unsafe-change-to-dm_ioctl-data_size.patch