From: Greg Kroah-Hartman Date: Tue, 3 Jun 2014 00:29:44 +0000 (-0700) Subject: 3.14-stable patches X-Git-Tag: v3.14.6~87 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=754b08817531ff805e1e79c1aa67b15931cdf0b9;p=thirdparty%2Fkernel%2Fstable-queue.git 3.14-stable patches added patches: cfg80211-add-cfg80211_sched_scan_stopped_rtnl.patch cfg80211-fix-few-minor-issues-in-reg_process_hint.patch cfg80211-free-sme-on-connection-failures.patch gpu-host1x-handle-the-correct-of-syncpt-regs.patch ipmi-fix-a-race-restarting-the-timer.patch ipmi-reset-the-kcs-timeout-when-starting-error-recovery.patch mac80211-fix-nested-rtnl-locking-on-ieee80211_reconfig.patch mac80211-fix-on-channel-remain-on-channel.patch mac80211-fix-suspend-vs.-association-race.patch timer-prevent-overflow-in-apply_slack.patch --- diff --git a/queue-3.14/cfg80211-add-cfg80211_sched_scan_stopped_rtnl.patch b/queue-3.14/cfg80211-add-cfg80211_sched_scan_stopped_rtnl.patch new file mode 100644 index 00000000000..344561bfdd6 --- /dev/null +++ b/queue-3.14/cfg80211-add-cfg80211_sched_scan_stopped_rtnl.patch @@ -0,0 +1,71 @@ +From 792e6aa7a15ea0fb16f8687e93caede1ea9118c7 Mon Sep 17 00:00:00 2001 +From: Eliad Peller +Date: Wed, 30 Apr 2014 16:14:23 +0300 +Subject: cfg80211: add cfg80211_sched_scan_stopped_rtnl + +From: Eliad Peller + +commit 792e6aa7a15ea0fb16f8687e93caede1ea9118c7 upstream. + +Add locked-version for cfg80211_sched_scan_stopped. +This is used for some users that might want to +call it when rtnl is already locked. + +Fixes: d43c6b6 ("mac80211: reschedule sched scan after HW restart") +Signed-off-by: Eliad Peller +Signed-off-by: Johannes Berg +Signed-off-by: Greg Kroah-Hartman + +--- + include/net/cfg80211.h | 12 ++++++++++++ + net/wireless/scan.c | 12 ++++++++++-- + 2 files changed, 22 insertions(+), 2 deletions(-) + +--- a/include/net/cfg80211.h ++++ b/include/net/cfg80211.h +@@ -3637,6 +3637,18 @@ void cfg80211_sched_scan_results(struct + void cfg80211_sched_scan_stopped(struct wiphy *wiphy); + + /** ++ * cfg80211_sched_scan_stopped_rtnl - notify that the scheduled scan has stopped ++ * ++ * @wiphy: the wiphy on which the scheduled scan stopped ++ * ++ * The driver can call this function to inform cfg80211 that the ++ * scheduled scan had to be stopped, for whatever reason. The driver ++ * is then called back via the sched_scan_stop operation when done. ++ * This function should be called with rtnl locked. ++ */ ++void cfg80211_sched_scan_stopped_rtnl(struct wiphy *wiphy); ++ ++/** + * cfg80211_inform_bss_width_frame - inform cfg80211 of a received BSS frame + * + * @wiphy: the wiphy reporting the BSS +--- a/net/wireless/scan.c ++++ b/net/wireless/scan.c +@@ -284,14 +284,22 @@ void cfg80211_sched_scan_results(struct + } + EXPORT_SYMBOL(cfg80211_sched_scan_results); + +-void cfg80211_sched_scan_stopped(struct wiphy *wiphy) ++void cfg80211_sched_scan_stopped_rtnl(struct wiphy *wiphy) + { + struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); + ++ ASSERT_RTNL(); ++ + trace_cfg80211_sched_scan_stopped(wiphy); + +- rtnl_lock(); + __cfg80211_stop_sched_scan(rdev, true); ++} ++EXPORT_SYMBOL(cfg80211_sched_scan_stopped_rtnl); ++ ++void cfg80211_sched_scan_stopped(struct wiphy *wiphy) ++{ ++ rtnl_lock(); ++ cfg80211_sched_scan_stopped_rtnl(wiphy); + rtnl_unlock(); + } + EXPORT_SYMBOL(cfg80211_sched_scan_stopped); diff --git a/queue-3.14/cfg80211-fix-few-minor-issues-in-reg_process_hint.patch b/queue-3.14/cfg80211-fix-few-minor-issues-in-reg_process_hint.patch new file mode 100644 index 00000000000..d795fafce48 --- /dev/null +++ b/queue-3.14/cfg80211-fix-few-minor-issues-in-reg_process_hint.patch @@ -0,0 +1,77 @@ +From 772f0389338cfcf96da1c178046dc7e1649ab554 Mon Sep 17 00:00:00 2001 +From: Ilan Peer +Date: Tue, 14 Jan 2014 15:17:23 +0200 +Subject: cfg80211: fix few minor issues in reg_process_hint() + +From: Ilan Peer + +commit 772f0389338cfcf96da1c178046dc7e1649ab554 upstream. + +Fix the following issues in reg_process_hint(): + +1. Add verification that wiphy is valid before processing + NL80211_REGDOMAIN_SET_BY_COUNTRY_IE. +2. Free the request in case of invalid initiator. +3. Remove WARN_ON check on reg_request->alpha2 as it is not a + pointer. + +Signed-off-by: Ilan Peer +Signed-off-by: Johannes Berg +Signed-off-by: Luis R. Rodriguez +Signed-off-by: Greg Kroah-Hartman + +--- + net/wireless/reg.c | 19 ++++++++++--------- + 1 file changed, 10 insertions(+), 9 deletions(-) + +--- a/net/wireless/reg.c ++++ b/net/wireless/reg.c +@@ -1683,17 +1683,9 @@ static void reg_process_hint(struct regu + struct wiphy *wiphy = NULL; + enum reg_request_treatment treatment; + +- if (WARN_ON(!reg_request->alpha2)) +- return; +- + if (reg_request->wiphy_idx != WIPHY_IDX_INVALID) + wiphy = wiphy_idx_to_wiphy(reg_request->wiphy_idx); + +- if (reg_request->initiator == NL80211_REGDOM_SET_BY_DRIVER && !wiphy) { +- kfree(reg_request); +- return; +- } +- + switch (reg_request->initiator) { + case NL80211_REGDOM_SET_BY_CORE: + reg_process_hint_core(reg_request); +@@ -1706,20 +1698,29 @@ static void reg_process_hint(struct regu + schedule_delayed_work(®_timeout, msecs_to_jiffies(3142)); + return; + case NL80211_REGDOM_SET_BY_DRIVER: ++ if (!wiphy) ++ goto out_free; + treatment = reg_process_hint_driver(wiphy, reg_request); + break; + case NL80211_REGDOM_SET_BY_COUNTRY_IE: ++ if (!wiphy) ++ goto out_free; + treatment = reg_process_hint_country_ie(wiphy, reg_request); + break; + default: + WARN(1, "invalid initiator %d\n", reg_request->initiator); +- return; ++ goto out_free; + } + + /* This is required so that the orig_* parameters are saved */ + if (treatment == REG_REQ_ALREADY_SET && wiphy && + wiphy->regulatory_flags & REGULATORY_STRICT_REG) + wiphy_update_regulatory(wiphy, reg_request->initiator); ++ ++ return; ++ ++out_free: ++ kfree(reg_request); + } + + /* diff --git a/queue-3.14/cfg80211-free-sme-on-connection-failures.patch b/queue-3.14/cfg80211-free-sme-on-connection-failures.patch new file mode 100644 index 00000000000..9ebeb040f6a --- /dev/null +++ b/queue-3.14/cfg80211-free-sme-on-connection-failures.patch @@ -0,0 +1,50 @@ +From c1fbb258846dfc425507a093922d2d001e54c3ea Mon Sep 17 00:00:00 2001 +From: Eliad Peller +Date: Wed, 30 Apr 2014 15:58:13 +0300 +Subject: cfg80211: free sme on connection failures + +From: Eliad Peller + +commit c1fbb258846dfc425507a093922d2d001e54c3ea upstream. + +cfg80211 is notified about connection failures by +__cfg80211_connect_result() call. However, this +function currently does not free cfg80211 sme. + +This results in hanging connection attempts in some cases + +e.g. when mac80211 authentication attempt is denied, +we have this function call: +ieee80211_rx_mgmt_auth() -> cfg80211_rx_mlme_mgmt() -> +cfg80211_process_auth() -> cfg80211_sme_rx_auth() -> +__cfg80211_connect_result() + +but cfg80211_sme_free() is never get called. + +Fixes: ceca7b712 ("cfg80211: separate internal SME implementation") +Signed-off-by: Eliad Peller +Signed-off-by: Johannes Berg +Signed-off-by: Greg Kroah-Hartman + +--- + net/wireless/sme.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/net/wireless/sme.c ++++ b/net/wireless/sme.c +@@ -235,7 +235,6 @@ void cfg80211_conn_work(struct work_stru + NULL, 0, NULL, 0, + WLAN_STATUS_UNSPECIFIED_FAILURE, + false, NULL); +- cfg80211_sme_free(wdev); + } + wdev_unlock(wdev); + } +@@ -649,6 +648,7 @@ void __cfg80211_connect_result(struct ne + cfg80211_unhold_bss(bss_from_pub(bss)); + cfg80211_put_bss(wdev->wiphy, bss); + } ++ cfg80211_sme_free(wdev); + return; + } + diff --git a/queue-3.14/gpu-host1x-handle-the-correct-of-syncpt-regs.patch b/queue-3.14/gpu-host1x-handle-the-correct-of-syncpt-regs.patch new file mode 100644 index 00000000000..1a1ac5b6d6c --- /dev/null +++ b/queue-3.14/gpu-host1x-handle-the-correct-of-syncpt-regs.patch @@ -0,0 +1,51 @@ +From 22bbd5d949dc7fdd72a4e78e767fa09d8e54b446 Mon Sep 17 00:00:00 2001 +From: Stephen Warren +Date: Fri, 4 Apr 2014 16:31:05 -0600 +Subject: gpu: host1x: handle the correct # of syncpt regs + +From: Stephen Warren + +commit 22bbd5d949dc7fdd72a4e78e767fa09d8e54b446 upstream. + +BIT_WORD() truncates rather than rounds, so the loops in +syncpt_thresh_isr() and _host1x_intr_disable_all_syncpt_intrs() use <= +rather than < in an attempt to process the correct number of registers +when rounding of the conversion of count of bits to count of words is +necessary. However, when rounding isn't necessary because the value is +already a multiple of the divisor (as is the case for all values of +nb_pts the code actually sees), this causes one too many registers to +be processed. + +Solve this by using and explicit DIV_ROUND_UP() call, rather than +BIT_WORD(), and comparing with < rather than <=. + +Fixes: 7ede0b0bf3e2 ("gpu: host1x: Add syncpoint wait and interrupts") +Signed-off-by: Stephen Warren +Acked-By: Terje Bergstrom +Signed-off-by: Thierry Reding +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/gpu/host1x/hw/intr_hw.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/drivers/gpu/host1x/hw/intr_hw.c ++++ b/drivers/gpu/host1x/hw/intr_hw.c +@@ -47,7 +47,7 @@ static irqreturn_t syncpt_thresh_isr(int + unsigned long reg; + int i, id; + +- for (i = 0; i <= BIT_WORD(host->info->nb_pts); i++) { ++ for (i = 0; i < DIV_ROUND_UP(host->info->nb_pts, 32); i++) { + reg = host1x_sync_readl(host, + HOST1X_SYNC_SYNCPT_THRESH_CPU0_INT_STATUS(i)); + for_each_set_bit(id, ®, BITS_PER_LONG) { +@@ -64,7 +64,7 @@ static void _host1x_intr_disable_all_syn + { + u32 i; + +- for (i = 0; i <= BIT_WORD(host->info->nb_pts); ++i) { ++ for (i = 0; i < DIV_ROUND_UP(host->info->nb_pts, 32); ++i) { + host1x_sync_writel(host, 0xffffffffu, + HOST1X_SYNC_SYNCPT_THRESH_INT_DISABLE(i)); + host1x_sync_writel(host, 0xffffffffu, diff --git a/queue-3.14/ipmi-fix-a-race-restarting-the-timer.patch b/queue-3.14/ipmi-fix-a-race-restarting-the-timer.patch new file mode 100644 index 00000000000..24b662abe37 --- /dev/null +++ b/queue-3.14/ipmi-fix-a-race-restarting-the-timer.patch @@ -0,0 +1,138 @@ +From 48e8ac2979920ffa39117e2d725afa3a749bfe8d Mon Sep 17 00:00:00 2001 +From: Bodo Stroesser +Date: Mon, 14 Apr 2014 09:46:51 -0500 +Subject: ipmi: Fix a race restarting the timer + +From: Bodo Stroesser + +commit 48e8ac2979920ffa39117e2d725afa3a749bfe8d upstream. + +With recent changes it is possible for the timer handler to detect an +idle interface and not start the timer, but the thread to start an +operation at the same time. The thread will not start the timer in that +instance, resulting in the timer not running. + +Instead, move all timer operations under the lock and start the timer in +the thread if it detect non-idle and the timer is not already running. +Moving under locks allows the last timeout to be set in both the thread +and the timer. 'Timer is not running' means that the timer is not +pending and smi_timeout() is not running. So we need a flag to detect +this correctly. + +Also fix a few other timeout bugs: setting the last timeout when the +interrupt has to be disabled and the timer started, and setting the last +timeout in check_start_timer_thread possibly racing with the timer + +Signed-off-by: Corey Minyard +Signed-off-by: Bodo Stroesser +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/char/ipmi/ipmi_si_intf.c | 46 +++++++++++++++++++++++---------------- + 1 file changed, 28 insertions(+), 18 deletions(-) + +--- a/drivers/char/ipmi/ipmi_si_intf.c ++++ b/drivers/char/ipmi/ipmi_si_intf.c +@@ -249,6 +249,9 @@ struct smi_info { + /* The timer for this si. */ + struct timer_list si_timer; + ++ /* This flag is set, if the timer is running (timer_pending() isn't enough) */ ++ bool timer_running; ++ + /* The time (in jiffies) the last timeout occurred at. */ + unsigned long last_timeout_jiffies; + +@@ -435,6 +438,13 @@ static void start_clear_flags(struct smi + smi_info->si_state = SI_CLEARING_FLAGS; + } + ++static void smi_mod_timer(struct smi_info *smi_info, unsigned long new_val) ++{ ++ smi_info->last_timeout_jiffies = jiffies; ++ mod_timer(&smi_info->si_timer, new_val); ++ smi_info->timer_running = true; ++} ++ + /* + * When we have a situtaion where we run out of memory and cannot + * allocate messages, we just leave them in the BMC and run the system +@@ -447,8 +457,7 @@ static inline void disable_si_irq(struct + start_disable_irq(smi_info); + smi_info->interrupt_disabled = 1; + if (!atomic_read(&smi_info->stop_operation)) +- mod_timer(&smi_info->si_timer, +- jiffies + SI_TIMEOUT_JIFFIES); ++ smi_mod_timer(smi_info, jiffies + SI_TIMEOUT_JIFFIES); + } + } + +@@ -908,15 +917,7 @@ static void sender(void * + list_add_tail(&msg->link, &smi_info->xmit_msgs); + + if (smi_info->si_state == SI_NORMAL && smi_info->curr_msg == NULL) { +- /* +- * last_timeout_jiffies is updated here to avoid +- * smi_timeout() handler passing very large time_diff +- * value to smi_event_handler() that causes +- * the send command to abort. +- */ +- smi_info->last_timeout_jiffies = jiffies; +- +- mod_timer(&smi_info->si_timer, jiffies + SI_TIMEOUT_JIFFIES); ++ smi_mod_timer(smi_info, jiffies + SI_TIMEOUT_JIFFIES); + + if (smi_info->thread) + wake_up_process(smi_info->thread); +@@ -1005,6 +1006,17 @@ static int ipmi_thread(void *data) + + spin_lock_irqsave(&(smi_info->si_lock), flags); + smi_result = smi_event_handler(smi_info, 0); ++ ++ /* ++ * If the driver is doing something, there is a possible ++ * race with the timer. If the timer handler see idle, ++ * and the thread here sees something else, the timer ++ * handler won't restart the timer even though it is ++ * required. So start it here if necessary. ++ */ ++ if (smi_result != SI_SM_IDLE && !smi_info->timer_running) ++ smi_mod_timer(smi_info, jiffies + SI_TIMEOUT_JIFFIES); ++ + spin_unlock_irqrestore(&(smi_info->si_lock), flags); + busy_wait = ipmi_thread_busy_wait(smi_result, smi_info, + &busy_until); +@@ -1074,10 +1086,6 @@ static void smi_timeout(unsigned long da + * SI_USEC_PER_JIFFY); + smi_result = smi_event_handler(smi_info, time_diff); + +- spin_unlock_irqrestore(&(smi_info->si_lock), flags); +- +- smi_info->last_timeout_jiffies = jiffies_now; +- + if ((smi_info->irq) && (!smi_info->interrupt_disabled)) { + /* Running with interrupts, only do long timeouts. */ + timeout = jiffies + SI_TIMEOUT_JIFFIES; +@@ -1099,7 +1107,10 @@ static void smi_timeout(unsigned long da + + do_mod_timer: + if (smi_result != SI_SM_IDLE) +- mod_timer(&(smi_info->si_timer), timeout); ++ smi_mod_timer(smi_info, timeout); ++ else ++ smi_info->timer_running = false; ++ spin_unlock_irqrestore(&(smi_info->si_lock), flags); + } + + static irqreturn_t si_irq_handler(int irq, void *data) +@@ -1147,8 +1158,7 @@ static int smi_start_processing(void + + /* Set up the timer that drives the interface. */ + setup_timer(&new_smi->si_timer, smi_timeout, (long)new_smi); +- new_smi->last_timeout_jiffies = jiffies; +- mod_timer(&new_smi->si_timer, jiffies + SI_TIMEOUT_JIFFIES); ++ smi_mod_timer(new_smi, jiffies + SI_TIMEOUT_JIFFIES); + + /* + * Check if the user forcefully enabled the daemon. diff --git a/queue-3.14/ipmi-reset-the-kcs-timeout-when-starting-error-recovery.patch b/queue-3.14/ipmi-reset-the-kcs-timeout-when-starting-error-recovery.patch new file mode 100644 index 00000000000..85429b8b271 --- /dev/null +++ b/queue-3.14/ipmi-reset-the-kcs-timeout-when-starting-error-recovery.patch @@ -0,0 +1,35 @@ +From eb6d78ec213e6938559b801421d64714dafcf4b2 Mon Sep 17 00:00:00 2001 +From: Corey Minyard +Date: Mon, 14 Apr 2014 09:46:52 -0500 +Subject: ipmi: Reset the KCS timeout when starting error recovery + +From: Corey Minyard + +commit eb6d78ec213e6938559b801421d64714dafcf4b2 upstream. + +The OBF timer in KCS was not reset in one situation when error recovery +was started, resulting in an immediate timeout. + +Reported-by: Bodo Stroesser +Signed-off-by: Corey Minyard +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/char/ipmi/ipmi_kcs_sm.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +--- a/drivers/char/ipmi/ipmi_kcs_sm.c ++++ b/drivers/char/ipmi/ipmi_kcs_sm.c +@@ -251,8 +251,9 @@ static inline int check_obf(struct si_sm + if (!GET_STATUS_OBF(status)) { + kcs->obf_timeout -= time; + if (kcs->obf_timeout < 0) { +- start_error_recovery(kcs, "OBF not ready in time"); +- return 1; ++ kcs->obf_timeout = OBF_RETRY_TIMEOUT; ++ start_error_recovery(kcs, "OBF not ready in time"); ++ return 1; + } + return 0; + } diff --git a/queue-3.14/mac80211-fix-nested-rtnl-locking-on-ieee80211_reconfig.patch b/queue-3.14/mac80211-fix-nested-rtnl-locking-on-ieee80211_reconfig.patch new file mode 100644 index 00000000000..bb69d9a69b1 --- /dev/null +++ b/queue-3.14/mac80211-fix-nested-rtnl-locking-on-ieee80211_reconfig.patch @@ -0,0 +1,34 @@ +From e669ba2d06c6195662601956454ac959892f0762 Mon Sep 17 00:00:00 2001 +From: Eliad Peller +Date: Wed, 30 Apr 2014 16:14:24 +0300 +Subject: mac80211: fix nested rtnl locking on ieee80211_reconfig + +From: Eliad Peller + +commit e669ba2d06c6195662601956454ac959892f0762 upstream. + +ieee80211_reconfig already holds rtnl, so calling +cfg80211_sched_scan_stopped results in deadlock. + +Use the rtnl-version of this function instead. + +Fixes: d43c6b6 ("mac80211: reschedule sched scan after HW restart") +Signed-off-by: Eliad Peller +Signed-off-by: Johannes Berg +Signed-off-by: Greg Kroah-Hartman + +--- + net/mac80211/util.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/net/mac80211/util.c ++++ b/net/mac80211/util.c +@@ -1754,7 +1754,7 @@ int ieee80211_reconfig(struct ieee80211_ + mutex_unlock(&local->mtx); + + if (sched_scan_stopped) +- cfg80211_sched_scan_stopped(local->hw.wiphy); ++ cfg80211_sched_scan_stopped_rtnl(local->hw.wiphy); + + /* + * If this is for hw restart things are still running. diff --git a/queue-3.14/mac80211-fix-on-channel-remain-on-channel.patch b/queue-3.14/mac80211-fix-on-channel-remain-on-channel.patch new file mode 100644 index 00000000000..f5bf768577e --- /dev/null +++ b/queue-3.14/mac80211-fix-on-channel-remain-on-channel.patch @@ -0,0 +1,100 @@ +From b4b177a5556a686909e643f1e9b6434c10de079f Mon Sep 17 00:00:00 2001 +From: Johannes Berg +Date: Wed, 14 May 2014 15:34:41 +0200 +Subject: mac80211: fix on-channel remain-on-channel + +From: Johannes Berg + +commit b4b177a5556a686909e643f1e9b6434c10de079f upstream. + +Jouni reported that if a remain-on-channel was active on the +same channel as the current operating channel, then the ROC +would start, but any frames transmitted using mgmt-tx on the +same channel would get delayed until after the ROC. + +The reason for this is that the ROC starts, but doesn't have +any handling for "remain on the same channel", so it stops +the interface queues. The later mgmt-tx then puts the frame +on the interface queues (since it's on the current operating +channel) and thus they get delayed until after the ROC. + +To fix this, add some logic to handle remaining on the same +channel specially and not stop the queues etc. in this case. +This not only fixes the bug but also improves behaviour in +this case as data frames etc. can continue to flow. + +Reported-by: Jouni Malinen +Tested-by: Jouni Malinen +Signed-off-by: Johannes Berg +Signed-off-by: Greg Kroah-Hartman + +--- + net/mac80211/ieee80211_i.h | 1 + + net/mac80211/offchannel.c | 27 ++++++++++++++++++++------- + 2 files changed, 21 insertions(+), 7 deletions(-) + +--- a/net/mac80211/ieee80211_i.h ++++ b/net/mac80211/ieee80211_i.h +@@ -317,6 +317,7 @@ struct ieee80211_roc_work { + + bool started, abort, hw_begun, notified; + bool to_be_freed; ++ bool on_channel; + + unsigned long hw_start_time; + +--- a/net/mac80211/offchannel.c ++++ b/net/mac80211/offchannel.c +@@ -333,7 +333,7 @@ void ieee80211_sw_roc_work(struct work_s + container_of(work, struct ieee80211_roc_work, work.work); + struct ieee80211_sub_if_data *sdata = roc->sdata; + struct ieee80211_local *local = sdata->local; +- bool started; ++ bool started, on_channel; + + mutex_lock(&local->mtx); + +@@ -354,14 +354,26 @@ void ieee80211_sw_roc_work(struct work_s + if (!roc->started) { + struct ieee80211_roc_work *dep; + +- /* start this ROC */ +- ieee80211_offchannel_stop_vifs(local); ++ WARN_ON(local->use_chanctx); ++ ++ /* If actually operating on the desired channel (with at least ++ * 20 MHz channel width) don't stop all the operations but still ++ * treat it as though the ROC operation started properly, so ++ * other ROC operations won't interfere with this one. ++ */ ++ roc->on_channel = roc->chan == local->_oper_chandef.chan && ++ local->_oper_chandef.width != NL80211_CHAN_WIDTH_5 && ++ local->_oper_chandef.width != NL80211_CHAN_WIDTH_10; + +- /* switch channel etc */ ++ /* start this ROC */ + ieee80211_recalc_idle(local); + +- local->tmp_channel = roc->chan; +- ieee80211_hw_config(local, 0); ++ if (!roc->on_channel) { ++ ieee80211_offchannel_stop_vifs(local); ++ ++ local->tmp_channel = roc->chan; ++ ieee80211_hw_config(local, 0); ++ } + + /* tell userspace or send frame */ + ieee80211_handle_roc_started(roc); +@@ -380,9 +392,10 @@ void ieee80211_sw_roc_work(struct work_s + finish: + list_del(&roc->list); + started = roc->started; ++ on_channel = roc->on_channel; + ieee80211_roc_notify_destroy(roc, !roc->abort); + +- if (started) { ++ if (started && !on_channel) { + ieee80211_flush_queues(local, NULL); + + local->tmp_channel = NULL; diff --git a/queue-3.14/mac80211-fix-suspend-vs.-association-race.patch b/queue-3.14/mac80211-fix-suspend-vs.-association-race.patch new file mode 100644 index 00000000000..ea3fcee4166 --- /dev/null +++ b/queue-3.14/mac80211-fix-suspend-vs.-association-race.patch @@ -0,0 +1,63 @@ +From c52666aef9f2dff39276eb53f15d99e2e229870f Mon Sep 17 00:00:00 2001 +From: Emmanuel Grumbach +Date: Tue, 13 May 2014 12:54:09 +0300 +Subject: mac80211: fix suspend vs. association race + +From: Emmanuel Grumbach + +commit c52666aef9f2dff39276eb53f15d99e2e229870f upstream. + +If the association is in progress while we suspend, the +stack will be in a messed up state. Clean it before we +suspend. + +This patch completes Johannes's patch: + +1a1cb744de160ee70086a77afff605bbc275d291 +Author: Johannes Berg + + mac80211: fix suspend vs. authentication race + +Fixes: 12e7f517029d ("mac80211: cleanup generic suspend/resume procedures") +Signed-off-by: Emmanuel Grumbach +Signed-off-by: Johannes Berg +Signed-off-by: Greg Kroah-Hartman + +--- + net/mac80211/mlme.c | 20 +++++++++++++------- + 1 file changed, 13 insertions(+), 7 deletions(-) + +--- a/net/mac80211/mlme.c ++++ b/net/mac80211/mlme.c +@@ -3511,18 +3511,24 @@ void ieee80211_mgd_quiesce(struct ieee80 + + sdata_lock(sdata); + +- if (ifmgd->auth_data) { ++ if (ifmgd->auth_data || ifmgd->assoc_data) { ++ const u8 *bssid = ifmgd->auth_data ? ++ ifmgd->auth_data->bss->bssid : ++ ifmgd->assoc_data->bss->bssid; ++ + /* +- * If we are trying to authenticate while suspending, cfg80211 +- * won't know and won't actually abort those attempts, thus we +- * need to do that ourselves. ++ * If we are trying to authenticate / associate while suspending, ++ * cfg80211 won't know and won't actually abort those attempts, ++ * thus we need to do that ourselves. + */ +- ieee80211_send_deauth_disassoc(sdata, +- ifmgd->auth_data->bss->bssid, ++ ieee80211_send_deauth_disassoc(sdata, bssid, + IEEE80211_STYPE_DEAUTH, + WLAN_REASON_DEAUTH_LEAVING, + false, frame_buf); +- ieee80211_destroy_auth_data(sdata, false); ++ if (ifmgd->assoc_data) ++ ieee80211_destroy_assoc_data(sdata, false); ++ if (ifmgd->auth_data) ++ ieee80211_destroy_auth_data(sdata, false); + cfg80211_tx_mlme_mgmt(sdata->dev, frame_buf, + IEEE80211_DEAUTH_FRAME_LEN); + } diff --git a/queue-3.14/series b/queue-3.14/series index 2bb24349704..199bf9ba309 100644 --- a/queue-3.14/series +++ b/queue-3.14/series @@ -24,3 +24,13 @@ iwlwifi-mvm-avoid-searching-unnecessary-columns.patch iwlwifi-mvm-rs-fix-and-cleanup-rs_get_rate_action.patch iwlwifi-mvm-rs-reinit-rs-if-no-tx-for-a-long-time.patch iwlwifi-7000-bump-api-to-9.patch +gpu-host1x-handle-the-correct-of-syncpt-regs.patch +timer-prevent-overflow-in-apply_slack.patch +ipmi-fix-a-race-restarting-the-timer.patch +ipmi-reset-the-kcs-timeout-when-starting-error-recovery.patch +cfg80211-fix-few-minor-issues-in-reg_process_hint.patch +cfg80211-free-sme-on-connection-failures.patch +cfg80211-add-cfg80211_sched_scan_stopped_rtnl.patch +mac80211-fix-nested-rtnl-locking-on-ieee80211_reconfig.patch +mac80211-fix-suspend-vs.-association-race.patch +mac80211-fix-on-channel-remain-on-channel.patch diff --git a/queue-3.14/timer-prevent-overflow-in-apply_slack.patch b/queue-3.14/timer-prevent-overflow-in-apply_slack.patch new file mode 100644 index 00000000000..046ded6504a --- /dev/null +++ b/queue-3.14/timer-prevent-overflow-in-apply_slack.patch @@ -0,0 +1,45 @@ +From 98a01e779f3c66b0b11cd7e64d531c0e41c95762 Mon Sep 17 00:00:00 2001 +From: Jiri Bohac +Date: Fri, 18 Apr 2014 17:23:11 +0200 +Subject: timer: Prevent overflow in apply_slack + +From: Jiri Bohac + +commit 98a01e779f3c66b0b11cd7e64d531c0e41c95762 upstream. + +On architectures with sizeof(int) < sizeof (long), the +computation of mask inside apply_slack() can be undefined if the +computed bit is > 32. + +E.g. with: expires = 0xffffe6f5 and slack = 25, we get: + +expires_limit = 0x20000000e +bit = 33 +mask = (1 << 33) - 1 /* undefined */ + +On x86, mask becomes 1 and and the slack is not applied properly. +On s390, mask is -1, expires is set to 0 and the timer fires immediately. + +Use 1UL << bit to solve that issue. + +Suggested-by: Deborah Townsend +Signed-off-by: Jiri Bohac +Link: http://lkml.kernel.org/r/20140418152310.GA13654@midget.suse.cz +Signed-off-by: Thomas Gleixner +Signed-off-by: Greg Kroah-Hartman + +--- + kernel/timer.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/kernel/timer.c ++++ b/kernel/timer.c +@@ -822,7 +822,7 @@ unsigned long apply_slack(struct timer_l + + bit = find_last_bit(&mask, BITS_PER_LONG); + +- mask = (1 << bit) - 1; ++ mask = (1UL << bit) - 1; + + expires_limit = expires_limit & ~(mask); +