From 92d436d22cf251b083dae1f7cf5e11b65e8b0688 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Mon, 2 Jun 2014 17:30:00 -0700 Subject: [PATCH] 3.10-stable patches added patches: 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-suspend-vs.-authentication-race.patch timer-prevent-overflow-in-apply_slack.patch --- ...1x-handle-the-correct-of-syncpt-regs.patch | 51 +++++++ ...ipmi-fix-a-race-restarting-the-timer.patch | 138 ++++++++++++++++++ ...timeout-when-starting-error-recovery.patch | 35 +++++ ...-fix-suspend-vs.-authentication-race.patch | 98 +++++++++++++ queue-3.10/series | 5 + ...imer-prevent-overflow-in-apply_slack.patch | 45 ++++++ 6 files changed, 372 insertions(+) create mode 100644 queue-3.10/gpu-host1x-handle-the-correct-of-syncpt-regs.patch create mode 100644 queue-3.10/ipmi-fix-a-race-restarting-the-timer.patch create mode 100644 queue-3.10/ipmi-reset-the-kcs-timeout-when-starting-error-recovery.patch create mode 100644 queue-3.10/mac80211-fix-suspend-vs.-authentication-race.patch create mode 100644 queue-3.10/timer-prevent-overflow-in-apply_slack.patch diff --git a/queue-3.10/gpu-host1x-handle-the-correct-of-syncpt-regs.patch b/queue-3.10/gpu-host1x-handle-the-correct-of-syncpt-regs.patch new file mode 100644 index 00000000000..db1e4a9fe64 --- /dev/null +++ b/queue-3.10/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 +@@ -48,7 +48,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) { +@@ -65,7 +65,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.10/ipmi-fix-a-race-restarting-the-timer.patch b/queue-3.10/ipmi-fix-a-race-restarting-the-timer.patch new file mode 100644 index 00000000000..55ac9dc65f2 --- /dev/null +++ b/queue-3.10/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 +@@ -244,6 +244,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; + +@@ -427,6 +430,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 +@@ -439,8 +449,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); + } + } + +@@ -900,15 +909,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); +@@ -997,6 +998,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); +@@ -1066,10 +1078,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; +@@ -1091,7 +1099,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) +@@ -1139,8 +1150,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.10/ipmi-reset-the-kcs-timeout-when-starting-error-recovery.patch b/queue-3.10/ipmi-reset-the-kcs-timeout-when-starting-error-recovery.patch new file mode 100644 index 00000000000..85429b8b271 --- /dev/null +++ b/queue-3.10/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.10/mac80211-fix-suspend-vs.-authentication-race.patch b/queue-3.10/mac80211-fix-suspend-vs.-authentication-race.patch new file mode 100644 index 00000000000..f16d51779e7 --- /dev/null +++ b/queue-3.10/mac80211-fix-suspend-vs.-authentication-race.patch @@ -0,0 +1,98 @@ +From 1a1cb744de160ee70086a77afff605bbc275d291 Mon Sep 17 00:00:00 2001 +From: Johannes Berg +Date: Wed, 19 Mar 2014 09:55:55 +0100 +Subject: mac80211: fix suspend vs. authentication race + +From: Johannes Berg + +commit 1a1cb744de160ee70086a77afff605bbc275d291 upstream. + +Since Stanislaw's patch removing the quiescing code, mac80211 had +a race regarding suspend vs. authentication: as cfg80211 doesn't +track authentication attempts, it can't abort them. Therefore the +attempts may be kept running while suspending, which can lead to +all kinds of issues, in at least some cases causing an error in +iwlmvm firmware. + +Fix this by aborting the authentication attempt when suspending. + +Cc: stable@vger.kernel.org +Fixes: 12e7f517029d ("mac80211: cleanup generic suspend/resume procedures") +Signed-off-by: Johannes Berg +Signed-off-by: Greg Kroah-Hartman + +--- + net/mac80211/ieee80211_i.h | 1 + + net/mac80211/mlme.c | 26 ++++++++++++++++++++++++++ + net/mac80211/pm.c | 14 +++++++++++--- + 3 files changed, 38 insertions(+), 3 deletions(-) + +--- a/net/mac80211/ieee80211_i.h ++++ b/net/mac80211/ieee80211_i.h +@@ -1270,6 +1270,7 @@ void ieee80211_sta_reset_conn_monitor(st + void ieee80211_mgd_stop(struct ieee80211_sub_if_data *sdata); + void ieee80211_mgd_conn_tx_status(struct ieee80211_sub_if_data *sdata, + __le16 fc, bool acked); ++void ieee80211_mgd_quiesce(struct ieee80211_sub_if_data *sdata); + void ieee80211_sta_restart(struct ieee80211_sub_if_data *sdata); + + /* IBSS code */ +--- a/net/mac80211/mlme.c ++++ b/net/mac80211/mlme.c +@@ -3754,6 +3754,32 @@ static void ieee80211_restart_sta_timer( + } + + #ifdef CONFIG_PM ++void ieee80211_mgd_quiesce(struct ieee80211_sub_if_data *sdata) ++{ ++ struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; ++ u8 frame_buf[IEEE80211_DEAUTH_FRAME_LEN]; ++ ++ mutex_lock(&ifmgd->mtx); ++ ++ if (ifmgd->auth_data) { ++ /* ++ * 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. ++ */ ++ ieee80211_send_deauth_disassoc(sdata, ++ ifmgd->auth_data->bss->bssid, ++ IEEE80211_STYPE_DEAUTH, ++ WLAN_REASON_DEAUTH_LEAVING, ++ false, frame_buf); ++ ieee80211_destroy_auth_data(sdata, false); ++ cfg80211_send_deauth(sdata->dev, frame_buf, ++ IEEE80211_DEAUTH_FRAME_LEN); ++ } ++ ++ mutex_unlock(&ifmgd->mtx); ++} ++ + void ieee80211_sta_restart(struct ieee80211_sub_if_data *sdata) + { + struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; +--- a/net/mac80211/pm.c ++++ b/net/mac80211/pm.c +@@ -101,10 +101,18 @@ int __ieee80211_suspend(struct ieee80211 + + /* remove all interfaces that were created in the driver */ + list_for_each_entry(sdata, &local->interfaces, list) { +- if (!ieee80211_sdata_running(sdata) || +- sdata->vif.type == NL80211_IFTYPE_AP_VLAN || +- sdata->vif.type == NL80211_IFTYPE_MONITOR) ++ if (!ieee80211_sdata_running(sdata)) + continue; ++ switch (sdata->vif.type) { ++ case NL80211_IFTYPE_AP_VLAN: ++ case NL80211_IFTYPE_MONITOR: ++ continue; ++ case NL80211_IFTYPE_STATION: ++ ieee80211_mgd_quiesce(sdata); ++ break; ++ default: ++ break; ++ } + + drv_remove_interface(local, sdata); + } diff --git a/queue-3.10/series b/queue-3.10/series index e8dba5aa646..95a83a122cb 100644 --- a/queue-3.10/series +++ b/queue-3.10/series @@ -11,3 +11,8 @@ topology-fix-compilation-warning-when-not-in-smp.patch mm-make-fixup_user_fault-check-the-vma-access-rights-too.patch serial-8250-fix-thread-unsafe-__dma_tx_complete-function.patch 8250_core-fix-unwanted-tx-chars-write.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 +mac80211-fix-suspend-vs.-authentication-race.patch diff --git a/queue-3.10/timer-prevent-overflow-in-apply_slack.patch b/queue-3.10/timer-prevent-overflow-in-apply_slack.patch new file mode 100644 index 00000000000..046ded6504a --- /dev/null +++ b/queue-3.10/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); + -- 2.47.3