From: Greg Kroah-Hartman Date: Fri, 30 Nov 2012 02:03:10 +0000 (-0800) Subject: 3.6-stable patches X-Git-Tag: v3.6.9~3 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=4ea46e8fcccd1eb9737ba9819de330e05ef828e6;p=thirdparty%2Fkernel%2Fstable-queue.git 3.6-stable patches added patches: ext4-remove-erroneous-ext4_superblock_csum_set-in-update_backups.patch get_dvb_firmware-fix-download-site-for-tda10046-firmware.patch mmc-sdhci-s3c-fix-the-wrong-number-of-max-bus-clocks.patch mm-vmscan-check-for-fatal-signals-iff-the-process-was-throttled.patch mpi-fix-compilation-on-mips-with-gcc-4.4-and-newer.patch nfc-fix-nfc_llcp_local-chained-list-insertion.patch nfc-fix-pn533-target-mode-memory-leak.patch nfc-pn533-fix-mem-leak-in-pn533_in_dep_link_up.patch nfc-pn533-fix-use-after-free.patch powerpc-eeh-lock-module-while-handling-eeh-event.patch watchdog-using-u64-in-get_sample_period.patch --- diff --git a/queue-3.6/ext4-remove-erroneous-ext4_superblock_csum_set-in-update_backups.patch b/queue-3.6/ext4-remove-erroneous-ext4_superblock_csum_set-in-update_backups.patch new file mode 100644 index 00000000000..3c7d7555315 --- /dev/null +++ b/queue-3.6/ext4-remove-erroneous-ext4_superblock_csum_set-in-update_backups.patch @@ -0,0 +1,41 @@ +From bef53b01faeb791e27605cba1a71ba21364cb23e Mon Sep 17 00:00:00 2001 +From: Tao Ma +Date: Thu, 20 Sep 2012 11:35:38 -0400 +Subject: ext4: remove erroneous ext4_superblock_csum_set() in update_backups() + +From: Tao Ma + +commit bef53b01faeb791e27605cba1a71ba21364cb23e upstream. + +The update_backups() function is used to backup all the metadata +blocks, so we should not take it for granted that 'data' is pointed to +a super block and use ext4_superblock_csum_set to calculate the +checksum there. In case where the data is a group descriptor block, +it will corrupt the last group descriptor, and then e2fsck will +complain about it it. + +As all the metadata checksums should already be OK when we do the +backup, remove the wrong ext4_superblock_csum_set and it should be +just fine. + +Reported-by: "Theodore Ts'o" +Signed-off-by: Tao Ma +Signed-off-by: "Theodore Ts'o" +Cc: Ben Hutchings +Signed-off-by: Greg Kroah-Hartman + +--- + fs/ext4/resize.c | 2 -- + 1 file changed, 2 deletions(-) + +--- a/fs/ext4/resize.c ++++ b/fs/ext4/resize.c +@@ -979,8 +979,6 @@ static void update_backups(struct super_ + goto exit_err; + } + +- ext4_superblock_csum_set(sb); +- + while ((group = ext4_list_backups(sb, &three, &five, &seven)) < last) { + struct buffer_head *bh; + diff --git a/queue-3.6/get_dvb_firmware-fix-download-site-for-tda10046-firmware.patch b/queue-3.6/get_dvb_firmware-fix-download-site-for-tda10046-firmware.patch new file mode 100644 index 00000000000..2dbe343997a --- /dev/null +++ b/queue-3.6/get_dvb_firmware-fix-download-site-for-tda10046-firmware.patch @@ -0,0 +1,31 @@ +From 25ec43d3e6306978cf66060ed18c4160ce8fc302 Mon Sep 17 00:00:00 2001 +From: Mauro Carvalho Chehab +Date: Fri, 28 Sep 2012 16:16:00 -0300 +Subject: get_dvb_firmware: fix download site for tda10046 firmware + +From: Mauro Carvalho Chehab + +commit 25ec43d3e6306978cf66060ed18c4160ce8fc302 upstream. + +The previous website doesn't exist anymore. Update it to one site that +actually exists. + +Signed-off-by: Mauro Carvalho Chehab +Signed-off-by: Peter Huewe +Signed-off-by: Greg Kroah-Hartman + +--- + Documentation/dvb/get_dvb_firmware | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/Documentation/dvb/get_dvb_firmware ++++ b/Documentation/dvb/get_dvb_firmware +@@ -116,7 +116,7 @@ sub tda10045 { + + sub tda10046 { + my $sourcefile = "TT_PCI_2.19h_28_11_2006.zip"; +- my $url = "http://www.tt-download.com/download/updates/219/$sourcefile"; ++ my $url = "http://technotrend.com.ua/download/software/219/$sourcefile"; + my $hash = "6a7e1e2f2644b162ff0502367553c72d"; + my $outfile = "dvb-fe-tda10046.fw"; + my $tmpdir = tempdir(DIR => "/tmp", CLEANUP => 1); diff --git a/queue-3.6/mm-vmscan-check-for-fatal-signals-iff-the-process-was-throttled.patch b/queue-3.6/mm-vmscan-check-for-fatal-signals-iff-the-process-was-throttled.patch new file mode 100644 index 00000000000..6584f9f1f08 --- /dev/null +++ b/queue-3.6/mm-vmscan-check-for-fatal-signals-iff-the-process-was-throttled.patch @@ -0,0 +1,138 @@ +From 50694c28f1e1dbea18272980d265742a5027fb63 Mon Sep 17 00:00:00 2001 +From: Mel Gorman +Date: Mon, 26 Nov 2012 16:29:48 -0800 +Subject: mm: vmscan: check for fatal signals iff the process was throttled + +From: Mel Gorman + +commit 50694c28f1e1dbea18272980d265742a5027fb63 upstream. + +Commit 5515061d22f0 ("mm: throttle direct reclaimers if PF_MEMALLOC +reserves are low and swap is backed by network storage") introduced a +check for fatal signals after a process gets throttled for network +storage. The intention was that if a process was throttled and got +killed that it should not trigger the OOM killer. As pointed out by +Minchan Kim and David Rientjes, this check is in the wrong place and too +broad. If a system is in am OOM situation and a process is exiting, it +can loop in __alloc_pages_slowpath() and calling direct reclaim in a +loop. As the fatal signal is pending it returns 1 as if it is making +forward progress and can effectively deadlock. + +This patch moves the fatal_signal_pending() check after throttling to +throttle_direct_reclaim() where it belongs. If the process is killed +while throttled, it will return immediately without direct reclaim +except now it will have TIF_MEMDIE set and will use the PFMEMALLOC +reserves. + +Minchan pointed out that it may be better to direct reclaim before +returning to avoid using the reserves because there may be pages that +can easily reclaim that would avoid using the reserves. However, we do +no such targetted reclaim and there is no guarantee that suitable pages +are available. As it is expected that this throttling happens when +swap-over-NFS is used there is a possibility that the process will +instead swap which may allocate network buffers from the PFMEMALLOC +reserves. Hence, in the swap-over-nfs case where a process can be +throtted and be killed it can use the reserves to exit or it can +potentially use reserves to swap a few pages and then exit. This patch +takes the option of using the reserves if necessary to allow the process +exit quickly. + +If this patch passes review it should be considered a -stable candidate +for 3.6. + +Signed-off-by: Mel Gorman +Cc: David Rientjes +Cc: Luigi Semenzato +Cc: Dan Magenheimer +Cc: KOSAKI Motohiro +Cc: Sonny Rao +Cc: Minchan Kim +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +Signed-off-by: CAI Qian +Signed-off-by: Greg Kroah-Hartman + +--- + mm/vmscan.c | 37 +++++++++++++++++++++++++++---------- + 1 file changed, 27 insertions(+), 10 deletions(-) + +--- a/mm/vmscan.c ++++ b/mm/vmscan.c +@@ -2176,9 +2176,12 @@ static bool pfmemalloc_watermark_ok(pg_d + * Throttle direct reclaimers if backing storage is backed by the network + * and the PFMEMALLOC reserve for the preferred node is getting dangerously + * depleted. kswapd will continue to make progress and wake the processes +- * when the low watermark is reached ++ * when the low watermark is reached. ++ * ++ * Returns true if a fatal signal was delivered during throttling. If this ++ * happens, the page allocator should not consider triggering the OOM killer. + */ +-static void throttle_direct_reclaim(gfp_t gfp_mask, struct zonelist *zonelist, ++static bool throttle_direct_reclaim(gfp_t gfp_mask, struct zonelist *zonelist, + nodemask_t *nodemask) + { + struct zone *zone; +@@ -2193,13 +2196,20 @@ static void throttle_direct_reclaim(gfp_ + * processes to block on log_wait_commit(). + */ + if (current->flags & PF_KTHREAD) +- return; ++ goto out; ++ ++ /* ++ * If a fatal signal is pending, this process should not throttle. ++ * It should return quickly so it can exit and free its memory ++ */ ++ if (fatal_signal_pending(current)) ++ goto out; + + /* Check if the pfmemalloc reserves are ok */ + first_zones_zonelist(zonelist, high_zoneidx, NULL, &zone); + pgdat = zone->zone_pgdat; + if (pfmemalloc_watermark_ok(pgdat)) +- return; ++ goto out; + + /* Account for the throttling */ + count_vm_event(PGSCAN_DIRECT_THROTTLE); +@@ -2215,12 +2225,20 @@ static void throttle_direct_reclaim(gfp_ + if (!(gfp_mask & __GFP_FS)) { + wait_event_interruptible_timeout(pgdat->pfmemalloc_wait, + pfmemalloc_watermark_ok(pgdat), HZ); +- return; ++ ++ goto check_pending; + } + + /* Throttle until kswapd wakes the process */ + wait_event_killable(zone->zone_pgdat->pfmemalloc_wait, + pfmemalloc_watermark_ok(pgdat)); ++ ++check_pending: ++ if (fatal_signal_pending(current)) ++ return true; ++ ++out: ++ return false; + } + + unsigned long try_to_free_pages(struct zonelist *zonelist, int order, +@@ -2242,13 +2260,12 @@ unsigned long try_to_free_pages(struct z + .gfp_mask = sc.gfp_mask, + }; + +- throttle_direct_reclaim(gfp_mask, zonelist, nodemask); +- + /* +- * Do not enter reclaim if fatal signal is pending. 1 is returned so +- * that the page allocator does not consider triggering OOM ++ * Do not enter reclaim if fatal signal was delivered while throttled. ++ * 1 is returned so that the page allocator does not OOM kill at this ++ * point. + */ +- if (fatal_signal_pending(current)) ++ if (throttle_direct_reclaim(gfp_mask, zonelist, nodemask)) + return 1; + + trace_mm_vmscan_direct_reclaim_begin(order, diff --git a/queue-3.6/mmc-sdhci-s3c-fix-the-wrong-number-of-max-bus-clocks.patch b/queue-3.6/mmc-sdhci-s3c-fix-the-wrong-number-of-max-bus-clocks.patch new file mode 100644 index 00000000000..b4d9abd4b59 --- /dev/null +++ b/queue-3.6/mmc-sdhci-s3c-fix-the-wrong-number-of-max-bus-clocks.patch @@ -0,0 +1,33 @@ +From 5feb54a1ab91a237e247c013b8c4fb100ea347b1 Mon Sep 17 00:00:00 2001 +From: Jaehoon Chung +Date: Wed, 19 Sep 2012 14:43:33 +0800 +Subject: mmc: sdhci-s3c: fix the wrong number of max bus clocks + +From: Jaehoon Chung + +commit 5feb54a1ab91a237e247c013b8c4fb100ea347b1 upstream. + +We can use up to four bus-clocks; but on module remove, we didn't +disable the fourth bus clock. + +Signed-off-by: Jaehoon Chung +Signed-off-by: Kyungmin Park +Signed-off-by: Chris Ball +Cc: Ben Hutchings +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/mmc/host/sdhci-s3c.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/mmc/host/sdhci-s3c.c ++++ b/drivers/mmc/host/sdhci-s3c.c +@@ -656,7 +656,7 @@ static int __devexit sdhci_s3c_remove(st + + pm_runtime_disable(&pdev->dev); + +- for (ptr = 0; ptr < 3; ptr++) { ++ for (ptr = 0; ptr < MAX_BUS_CLK; ptr++) { + if (sc->clk_bus[ptr]) { + clk_disable(sc->clk_bus[ptr]); + clk_put(sc->clk_bus[ptr]); diff --git a/queue-3.6/mpi-fix-compilation-on-mips-with-gcc-4.4-and-newer.patch b/queue-3.6/mpi-fix-compilation-on-mips-with-gcc-4.4-and-newer.patch new file mode 100644 index 00000000000..e7988eb661a --- /dev/null +++ b/queue-3.6/mpi-fix-compilation-on-mips-with-gcc-4.4-and-newer.patch @@ -0,0 +1,66 @@ +From a3cea9894157c20a5b1ec08b7e0b5f2019740c10 Mon Sep 17 00:00:00 2001 +From: Manuel Lauss +Date: Thu, 22 Nov 2012 11:58:22 +0100 +Subject: MPI: Fix compilation on MIPS with GCC 4.4 and newer + +From: Manuel Lauss + +commit a3cea9894157c20a5b1ec08b7e0b5f2019740c10 upstream. + +Since 4.4 GCC on MIPS no longer recognizes the "h" constraint, +leading to this build failure: + + CC lib/mpi/generic_mpih-mul1.o +lib/mpi/generic_mpih-mul1.c: In function 'mpihelp_mul_1': +lib/mpi/generic_mpih-mul1.c:50:3: error: impossible constraint in 'asm' + +This patch updates MPI with the latest umul_ppm implementations for MIPS. + +Signed-off-by: Manuel Lauss +Cc: Linux-MIPS +Cc: Dmitry Kasatkin +Cc: James Morris +Patchwork: https://patchwork.linux-mips.org/patch/4612/ +Signed-off-by: Ralf Baechle +Cc: Shuah Khan +Signed-off-by: Greg Kroah-Hartman + +--- + lib/mpi/longlong.h | 19 +++++++++++++++++-- + 1 file changed, 17 insertions(+), 2 deletions(-) + +--- a/lib/mpi/longlong.h ++++ b/lib/mpi/longlong.h +@@ -703,7 +703,14 @@ do { \ + ************** MIPS ***************** + ***************************************/ + #if defined(__mips__) && W_TYPE_SIZE == 32 +-#if __GNUC__ > 2 || __GNUC_MINOR__ >= 7 ++#if __GNUC__ >= 4 && __GNUC_MINOR__ >= 4 ++#define umul_ppmm(w1, w0, u, v) \ ++do { \ ++ UDItype __ll = (UDItype)(u) * (v); \ ++ w1 = __ll >> 32; \ ++ w0 = __ll; \ ++} while (0) ++#elif __GNUC__ > 2 || __GNUC_MINOR__ >= 7 + #define umul_ppmm(w1, w0, u, v) \ + __asm__ ("multu %2,%3" \ + : "=l" ((USItype)(w0)), \ +@@ -728,7 +735,15 @@ do { \ + ************** MIPS/64 ************** + ***************************************/ + #if (defined(__mips) && __mips >= 3) && W_TYPE_SIZE == 64 +-#if __GNUC__ > 2 || __GNUC_MINOR__ >= 7 ++#if __GNUC__ >= 4 && __GNUC_MINOR__ >= 4 ++#define umul_ppmm(w1, w0, u, v) \ ++do { \ ++ typedef unsigned int __ll_UTItype __attribute__((mode(TI))); \ ++ __ll_UTItype __ll = (__ll_UTItype)(u) * (v); \ ++ w1 = __ll >> 64; \ ++ w0 = __ll; \ ++} while (0) ++#elif __GNUC__ > 2 || __GNUC_MINOR__ >= 7 + #define umul_ppmm(w1, w0, u, v) \ + __asm__ ("dmultu %2,%3" \ + : "=l" ((UDItype)(w0)), \ diff --git a/queue-3.6/nfc-fix-nfc_llcp_local-chained-list-insertion.patch b/queue-3.6/nfc-fix-nfc_llcp_local-chained-list-insertion.patch new file mode 100644 index 00000000000..d8290d386b6 --- /dev/null +++ b/queue-3.6/nfc-fix-nfc_llcp_local-chained-list-insertion.patch @@ -0,0 +1,31 @@ +From 16a78e9fed5e8baa8480ae3413f4328c4537c599 Mon Sep 17 00:00:00 2001 +From: Thierry Escande +Date: Fri, 12 Oct 2012 15:25:43 +0200 +Subject: NFC: Fix nfc_llcp_local chained list insertion + +From: Thierry Escande + +commit 16a78e9fed5e8baa8480ae3413f4328c4537c599 upstream. + +list_add was called with swapped parameters + +Signed-off-by: Thierry Escande +Signed-off-by: Samuel Ortiz +Signed-off-by: Peter Huewe +Signed-off-by: Greg Kroah-Hartman + +--- + net/nfc/llcp/llcp.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/net/nfc/llcp/llcp.c ++++ b/net/nfc/llcp/llcp.c +@@ -1190,7 +1190,7 @@ int nfc_llcp_register_device(struct nfc_ + local->remote_miu = LLCP_DEFAULT_MIU; + local->remote_lto = LLCP_DEFAULT_LTO; + +- list_add(&llcp_devices, &local->list); ++ list_add(&local->list, &llcp_devices); + + return 0; + diff --git a/queue-3.6/nfc-fix-pn533-target-mode-memory-leak.patch b/queue-3.6/nfc-fix-pn533-target-mode-memory-leak.patch new file mode 100644 index 00000000000..01963959260 --- /dev/null +++ b/queue-3.6/nfc-fix-pn533-target-mode-memory-leak.patch @@ -0,0 +1,44 @@ +From 5b412fd11c918171c98a253d8a3484afa9f69ca5 Mon Sep 17 00:00:00 2001 +From: Thierry Escande +Date: Thu, 15 Nov 2012 18:24:28 +0100 +Subject: NFC: Fix pn533 target mode memory leak + +From: Thierry Escande + +commit 5b412fd11c918171c98a253d8a3484afa9f69ca5 upstream. + +In target mode, sent sk_buff were not freed in pn533_tm_send_complete + +Signed-off-by: Thierry Escande +Signed-off-by: Samuel Ortiz +Signed-off-by: Peter Huewe +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/nfc/pn533.c | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +--- a/drivers/nfc/pn533.c ++++ b/drivers/nfc/pn533.c +@@ -2014,8 +2014,12 @@ error: + static int pn533_tm_send_complete(struct pn533 *dev, void *arg, + u8 *params, int params_len) + { ++ struct sk_buff *skb_out = arg; ++ + nfc_dev_dbg(&dev->interface->dev, "%s", __func__); + ++ dev_kfree_skb(skb_out); ++ + if (params_len < 0) { + nfc_dev_err(&dev->interface->dev, + "Error %d when sending data", +@@ -2053,7 +2057,7 @@ static int pn533_tm_send(struct nfc_dev + + rc = pn533_send_cmd_frame_async(dev, out_frame, dev->in_frame, + dev->in_maxlen, pn533_tm_send_complete, +- NULL, GFP_KERNEL); ++ skb, GFP_KERNEL); + if (rc) { + nfc_dev_err(&dev->interface->dev, + "Error %d when trying to send data", rc); diff --git a/queue-3.6/nfc-pn533-fix-mem-leak-in-pn533_in_dep_link_up.patch b/queue-3.6/nfc-pn533-fix-mem-leak-in-pn533_in_dep_link_up.patch new file mode 100644 index 00000000000..e995f56333e --- /dev/null +++ b/queue-3.6/nfc-pn533-fix-mem-leak-in-pn533_in_dep_link_up.patch @@ -0,0 +1,58 @@ +From 70418e6efcf4f8652cc08e3f2ab8ae35f0948fd9 Mon Sep 17 00:00:00 2001 +From: Waldemar Rymarkiewicz +Date: Thu, 11 Oct 2012 14:04:00 +0200 +Subject: NFC: pn533: Fix mem leak in pn533_in_dep_link_up + +From: Waldemar Rymarkiewicz + +commit 70418e6efcf4f8652cc08e3f2ab8ae35f0948fd9 upstream. + +cmd is allocated in pn533_dep_link_up and passed as an arg to +pn533_send_cmd_frame_async together with a complete cb. + +arg is passed to the cb and must be kfreed there. + +Signed-off-by: Waldemar Rymarkiewicz +Signed-off-by: Samuel Ortiz +Signed-off-by: Peter Huewe +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/nfc/pn533.c | 8 +++++--- + 1 file changed, 5 insertions(+), 3 deletions(-) + +--- a/drivers/nfc/pn533.c ++++ b/drivers/nfc/pn533.c +@@ -1618,11 +1618,14 @@ static void pn533_deactivate_target(stru + static int pn533_in_dep_link_up_complete(struct pn533 *dev, void *arg, + u8 *params, int params_len) + { +- struct pn533_cmd_jump_dep *cmd; + struct pn533_cmd_jump_dep_response *resp; + struct nfc_target nfc_target; + u8 target_gt_len; + int rc; ++ struct pn533_cmd_jump_dep *cmd = (struct pn533_cmd_jump_dep *)arg; ++ u8 active = cmd->active; ++ ++ kfree(arg); + + if (params_len == -ENOENT) { + nfc_dev_dbg(&dev->interface->dev, ""); +@@ -1644,7 +1647,6 @@ static int pn533_in_dep_link_up_complete + } + + resp = (struct pn533_cmd_jump_dep_response *) params; +- cmd = (struct pn533_cmd_jump_dep *) arg; + rc = resp->status & PN533_CMD_RET_MASK; + if (rc != PN533_CMD_RET_SUCCESS) { + nfc_dev_err(&dev->interface->dev, +@@ -1674,7 +1676,7 @@ static int pn533_in_dep_link_up_complete + if (rc == 0) + rc = nfc_dep_link_is_up(dev->nfc_dev, + dev->nfc_dev->targets[0].idx, +- !cmd->active, NFC_RF_INITIATOR); ++ !active, NFC_RF_INITIATOR); + + return 0; + } diff --git a/queue-3.6/nfc-pn533-fix-use-after-free.patch b/queue-3.6/nfc-pn533-fix-use-after-free.patch new file mode 100644 index 00000000000..4dba5fae616 --- /dev/null +++ b/queue-3.6/nfc-pn533-fix-use-after-free.patch @@ -0,0 +1,39 @@ +From 770f750bc2b8312489c8e45306f551d08a319d3c Mon Sep 17 00:00:00 2001 +From: Szymon Janc +Date: Mon, 29 Oct 2012 14:04:43 +0100 +Subject: NFC: pn533: Fix use after free + +From: Szymon Janc + +commit 770f750bc2b8312489c8e45306f551d08a319d3c upstream. + +cmd was freed in pn533_dep_link_up regardless of +pn533_send_cmd_frame_async return code. Cmd is passed as argument to +pn533_in_dep_link_up_complete callback and should be freed there. + +Signed-off-by: Szymon Janc +Signed-off-by: Samuel Ortiz +Signed-off-by: Peter Huewe +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/nfc/pn533.c | 8 ++------ + 1 file changed, 2 insertions(+), 6 deletions(-) + +--- a/drivers/nfc/pn533.c ++++ b/drivers/nfc/pn533.c +@@ -1759,12 +1759,8 @@ static int pn533_dep_link_up(struct nfc_ + rc = pn533_send_cmd_frame_async(dev, dev->out_frame, dev->in_frame, + dev->in_maxlen, pn533_in_dep_link_up_complete, + cmd, GFP_KERNEL); +- if (rc) +- goto out; +- +- +-out: +- kfree(cmd); ++ if (rc < 0) ++ kfree(cmd); + + return rc; + } diff --git a/queue-3.6/powerpc-eeh-lock-module-while-handling-eeh-event.patch b/queue-3.6/powerpc-eeh-lock-module-while-handling-eeh-event.patch new file mode 100644 index 00000000000..6a6ae6a2bc8 --- /dev/null +++ b/queue-3.6/powerpc-eeh-lock-module-while-handling-eeh-event.patch @@ -0,0 +1,260 @@ +From feadf7c0a1a7c08c74bebb4a13b755f8c40e3bbc Mon Sep 17 00:00:00 2001 +From: Gavin Shan +Date: Mon, 17 Sep 2012 04:34:27 +0000 +Subject: powerpc/eeh: Lock module while handling EEH event + +From: Gavin Shan + +commit feadf7c0a1a7c08c74bebb4a13b755f8c40e3bbc upstream. + +The EEH core is talking with the PCI device driver to determine the +action (purely reset, or PCI device removal). During the period, the +driver might be unloaded and in turn causes kernel crash as follows: + +EEH: Detected PCI bus error on PHB#4-PE#10000 +EEH: This PCI device has failed 3 times in the last hour +lpfc 0004:01:00.0: 0:2710 PCI channel disable preparing for reset +Unable to handle kernel paging request for data at address 0x00000490 +Faulting instruction address: 0xd00000000e682c90 +cpu 0x1: Vector: 300 (Data Access) at [c000000fc75ffa20] + pc: d00000000e682c90: .lpfc_io_error_detected+0x30/0x240 [lpfc] + lr: d00000000e682c8c: .lpfc_io_error_detected+0x2c/0x240 [lpfc] + sp: c000000fc75ffca0 + msr: 8000000000009032 + dar: 490 + dsisr: 40000000 + current = 0xc000000fc79b88b0 + paca = 0xc00000000edb0380 softe: 0 irq_happened: 0x00 + pid = 3386, comm = eehd +enter ? for help +[c000000fc75ffca0] c000000fc75ffd30 (unreliable) +[c000000fc75ffd30] c00000000004fd3c .eeh_report_error+0x7c/0xf0 +[c000000fc75ffdc0] c00000000004ee00 .eeh_pe_dev_traverse+0xa0/0x180 +[c000000fc75ffe70] c00000000004ffd8 .eeh_handle_event+0x68/0x300 +[c000000fc75fff00] c0000000000503a0 .eeh_event_handler+0x130/0x1a0 +[c000000fc75fff90] c000000000020138 .kernel_thread+0x54/0x70 +1:mon> + +The patch increases the reference of the corresponding driver modules +while EEH core does the negotiation with PCI device driver so that the +corresponding driver modules can't be unloaded during the period and +we're safe to refer the callbacks. + +Reported-by: Alexey Kardashevskiy +Signed-off-by: Gavin Shan +Signed-off-by: Benjamin Herrenschmidt +[ herton: backported for 3.5, adjusted driver assignments, return 0 + instead of NULL, assume dev is not NULL ] +Signed-off-by: Herton Ronaldo Krzesinski +Cc: Ben Hutchings +Signed-off-by: Greg Kroah-Hartman +--- + arch/powerpc/platforms/pseries/eeh_driver.c | 95 +++++++++++++++++++++------- + 1 file changed, 74 insertions(+), 21 deletions(-) + +--- a/arch/powerpc/platforms/pseries/eeh_driver.c ++++ b/arch/powerpc/platforms/pseries/eeh_driver.c +@@ -25,6 +25,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -47,6 +48,41 @@ static inline const char *eeh_pcid_name( + return ""; + } + ++/** ++ * eeh_pcid_get - Get the PCI device driver ++ * @pdev: PCI device ++ * ++ * The function is used to retrieve the PCI device driver for ++ * the indicated PCI device. Besides, we will increase the reference ++ * of the PCI device driver to prevent that being unloaded on ++ * the fly. Otherwise, kernel crash would be seen. ++ */ ++static inline struct pci_driver *eeh_pcid_get(struct pci_dev *pdev) ++{ ++ if (!pdev || !pdev->driver) ++ return NULL; ++ ++ if (!try_module_get(pdev->driver->driver.owner)) ++ return NULL; ++ ++ return pdev->driver; ++} ++ ++/** ++ * eeh_pcid_put - Dereference on the PCI device driver ++ * @pdev: PCI device ++ * ++ * The function is called to do dereference on the PCI device ++ * driver of the indicated PCI device. ++ */ ++static inline void eeh_pcid_put(struct pci_dev *pdev) ++{ ++ if (!pdev || !pdev->driver) ++ return; ++ ++ module_put(pdev->driver->driver.owner); ++} ++ + #if 0 + static void print_device_node_tree(struct pci_dn *pdn, int dent) + { +@@ -126,18 +162,20 @@ static void eeh_enable_irq(struct pci_de + static int eeh_report_error(struct pci_dev *dev, void *userdata) + { + enum pci_ers_result rc, *res = userdata; +- struct pci_driver *driver = dev->driver; ++ struct pci_driver *driver; + + dev->error_state = pci_channel_io_frozen; + +- if (!driver) +- return 0; ++ driver = eeh_pcid_get(dev); ++ if (!driver) return 0; + + eeh_disable_irq(dev); + + if (!driver->err_handler || +- !driver->err_handler->error_detected) ++ !driver->err_handler->error_detected) { ++ eeh_pcid_put(dev); + return 0; ++ } + + rc = driver->err_handler->error_detected(dev, pci_channel_io_frozen); + +@@ -145,6 +183,7 @@ static int eeh_report_error(struct pci_d + if (rc == PCI_ERS_RESULT_NEED_RESET) *res = rc; + if (*res == PCI_ERS_RESULT_NONE) *res = rc; + ++ eeh_pcid_put(dev); + return 0; + } + +@@ -160,12 +199,16 @@ static int eeh_report_error(struct pci_d + static int eeh_report_mmio_enabled(struct pci_dev *dev, void *userdata) + { + enum pci_ers_result rc, *res = userdata; +- struct pci_driver *driver = dev->driver; ++ struct pci_driver *driver; + +- if (!driver || +- !driver->err_handler || +- !driver->err_handler->mmio_enabled) ++ driver = eeh_pcid_get(dev); ++ if (!driver) return 0; ++ ++ if (!driver->err_handler || ++ !driver->err_handler->mmio_enabled) { ++ eeh_pcid_put(dev); + return 0; ++ } + + rc = driver->err_handler->mmio_enabled(dev); + +@@ -173,6 +216,7 @@ static int eeh_report_mmio_enabled(struc + if (rc == PCI_ERS_RESULT_NEED_RESET) *res = rc; + if (*res == PCI_ERS_RESULT_NONE) *res = rc; + ++ eeh_pcid_put(dev); + return 0; + } + +@@ -189,18 +233,20 @@ static int eeh_report_mmio_enabled(struc + static int eeh_report_reset(struct pci_dev *dev, void *userdata) + { + enum pci_ers_result rc, *res = userdata; +- struct pci_driver *driver = dev->driver; +- +- if (!driver) +- return 0; ++ struct pci_driver *driver; + + dev->error_state = pci_channel_io_normal; + ++ driver = eeh_pcid_get(dev); ++ if (!driver) return 0; ++ + eeh_enable_irq(dev); + + if (!driver->err_handler || +- !driver->err_handler->slot_reset) ++ !driver->err_handler->slot_reset) { ++ eeh_pcid_put(dev); + return 0; ++ } + + rc = driver->err_handler->slot_reset(dev); + if ((*res == PCI_ERS_RESULT_NONE) || +@@ -208,6 +254,7 @@ static int eeh_report_reset(struct pci_d + if (*res == PCI_ERS_RESULT_DISCONNECT && + rc == PCI_ERS_RESULT_NEED_RESET) *res = rc; + ++ eeh_pcid_put(dev); + return 0; + } + +@@ -222,21 +269,24 @@ static int eeh_report_reset(struct pci_d + */ + static int eeh_report_resume(struct pci_dev *dev, void *userdata) + { +- struct pci_driver *driver = dev->driver; ++ struct pci_driver *driver; + + dev->error_state = pci_channel_io_normal; + +- if (!driver) +- return 0; ++ driver = eeh_pcid_get(dev); ++ if (!driver) return 0; + + eeh_enable_irq(dev); + + if (!driver->err_handler || +- !driver->err_handler->resume) ++ !driver->err_handler->resume) { ++ eeh_pcid_put(dev); + return 0; ++ } + + driver->err_handler->resume(dev); + ++ eeh_pcid_put(dev); + return 0; + } + +@@ -250,21 +300,24 @@ static int eeh_report_resume(struct pci_ + */ + static int eeh_report_failure(struct pci_dev *dev, void *userdata) + { +- struct pci_driver *driver = dev->driver; ++ struct pci_driver *driver; + + dev->error_state = pci_channel_io_perm_failure; + +- if (!driver) +- return 0; ++ driver = eeh_pcid_get(dev); ++ if (!driver) return 0; + + eeh_disable_irq(dev); + + if (!driver->err_handler || +- !driver->err_handler->error_detected) ++ !driver->err_handler->error_detected) { ++ eeh_pcid_put(dev); + return 0; ++ } + + driver->err_handler->error_detected(dev, pci_channel_io_perm_failure); + ++ eeh_pcid_put(dev); + return 0; + } + diff --git a/queue-3.6/series b/queue-3.6/series index 83585a42668..f8b4c650161 100644 --- a/queue-3.6/series +++ b/queue-3.6/series @@ -40,3 +40,14 @@ hid-add-quirk-for-freescale-i.mx28-rom-recovery.patch kvm-x86-invalid-opcode-oops-on-set_sregs-with-osxsave-bit-set-cve-2012-4461.patch ixgbe-add-support-for-x540-at1.patch sata_svw-check-dma-start-bit-before-reset.patch +get_dvb_firmware-fix-download-site-for-tda10046-firmware.patch +nfc-pn533-fix-use-after-free.patch +nfc-fix-pn533-target-mode-memory-leak.patch +nfc-pn533-fix-mem-leak-in-pn533_in_dep_link_up.patch +nfc-fix-nfc_llcp_local-chained-list-insertion.patch +mm-vmscan-check-for-fatal-signals-iff-the-process-was-throttled.patch +watchdog-using-u64-in-get_sample_period.patch +mpi-fix-compilation-on-mips-with-gcc-4.4-and-newer.patch +ext4-remove-erroneous-ext4_superblock_csum_set-in-update_backups.patch +powerpc-eeh-lock-module-while-handling-eeh-event.patch +mmc-sdhci-s3c-fix-the-wrong-number-of-max-bus-clocks.patch diff --git a/queue-3.6/watchdog-using-u64-in-get_sample_period.patch b/queue-3.6/watchdog-using-u64-in-get_sample_period.patch new file mode 100644 index 00000000000..c03223e9d4b --- /dev/null +++ b/queue-3.6/watchdog-using-u64-in-get_sample_period.patch @@ -0,0 +1,53 @@ +From 8ffeb9b0e6369135bf03a073514f571ef10606b9 Mon Sep 17 00:00:00 2001 +From: Chuansheng Liu +Date: Mon, 26 Nov 2012 16:29:54 -0800 +Subject: watchdog: using u64 in get_sample_period() + +From: Chuansheng Liu + +commit 8ffeb9b0e6369135bf03a073514f571ef10606b9 upstream. + +In get_sample_period(), unsigned long is not enough: + + watchdog_thresh * 2 * (NSEC_PER_SEC / 5) + +case1: + watchdog_thresh is 10 by default, the sample value will be: 0xEE6B2800 + +case2: + set watchdog_thresh is 20, the sample value will be: 0x1 DCD6 5000 + +In case2, we need use u64 to express the sample period. Otherwise, +changing the threshold thru proc often can not be successful. + +Signed-off-by: liu chuansheng +Acked-by: Don Zickus +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +Signed-off-by: Shuah Khan +Signed-off-by: Greg Kroah-Hartman + +--- + kernel/watchdog.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/kernel/watchdog.c ++++ b/kernel/watchdog.c +@@ -113,7 +113,7 @@ static unsigned long get_timestamp(int t + return cpu_clock(this_cpu) >> 30LL; /* 2^30 ~= 10^9 */ + } + +-static unsigned long get_sample_period(void) ++static u64 get_sample_period(void) + { + /* + * convert watchdog_thresh from seconds to ns +@@ -122,7 +122,7 @@ static unsigned long get_sample_period(v + * and hard thresholds) to increment before the + * hardlockup detector generates a warning + */ +- return get_softlockup_thresh() * (NSEC_PER_SEC / 5); ++ return get_softlockup_thresh() * ((u64)NSEC_PER_SEC / 5); + } + + /* Commands for resetting the watchdog */