From 4506fc492822c23c42ac17f8a7729c67f47f0657 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Mon, 9 Jan 2012 11:40:59 -0800 Subject: [PATCH] 3.2-stable patches 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 --- .../bcma-support-for-suspend-and-resume.patch | 114 ++++++++++++++++++ .../documentation-update-stable-address.patch | 52 ++++++++ ...ing-fw_priv-fw-in-sysfs-loading-file.patch | 78 ++++++++++++ ...bertas-clean-up-scan-thread-handling.patch | 84 +++++++++++++ ...g-in-calculating-requested-vram-size.patch | 30 +++++ ...tting-of-the-pseudo-palette-for-8bpp.patch | 87 +++++++++++++ ...obe_hcall_entry-and-probe_hcall_exit.patch | 80 ++++++++++++ ...-time-handle-wrapping-of-decrementer.patch | 87 +++++++++++++ .../rt2800usb-move-id-out-of-unknown.patch | 41 +++++++ queue-3.2/series | 12 ++ ...uffer-bound-when-processing-nvs-data.patch | 66 ++++++++++ queue-3.2/wl12xx-restore-testmode-abi.patch | 30 +++++ ...idate-fem-index-from-ini-file-and-fw.patch | 73 +++++++++++ 13 files changed, 834 insertions(+) create mode 100644 queue-3.2/bcma-support-for-suspend-and-resume.patch create mode 100644 queue-3.2/documentation-update-stable-address.patch create mode 100644 queue-3.2/firmware-fix-an-oops-on-reading-fw_priv-fw-in-sysfs-loading-file.patch create mode 100644 queue-3.2/libertas-clean-up-scan-thread-handling.patch create mode 100644 queue-3.2/offb-fix-bug-in-calculating-requested-vram-size.patch create mode 100644 queue-3.2/offb-fix-setting-of-the-pseudo-palette-for-8bpp.patch create mode 100644 queue-3.2/powerpc-fix-unpaired-probe_hcall_entry-and-probe_hcall_exit.patch create mode 100644 queue-3.2/powerpc-time-handle-wrapping-of-decrementer.patch create mode 100644 queue-3.2/rt2800usb-move-id-out-of-unknown.patch create mode 100644 queue-3.2/wl12xx-check-buffer-bound-when-processing-nvs-data.patch create mode 100644 queue-3.2/wl12xx-restore-testmode-abi.patch create mode 100644 queue-3.2/wl12xx-validate-fem-index-from-ini-file-and-fw.patch 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 index 00000000000..34fe63b0e47 --- /dev/null +++ b/queue-3.2/bcma-support-for-suspend-and-resume.patch @@ -0,0 +1,114 @@ +From 775ab52142b02237a54184238e922251c59a2b5c Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= +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 + +commit 775ab52142b02237a54184238e922251c59a2b5c upstream. + +bcma used to lock up machine without enabling PCI or initializing CC. + +Signed-off-by: Rafał Miłecki +Signed-off-by: John W. Linville +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..8c4082fc52c --- /dev/null +++ b/queue-3.2/documentation-update-stable-address.patch @@ -0,0 +1,52 @@ +From 2eb7f204db51969ea558802a6601d79c2fb273b9 Mon Sep 17 00:00:00 2001 +From: Joe Perches +Date: Fri, 9 Dec 2011 14:12:00 -0800 +Subject: Documentation: Update stable address + +From: Joe Perches + +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 +Signed-off-by: Greg Kroah-Hartman + +--- + 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 , and are +-released as needs dictate. The normal release period is approximately ++2.6.x.y are maintained by the "stable" team , 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 index 00000000000..52dbb1b19bd --- /dev/null +++ b/queue-3.2/firmware-fix-an-oops-on-reading-fw_priv-fw-in-sysfs-loading-file.patch @@ -0,0 +1,78 @@ +From eea915bb0d1358755f151eaefb8208a2d5f3e10c Mon Sep 17 00:00:00 2001 +From: Neil Horman +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 + +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 +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..88307533084 --- /dev/null +++ b/queue-3.2/libertas-clean-up-scan-thread-handling.patch @@ -0,0 +1,84 @@ +From afbca95f95f2bf7283a72670c24c1f6de00b1cb5 Mon Sep 17 00:00:00 2001 +From: Andres Salomon +Date: Mon, 19 Dec 2011 12:22:58 -0800 +Subject: libertas: clean up scan thread handling + +From: Andres Salomon + +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 : [] 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 +Signed-off-by: John W. Linville +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..9a2f9d3ae97 --- /dev/null +++ b/queue-3.2/offb-fix-bug-in-calculating-requested-vram-size.patch @@ -0,0 +1,30 @@ +From c055fe0797b7bd8f6f21a13598a55a16d5c13ae7 Mon Sep 17 00:00:00 2001 +From: Benjamin Herrenschmidt +Date: Tue, 3 Jan 2012 12:09:15 +1100 +Subject: offb: Fix bug in calculating requested vram size + +From: Benjamin Herrenschmidt + +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 +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..8f8748e892d --- /dev/null +++ b/queue-3.2/offb-fix-setting-of-the-pseudo-palette-for-8bpp.patch @@ -0,0 +1,87 @@ +From 1bb0b7d21584b3f878e2bc880db62351ddee5185 Mon Sep 17 00:00:00 2001 +From: Benjamin Herrenschmidt +Date: Wed, 28 Dec 2011 00:10:16 +0000 +Subject: offb: Fix setting of the pseudo-palette for >8bpp + +From: Benjamin Herrenschmidt + +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 +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..8cb1419d72a --- /dev/null +++ b/queue-3.2/powerpc-fix-unpaired-probe_hcall_entry-and-probe_hcall_exit.patch @@ -0,0 +1,80 @@ +From e4f387d8db3ba3c2dae4d8bdfe7bb5f4fe1bcb0d Mon Sep 17 00:00:00 2001 +From: Li Zhong +Date: Sun, 18 Dec 2011 16:03:04 +0000 +Subject: powerpc: Fix unpaired probe_hcall_entry and probe_hcall_exit + +From: Li Zhong + +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 +Signed-off-by: Li Zhong +Tested-by: Paul E. McKenney +Signed-off-by: Benjamin Herrenschmidt +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..4cff991b48f --- /dev/null +++ b/queue-3.2/powerpc-time-handle-wrapping-of-decrementer.patch @@ -0,0 +1,87 @@ +From 37fb9a0231ee43d42d069863bdfd567fca2b61af Mon Sep 17 00:00:00 2001 +From: Anton Blanchard +Date: Wed, 23 Nov 2011 20:07:17 +0000 +Subject: powerpc/time: Handle wrapping of decrementer + +From: Anton Blanchard + +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 +Signed-off-by: Benjamin Herrenschmidt +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..cfacb38a4bf --- /dev/null +++ b/queue-3.2/rt2800usb-move-id-out-of-unknown.patch @@ -0,0 +1,41 @@ +From 3f81f8f1524ccca24df1029b0cf825ecef5e5cdc Mon Sep 17 00:00:00 2001 +From: Larry Finger +Date: Tue, 27 Dec 2011 12:22:51 -0600 +Subject: rt2800usb: Move ID out of unknown + +From: Larry Finger + +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 +Acked-by: Gertjan van Wingerde +Acked-by: Ivo van Doorn +Signed-off-by: John W. Linville +Signed-off-by: Greg Kroah-Hartman + +--- + 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) }, diff --git a/queue-3.2/series b/queue-3.2/series index 26643c8a999..2d38c4fbe2a 100644 --- a/queue-3.2/series +++ b/queue-3.2/series @@ -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 index 00000000000..a7520434002 --- /dev/null +++ b/queue-3.2/wl12xx-check-buffer-bound-when-processing-nvs-data.patch @@ -0,0 +1,66 @@ +From f6efe96edd9c41c624c8f4ddbc4930c1a2d8f1e1 Mon Sep 17 00:00:00 2001 +From: Pontus Fuchs +Date: Tue, 18 Oct 2011 09:23:42 +0200 +Subject: wl12xx: Check buffer bound when processing nvs data + +From: Pontus Fuchs + +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 +Reviewed-by: Luciano Coelho +Signed-off-by: Luciano Coelho +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..c921e79a83f --- /dev/null +++ b/queue-3.2/wl12xx-restore-testmode-abi.patch @@ -0,0 +1,30 @@ +From 3f1764945eaac532c20ab1f23afa352a40f797b2 Mon Sep 17 00:00:00 2001 +From: Pontus Fuchs +Date: Thu, 1 Dec 2011 12:13:44 +0100 +Subject: wl12xx: Restore testmode ABI + +From: Pontus Fuchs + +commit 3f1764945eaac532c20ab1f23afa352a40f797b2 upstream. + +Commit 80900d0140a7648587982c8f299830e900e49165 accidently broke +the ABI for testmode commands. Restore the ABI again. + +Signed-off-by: Pontus Fuchs +Signed-off-by: Luciano Coelho +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..7dfb5fb7592 --- /dev/null +++ b/queue-3.2/wl12xx-validate-fem-index-from-ini-file-and-fw.patch @@ -0,0 +1,73 @@ +From 2131d3c2f99b081806fdae7662c92fe6acda52af Mon Sep 17 00:00:00 2001 +From: Pontus Fuchs +Date: Tue, 18 Oct 2011 09:23:41 +0200 +Subject: wl12xx: Validate FEM index from ini file and FW + +From: Pontus Fuchs + +commit 2131d3c2f99b081806fdae7662c92fe6acda52af upstream. + +Check for out of bound FEM index to prevent reading beyond ini +memory end. + +Signed-off-by: Pontus Fuchs +Reviewed-by: Luciano Coelho +Signed-off-by: Luciano Coelho +Signed-off-by: Greg Kroah-Hartman + +--- + 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); + -- 2.47.3