From 7012a5360f275363ff935ff6dd14b48e97315f5e Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Thu, 1 Mar 2012 13:35:18 -0800 Subject: 2.6.32-stable patches added patches: firmware-loader-allow-builtin-firmware-load-even-if-usermodehelper-is-disabled.patch pm-print-a-warning-if-firmware-is-requested-when-tasks.patch pm-sleep-fix-freezer-failures-due-to-racy-usermodehelper_is_disabled.patch pm-sleep-fix-read_unlock_usermodehelper-call.patch --- ...e-load-even-if-usermodehelper-is-disabled.patch | 71 ++++++++ ...rning-if-firmware-is-requested-when-tasks.patch | 82 ++++++++++ ...es-due-to-racy-usermodehelper_is_disabled.patch | 178 +++++++++++++++++++++ ...sleep-fix-read_unlock_usermodehelper-call.patch | 40 +++++ queue-2.6.32/series | 4 + 5 files changed, 375 insertions(+) create mode 100644 queue-2.6.32/firmware-loader-allow-builtin-firmware-load-even-if-usermodehelper-is-disabled.patch create mode 100644 queue-2.6.32/pm-print-a-warning-if-firmware-is-requested-when-tasks.patch create mode 100644 queue-2.6.32/pm-sleep-fix-freezer-failures-due-to-racy-usermodehelper_is_disabled.patch create mode 100644 queue-2.6.32/pm-sleep-fix-read_unlock_usermodehelper-call.patch diff --git a/queue-2.6.32/firmware-loader-allow-builtin-firmware-load-even-if-usermodehelper-is-disabled.patch b/queue-2.6.32/firmware-loader-allow-builtin-firmware-load-even-if-usermodehelper-is-disabled.patch new file mode 100644 index 0000000..256c2c4 --- /dev/null +++ b/queue-2.6.32/firmware-loader-allow-builtin-firmware-load-even-if-usermodehelper-is-disabled.patch @@ -0,0 +1,71 @@ +From srivatsa.bhat@linux.vnet.ibm.com Thu Mar 1 13:31:42 2012 +From: "Srivatsa S. Bhat" +Date: Wed, 29 Feb 2012 12:23:20 +0530 +Subject: firmware loader: allow builtin firmware load even if usermodehelper is disabled +To: gregkh@linuxfoundation.org +Cc: stable@vger.kernel.org, rjw@sisk.pl, valdis.kletnieks@vt.edu, cloos@hjcloos.com, riesebie@lxtec.de, torvalds@linux-foundation.org, penguin-kernel@i-love.sakura.ne.jp, srivatsa.bhat@linux.vnet.ibm.com +Message-ID: <20120229065249.4761.69035.stgit@srivatsabhat.in.ibm.com> + + +From: Linus Torvalds + +[ Upstream commit caca9510ff4e5d842c0589110243d60927836222 ] + +In commit a144c6a6c924 ("PM: Print a warning if firmware is requested +when tasks are frozen") we not only printed a warning if somebody tried +to load the firmware when tasks are frozen - we also failed the load. + +But that check was done before the check for built-in firmware, and then +when we disallowed usermode helpers during bootup (commit 288d5abec831: +"Boot up with usermodehelper disabled"), that actually means that +built-in modules can no longer load their firmware even if the firmware +is built in too. Which used to work, and some people depended on it for +the R100 driver. + +So move the test for usermodehelper_is_disabled() down, to after +checking the built-in firmware. + +This should fix: + + https://bugzilla.kernel.org/show_bug.cgi?id=40952 + +Reported-by: James Cloos +Bisected-by: Elimar Riesebieter +Cc: Michel Dänzer +Cc: Rafael Wysocki +Cc: Valdis Kletnieks +Signed-off-by: Linus Torvalds +Signed-off-by: Srivatsa S. Bhat +Signed-off-by: Greg Kroah-Hartman +--- + + drivers/base/firmware_class.c | 11 ++++++----- + 1 file changed, 6 insertions(+), 5 deletions(-) + +--- a/drivers/base/firmware_class.c ++++ b/drivers/base/firmware_class.c +@@ -489,11 +489,6 @@ _request_firmware(const struct firmware + if (!firmware_p) + return -EINVAL; + +- if (WARN_ON(usermodehelper_is_disabled())) { +- dev_err(device, "firmware: %s will not be loaded\n", name); +- return -EBUSY; +- } +- + *firmware_p = firmware = kzalloc(sizeof(*firmware), GFP_KERNEL); + if (!firmware) { + dev_err(device, "%s: kmalloc(struct firmware) failed\n", +@@ -513,6 +508,12 @@ _request_firmware(const struct firmware + return 0; + } + ++ if (WARN_ON(usermodehelper_is_disabled())) { ++ dev_err(device, "firmware: %s will not be loaded\n", name); ++ retval = -EBUSY; ++ goto out; ++ } ++ + if (uevent) + dev_info(device, "firmware: requesting %s\n", name); + diff --git a/queue-2.6.32/pm-print-a-warning-if-firmware-is-requested-when-tasks.patch b/queue-2.6.32/pm-print-a-warning-if-firmware-is-requested-when-tasks.patch new file mode 100644 index 0000000..d72e292 --- /dev/null +++ b/queue-2.6.32/pm-print-a-warning-if-firmware-is-requested-when-tasks.patch @@ -0,0 +1,82 @@ +From srivatsa.bhat@linux.vnet.ibm.com Thu Mar 1 13:30:46 2012 +From: "Srivatsa S. Bhat" +Date: Wed, 29 Feb 2012 12:22:41 +0530 +Subject: PM: Print a warning if firmware is requested when tasks are frozen +To: gregkh@linuxfoundation.org +Cc: stable@vger.kernel.org, rjw@sisk.pl, valdis.kletnieks@vt.edu, cloos@hjcloos.com, riesebie@lxtec.de, torvalds@linux-foundation.org, penguin-kernel@i-love.sakura.ne.jp, srivatsa.bhat@linux.vnet.ibm.com +Message-ID: <20120229065115.4761.59767.stgit@srivatsabhat.in.ibm.com> + + +From: Rafael J. Wysocki + +[ Upstream commit a144c6a6c924aa1da04dd77fb84b89927354fdff ] + +Some drivers erroneously use request_firmware() from their ->resume() +(or ->thaw(), or ->restore()) callbacks, which is not going to work +unless the firmware has been built in. This causes system resume to +stall until the firmware-loading timeout expires, which makes users +think that the resume has failed and reboot their machines +unnecessarily. For this reason, make _request_firmware() print a +warning and return immediately with error code if it has been called +when tasks are frozen and it's impossible to start any new usermode +helpers. + +Signed-off-by: Rafael J. Wysocki +Acked-by: Greg Kroah-Hartman +Reviewed-by: Valdis Kletnieks +Signed-off-by: Srivatsa S. Bhat +Signed-off-by: Greg Kroah-Hartman +--- + + drivers/base/firmware_class.c | 5 +++++ + include/linux/kmod.h | 5 +++++ + kernel/kmod.c | 9 +++++++++ + 3 files changed, 19 insertions(+) + +--- a/drivers/base/firmware_class.c ++++ b/drivers/base/firmware_class.c +@@ -489,6 +489,11 @@ _request_firmware(const struct firmware + if (!firmware_p) + return -EINVAL; + ++ if (WARN_ON(usermodehelper_is_disabled())) { ++ dev_err(device, "firmware: %s will not be loaded\n", name); ++ return -EBUSY; ++ } ++ + *firmware_p = firmware = kzalloc(sizeof(*firmware), GFP_KERNEL); + if (!firmware) { + dev_err(device, "%s: kmalloc(struct firmware) failed\n", +--- a/include/linux/kmod.h ++++ b/include/linux/kmod.h +@@ -104,7 +104,12 @@ struct file; + extern int call_usermodehelper_pipe(char *path, char *argv[], char *envp[], + struct file **filp); + ++#ifdef CONFIG_PM_SLEEP + extern int usermodehelper_disable(void); + extern void usermodehelper_enable(void); ++extern bool usermodehelper_is_disabled(void); ++#else ++static inline bool usermodehelper_is_disabled(void) { return false; } ++#endif + + #endif /* __LINUX_KMOD_H__ */ +--- a/kernel/kmod.c ++++ b/kernel/kmod.c +@@ -337,6 +337,15 @@ void usermodehelper_enable(void) + usermodehelper_disabled = 0; + } + ++/** ++ * usermodehelper_is_disabled - check if new helpers are allowed to be started ++ */ ++bool usermodehelper_is_disabled(void) ++{ ++ return usermodehelper_disabled; ++} ++EXPORT_SYMBOL_GPL(usermodehelper_is_disabled); ++ + static void helper_lock(void) + { + atomic_inc(&running_helpers); diff --git a/queue-2.6.32/pm-sleep-fix-freezer-failures-due-to-racy-usermodehelper_is_disabled.patch b/queue-2.6.32/pm-sleep-fix-freezer-failures-due-to-racy-usermodehelper_is_disabled.patch new file mode 100644 index 0000000..06d5d16 --- /dev/null +++ b/queue-2.6.32/pm-sleep-fix-freezer-failures-due-to-racy-usermodehelper_is_disabled.patch @@ -0,0 +1,178 @@ +From srivatsa.bhat@linux.vnet.ibm.com Thu Mar 1 13:32:07 2012 +From: "Srivatsa S. Bhat" +Date: Wed, 29 Feb 2012 12:24:01 +0530 +Subject: PM / Sleep: Fix freezer failures due to racy usermodehelper_is_disabled() +To: gregkh@linuxfoundation.org +Cc: stable@vger.kernel.org, rjw@sisk.pl, valdis.kletnieks@vt.edu, cloos@hjcloos.com, riesebie@lxtec.de, torvalds@linux-foundation.org, penguin-kernel@i-love.sakura.ne.jp, srivatsa.bhat@linux.vnet.ibm.com +Message-ID: <20120229065327.4761.48161.stgit@srivatsabhat.in.ibm.com> + + +From: Srivatsa S. Bhat + +[ Upstream commit b298d289c79211508f11cb50749b0d1d54eb244a ] + +Commit a144c6a (PM: Print a warning if firmware is requested when tasks +are frozen) introduced usermodehelper_is_disabled() to warn and exit +immediately if firmware is requested when usermodehelpers are disabled. + +However, it is racy. Consider the following scenario, currently used in +drivers/base/firmware_class.c: + +... +if (usermodehelper_is_disabled()) + goto out; + +/* Do actual work */ +... + +out: + return err; + +Nothing prevents someone from disabling usermodehelpers just after the check +in the 'if' condition, which means that it is quite possible to try doing the +"actual work" with usermodehelpers disabled, leading to undesirable +consequences. + +In particular, this race condition in _request_firmware() causes task freezing +failures whenever suspend/hibernation is in progress because, it wrongly waits +to get the firmware/microcode image from userspace when actually the +usermodehelpers are disabled or userspace has been frozen. +Some of the example scenarios that cause freezing failures due to this race +are those that depend on userspace via request_firmware(), such as x86 +microcode module initialization and microcode image reload. + +Previous discussions about this issue can be found at: +http://thread.gmane.org/gmane.linux.kernel/1198291/focus=1200591 + +This patch adds proper synchronization to fix this issue. + +It is to be noted that this patchset fixes the freezing failures but doesn't +remove the warnings. IOW, it does not attempt to add explicit synchronization +to x86 microcode driver to avoid requesting microcode image at inopportune +moments. Because, the warnings were introduced to highlight such cases, in the +first place. And we need not silence the warnings, since we take care of the +*real* problem (freezing failure) and hence, after that, the warnings are +pretty harmless anyway. + +Signed-off-by: Srivatsa S. Bhat +Signed-off-by: Rafael J. Wysocki +Signed-off-by: Greg Kroah-Hartman +--- + + drivers/base/firmware_class.c | 3 +++ + include/linux/kmod.h | 4 ++++ + kernel/kmod.c | 24 +++++++++++++++++++++++- + 3 files changed, 30 insertions(+), 1 deletion(-) + +--- a/drivers/base/firmware_class.c ++++ b/drivers/base/firmware_class.c +@@ -508,6 +508,8 @@ _request_firmware(const struct firmware + return 0; + } + ++ read_lock_usermodehelper(); ++ + if (WARN_ON(usermodehelper_is_disabled())) { + dev_err(device, "firmware: %s will not be loaded\n", name); + retval = -EBUSY; +@@ -551,6 +553,7 @@ error_kfree_fw: + kfree(firmware); + *firmware_p = NULL; + out: ++ read_unlock_usermodehelper(); + return retval; + } + +--- a/include/linux/kmod.h ++++ b/include/linux/kmod.h +@@ -108,8 +108,12 @@ extern int call_usermodehelper_pipe(char + extern int usermodehelper_disable(void); + extern void usermodehelper_enable(void); + extern bool usermodehelper_is_disabled(void); ++extern void read_lock_usermodehelper(void); ++extern void read_unlock_usermodehelper(void); + #else + static inline bool usermodehelper_is_disabled(void) { return false; } ++static inline void read_lock_usermodehelper(void) {} ++static inline void read_unlock_usermodehelper(void) {} + #endif + + #endif /* __LINUX_KMOD_H__ */ +--- a/kernel/kmod.c ++++ b/kernel/kmod.c +@@ -35,6 +35,7 @@ + #include + #include + #include ++#include + #include + + #include +@@ -43,6 +44,8 @@ extern int max_threads; + + static struct workqueue_struct *khelper_wq; + ++static DECLARE_RWSEM(umhelper_sem); ++ + #ifdef CONFIG_MODULES + + /* +@@ -286,6 +289,7 @@ static void __call_usermodehelper(struct + * If set, call_usermodehelper_exec() will exit immediately returning -EBUSY + * (used for preventing user land processes from being created after the user + * land has been frozen during a system-wide hibernation or suspend operation). ++ * Should always be manipulated under umhelper_sem acquired for write. + */ + static int usermodehelper_disabled; + +@@ -304,6 +308,18 @@ static DECLARE_WAIT_QUEUE_HEAD(running_h + */ + #define RUNNING_HELPERS_TIMEOUT (5 * HZ) + ++void read_lock_usermodehelper(void) ++{ ++ down_read(&umhelper_sem); ++} ++EXPORT_SYMBOL_GPL(read_lock_usermodehelper); ++ ++void read_unlock_usermodehelper(void) ++{ ++ up_read(&umhelper_sem); ++} ++EXPORT_SYMBOL_GPL(read_unlock_usermodehelper); ++ + /** + * usermodehelper_disable - prevent new helpers from being started + */ +@@ -311,8 +327,10 @@ int usermodehelper_disable(void) + { + long retval; + ++ down_write(&umhelper_sem); + usermodehelper_disabled = 1; +- smp_mb(); ++ up_write(&umhelper_sem); ++ + /* + * From now on call_usermodehelper_exec() won't start any new + * helpers, so it is sufficient if running_helpers turns out to +@@ -325,7 +343,9 @@ int usermodehelper_disable(void) + if (retval) + return 0; + ++ down_write(&umhelper_sem); + usermodehelper_disabled = 0; ++ up_write(&umhelper_sem); + return -EAGAIN; + } + +@@ -334,7 +354,9 @@ int usermodehelper_disable(void) + */ + void usermodehelper_enable(void) + { ++ down_write(&umhelper_sem); + usermodehelper_disabled = 0; ++ up_write(&umhelper_sem); + } + + /** diff --git a/queue-2.6.32/pm-sleep-fix-read_unlock_usermodehelper-call.patch b/queue-2.6.32/pm-sleep-fix-read_unlock_usermodehelper-call.patch new file mode 100644 index 0000000..eff200d --- /dev/null +++ b/queue-2.6.32/pm-sleep-fix-read_unlock_usermodehelper-call.patch @@ -0,0 +1,40 @@ +From srivatsa.bhat@linux.vnet.ibm.com Thu Mar 1 13:32:36 2012 +From: "Srivatsa S. Bhat" +Date: Wed, 29 Feb 2012 12:24:56 +0530 +Subject: PM / Sleep: Fix read_unlock_usermodehelper() call. +To: gregkh@linuxfoundation.org +Cc: stable@vger.kernel.org, rjw@sisk.pl, valdis.kletnieks@vt.edu, cloos@hjcloos.com, riesebie@lxtec.de, torvalds@linux-foundation.org, penguin-kernel@i-love.sakura.ne.jp, srivatsa.bhat@linux.vnet.ibm.com +Message-ID: <20120229065409.4761.81272.stgit@srivatsabhat.in.ibm.com> + + +From: Tetsuo Handa + +[ Upstream commit e4c89a508f4385a0cd8681c2749a2cd2fa476e40 ] + +Commit b298d289 + "PM / Sleep: Fix freezer failures due to racy usermodehelper_is_disabled()" +added read_unlock_usermodehelper() but read_unlock_usermodehelper() is called +without read_lock_usermodehelper() when kmalloc() failed. + +Signed-off-by: Tetsuo Handa +Acked-by: Srivatsa S. Bhat +Signed-off-by: Rafael J. Wysocki +Signed-off-by: Srivatsa S. Bhat +Signed-off-by: Greg Kroah-Hartman +--- + + drivers/base/firmware_class.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +--- a/drivers/base/firmware_class.c ++++ b/drivers/base/firmware_class.c +@@ -493,8 +493,7 @@ _request_firmware(const struct firmware + if (!firmware) { + dev_err(device, "%s: kmalloc(struct firmware) failed\n", + __func__); +- retval = -ENOMEM; +- goto out; ++ return -ENOMEM; + } + + for (builtin = __start_builtin_fw; builtin != __end_builtin_fw; diff --git a/queue-2.6.32/series b/queue-2.6.32/series index b05a792..21d446e 100644 --- a/queue-2.6.32/series +++ b/queue-2.6.32/series @@ -28,3 +28,7 @@ cdrom-use-copy_to_user-without-the-underscores.patch autofs-work-around-unhappy-compat-problem-on-x86-64.patch fix-autofs-compile-without-config_compat.patch compat-fix-compile-breakage-on-s390.patch +pm-print-a-warning-if-firmware-is-requested-when-tasks.patch +firmware-loader-allow-builtin-firmware-load-even-if-usermodehelper-is-disabled.patch +pm-sleep-fix-freezer-failures-due-to-racy-usermodehelper_is_disabled.patch +pm-sleep-fix-read_unlock_usermodehelper-call.patch -- cgit 1.2.3-korg