]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
more .32 patches
authorGreg Kroah-Hartman <gregkh@suse.de>
Wed, 3 Feb 2010 04:49:18 +0000 (20:49 -0800)
committerGreg Kroah-Hartman <gregkh@suse.de>
Wed, 3 Feb 2010 04:49:18 +0000 (20:49 -0800)
queue-2.6.32/be2net-bug-fix-to-support-newer-generation-of-be-asic.patch [new file with mode: 0644]
queue-2.6.32/be2net-fix-memset-arg-ordering.patch [new file with mode: 0644]
queue-2.6.32/connector-delete-buggy-notification-code.patch [new file with mode: 0644]
queue-2.6.32/idr-fix-a-critical-misallocation-bug.patch [new file with mode: 0644]
queue-2.6.32/mac80211-fix-null-pointer-dereference-when-ftrace-is-enabled.patch [new file with mode: 0644]
queue-2.6.32/mm-flush-dcache-before-writing-into-page-to-avoid-alias.patch [new file with mode: 0644]
queue-2.6.32/series

diff --git a/queue-2.6.32/be2net-bug-fix-to-support-newer-generation-of-be-asic.patch b/queue-2.6.32/be2net-bug-fix-to-support-newer-generation-of-be-asic.patch
new file mode 100644 (file)
index 0000000..6a86a65
--- /dev/null
@@ -0,0 +1,104 @@
+From 7b139c83c590d4965259aad8889cbb08104b2891 Mon Sep 17 00:00:00 2001
+From: Ajit Khaparde <ajitk@serverengines.com>
+Date: Wed, 27 Jan 2010 21:56:44 +0000
+Subject: be2net: Bug fix to support newer generation of BE ASIC
+
+From: Ajit Khaparde <ajitk@serverengines.com>
+
+commit 7b139c83c590d4965259aad8889cbb08104b2891 upstream.
+
+Bug fix in be2net for newer generation of BladeEngine ASIC.
+
+Signed-off-by: Ajit Khaparde <ajitk@serverengines.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/net/benet/be.h      |    5 +++++
+ drivers/net/benet/be_cmds.h |    3 ++-
+ drivers/net/benet/be_main.c |   25 +++++++++++++++++++++++--
+ 3 files changed, 30 insertions(+), 3 deletions(-)
+
+--- a/drivers/net/benet/be.h
++++ b/drivers/net/benet/be.h
+@@ -272,8 +272,13 @@ struct be_adapter {
+       u32 cap;
+       u32 rx_fc;              /* Rx flow control */
+       u32 tx_fc;              /* Tx flow control */
++      u8 generation;          /* BladeEngine ASIC generation */
+ };
++/* BladeEngine Generation numbers */
++#define BE_GEN2 2
++#define BE_GEN3 3
++
+ extern const struct ethtool_ops be_ethtool_ops;
+ #define drvr_stats(adapter)           (&adapter->stats.drvr_stats)
+--- a/drivers/net/benet/be_cmds.h
++++ b/drivers/net/benet/be_cmds.h
+@@ -154,7 +154,8 @@ struct be_cmd_req_hdr {
+       u8 domain;              /* dword 0 */
+       u32 timeout;            /* dword 1 */
+       u32 request_length;     /* dword 2 */
+-      u32 rsvd;               /* dword 3 */
++      u8 version;             /* dword 3 */
++      u8 rsvd[3];             /* dword 3 */
+ };
+ #define RESP_HDR_INFO_OPCODE_SHIFT    0       /* bits 0 - 7 */
+--- a/drivers/net/benet/be_main.c
++++ b/drivers/net/benet/be_main.c
+@@ -1944,6 +1944,7 @@ static void be_unmap_pci_bars(struct be_
+ static int be_map_pci_bars(struct be_adapter *adapter)
+ {
+       u8 __iomem *addr;
++      int pcicfg_reg;
+       addr = ioremap_nocache(pci_resource_start(adapter->pdev, 2),
+                       pci_resource_len(adapter->pdev, 2));
+@@ -1957,8 +1958,13 @@ static int be_map_pci_bars(struct be_ada
+               goto pci_map_err;
+       adapter->db = addr;
+-      addr = ioremap_nocache(pci_resource_start(adapter->pdev, 1),
+-                      pci_resource_len(adapter->pdev, 1));
++      if (adapter->generation == BE_GEN2)
++              pcicfg_reg = 1;
++      else
++              pcicfg_reg = 0;
++
++      addr = ioremap_nocache(pci_resource_start(adapter->pdev, pcicfg_reg),
++                      pci_resource_len(adapter->pdev, pcicfg_reg));
+       if (addr == NULL)
+               goto pci_map_err;
+       adapter->pcicfg = addr;
+@@ -2028,6 +2034,7 @@ static int be_stats_init(struct be_adapt
+       cmd->va = pci_alloc_consistent(adapter->pdev, cmd->size, &cmd->dma);
+       if (cmd->va == NULL)
+               return -1;
++      memset(cmd->va, cmd->size, 0);
+       return 0;
+ }
+@@ -2101,6 +2108,20 @@ static int __devinit be_probe(struct pci
+               goto rel_reg;
+       }
+       adapter = netdev_priv(netdev);
++
++      switch (pdev->device) {
++      case BE_DEVICE_ID1:
++      case OC_DEVICE_ID1:
++              adapter->generation = BE_GEN2;
++              break;
++      case BE_DEVICE_ID2:
++      case OC_DEVICE_ID2:
++              adapter->generation = BE_GEN3;
++              break;
++      default:
++              adapter->generation = 0;
++      }
++
+       adapter->pdev = pdev;
+       pci_set_drvdata(pdev, adapter);
+       adapter->netdev = netdev;
diff --git a/queue-2.6.32/be2net-fix-memset-arg-ordering.patch b/queue-2.6.32/be2net-fix-memset-arg-ordering.patch
new file mode 100644 (file)
index 0000000..e57cf81
--- /dev/null
@@ -0,0 +1,29 @@
+From d291b9af1a1a12f59a464494900c6e0db26e2ec3 Mon Sep 17 00:00:00 2001
+From: David S. Miller <davem@davemloft.net>
+Date: Thu, 28 Jan 2010 21:36:21 -0800
+Subject: be2net: Fix memset() arg ordering.
+
+From: David S. Miller <davem@davemloft.net>
+
+commit d291b9af1a1a12f59a464494900c6e0db26e2ec3 upstream.
+
+Noticed by Ben Hutchings.
+
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/net/benet/be_main.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/net/benet/be_main.c
++++ b/drivers/net/benet/be_main.c
+@@ -2034,7 +2034,7 @@ static int be_stats_init(struct be_adapt
+       cmd->va = pci_alloc_consistent(adapter->pdev, cmd->size, &cmd->dma);
+       if (cmd->va == NULL)
+               return -1;
+-      memset(cmd->va, cmd->size, 0);
++      memset(cmd->va, 0, cmd->size);
+       return 0;
+ }
diff --git a/queue-2.6.32/connector-delete-buggy-notification-code.patch b/queue-2.6.32/connector-delete-buggy-notification-code.patch
new file mode 100644 (file)
index 0000000..55b0793
--- /dev/null
@@ -0,0 +1,326 @@
+From f98bfbd78c37c5946cc53089da32a5f741efdeb7 Mon Sep 17 00:00:00 2001
+From: Evgeniy Polyakov <zbr@ioremap.net>
+Date: Tue, 2 Feb 2010 15:58:48 -0800
+Subject: connector: Delete buggy notification code.
+
+From: Evgeniy Polyakov <zbr@ioremap.net>
+
+commit f98bfbd78c37c5946cc53089da32a5f741efdeb7 upstream.
+
+On Tue, Feb 02, 2010 at 02:57:14PM -0800, Greg KH (gregkh@suse.de) wrote:
+> > There are at least two ways to fix it: using a big cannon and a small
+> > one. The former way is to disable notification registration, since it is
+> > not used by anyone at all. Second way is to check whether calling
+> > process is root and its destination group is -1 (kind of priveledged
+> > one) before command is dispatched to workqueue.
+>
+> Well if no one is using it, removing it makes the most sense, right?
+>
+> No objection from me, care to make up a patch either way for this?
+
+Getting it is not used, let's drop support for notifications about
+(un)registered events from connector.
+Another option was to check credentials on receiving, but we can always
+restore it without bugs if needed, but genetlink has a wider code base
+and none complained, that userspace can not get notification when some
+other clients were (un)registered.
+
+Kudos for Sebastian Krahmer <krahmer@suse.de>, who found a bug in the
+code.
+
+Signed-off-by: Evgeniy Polyakov <zbr@ioremap.net>
+Acked-by: Greg Kroah-Hartman <gregkh@suse.de>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/connector/connector.c |  175 ------------------------------------------
+ include/linux/connector.h     |   32 -------
+ 2 files changed, 207 deletions(-)
+
+--- a/drivers/connector/connector.c
++++ b/drivers/connector/connector.c
+@@ -36,17 +36,6 @@ MODULE_LICENSE("GPL");
+ MODULE_AUTHOR("Evgeniy Polyakov <zbr@ioremap.net>");
+ MODULE_DESCRIPTION("Generic userspace <-> kernelspace connector.");
+-static u32 cn_idx = CN_IDX_CONNECTOR;
+-static u32 cn_val = CN_VAL_CONNECTOR;
+-
+-module_param(cn_idx, uint, 0);
+-module_param(cn_val, uint, 0);
+-MODULE_PARM_DESC(cn_idx, "Connector's main device idx.");
+-MODULE_PARM_DESC(cn_val, "Connector's main device val.");
+-
+-static DEFINE_MUTEX(notify_lock);
+-static LIST_HEAD(notify_list);
+-
+ static struct cn_dev cdev;
+ static int cn_already_initialized;
+@@ -210,54 +199,6 @@ static void cn_rx_skb(struct sk_buff *__
+ }
+ /*
+- * Notification routing.
+- *
+- * Gets id and checks if there are notification request for it's idx
+- * and val.  If there are such requests notify the listeners with the
+- * given notify event.
+- *
+- */
+-static void cn_notify(struct cb_id *id, u32 notify_event)
+-{
+-      struct cn_ctl_entry *ent;
+-
+-      mutex_lock(&notify_lock);
+-      list_for_each_entry(ent, &notify_list, notify_entry) {
+-              int i;
+-              struct cn_notify_req *req;
+-              struct cn_ctl_msg *ctl = ent->msg;
+-              int idx_found, val_found;
+-
+-              idx_found = val_found = 0;
+-
+-              req = (struct cn_notify_req *)ctl->data;
+-              for (i = 0; i < ctl->idx_notify_num; ++i, ++req) {
+-                      if (id->idx >= req->first &&
+-                                      id->idx < req->first + req->range) {
+-                              idx_found = 1;
+-                              break;
+-                      }
+-              }
+-
+-              for (i = 0; i < ctl->val_notify_num; ++i, ++req) {
+-                      if (id->val >= req->first &&
+-                                      id->val < req->first + req->range) {
+-                              val_found = 1;
+-                              break;
+-                      }
+-              }
+-
+-              if (idx_found && val_found) {
+-                      struct cn_msg m = { .ack = notify_event, };
+-
+-                      memcpy(&m.id, id, sizeof(m.id));
+-                      cn_netlink_send(&m, ctl->group, GFP_KERNEL);
+-              }
+-      }
+-      mutex_unlock(&notify_lock);
+-}
+-
+-/*
+  * Callback add routing - adds callback with given ID and name.
+  * If there is registered callback with the same ID it will not be added.
+  *
+@@ -276,8 +217,6 @@ int cn_add_callback(struct cb_id *id, ch
+       if (err)
+               return err;
+-      cn_notify(id, 0);
+-
+       return 0;
+ }
+ EXPORT_SYMBOL_GPL(cn_add_callback);
+@@ -295,111 +234,9 @@ void cn_del_callback(struct cb_id *id)
+       struct cn_dev *dev = &cdev;
+       cn_queue_del_callback(dev->cbdev, id);
+-      cn_notify(id, 1);
+ }
+ EXPORT_SYMBOL_GPL(cn_del_callback);
+-/*
+- * Checks two connector's control messages to be the same.
+- * Returns 1 if they are the same or if the first one is corrupted.
+- */
+-static int cn_ctl_msg_equals(struct cn_ctl_msg *m1, struct cn_ctl_msg *m2)
+-{
+-      int i;
+-      struct cn_notify_req *req1, *req2;
+-
+-      if (m1->idx_notify_num != m2->idx_notify_num)
+-              return 0;
+-
+-      if (m1->val_notify_num != m2->val_notify_num)
+-              return 0;
+-
+-      if (m1->len != m2->len)
+-              return 0;
+-
+-      if ((m1->idx_notify_num + m1->val_notify_num) * sizeof(*req1) !=
+-          m1->len)
+-              return 1;
+-
+-      req1 = (struct cn_notify_req *)m1->data;
+-      req2 = (struct cn_notify_req *)m2->data;
+-
+-      for (i = 0; i < m1->idx_notify_num; ++i) {
+-              if (req1->first != req2->first || req1->range != req2->range)
+-                      return 0;
+-              req1++;
+-              req2++;
+-      }
+-
+-      for (i = 0; i < m1->val_notify_num; ++i) {
+-              if (req1->first != req2->first || req1->range != req2->range)
+-                      return 0;
+-              req1++;
+-              req2++;
+-      }
+-
+-      return 1;
+-}
+-
+-/*
+- * Main connector device's callback.
+- *
+- * Used for notification of a request's processing.
+- */
+-static void cn_callback(struct cn_msg *msg, struct netlink_skb_parms *nsp)
+-{
+-      struct cn_ctl_msg *ctl;
+-      struct cn_ctl_entry *ent;
+-      u32 size;
+-
+-      if (msg->len < sizeof(*ctl))
+-              return;
+-
+-      ctl = (struct cn_ctl_msg *)msg->data;
+-
+-      size = (sizeof(*ctl) + ((ctl->idx_notify_num +
+-                               ctl->val_notify_num) *
+-                              sizeof(struct cn_notify_req)));
+-
+-      if (msg->len != size)
+-              return;
+-
+-      if (ctl->len + sizeof(*ctl) != msg->len)
+-              return;
+-
+-      /*
+-       * Remove notification.
+-       */
+-      if (ctl->group == 0) {
+-              struct cn_ctl_entry *n;
+-
+-              mutex_lock(&notify_lock);
+-              list_for_each_entry_safe(ent, n, &notify_list, notify_entry) {
+-                      if (cn_ctl_msg_equals(ent->msg, ctl)) {
+-                              list_del(&ent->notify_entry);
+-                              kfree(ent);
+-                      }
+-              }
+-              mutex_unlock(&notify_lock);
+-
+-              return;
+-      }
+-
+-      size += sizeof(*ent);
+-
+-      ent = kzalloc(size, GFP_KERNEL);
+-      if (!ent)
+-              return;
+-
+-      ent->msg = (struct cn_ctl_msg *)(ent + 1);
+-
+-      memcpy(ent->msg, ctl, size - sizeof(*ent));
+-
+-      mutex_lock(&notify_lock);
+-      list_add(&ent->notify_entry, &notify_list);
+-      mutex_unlock(&notify_lock);
+-}
+-
+ static int cn_proc_show(struct seq_file *m, void *v)
+ {
+       struct cn_queue_dev *dev = cdev.cbdev;
+@@ -437,11 +274,8 @@ static const struct file_operations cn_f
+ static int __devinit cn_init(void)
+ {
+       struct cn_dev *dev = &cdev;
+-      int err;
+       dev->input = cn_rx_skb;
+-      dev->id.idx = cn_idx;
+-      dev->id.val = cn_val;
+       dev->nls = netlink_kernel_create(&init_net, NETLINK_CONNECTOR,
+                                        CN_NETLINK_USERS + 0xf,
+@@ -457,14 +291,6 @@ static int __devinit cn_init(void)
+       cn_already_initialized = 1;
+-      err = cn_add_callback(&dev->id, "connector", &cn_callback);
+-      if (err) {
+-              cn_already_initialized = 0;
+-              cn_queue_free_dev(dev->cbdev);
+-              netlink_kernel_release(dev->nls);
+-              return -EINVAL;
+-      }
+-
+       proc_net_fops_create(&init_net, "connector", S_IRUGO, &cn_file_ops);
+       return 0;
+@@ -478,7 +304,6 @@ static void __devexit cn_fini(void)
+       proc_net_remove(&init_net, "connector");
+-      cn_del_callback(&dev->id);
+       cn_queue_free_dev(dev->cbdev);
+       netlink_kernel_release(dev->nls);
+ }
+--- a/include/linux/connector.h
++++ b/include/linux/connector.h
+@@ -24,9 +24,6 @@
+ #include <linux/types.h>
+-#define CN_IDX_CONNECTOR              0xffffffff
+-#define CN_VAL_CONNECTOR              0xffffffff
+-
+ /*
+  * Process Events connector unique ids -- used for message routing
+  */
+@@ -73,30 +70,6 @@ struct cn_msg {
+       __u8 data[0];
+ };
+-/*
+- * Notify structure - requests notification about
+- * registering/unregistering idx/val in range [first, first+range].
+- */
+-struct cn_notify_req {
+-      __u32 first;
+-      __u32 range;
+-};
+-
+-/*
+- * Main notification control message
+- * *_notify_num       - number of appropriate cn_notify_req structures after 
+- *                            this struct.
+- * group              - notification receiver's idx.
+- * len                        - total length of the attached data.
+- */
+-struct cn_ctl_msg {
+-      __u32 idx_notify_num;
+-      __u32 val_notify_num;
+-      __u32 group;
+-      __u32 len;
+-      __u8 data[0];
+-};
+-
+ #ifdef __KERNEL__
+ #include <asm/atomic.h>
+@@ -149,11 +122,6 @@ struct cn_callback_entry {
+       u32 seq, group;
+ };
+-struct cn_ctl_entry {
+-      struct list_head notify_entry;
+-      struct cn_ctl_msg *msg;
+-};
+-
+ struct cn_dev {
+       struct cb_id id;
diff --git a/queue-2.6.32/idr-fix-a-critical-misallocation-bug.patch b/queue-2.6.32/idr-fix-a-critical-misallocation-bug.patch
new file mode 100644 (file)
index 0000000..d02e310
--- /dev/null
@@ -0,0 +1,148 @@
+From 859ddf09743a8cc680af33f7259ccd0fd36bfe9d Mon Sep 17 00:00:00 2001
+From: Tejun Heo <tj@kernel.org>
+Date: Tue, 2 Feb 2010 13:43:58 -0800
+Subject: idr: fix a critical misallocation bug
+
+From: Tejun Heo <tj@kernel.org>
+
+commit 859ddf09743a8cc680af33f7259ccd0fd36bfe9d upstream.
+
+Eric Paris located a bug in idr.  With IDR_BITS of 6, it grows to three
+layers when id 4096 is first allocated.  When that happens, idr wraps
+incorrectly and searches the idr array ignoring the high bits.  The
+following test code from Eric demonstrates the bug nicely.
+
+#include <linux/idr.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+
+static DEFINE_IDR(test_idr);
+
+int init_module(void)
+{
+       int ret, forty95, forty96;
+       void *addr;
+
+       /* add 2 entries both with 4095 as the start address */
+again1:
+       if (!idr_pre_get(&test_idr, GFP_KERNEL))
+               return -ENOMEM;
+       ret = idr_get_new_above(&test_idr, (void *)4095, 4095, &forty95);
+       if (ret) {
+               if (ret == -EAGAIN)
+                       goto again1;
+               return ret;
+       }
+       if (forty95 != 4095)
+               printk(KERN_ERR "hmmm, forty95=%d\n", forty95);
+
+again2:
+       if (!idr_pre_get(&test_idr, GFP_KERNEL))
+               return -ENOMEM;
+       ret = idr_get_new_above(&test_idr, (void *)4096, 4095, &forty96);
+       if (ret) {
+               if (ret == -EAGAIN)
+                       goto again2;
+               return ret;
+       }
+       if (forty96 != 4096)
+               printk(KERN_ERR "hmmm, forty96=%d\n", forty96);
+
+       /* try to find the 2 entries, noticing that 4096 broke */
+       addr = idr_find(&test_idr, forty95);
+       if ((int)addr != forty95)
+               printk(KERN_ERR "hmmm, after find forty95=%d addr=%d\n", forty95, (int)addr);
+       addr = idr_find(&test_idr, forty96);
+       if ((int)addr != forty96)
+               printk(KERN_ERR "hmmm, after find forty96=%d addr=%d\n", forty96, (int)addr);
+       /* really weird, the entry which should be at 4096 is actually at 0!! */
+       addr = idr_find(&test_idr, 0);
+       if ((int)addr)
+               printk(KERN_ERR "found an entry at id=0 for addr=%d\n", (int)addr);
+
+       idr_remove(&test_idr, forty95);
+       idr_remove(&test_idr, forty96);
+
+       return 0;
+}
+
+void cleanup_module(void)
+{
+}
+
+MODULE_AUTHOR("Eric Paris <eparis@redhat.com>");
+MODULE_DESCRIPTION("Simple idr test");
+MODULE_LICENSE("GPL");
+
+This happens because when sub_alloc() back tracks it doesn't always do it
+step-by-step while the over-the-limit detection assumes step-by-step
+backtracking.  The logic in sub_alloc() looks like the following.
+
+  restart:
+    clear pa[top level + 1] for end cond detection
+    l = top level
+    while (true) {
+       search for empty slot at this level
+       if (not found) {
+           push id to the next possible value
+           l++
+A:         if (pa[l] is clear)
+               failed, return asking caller to grow the tree
+           if (going up 1 level gives more slots to search)
+               continue the while loop above with the incremented l
+           else
+C:             goto restart
+       }
+       adjust id accordingly to the found slot
+       if (l == 0)
+           return found id;
+       create lower level if not there yet
+       record pa[l] and l--
+    }
+
+Test A is the fail exit condition but this assumes that failure is
+propagated upwared one level at a time but the B optimization path breaks
+the assumption and restarts the whole thing with a start value which is
+above the possible limit with the current layers.  sub_alloc() assumes the
+start id value is inside the limit when called and test A is the only exit
+condition check, so it ends up searching for empty slot while ignoring
+high set bit.
+
+So, for 4095->4096 test, level0 search fails but pa[1] contains a valid
+pointer.  However, going up 1 level wouldn't give any more empty slot so
+it takes C and when the whole thing restarts nobody notices the high bit
+set beyond the top level.
+
+This patch fixes the bug by changing the fail exit condition check to full
+id limit check.
+
+Based-on-patch-from: Eric Paris <eparis@redhat.com>
+Reported-by: Eric Paris <eparis@redhat.com>
+Signed-off-by: Tejun Heo <tj@kernel.org>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+--- a/lib/idr.c
++++ b/lib/idr.c
+@@ -140,8 +140,7 @@ static int sub_alloc(struct idr *idp, int *starting_id, struct idr_layer **pa)
+       id = *starting_id;
+  restart:
+       p = idp->top;
+-      l = idp->layers;
+-      pa[l--] = NULL;
++      l = p->layer;
+       while (1) {
+               /*
+                * We run around this while until we reach the leaf node...
+@@ -155,8 +154,8 @@ static int sub_alloc(struct idr *idp, int *starting_id, struct idr_layer **pa)
+                       oid = id;
+                       id = (id | ((1 << (IDR_BITS * l)) - 1)) + 1;
+-                      /* if already at the top layer, we need to grow */
+-                      if (!(p = pa[l])) {
++                      /* did id go over the limit? */
++                      if (id >= (1 << (idp->layers * IDR_BITS))) {
+                               *starting_id = id;
+                               return IDR_NEED_TO_GROW;
+                       }
diff --git a/queue-2.6.32/mac80211-fix-null-pointer-dereference-when-ftrace-is-enabled.patch b/queue-2.6.32/mac80211-fix-null-pointer-dereference-when-ftrace-is-enabled.patch
new file mode 100644 (file)
index 0000000..8269ce5
--- /dev/null
@@ -0,0 +1,51 @@
+From 3092ad054406f069991ca561adc74f2d9fbb6867 Mon Sep 17 00:00:00 2001
+From: Zhu Yi <yi.zhu@intel.com>
+Date: Tue, 26 Jan 2010 15:58:57 +0800
+Subject: mac80211: fix NULL pointer dereference when ftrace is enabled
+
+From: Zhu Yi <yi.zhu@intel.com>
+
+commit 3092ad054406f069991ca561adc74f2d9fbb6867 upstream.
+
+I got below kernel oops when I try to bring down the network interface if
+ftrace is enabled. The root cause is drv_ampdu_action() is passed with a
+NULL ssn pointer in the BA session tear down case. We need to check and
+avoid dereferencing it in trace entry assignment.
+
+BUG: unable to handle kernel NULL pointer dereference
+Modules linked in: at (null)
+IP: [<f98fe02a>] ftrace_raw_event_drv_ampdu_action+0x10a/0x160 [mac80211]
+*pde = 00000000
+Oops: 0000 [#1] SMP DEBUG_PAGEALLOC
+[...]
+Call Trace:
+ [<f98fdf20>] ? ftrace_raw_event_drv_ampdu_action+0x0/0x160 [mac80211]
+ [<f98dac4c>] ? __ieee80211_stop_rx_ba_session+0xfc/0x220 [mac80211]
+ [<f98d97fb>] ? ieee80211_sta_tear_down_BA_sessions+0x3b/0x50 [mac80211]
+ [<f98dc6f6>] ? ieee80211_set_disassoc+0xe6/0x230 [mac80211]
+ [<f98dc6ac>] ? ieee80211_set_disassoc+0x9c/0x230 [mac80211]
+ [<f98dcbb8>] ? ieee80211_mgd_deauth+0x158/0x170 [mac80211]
+ [<f98e4bdb>] ? ieee80211_deauth+0x1b/0x20 [mac80211]
+ [<f8987f49>] ? __cfg80211_mlme_deauth+0xe9/0x120 [cfg80211]
+ [<f898b870>] ? __cfg80211_disconnect+0x170/0x1d0 [cfg80211]
+
+Cc: Johannes Berg <johannes@sipsolutions.net>
+Signed-off-by: Zhu Yi <yi.zhu@intel.com>
+Signed-off-by: John W. Linville <linville@tuxdriver.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ net/mac80211/driver-trace.h |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/net/mac80211/driver-trace.h
++++ b/net/mac80211/driver-trace.h
+@@ -655,7 +655,7 @@ TRACE_EVENT(drv_ampdu_action,
+               __entry->ret = ret;
+               __entry->action = action;
+               __entry->tid = tid;
+-              __entry->ssn = *ssn;
++              __entry->ssn = ssn ? *ssn : 0;
+       ),
+       TP_printk(
diff --git a/queue-2.6.32/mm-flush-dcache-before-writing-into-page-to-avoid-alias.patch b/queue-2.6.32/mm-flush-dcache-before-writing-into-page-to-avoid-alias.patch
new file mode 100644 (file)
index 0000000..2425327
--- /dev/null
@@ -0,0 +1,75 @@
+From 931e80e4b3263db75c8e34f078d22f11bbabd3a3 Mon Sep 17 00:00:00 2001
+From: anfei zhou <anfei.zhou@gmail.com>
+Date: Tue, 2 Feb 2010 13:44:02 -0800
+Subject: mm: flush dcache before writing into page to avoid alias
+
+From: anfei zhou <anfei.zhou@gmail.com>
+
+commit 931e80e4b3263db75c8e34f078d22f11bbabd3a3 upstream.
+
+The cache alias problem will happen if the changes of user shared mapping
+is not flushed before copying, then user and kernel mapping may be mapped
+into two different cache line, it is impossible to guarantee the coherence
+after iov_iter_copy_from_user_atomic.  So the right steps should be:
+
+       flush_dcache_page(page);
+       kmap_atomic(page);
+       write to page;
+       kunmap_atomic(page);
+       flush_dcache_page(page);
+
+More precisely, we might create two new APIs flush_dcache_user_page and
+flush_dcache_kern_page to replace the two flush_dcache_page accordingly.
+
+Here is a snippet tested on omap2430 with VIPT cache, and I think it is
+not ARM-specific:
+
+       int val = 0x11111111;
+       fd = open("abc", O_RDWR);
+       addr = mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
+       *(addr+0) = 0x44444444;
+       tmp = *(addr+0);
+       *(addr+1) = 0x77777777;
+       write(fd, &val, sizeof(int));
+       close(fd);
+
+The results are not always 0x11111111 0x77777777 at the beginning as expected.  Sometimes we see 0x44444444 0x77777777.
+
+Signed-off-by: Anfei <anfei.zhou@gmail.com>
+Cc: Russell King <rmk@arm.linux.org.uk>
+Cc: Miklos Szeredi <miklos@szeredi.hu>
+Cc: Nick Piggin <nickpiggin@yahoo.com.au>
+Cc: <linux-arch@vger.kernel.org>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ fs/fuse/file.c |    3 +++
+ mm/filemap.c   |    3 +++
+ 2 files changed, 6 insertions(+)
+
+--- a/fs/fuse/file.c
++++ b/fs/fuse/file.c
+@@ -828,6 +828,9 @@ static ssize_t fuse_fill_write_pages(str
+               if (!page)
+                       break;
++              if (mapping_writably_mapped(mapping))
++                      flush_dcache_page(page);
++
+               pagefault_disable();
+               tmp = iov_iter_copy_from_user_atomic(page, ii, offset, bytes);
+               pagefault_enable();
+--- a/mm/filemap.c
++++ b/mm/filemap.c
+@@ -2253,6 +2253,9 @@ again:
+               if (unlikely(status))
+                       break;
++              if (mapping_writably_mapped(mapping))
++                      flush_dcache_page(page);
++
+               pagefault_disable();
+               copied = iov_iter_copy_from_user_atomic(page, i, offset, bytes);
+               pagefault_enable();
index 01c70402d0bd395a0d19bb78b58653b6a6ebb93e..aef32fc1a4b8d98673bfebfd97420e8f15916a34 100644 (file)
@@ -58,3 +58,9 @@ random-drop-weird-m_time-a_time-manipulation.patch
 random-remove-unused-inode-variable.patch
 block-fix-bugs-in-bio-integrity-mempool-usage.patch
 usb-r8a66597-hdc-disable-interrupts-fix.patch
+connector-delete-buggy-notification-code.patch
+be2net-bug-fix-to-support-newer-generation-of-be-asic.patch
+be2net-fix-memset-arg-ordering.patch
+mm-flush-dcache-before-writing-into-page-to-avoid-alias.patch
+idr-fix-a-critical-misallocation-bug.patch
+mac80211-fix-null-pointer-dereference-when-ftrace-is-enabled.patch