From: Greg Kroah-Hartman Date: Tue, 3 Jun 2014 00:34:47 +0000 (-0700) Subject: 3.4-stable patches X-Git-Tag: v3.14.6~85 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=e860c093397c202796ab0f134e9065c8e0c49162;p=thirdparty%2Fkernel%2Fstable-queue.git 3.4-stable patches added patches: ipmi-fix-a-race-restarting-the-timer.patch ipmi-reset-the-kcs-timeout-when-starting-error-recovery.patch timer-prevent-overflow-in-apply_slack.patch --- diff --git a/queue-3.4/ipmi-fix-a-race-restarting-the-timer.patch b/queue-3.4/ipmi-fix-a-race-restarting-the-timer.patch new file mode 100644 index 00000000000..e13922cbcdd --- /dev/null +++ b/queue-3.4/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); + } + } + +@@ -896,15 +905,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); +@@ -993,6 +994,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); +@@ -1062,10 +1074,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; +@@ -1087,7 +1095,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) +@@ -1135,8 +1146,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.4/ipmi-reset-the-kcs-timeout-when-starting-error-recovery.patch b/queue-3.4/ipmi-reset-the-kcs-timeout-when-starting-error-recovery.patch new file mode 100644 index 00000000000..85429b8b271 --- /dev/null +++ b/queue-3.4/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.4/series b/queue-3.4/series index 4e9171191ca..41b14f7fade 100644 --- a/queue-3.4/series +++ b/queue-3.4/series @@ -36,3 +36,6 @@ futex-prevent-attaching-to-kernel-threads.patch ftrace-module-hardcode-ftrace_module_init-call-into-load_module.patch pata_at91-fix-ata_host_activate-failure-handling.patch mm-make-fixup_user_fault-check-the-vma-access-rights-too.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 diff --git a/queue-3.4/timer-prevent-overflow-in-apply_slack.patch b/queue-3.4/timer-prevent-overflow-in-apply_slack.patch new file mode 100644 index 00000000000..78a7169d137 --- /dev/null +++ b/queue-3.4/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 +@@ -815,7 +815,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); +