]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
3.2-stable patches
authorGreg Kroah-Hartman <gregkh@suse.de>
Mon, 9 Jan 2012 19:40:59 +0000 (11:40 -0800)
committerGreg Kroah-Hartman <gregkh@suse.de>
Mon, 9 Jan 2012 19:40:59 +0000 (11:40 -0800)
added patches:
bcma-support-for-suspend-and-resume.patch
documentation-update-stable-address.patch
firmware-fix-an-oops-on-reading-fw_priv-fw-in-sysfs-loading-file.patch
libertas-clean-up-scan-thread-handling.patch
offb-fix-bug-in-calculating-requested-vram-size.patch
offb-fix-setting-of-the-pseudo-palette-for-8bpp.patch
powerpc-fix-unpaired-probe_hcall_entry-and-probe_hcall_exit.patch
powerpc-time-handle-wrapping-of-decrementer.patch
rt2800usb-move-id-out-of-unknown.patch
wl12xx-check-buffer-bound-when-processing-nvs-data.patch
wl12xx-restore-testmode-abi.patch
wl12xx-validate-fem-index-from-ini-file-and-fw.patch

13 files changed:
queue-3.2/bcma-support-for-suspend-and-resume.patch [new file with mode: 0644]
queue-3.2/documentation-update-stable-address.patch [new file with mode: 0644]
queue-3.2/firmware-fix-an-oops-on-reading-fw_priv-fw-in-sysfs-loading-file.patch [new file with mode: 0644]
queue-3.2/libertas-clean-up-scan-thread-handling.patch [new file with mode: 0644]
queue-3.2/offb-fix-bug-in-calculating-requested-vram-size.patch [new file with mode: 0644]
queue-3.2/offb-fix-setting-of-the-pseudo-palette-for-8bpp.patch [new file with mode: 0644]
queue-3.2/powerpc-fix-unpaired-probe_hcall_entry-and-probe_hcall_exit.patch [new file with mode: 0644]
queue-3.2/powerpc-time-handle-wrapping-of-decrementer.patch [new file with mode: 0644]
queue-3.2/rt2800usb-move-id-out-of-unknown.patch [new file with mode: 0644]
queue-3.2/series
queue-3.2/wl12xx-check-buffer-bound-when-processing-nvs-data.patch [new file with mode: 0644]
queue-3.2/wl12xx-restore-testmode-abi.patch [new file with mode: 0644]
queue-3.2/wl12xx-validate-fem-index-from-ini-file-and-fw.patch [new file with mode: 0644]

diff --git a/queue-3.2/bcma-support-for-suspend-and-resume.patch b/queue-3.2/bcma-support-for-suspend-and-resume.patch
new file mode 100644 (file)
index 0000000..34fe63b
--- /dev/null
@@ -0,0 +1,114 @@
+From 775ab52142b02237a54184238e922251c59a2b5c Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <zajec5@gmail.com>
+Date: Fri, 9 Dec 2011 22:16:07 +0100
+Subject: bcma: support for suspend and resume
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Rafał Miłecki <zajec5@gmail.com>
+
+commit 775ab52142b02237a54184238e922251c59a2b5c upstream.
+
+bcma used to lock up machine without enabling PCI or initializing CC.
+
+Signed-off-by: Rafał Miłecki <zajec5@gmail.com>
+Signed-off-by: John W. Linville <linville@tuxdriver.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/bcma/bcma_private.h |    3 +++
+ drivers/bcma/host_pci.c     |   37 +++++++++++++++++++++++++++++++++++++
+ drivers/bcma/main.c         |   16 ++++++++++++++++
+ 3 files changed, 56 insertions(+)
+
+--- a/drivers/bcma/bcma_private.h
++++ b/drivers/bcma/bcma_private.h
+@@ -18,6 +18,9 @@ void bcma_bus_unregister(struct bcma_bus
+ int __init bcma_bus_early_register(struct bcma_bus *bus,
+                                  struct bcma_device *core_cc,
+                                  struct bcma_device *core_mips);
++#ifdef CONFIG_PM
++int bcma_bus_resume(struct bcma_bus *bus);
++#endif
+ /* scan.c */
+ int bcma_bus_scan(struct bcma_bus *bus);
+--- a/drivers/bcma/host_pci.c
++++ b/drivers/bcma/host_pci.c
+@@ -224,6 +224,41 @@ static void bcma_host_pci_remove(struct
+       pci_set_drvdata(dev, NULL);
+ }
++#ifdef CONFIG_PM
++static int bcma_host_pci_suspend(struct pci_dev *dev, pm_message_t state)
++{
++      /* Host specific */
++      pci_save_state(dev);
++      pci_disable_device(dev);
++      pci_set_power_state(dev, pci_choose_state(dev, state));
++
++      return 0;
++}
++
++static int bcma_host_pci_resume(struct pci_dev *dev)
++{
++      struct bcma_bus *bus = pci_get_drvdata(dev);
++      int err;
++
++      /* Host specific */
++      pci_set_power_state(dev, 0);
++      err = pci_enable_device(dev);
++      if (err)
++              return err;
++      pci_restore_state(dev);
++
++      /* Bus specific */
++      err = bcma_bus_resume(bus);
++      if (err)
++              return err;
++
++      return 0;
++}
++#else /* CONFIG_PM */
++# define bcma_host_pci_suspend        NULL
++# define bcma_host_pci_resume NULL
++#endif /* CONFIG_PM */
++
+ static DEFINE_PCI_DEVICE_TABLE(bcma_pci_bridge_tbl) = {
+       { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x0576) },
+       { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4331) },
+@@ -239,6 +274,8 @@ static struct pci_driver bcma_pci_bridge
+       .id_table = bcma_pci_bridge_tbl,
+       .probe = bcma_host_pci_probe,
+       .remove = bcma_host_pci_remove,
++      .suspend = bcma_host_pci_suspend,
++      .resume = bcma_host_pci_resume,
+ };
+ int __init bcma_host_pci_init(void)
+--- a/drivers/bcma/main.c
++++ b/drivers/bcma/main.c
+@@ -240,6 +240,22 @@ int __init bcma_bus_early_register(struc
+       return 0;
+ }
++#ifdef CONFIG_PM
++int bcma_bus_resume(struct bcma_bus *bus)
++{
++      struct bcma_device *core;
++
++      /* Init CC core */
++      core = bcma_find_core(bus, BCMA_CORE_CHIPCOMMON);
++      if (core) {
++              bus->drv_cc.setup_done = false;
++              bcma_core_chipcommon_init(&bus->drv_cc);
++      }
++
++      return 0;
++}
++#endif
++
+ int __bcma_driver_register(struct bcma_driver *drv, struct module *owner)
+ {
+       drv->drv.name = drv->name;
diff --git a/queue-3.2/documentation-update-stable-address.patch b/queue-3.2/documentation-update-stable-address.patch
new file mode 100644 (file)
index 0000000..8c4082f
--- /dev/null
@@ -0,0 +1,52 @@
+From 2eb7f204db51969ea558802a6601d79c2fb273b9 Mon Sep 17 00:00:00 2001
+From: Joe Perches <joe@perches.com>
+Date: Fri, 9 Dec 2011 14:12:00 -0800
+Subject: Documentation: Update stable address
+
+From: Joe Perches <joe@perches.com>
+
+commit 2eb7f204db51969ea558802a6601d79c2fb273b9 upstream.
+
+The Japanese/Korean/Chinese versions still need updating.
+
+Also, the stable kernel 2.6.x.y descriptions are out of date
+and should be updated as well.
+
+Signed-off-by: Joe Perches <joe@perches.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ Documentation/HOWTO                         |    4 ++--
+ Documentation/development-process/5.Posting |    8 ++++----
+ 2 files changed, 6 insertions(+), 6 deletions(-)
+
+--- a/Documentation/HOWTO
++++ b/Documentation/HOWTO
+@@ -275,8 +275,8 @@ versions.
+ If no 2.6.x.y kernel is available, then the highest numbered 2.6.x
+ kernel is the current stable kernel.
+-2.6.x.y are maintained by the "stable" team <stable@kernel.org>, and are
+-released as needs dictate.  The normal release period is approximately 
++2.6.x.y are maintained by the "stable" team <stable@vger.kernel.org>, and
++are released as needs dictate.  The normal release period is approximately
+ two weeks, but it can be longer if there are no pressing problems.  A
+ security-related problem, instead, can cause a release to happen almost
+ instantly.
+--- a/Documentation/development-process/5.Posting
++++ b/Documentation/development-process/5.Posting
+@@ -271,10 +271,10 @@ copies should go to:
+    the linux-kernel list.
+  - If you are fixing a bug, think about whether the fix should go into the
+-   next stable update.  If so, stable@kernel.org should get a copy of the
+-   patch.  Also add a "Cc: stable@kernel.org" to the tags within the patch
+-   itself; that will cause the stable team to get a notification when your
+-   fix goes into the mainline.
++   next stable update.  If so, stable@vger.kernel.org should get a copy of
++   the patch.  Also add a "Cc: stable@vger.kernel.org" to the tags within
++   the patch itself; that will cause the stable team to get a notification
++   when your fix goes into the mainline.
+ When selecting recipients for a patch, it is good to have an idea of who
+ you think will eventually accept the patch and get it merged.  While it
diff --git a/queue-3.2/firmware-fix-an-oops-on-reading-fw_priv-fw-in-sysfs-loading-file.patch b/queue-3.2/firmware-fix-an-oops-on-reading-fw_priv-fw-in-sysfs-loading-file.patch
new file mode 100644 (file)
index 0000000..52dbb1b
--- /dev/null
@@ -0,0 +1,78 @@
+From eea915bb0d1358755f151eaefb8208a2d5f3e10c Mon Sep 17 00:00:00 2001
+From: Neil Horman <nhorman@tuxdriver.com>
+Date: Mon, 2 Jan 2012 15:31:23 -0500
+Subject: firmware: Fix an oops on reading fw_priv->fw in sysfs loading file
+
+From: Neil Horman <nhorman@tuxdriver.com>
+
+commit eea915bb0d1358755f151eaefb8208a2d5f3e10c upstream.
+
+This oops was reported recently:
+firmware_loading_store+0xf9/0x17b
+dev_attr_store+0x20/0x22
+sysfs_write_file+0x101/0x134
+vfs_write+0xac/0xf3
+sys_write+0x4a/0x6e
+system_call_fastpath+0x16/0x1b
+
+The complete backtrace was unfortunately not captured, but details can be found
+here:
+https://bugzilla.redhat.com/show_bug.cgi?id=769920
+
+The cause is fairly clear.
+
+Its caused by the fact that firmware_loading_store has a case 0 in its
+switch statement that reads and writes the fw_priv->fw poniter without the
+protection of the fw_lock mutex.  since there is a window between the time that
+_request_firmware sets fw_priv->fw to NULL and the time the corresponding sysfs
+file is unregistered, its possible for a user space application to race in, and
+write a zero to the loading file, causing a NULL dereference in
+firmware_loading_store.  Fix it by extending the protection of the fw_lock mutex
+to cover all of the firware_loading_store function.
+
+Signed-off-by: Neil Horman <nhorman@tuxdriver.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/base/firmware_class.c |   14 +++++++-------
+ 1 file changed, 7 insertions(+), 7 deletions(-)
+
+--- a/drivers/base/firmware_class.c
++++ b/drivers/base/firmware_class.c
+@@ -226,13 +226,13 @@ static ssize_t firmware_loading_store(st
+       int loading = simple_strtol(buf, NULL, 10);
+       int i;
++      mutex_lock(&fw_lock);
++
++      if (!fw_priv->fw)
++              goto out;
++
+       switch (loading) {
+       case 1:
+-              mutex_lock(&fw_lock);
+-              if (!fw_priv->fw) {
+-                      mutex_unlock(&fw_lock);
+-                      break;
+-              }
+               firmware_free_data(fw_priv->fw);
+               memset(fw_priv->fw, 0, sizeof(struct firmware));
+               /* If the pages are not owned by 'struct firmware' */
+@@ -243,7 +243,6 @@ static ssize_t firmware_loading_store(st
+               fw_priv->page_array_size = 0;
+               fw_priv->nr_pages = 0;
+               set_bit(FW_STATUS_LOADING, &fw_priv->status);
+-              mutex_unlock(&fw_lock);
+               break;
+       case 0:
+               if (test_bit(FW_STATUS_LOADING, &fw_priv->status)) {
+@@ -274,7 +273,8 @@ static ssize_t firmware_loading_store(st
+               fw_load_abort(fw_priv);
+               break;
+       }
+-
++out:
++      mutex_unlock(&fw_lock);
+       return count;
+ }
diff --git a/queue-3.2/libertas-clean-up-scan-thread-handling.patch b/queue-3.2/libertas-clean-up-scan-thread-handling.patch
new file mode 100644 (file)
index 0000000..8830753
--- /dev/null
@@ -0,0 +1,84 @@
+From afbca95f95f2bf7283a72670c24c1f6de00b1cb5 Mon Sep 17 00:00:00 2001
+From: Andres Salomon <dilinger@queued.net>
+Date: Mon, 19 Dec 2011 12:22:58 -0800
+Subject: libertas: clean up scan thread handling
+
+From: Andres Salomon <dilinger@queued.net>
+
+commit afbca95f95f2bf7283a72670c24c1f6de00b1cb5 upstream.
+
+The libertas scan thread expects priv->scan_req to be non-NULL.  In theory,
+it should always be set.  In practice, we've seen the following oops:
+
+[ 8363.067444] Unable to handle kernel NULL pointer dereference at virtual address 00000004
+[ 8363.067490] pgd = c0004000
+[ 8363.078393] [00000004] *pgd=00000000
+[ 8363.086711] Internal error: Oops: 17 [#1] PREEMPT
+[ 8363.091375] Modules linked in: fuse libertas_sdio libertas psmouse mousedev ov7670 mmp_camera joydev videobuf2_core videobuf2_dma_sg videobuf2_memops [last unloaded: scsi_wait_scan]
+[ 8363.107490] CPU: 0    Not tainted  (3.0.0-gf7ccc69 #671)
+[ 8363.112799] PC is at lbs_scan_worker+0x108/0x5a4 [libertas]
+[ 8363.118326] LR is at 0x0
+[ 8363.120836] pc : [<bf03a854>]    lr : [<00000000>]    psr: 60000113
+[ 8363.120845] sp : ee66bf48  ip : 00000000  fp : 00000000
+[ 8363.120845] r10: ee2c2088  r9 : c04e2efc  r8 : eef97005
+[ 8363.132231] r7 : eee0716f  r6 : ee2c02c0  r5 : ee2c2088  r4 : eee07160
+[ 8363.137419] r3 : 00000000  r2 : a0000113  r1 : 00000001  r0 : eee07160
+[ 8363.143896] Flags: nZCv  IRQs on  FIQs on  Mode SVC_32  ISA ARM  Segment kernel
+[ 8363.157630] Control: 10c5387d  Table: 2e754019  DAC: 00000015
+[ 8363.163334] Process kworker/u:1 (pid: 25, stack limit = 0xee66a2f8)
+
+While I've not found a smoking gun, there are two places that raised red flags
+for me.  The first is in _internal_start_scan, when we queue up a scan; we
+first queue the worker, and then set priv->scan_req.  There's theoretically
+a 50mS delay which should be plenty, but doing things that way just seems
+racy (and not in the good way).
+
+The second is in the scan worker thread itself.  Depending on the state of
+priv->scan_channel, we cancel pending scan runs and then requeue a run in
+300mS.  We then send the scan command down to the hardware, sleep, and if
+we get scan results for all the desired channels, we set priv->scan_req to
+NULL.  However, it that's happened in less than 300mS, what happens with
+the pending scan run?
+
+This patch addresses both of those concerns.  With the patch applied, we
+have not seen the oops in the past two weeks.
+
+Signed-off-by: Andres Salomon <dilinger@queued.net>
+Signed-off-by: John W. Linville <linville@tuxdriver.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/net/wireless/libertas/cfg.c |   10 ++++++----
+ 1 file changed, 6 insertions(+), 4 deletions(-)
+
+--- a/drivers/net/wireless/libertas/cfg.c
++++ b/drivers/net/wireless/libertas/cfg.c
+@@ -728,9 +728,11 @@ static void lbs_scan_worker(struct work_
+               le16_to_cpu(scan_cmd->hdr.size),
+               lbs_ret_scan, 0);
+-      if (priv->scan_channel >= priv->scan_req->n_channels)
++      if (priv->scan_channel >= priv->scan_req->n_channels) {
+               /* Mark scan done */
++              cancel_delayed_work(&priv->scan_work);
+               lbs_scan_done(priv);
++      }
+       /* Restart network */
+       if (carrier)
+@@ -759,12 +761,12 @@ static void _internal_start_scan(struct
+               request->n_ssids, request->n_channels, request->ie_len);
+       priv->scan_channel = 0;
+-      queue_delayed_work(priv->work_thread, &priv->scan_work,
+-              msecs_to_jiffies(50));
+-
+       priv->scan_req = request;
+       priv->internal_scan = internal;
++      queue_delayed_work(priv->work_thread, &priv->scan_work,
++              msecs_to_jiffies(50));
++
+       lbs_deb_leave(LBS_DEB_CFG80211);
+ }
diff --git a/queue-3.2/offb-fix-bug-in-calculating-requested-vram-size.patch b/queue-3.2/offb-fix-bug-in-calculating-requested-vram-size.patch
new file mode 100644 (file)
index 0000000..9a2f9d3
--- /dev/null
@@ -0,0 +1,30 @@
+From c055fe0797b7bd8f6f21a13598a55a16d5c13ae7 Mon Sep 17 00:00:00 2001
+From: Benjamin Herrenschmidt <benh@kernel.crashing.org>
+Date: Tue, 3 Jan 2012 12:09:15 +1100
+Subject: offb: Fix bug in calculating requested vram size
+
+From: Benjamin Herrenschmidt <benh@kernel.crashing.org>
+
+commit c055fe0797b7bd8f6f21a13598a55a16d5c13ae7 upstream.
+
+We used to try to request 8 times more vram than needed, which would
+fail if the card has a too small BAR (observed with qemu & kvm).
+
+Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/video/offb.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/video/offb.c
++++ b/drivers/video/offb.c
+@@ -377,7 +377,7 @@ static void __init offb_init_fb(const ch
+                               int pitch, unsigned long address,
+                               int foreign_endian, struct device_node *dp)
+ {
+-      unsigned long res_size = pitch * height * (depth + 7) / 8;
++      unsigned long res_size = pitch * height;
+       struct offb_par *par = &default_par;
+       unsigned long res_start = address;
+       struct fb_fix_screeninfo *fix;
diff --git a/queue-3.2/offb-fix-setting-of-the-pseudo-palette-for-8bpp.patch b/queue-3.2/offb-fix-setting-of-the-pseudo-palette-for-8bpp.patch
new file mode 100644 (file)
index 0000000..8f8748e
--- /dev/null
@@ -0,0 +1,87 @@
+From 1bb0b7d21584b3f878e2bc880db62351ddee5185 Mon Sep 17 00:00:00 2001
+From: Benjamin Herrenschmidt <benh@kernel.crashing.org>
+Date: Wed, 28 Dec 2011 00:10:16 +0000
+Subject: offb: Fix setting of the pseudo-palette for >8bpp
+
+From: Benjamin Herrenschmidt <benh@kernel.crashing.org>
+
+commit 1bb0b7d21584b3f878e2bc880db62351ddee5185 upstream.
+
+When using a >8bpp framebuffer, offb advertises truecolor, not directcolor,
+and doesn't touch the color map even if it has a corresponding access method
+for the real hardware.
+
+Thus it needs to set the pseudo-palette with all 3 components of the color,
+like other truecolor framebuffers, not with copies of the color index like
+a directcolor framebuffer would do.
+
+This went unnoticed for a long time because it's pretty hard to get offb
+to kick in with anything but 8bpp (old BootX under MacOS will do that and
+qemu does it).
+
+Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/video/offb.c |   44 ++++++++++++++++++++------------------------
+ 1 file changed, 20 insertions(+), 24 deletions(-)
+
+--- a/drivers/video/offb.c
++++ b/drivers/video/offb.c
+@@ -100,36 +100,32 @@ static int offb_setcolreg(u_int regno, u
+                         u_int transp, struct fb_info *info)
+ {
+       struct offb_par *par = (struct offb_par *) info->par;
+-      int i, depth;
+-      u32 *pal = info->pseudo_palette;
+-      depth = info->var.bits_per_pixel;
+-      if (depth == 16)
+-              depth = (info->var.green.length == 5) ? 15 : 16;
++      if (info->fix.visual == FB_VISUAL_TRUECOLOR) {
++              u32 *pal = info->pseudo_palette;
++              u32 cr = red >> (16 - info->var.red.length);
++              u32 cg = green >> (16 - info->var.green.length);
++              u32 cb = blue >> (16 - info->var.blue.length);
++              u32 value;
+-      if (regno > 255 ||
+-          (depth == 16 && regno > 63) ||
+-          (depth == 15 && regno > 31))
+-              return 1;
++              if (regno >= 16)
++                      return -EINVAL;
+-      if (regno < 16) {
+-              switch (depth) {
+-              case 15:
+-                      pal[regno] = (regno << 10) | (regno << 5) | regno;
+-                      break;
+-              case 16:
+-                      pal[regno] = (regno << 11) | (regno << 5) | regno;
+-                      break;
+-              case 24:
+-                      pal[regno] = (regno << 16) | (regno << 8) | regno;
+-                      break;
+-              case 32:
+-                      i = (regno << 8) | regno;
+-                      pal[regno] = (i << 16) | i;
+-                      break;
++              value = (cr << info->var.red.offset) |
++                      (cg << info->var.green.offset) |
++                      (cb << info->var.blue.offset);
++              if (info->var.transp.length > 0) {
++                      u32 mask = (1 << info->var.transp.length) - 1;
++                      mask <<= info->var.transp.offset;
++                      value |= mask;
+               }
++              pal[regno] = value;
++              return 0;
+       }
++      if (regno > 255)
++              return -EINVAL;
++
+       red >>= 8;
+       green >>= 8;
+       blue >>= 8;
diff --git a/queue-3.2/powerpc-fix-unpaired-probe_hcall_entry-and-probe_hcall_exit.patch b/queue-3.2/powerpc-fix-unpaired-probe_hcall_entry-and-probe_hcall_exit.patch
new file mode 100644 (file)
index 0000000..8cb1419
--- /dev/null
@@ -0,0 +1,80 @@
+From e4f387d8db3ba3c2dae4d8bdfe7bb5f4fe1bcb0d Mon Sep 17 00:00:00 2001
+From: Li Zhong <zhong@linux.vnet.ibm.com>
+Date: Sun, 18 Dec 2011 16:03:04 +0000
+Subject: powerpc: Fix unpaired probe_hcall_entry and probe_hcall_exit
+
+From: Li Zhong <zhong@linux.vnet.ibm.com>
+
+commit e4f387d8db3ba3c2dae4d8bdfe7bb5f4fe1bcb0d upstream.
+
+Unpaired calling of probe_hcall_entry and probe_hcall_exit might happen
+as following, which could cause incorrect preempt count.
+
+__trace_hcall_entry => trace_hcall_entry -> probe_hcall_entry =>
+get_cpu_var => preempt_disable
+
+__trace_hcall_exit => trace_hcall_exit -> probe_hcall_exit =>
+put_cpu_var => preempt_enable
+
+where:
+A => B and A -> B means A calls B, but
+=> means A will call B through function name, and B will definitely be
+called.
+-> means A will call B through function pointer, so B might not be
+called if the function pointer is not set.
+
+So error happens when only one of probe_hcall_entry and probe_hcall_exit
+get called during a hcall.
+
+This patch tries to move the preempt count operations from
+probe_hcall_entry and probe_hcall_exit to its callers.
+
+Reported-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
+Signed-off-by: Li Zhong <zhong@linux.vnet.ibm.com>
+Tested-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
+Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ arch/powerpc/platforms/pseries/hvCall_inst.c |    4 +---
+ arch/powerpc/platforms/pseries/lpar.c        |    2 ++
+ 2 files changed, 3 insertions(+), 3 deletions(-)
+
+--- a/arch/powerpc/platforms/pseries/hvCall_inst.c
++++ b/arch/powerpc/platforms/pseries/hvCall_inst.c
+@@ -109,7 +109,7 @@ static void probe_hcall_entry(void *igno
+       if (opcode > MAX_HCALL_OPCODE)
+               return;
+-      h = &get_cpu_var(hcall_stats)[opcode / 4];
++      h = &__get_cpu_var(hcall_stats)[opcode / 4];
+       h->tb_start = mftb();
+       h->purr_start = mfspr(SPRN_PURR);
+ }
+@@ -126,8 +126,6 @@ static void probe_hcall_exit(void *ignor
+       h->num_calls++;
+       h->tb_total += mftb() - h->tb_start;
+       h->purr_total += mfspr(SPRN_PURR) - h->purr_start;
+-
+-      put_cpu_var(hcall_stats);
+ }
+ static int __init hcall_inst_init(void)
+--- a/arch/powerpc/platforms/pseries/lpar.c
++++ b/arch/powerpc/platforms/pseries/lpar.c
+@@ -554,6 +554,7 @@ void __trace_hcall_entry(unsigned long o
+               goto out;
+       (*depth)++;
++      preempt_disable();
+       trace_hcall_entry(opcode, args);
+       (*depth)--;
+@@ -576,6 +577,7 @@ void __trace_hcall_exit(long opcode, uns
+       (*depth)++;
+       trace_hcall_exit(opcode, retval, retbuf);
++      preempt_enable();
+       (*depth)--;
+ out:
diff --git a/queue-3.2/powerpc-time-handle-wrapping-of-decrementer.patch b/queue-3.2/powerpc-time-handle-wrapping-of-decrementer.patch
new file mode 100644 (file)
index 0000000..4cff991
--- /dev/null
@@ -0,0 +1,87 @@
+From 37fb9a0231ee43d42d069863bdfd567fca2b61af Mon Sep 17 00:00:00 2001
+From: Anton Blanchard <anton@samba.org>
+Date: Wed, 23 Nov 2011 20:07:17 +0000
+Subject: powerpc/time: Handle wrapping of decrementer
+
+From: Anton Blanchard <anton@samba.org>
+
+commit 37fb9a0231ee43d42d069863bdfd567fca2b61af upstream.
+
+When re-enabling interrupts we have code to handle edge sensitive
+decrementers by resetting the decrementer to 1 whenever it is negative.
+If interrupts were disabled long enough that the decrementer wrapped to
+positive we do nothing. This means interrupts can be delayed for a long
+time until it finally goes negative again.
+
+While we hope interrupts are never be disabled long enough for the
+decrementer to go positive, we have a very good test team that can
+drive any kernel into the ground. The softlockup data we get back
+from these fails could be seconds in the future, completely missing
+the cause of the lockup.
+
+We already keep track of the timebase of the next event so use that
+to work out if we should trigger a decrementer exception.
+
+Signed-off-by: Anton Blanchard <anton@samba.org>
+Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ arch/powerpc/include/asm/time.h |    2 ++
+ arch/powerpc/kernel/irq.c       |   15 ++++++---------
+ arch/powerpc/kernel/time.c      |    9 +++++++++
+ 3 files changed, 17 insertions(+), 9 deletions(-)
+
+--- a/arch/powerpc/include/asm/time.h
++++ b/arch/powerpc/include/asm/time.h
+@@ -219,5 +219,7 @@ DECLARE_PER_CPU(struct cpu_usage, cpu_us
+ extern void secondary_cpu_time_init(void);
+ extern void iSeries_time_init_early(void);
++extern void decrementer_check_overflow(void);
++
+ #endif /* __KERNEL__ */
+ #endif /* __POWERPC_TIME_H */
+--- a/arch/powerpc/kernel/irq.c
++++ b/arch/powerpc/kernel/irq.c
+@@ -164,16 +164,13 @@ notrace void arch_local_irq_restore(unsi
+        */
+       local_paca->hard_enabled = en;
+-#ifndef CONFIG_BOOKE
+-      /* On server, re-trigger the decrementer if it went negative since
+-       * some processors only trigger on edge transitions of the sign bit.
+-       *
+-       * BookE has a level sensitive decrementer (latches in TSR) so we
+-       * don't need that
++      /*
++       * Trigger the decrementer if we have a pending event. Some processors
++       * only trigger on edge transitions of the sign bit. We might also
++       * have disabled interrupts long enough that the decrementer wrapped
++       * to positive.
+        */
+-      if ((int)mfspr(SPRN_DEC) < 0)
+-              mtspr(SPRN_DEC, 1);
+-#endif /* CONFIG_BOOKE */
++      decrementer_check_overflow();
+       /*
+        * Force the delivery of pending soft-disabled interrupts on PS3.
+--- a/arch/powerpc/kernel/time.c
++++ b/arch/powerpc/kernel/time.c
+@@ -889,6 +889,15 @@ static void __init clocksource_init(void
+              clock->name, clock->mult, clock->shift);
+ }
++void decrementer_check_overflow(void)
++{
++      u64 now = get_tb_or_rtc();
++      struct decrementer_clock *decrementer = &__get_cpu_var(decrementers);
++
++      if (now >= decrementer->next_tb)
++              set_dec(1);
++}
++
+ static int decrementer_set_next_event(unsigned long evt,
+                                     struct clock_event_device *dev)
+ {
diff --git a/queue-3.2/rt2800usb-move-id-out-of-unknown.patch b/queue-3.2/rt2800usb-move-id-out-of-unknown.patch
new file mode 100644 (file)
index 0000000..cfacb38
--- /dev/null
@@ -0,0 +1,41 @@
+From 3f81f8f1524ccca24df1029b0cf825ecef5e5cdc Mon Sep 17 00:00:00 2001
+From: Larry Finger <Larry.Finger@lwfinger.net>
+Date: Tue, 27 Dec 2011 12:22:51 -0600
+Subject: rt2800usb: Move ID out of unknown
+
+From: Larry Finger <Larry.Finger@lwfinger.net>
+
+commit 3f81f8f1524ccca24df1029b0cf825ecef5e5cdc upstream.
+
+Testing on the openSUSE wireless forum has shown that a Linksys
+WUSB54GC v3 with USB ID 1737:0077 works with rt2800usb when the ID is
+written to /sys/.../new_id. This ID can therefore be moved out of UNKNOWN.
+
+Signed-off-by: Larry Finger <Larry.Finger@lwfinger.net>
+Acked-by: Gertjan van Wingerde <gwingerde@gmail.com>
+Acked-by: Ivo van Doorn <IvDoorn@gmail.com>
+Signed-off-by: John W. Linville <linville@tuxdriver.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/net/wireless/rt2x00/rt2800usb.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/net/wireless/rt2x00/rt2800usb.c
++++ b/drivers/net/wireless/rt2x00/rt2800usb.c
+@@ -976,6 +976,7 @@ static struct usb_device_id rt2800usb_de
+       { USB_DEVICE(0x13b1, 0x0031) },
+       { USB_DEVICE(0x1737, 0x0070) },
+       { USB_DEVICE(0x1737, 0x0071) },
++      { USB_DEVICE(0x1737, 0x0077) },
+       /* Logitec */
+       { USB_DEVICE(0x0789, 0x0162) },
+       { USB_DEVICE(0x0789, 0x0163) },
+@@ -1171,7 +1172,6 @@ static struct usb_device_id rt2800usb_de
+       { USB_DEVICE(0x1740, 0x0605) },
+       { USB_DEVICE(0x1740, 0x0615) },
+       /* Linksys */
+-      { USB_DEVICE(0x1737, 0x0077) },
+       { USB_DEVICE(0x1737, 0x0078) },
+       /* Logitec */
+       { USB_DEVICE(0x0789, 0x0168) },
index 26643c8a999384a363522395ec4f0a8c5390f003..2d38c4fbe2adf913e112134cd129a4fb0e14433e 100644 (file)
@@ -1 +1,13 @@
 maintainers-stable-update-address.patch
+documentation-update-stable-address.patch
+firmware-fix-an-oops-on-reading-fw_priv-fw-in-sysfs-loading-file.patch
+rt2800usb-move-id-out-of-unknown.patch
+offb-fix-setting-of-the-pseudo-palette-for-8bpp.patch
+offb-fix-bug-in-calculating-requested-vram-size.patch
+libertas-clean-up-scan-thread-handling.patch
+bcma-support-for-suspend-and-resume.patch
+wl12xx-validate-fem-index-from-ini-file-and-fw.patch
+wl12xx-check-buffer-bound-when-processing-nvs-data.patch
+wl12xx-restore-testmode-abi.patch
+powerpc-time-handle-wrapping-of-decrementer.patch
+powerpc-fix-unpaired-probe_hcall_entry-and-probe_hcall_exit.patch
diff --git a/queue-3.2/wl12xx-check-buffer-bound-when-processing-nvs-data.patch b/queue-3.2/wl12xx-check-buffer-bound-when-processing-nvs-data.patch
new file mode 100644 (file)
index 0000000..a752043
--- /dev/null
@@ -0,0 +1,66 @@
+From f6efe96edd9c41c624c8f4ddbc4930c1a2d8f1e1 Mon Sep 17 00:00:00 2001
+From: Pontus Fuchs <pontus.fuchs@gmail.com>
+Date: Tue, 18 Oct 2011 09:23:42 +0200
+Subject: wl12xx: Check buffer bound when processing nvs data
+
+From: Pontus Fuchs <pontus.fuchs@gmail.com>
+
+commit f6efe96edd9c41c624c8f4ddbc4930c1a2d8f1e1 upstream.
+
+An nvs with malformed contents could cause the processing of the
+calibration data to read beyond the end of the buffer. Prevent this
+from happening by adding bound checking.
+
+Signed-off-by: Pontus Fuchs <pontus.fuchs@gmail.com>
+Reviewed-by: Luciano Coelho <coelho@ti.com>
+Signed-off-by: Luciano Coelho <coelho@ti.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/net/wireless/wl12xx/boot.c |   14 ++++++++++++++
+ 1 file changed, 14 insertions(+)
+
+--- a/drivers/net/wireless/wl12xx/boot.c
++++ b/drivers/net/wireless/wl12xx/boot.c
+@@ -347,6 +347,9 @@ static int wl1271_boot_upload_nvs(struct
+               nvs_ptr += 3;
+               for (i = 0; i < burst_len; i++) {
++                      if (nvs_ptr + 3 >= (u8 *) wl->nvs + nvs_len)
++                              goto out_badnvs;
++
+                       val = (nvs_ptr[0] | (nvs_ptr[1] << 8)
+                              | (nvs_ptr[2] << 16) | (nvs_ptr[3] << 24));
+@@ -358,6 +361,9 @@ static int wl1271_boot_upload_nvs(struct
+                       nvs_ptr += 4;
+                       dest_addr += 4;
+               }
++
++              if (nvs_ptr >= (u8 *) wl->nvs + nvs_len)
++                      goto out_badnvs;
+       }
+       /*
+@@ -369,6 +375,10 @@ static int wl1271_boot_upload_nvs(struct
+        */
+       nvs_ptr = (u8 *)wl->nvs +
+                       ALIGN(nvs_ptr - (u8 *)wl->nvs + 7, 4);
++
++      if (nvs_ptr >= (u8 *) wl->nvs + nvs_len)
++              goto out_badnvs;
++
+       nvs_len -= nvs_ptr - (u8 *)wl->nvs;
+       /* Now we must set the partition correctly */
+@@ -384,6 +394,10 @@ static int wl1271_boot_upload_nvs(struct
+       kfree(nvs_aligned);
+       return 0;
++
++out_badnvs:
++      wl1271_error("nvs data is malformed");
++      return -EILSEQ;
+ }
+ static void wl1271_boot_enable_interrupts(struct wl1271 *wl)
diff --git a/queue-3.2/wl12xx-restore-testmode-abi.patch b/queue-3.2/wl12xx-restore-testmode-abi.patch
new file mode 100644 (file)
index 0000000..c921e79
--- /dev/null
@@ -0,0 +1,30 @@
+From 3f1764945eaac532c20ab1f23afa352a40f797b2 Mon Sep 17 00:00:00 2001
+From: Pontus Fuchs <pontus.fuchs@gmail.com>
+Date: Thu, 1 Dec 2011 12:13:44 +0100
+Subject: wl12xx: Restore testmode ABI
+
+From: Pontus Fuchs <pontus.fuchs@gmail.com>
+
+commit 3f1764945eaac532c20ab1f23afa352a40f797b2 upstream.
+
+Commit 80900d0140a7648587982c8f299830e900e49165 accidently broke
+the ABI for testmode commands. Restore the ABI again.
+
+Signed-off-by: Pontus Fuchs <pontus.fuchs@gmail.com>
+Signed-off-by: Luciano Coelho <coelho@ti.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/net/wireless/wl12xx/testmode.c |    1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/drivers/net/wireless/wl12xx/testmode.c
++++ b/drivers/net/wireless/wl12xx/testmode.c
+@@ -36,6 +36,7 @@ enum wl1271_tm_commands {
+       WL1271_TM_CMD_TEST,
+       WL1271_TM_CMD_INTERROGATE,
+       WL1271_TM_CMD_CONFIGURE,
++      WL1271_TM_CMD_NVS_PUSH,         /* Not in use. Keep to not break ABI */
+       WL1271_TM_CMD_SET_PLT_MODE,
+       WL1271_TM_CMD_RECOVER,
diff --git a/queue-3.2/wl12xx-validate-fem-index-from-ini-file-and-fw.patch b/queue-3.2/wl12xx-validate-fem-index-from-ini-file-and-fw.patch
new file mode 100644 (file)
index 0000000..7dfb5fb
--- /dev/null
@@ -0,0 +1,73 @@
+From 2131d3c2f99b081806fdae7662c92fe6acda52af Mon Sep 17 00:00:00 2001
+From: Pontus Fuchs <pontus.fuchs@gmail.com>
+Date: Tue, 18 Oct 2011 09:23:41 +0200
+Subject: wl12xx: Validate FEM index from ini file and FW
+
+From: Pontus Fuchs <pontus.fuchs@gmail.com>
+
+commit 2131d3c2f99b081806fdae7662c92fe6acda52af upstream.
+
+Check for out of bound FEM index to prevent reading beyond ini
+memory end.
+
+Signed-off-by: Pontus Fuchs <pontus.fuchs@gmail.com>
+Reviewed-by: Luciano Coelho <coelho@ti.com>
+Signed-off-by: Luciano Coelho <coelho@ti.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/net/wireless/wl12xx/cmd.c |   22 ++++++++++++++++++++++
+ 1 file changed, 22 insertions(+)
+
+--- a/drivers/net/wireless/wl12xx/cmd.c
++++ b/drivers/net/wireless/wl12xx/cmd.c
+@@ -120,6 +120,11 @@ int wl1271_cmd_general_parms(struct wl12
+       if (!wl->nvs)
+               return -ENODEV;
++      if (gp->tx_bip_fem_manufacturer >= WL1271_INI_FEM_MODULE_COUNT) {
++              wl1271_warning("FEM index from INI out of bounds");
++              return -EINVAL;
++      }
++
+       gen_parms = kzalloc(sizeof(*gen_parms), GFP_KERNEL);
+       if (!gen_parms)
+               return -ENOMEM;
+@@ -143,6 +148,12 @@ int wl1271_cmd_general_parms(struct wl12
+       gp->tx_bip_fem_manufacturer =
+               gen_parms->general_params.tx_bip_fem_manufacturer;
++      if (gp->tx_bip_fem_manufacturer >= WL1271_INI_FEM_MODULE_COUNT) {
++              wl1271_warning("FEM index from FW out of bounds");
++              ret = -EINVAL;
++              goto out;
++      }
++
+       wl1271_debug(DEBUG_CMD, "FEM autodetect: %s, manufacturer: %d\n",
+                    answer ? "auto" : "manual", gp->tx_bip_fem_manufacturer);
+@@ -162,6 +173,11 @@ int wl128x_cmd_general_parms(struct wl12
+       if (!wl->nvs)
+               return -ENODEV;
++      if (gp->tx_bip_fem_manufacturer >= WL1271_INI_FEM_MODULE_COUNT) {
++              wl1271_warning("FEM index from ini out of bounds");
++              return -EINVAL;
++      }
++
+       gen_parms = kzalloc(sizeof(*gen_parms), GFP_KERNEL);
+       if (!gen_parms)
+               return -ENOMEM;
+@@ -186,6 +202,12 @@ int wl128x_cmd_general_parms(struct wl12
+       gp->tx_bip_fem_manufacturer =
+               gen_parms->general_params.tx_bip_fem_manufacturer;
++      if (gp->tx_bip_fem_manufacturer >= WL1271_INI_FEM_MODULE_COUNT) {
++              wl1271_warning("FEM index from FW out of bounds");
++              ret = -EINVAL;
++              goto out;
++      }
++
+       wl1271_debug(DEBUG_CMD, "FEM autodetect: %s, manufacturer: %d\n",
+                    answer ? "auto" : "manual", gp->tx_bip_fem_manufacturer);