From: Greg Kroah-Hartman Date: Fri, 30 Nov 2012 02:03:01 +0000 (-0800) Subject: 3.4-stable patches X-Git-Tag: v3.6.9~4 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=e35b7f8f0e8d33b46c26b8250b21419f43914dd2;p=thirdparty%2Fkernel%2Fstable-queue.git 3.4-stable patches added patches: arm-omap-counter-add-locking-to-read_persistent_clock.patch get_dvb_firmware-fix-download-site-for-tda10046-firmware.patch iwlwifi-fix-6000-series-channel-switch-command.patch mmc-sdhci-s3c-fix-the-wrong-number-of-max-bus-clocks.patch mpi-fix-compilation-on-mips-with-gcc-4.4-and-newer.patch net-wireless-ipw2200-fix-panic-occurring-in-ipw_handle_promiscuous_tx.patch nfc-fix-nfc_llcp_local-chained-list-insertion.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 timekeeping-cast-raw_interval-to-u64-to-avoid-shift-overflow.patch usb-mct_u232-fix-broken-close.patch watchdog-using-u64-in-get_sample_period.patch --- diff --git a/queue-3.4/arm-omap-counter-add-locking-to-read_persistent_clock.patch b/queue-3.4/arm-omap-counter-add-locking-to-read_persistent_clock.patch new file mode 100644 index 00000000000..158833381f0 --- /dev/null +++ b/queue-3.4/arm-omap-counter-add-locking-to-read_persistent_clock.patch @@ -0,0 +1,59 @@ +From: Colin Cross +Date: Mon, 8 Oct 2012 14:01:12 -0700 +Subject: ARM: OMAP: counter: add locking to read_persistent_clock + +commit 9d7d6e363b06934221b81a859d509844c97380df upstream. + +read_persistent_clock uses a global variable, use a spinlock to +ensure non-atomic updates to the variable don't overlap and cause +time to move backwards. + +Signed-off-by: Colin Cross +Signed-off-by: R Sricharan +Signed-off-by: Tony Lindgren +[bwh: Backported to 3.2: adjust context] +Signed-off-by: Ben Hutchings +Signed-off-by: Greg Kroah-Hartman +--- + arch/arm/plat-omap/counter_32k.c | 21 ++++++++++++++------- + 1 file changed, 14 insertions(+), 7 deletions(-) + +--- a/arch/arm/plat-omap/counter_32k.c ++++ b/arch/arm/plat-omap/counter_32k.c +@@ -50,22 +50,29 @@ static u32 notrace omap_32k_read_sched_c + * nsecs and adds to a monotonically increasing timespec. + */ + static struct timespec persistent_ts; +-static cycles_t cycles, last_cycles; ++static cycles_t cycles; + static unsigned int persistent_mult, persistent_shift; ++static DEFINE_SPINLOCK(read_persistent_clock_lock); ++ + void read_persistent_clock(struct timespec *ts) + { + unsigned long long nsecs; +- cycles_t delta; +- struct timespec *tsp = &persistent_ts; ++ cycles_t last_cycles; ++ unsigned long flags; ++ ++ spin_lock_irqsave(&read_persistent_clock_lock, flags); + + last_cycles = cycles; + cycles = timer_32k_base ? __raw_readl(timer_32k_base) : 0; +- delta = cycles - last_cycles; + +- nsecs = clocksource_cyc2ns(delta, persistent_mult, persistent_shift); ++ nsecs = clocksource_cyc2ns(cycles - last_cycles, ++ persistent_mult, persistent_shift); ++ ++ timespec_add_ns(&persistent_ts, nsecs); ++ ++ *ts = persistent_ts; + +- timespec_add_ns(tsp, nsecs); +- *ts = *tsp; ++ spin_unlock_irqrestore(&read_persistent_clock_lock, flags); + } + + int __init omap_init_clocksource_32k(void) diff --git a/queue-3.4/get_dvb_firmware-fix-download-site-for-tda10046-firmware.patch b/queue-3.4/get_dvb_firmware-fix-download-site-for-tda10046-firmware.patch new file mode 100644 index 00000000000..45d9b1ae527 --- /dev/null +++ b/queue-3.4/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 +@@ -115,7 +115,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.4/iwlwifi-fix-6000-series-channel-switch-command.patch b/queue-3.4/iwlwifi-fix-6000-series-channel-switch-command.patch new file mode 100644 index 00000000000..78a7f8ac7d0 --- /dev/null +++ b/queue-3.4/iwlwifi-fix-6000-series-channel-switch-command.patch @@ -0,0 +1,105 @@ +From 8f7b8db6e0557c8437adf9371e020cd89a7e85dc Mon Sep 17 00:00:00 2001 +From: Johannes Berg +Date: Tue, 25 Sep 2012 16:40:12 +0200 +Subject: iwlwifi: fix 6000 series channel switch command + +From: Johannes Berg + +commit 8f7b8db6e0557c8437adf9371e020cd89a7e85dc upstream. + +The channel switch command for 6000 series devices +is larger than the maximum inline command size of +320 bytes. The command is therefore refused with a +warning. Fix this by allocating the command and +using the NOCOPY mechanism. + +Reviewed-by: Emmanuel Grumbach +Signed-off-by: Johannes Berg +Cc: Ben Hutchings +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/net/wireless/iwlwifi/iwl-6000.c | 33 ++++++++++++++++++++------------ + 1 file changed, 21 insertions(+), 12 deletions(-) + +--- a/drivers/net/wireless/iwlwifi/iwl-6000.c ++++ b/drivers/net/wireless/iwlwifi/iwl-6000.c +@@ -170,7 +170,7 @@ static int iwl6000_hw_channel_switch(str + * See iwlagn_mac_channel_switch. + */ + struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; +- struct iwl6000_channel_switch_cmd cmd; ++ struct iwl6000_channel_switch_cmd *cmd; + const struct iwl_channel_info *ch_info; + u32 switch_time_in_usec, ucode_switch_time; + u16 ch; +@@ -180,18 +180,25 @@ static int iwl6000_hw_channel_switch(str + struct ieee80211_vif *vif = ctx->vif; + struct iwl_host_cmd hcmd = { + .id = REPLY_CHANNEL_SWITCH, +- .len = { sizeof(cmd), }, ++ .len = { sizeof(*cmd), }, + .flags = CMD_SYNC, +- .data = { &cmd, }, ++ .dataflags[0] = IWL_HCMD_DFL_NOCOPY, + }; ++ int err; + +- cmd.band = priv->band == IEEE80211_BAND_2GHZ; ++ cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); ++ if (!cmd) ++ return -ENOMEM; ++ ++ hcmd.data[0] = cmd; ++ ++ cmd->band = priv->band == IEEE80211_BAND_2GHZ; + ch = ch_switch->channel->hw_value; + IWL_DEBUG_11H(priv, "channel switch from %u to %u\n", + ctx->active.channel, ch); +- cmd.channel = cpu_to_le16(ch); +- cmd.rxon_flags = ctx->staging.flags; +- cmd.rxon_filter_flags = ctx->staging.filter_flags; ++ cmd->channel = cpu_to_le16(ch); ++ cmd->rxon_flags = ctx->staging.flags; ++ cmd->rxon_filter_flags = ctx->staging.filter_flags; + switch_count = ch_switch->count; + tsf_low = ch_switch->timestamp & 0x0ffffffff; + /* +@@ -207,30 +214,32 @@ static int iwl6000_hw_channel_switch(str + switch_count = 0; + } + if (switch_count <= 1) +- cmd.switch_time = cpu_to_le32(priv->ucode_beacon_time); ++ cmd->switch_time = cpu_to_le32(priv->ucode_beacon_time); + else { + switch_time_in_usec = + vif->bss_conf.beacon_int * switch_count * TIME_UNIT; + ucode_switch_time = iwl_usecs_to_beacons(priv, + switch_time_in_usec, + beacon_interval); +- cmd.switch_time = iwl_add_beacon_time(priv, ++ cmd->switch_time = iwl_add_beacon_time(priv, + priv->ucode_beacon_time, + ucode_switch_time, + beacon_interval); + } + IWL_DEBUG_11H(priv, "uCode time for the switch is 0x%x\n", +- cmd.switch_time); ++ cmd->switch_time); + ch_info = iwl_get_channel_info(priv, priv->band, ch); + if (ch_info) +- cmd.expect_beacon = is_channel_radar(ch_info); ++ cmd->expect_beacon = is_channel_radar(ch_info); + else { + IWL_ERR(priv, "invalid channel switch from %u to %u\n", + ctx->active.channel, ch); + return -EFAULT; + } + +- return iwl_dvm_send_cmd(priv, &hcmd); ++ err = iwl_dvm_send_cmd(priv, &hcmd); ++ kfree(cmd); ++ return err; + } + + static struct iwl_lib_ops iwl6000_lib = { diff --git a/queue-3.4/mmc-sdhci-s3c-fix-the-wrong-number-of-max-bus-clocks.patch b/queue-3.4/mmc-sdhci-s3c-fix-the-wrong-number-of-max-bus-clocks.patch new file mode 100644 index 00000000000..b4d9abd4b59 --- /dev/null +++ b/queue-3.4/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.4/mpi-fix-compilation-on-mips-with-gcc-4.4-and-newer.patch b/queue-3.4/mpi-fix-compilation-on-mips-with-gcc-4.4-and-newer.patch new file mode 100644 index 00000000000..e7988eb661a --- /dev/null +++ b/queue-3.4/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.4/net-wireless-ipw2200-fix-panic-occurring-in-ipw_handle_promiscuous_tx.patch b/queue-3.4/net-wireless-ipw2200-fix-panic-occurring-in-ipw_handle_promiscuous_tx.patch new file mode 100644 index 00000000000..17cc25737da --- /dev/null +++ b/queue-3.4/net-wireless-ipw2200-fix-panic-occurring-in-ipw_handle_promiscuous_tx.patch @@ -0,0 +1,45 @@ +From bf11315eeda510ea4fc1a2bf972d8155d31d89b4 Mon Sep 17 00:00:00 2001 +From: Stanislav Yakovlev +Date: Mon, 15 Oct 2012 14:14:32 +0000 +Subject: net/wireless: ipw2200: Fix panic occurring in ipw_handle_promiscuous_tx() + +From: Stanislav Yakovlev + +commit bf11315eeda510ea4fc1a2bf972d8155d31d89b4 upstream. + +The driver does not count space of radiotap fields when allocating skb for +radiotap packet. This leads to kernel panic with the following call trace: + +... +[67607.676067] [] error_code+0x67/0x6c +[67607.676067] [] ? skb_put+0x91/0xa0 +[67607.676067] [] ? ipw_handle_promiscuous_tx+0x16b/0x2d0 [ipw2200] +[67607.676067] [] ipw_handle_promiscuous_tx+0x16b/0x2d0 [ipw2200] +[67607.676067] [] ipw_net_hard_start_xmit+0x8b/0x90 [ipw2200] +[67607.676067] [] libipw_xmit+0x55a/0x980 [libipw] +[67607.676067] [] dev_hard_start_xmit+0x218/0x4d0 +... + +This bug was found by VittGam. +https://bugzilla.kernel.org/show_bug.cgi?id=43255 + +Signed-off-by: Stanislav Yakovlev +Signed-off-by: John W. Linville +Cc: Ben Hutchings +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/net/wireless/ipw2x00/ipw2200.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/net/wireless/ipw2x00/ipw2200.c ++++ b/drivers/net/wireless/ipw2x00/ipw2200.c +@@ -10471,7 +10471,7 @@ static void ipw_handle_promiscuous_tx(st + } else + len = src->len; + +- dst = alloc_skb(len + sizeof(*rt_hdr), GFP_ATOMIC); ++ dst = alloc_skb(len + sizeof(*rt_hdr) + sizeof(u16)*2, GFP_ATOMIC); + if (!dst) + continue; + diff --git a/queue-3.4/nfc-fix-nfc_llcp_local-chained-list-insertion.patch b/queue-3.4/nfc-fix-nfc_llcp_local-chained-list-insertion.patch new file mode 100644 index 00000000000..c77698875bd --- /dev/null +++ b/queue-3.4/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 +@@ -966,7 +966,7 @@ int nfc_llcp_register_device(struct nfc_ + local->remote_lto = LLCP_DEFAULT_LTO; + local->remote_rw = LLCP_DEFAULT_RW; + +- list_add(&llcp_devices, &local->list); ++ list_add(&local->list, &llcp_devices); + + return 0; + diff --git a/queue-3.4/nfc-pn533-fix-mem-leak-in-pn533_in_dep_link_up.patch b/queue-3.4/nfc-pn533-fix-mem-leak-in-pn533_in_dep_link_up.patch new file mode 100644 index 00000000000..99cb312266a --- /dev/null +++ b/queue-3.4/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 +@@ -1278,11 +1278,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, ""); +@@ -1304,7 +1307,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, +@@ -1334,7 +1336,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.4/nfc-pn533-fix-use-after-free.patch b/queue-3.4/nfc-pn533-fix-use-after-free.patch new file mode 100644 index 00000000000..051bc5b83e6 --- /dev/null +++ b/queue-3.4/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 +@@ -1385,12 +1385,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.4/powerpc-eeh-lock-module-while-handling-eeh-event.patch b/queue-3.4/powerpc-eeh-lock-module-while-handling-eeh-event.patch new file mode 100644 index 00000000000..6a6ae6a2bc8 --- /dev/null +++ b/queue-3.4/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.4/series b/queue-3.4/series index d271bc96962..8d37b28fcc5 100644 --- a/queue-3.4/series +++ b/queue-3.4/series @@ -41,3 +41,16 @@ scsi-silence-unnecessary-warnings-about-ioctl-to-partition.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-pn533-fix-mem-leak-in-pn533_in_dep_link_up.patch +nfc-fix-nfc_llcp_local-chained-list-insertion.patch +usb-mct_u232-fix-broken-close.patch +watchdog-using-u64-in-get_sample_period.patch +mpi-fix-compilation-on-mips-with-gcc-4.4-and-newer.patch +powerpc-eeh-lock-module-while-handling-eeh-event.patch +mmc-sdhci-s3c-fix-the-wrong-number-of-max-bus-clocks.patch +arm-omap-counter-add-locking-to-read_persistent_clock.patch +timekeeping-cast-raw_interval-to-u64-to-avoid-shift-overflow.patch +net-wireless-ipw2200-fix-panic-occurring-in-ipw_handle_promiscuous_tx.patch +iwlwifi-fix-6000-series-channel-switch-command.patch diff --git a/queue-3.4/timekeeping-cast-raw_interval-to-u64-to-avoid-shift-overflow.patch b/queue-3.4/timekeeping-cast-raw_interval-to-u64-to-avoid-shift-overflow.patch new file mode 100644 index 00000000000..2efe9b7cdfa --- /dev/null +++ b/queue-3.4/timekeeping-cast-raw_interval-to-u64-to-avoid-shift-overflow.patch @@ -0,0 +1,36 @@ +From 5b3900cd409466c0070b234d941650685ad0c791 Mon Sep 17 00:00:00 2001 +From: Dan Carpenter +Date: Tue, 9 Oct 2012 10:18:23 +0300 +Subject: timekeeping: Cast raw_interval to u64 to avoid shift overflow + +From: Dan Carpenter + +commit 5b3900cd409466c0070b234d941650685ad0c791 upstream. + +We fixed a bunch of integer overflows in timekeeping code during the 3.6 +cycle. I did an audit based on that and found this potential overflow. + +Signed-off-by: Dan Carpenter +Acked-by: John Stultz +Link: http://lkml.kernel.org/r/20121009071823.GA19159@elgon.mountain +Signed-off-by: Thomas Gleixner +Cc: Ben Hutchings +[ herton: adapt for 3.5, timekeeper instead of tk pointer ] +Signed-off-by: Herton Ronaldo Krzesinski +Signed-off-by: Greg Kroah-Hartman + +--- + kernel/time/timekeeping.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/kernel/time/timekeeping.c ++++ b/kernel/time/timekeeping.c +@@ -1014,7 +1014,7 @@ static cycle_t logarithmic_accumulation( + } + + /* Accumulate raw time */ +- raw_nsecs = timekeeper.raw_interval << shift; ++ raw_nsecs = (u64)timekeeper.raw_interval << shift; + raw_nsecs += timekeeper.raw_time.tv_nsec; + if (raw_nsecs >= NSEC_PER_SEC) { + u64 raw_secs = raw_nsecs; diff --git a/queue-3.4/usb-mct_u232-fix-broken-close.patch b/queue-3.4/usb-mct_u232-fix-broken-close.patch new file mode 100644 index 00000000000..b97e12ed771 --- /dev/null +++ b/queue-3.4/usb-mct_u232-fix-broken-close.patch @@ -0,0 +1,51 @@ +From 5260e458f5eff269a43e4f1e9c47186c57b88ddb Mon Sep 17 00:00:00 2001 +From: Johan Hovold +Date: Thu, 25 Oct 2012 10:29:14 +0200 +Subject: USB: mct_u232: fix broken close + +From: Johan Hovold + +commit 5260e458f5eff269a43e4f1e9c47186c57b88ddb upstream. + +Make sure generic close is called at close. + +The driver relies on the generic write implementation but did not call +generic close. + +Note that the call to kill the read urb is not redundant, as mct_u232 +uses an interrupt urb from the second port as the read urb and that +generic close therefore fails to kill it. + +Compile-only tested. + +Signed-off-by: Johan Hovold +Signed-off-by: Greg Kroah-Hartman +[bwh: Backported to 3.2: adjust context] +Signed-off-by: Ben Hutchings +--- + drivers/usb/serial/mct_u232.c | 14 ++++++++------ + 1 file changed, 8 insertions(+), 6 deletions(-) + +--- a/drivers/usb/serial/mct_u232.c ++++ b/drivers/usb/serial/mct_u232.c +@@ -533,12 +533,14 @@ static void mct_u232_close(struct usb_se + { + dbg("%s port %d", __func__, port->number); + +- if (port->serial->dev) { +- /* shutdown our urbs */ +- usb_kill_urb(port->write_urb); +- usb_kill_urb(port->read_urb); +- usb_kill_urb(port->interrupt_in_urb); +- } ++ /* ++ * Must kill the read urb as it is actually an interrupt urb, which ++ * generic close thus fails to kill. ++ */ ++ usb_kill_urb(port->read_urb); ++ usb_kill_urb(port->interrupt_in_urb); ++ ++ usb_serial_generic_close(port); + } /* mct_u232_close */ + + diff --git a/queue-3.4/watchdog-using-u64-in-get_sample_period.patch b/queue-3.4/watchdog-using-u64-in-get_sample_period.patch new file mode 100644 index 00000000000..b44c4110723 --- /dev/null +++ b/queue-3.4/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 +@@ -112,7 +112,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 +@@ -121,7 +121,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 */