aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLuis R. Rodriguez <mcgrof@kernel.org>2018-03-10 09:14:59 -0500
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2018-03-20 04:28:47 -0400
commit995e8695f65db7a8b465b5c27887b32e8e5bb66e (patch)
tree14765863ac5c5cf5a646f7f8dc807c4de9d147a2
parent9952db75e0659d9db62d76d9a351fdae06898642 (diff)
firmware: ensure the firmware cache is not used on incompatible calls
request_firmware_into_buf() explicitly disables the firmware cache, meanwhile the firmware cache cannot be used when request_firmware_nowait() is used without the uevent. Enforce a sanity check for this to avoid future issues undocumented behaviours should misuses of the firmware cache happen later. One of the reasons we want to enforce this is the firmware cache is used for helping with suspend/resume, and if incompatible calls use it they can stall suspend. Signed-off-by: Luis R. Rodriguez <mcgrof@kernel.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--drivers/base/firmware_loader/main.c14
1 files changed, 14 insertions, 0 deletions
diff --git a/drivers/base/firmware_loader/main.c b/drivers/base/firmware_loader/main.c
index b569d8a09392..2913bb0e5e7b 100644
--- a/drivers/base/firmware_loader/main.c
+++ b/drivers/base/firmware_loader/main.c
@@ -431,6 +431,11 @@ static int fw_add_devm_name(struct device *dev, const char *name)
431 return 0; 431 return 0;
432} 432}
433#else 433#else
434static bool fw_cache_is_setup(struct device *dev, const char *name)
435{
436 return false;
437}
438
434static int fw_add_devm_name(struct device *dev, const char *name) 439static int fw_add_devm_name(struct device *dev, const char *name)
435{ 440{
436 return 0; 441 return 0;
@@ -672,6 +677,9 @@ request_firmware_into_buf(const struct firmware **firmware_p, const char *name,
672{ 677{
673 int ret; 678 int ret;
674 679
680 if (fw_cache_is_setup(device, name))
681 return -EOPNOTSUPP;
682
675 __module_get(THIS_MODULE); 683 __module_get(THIS_MODULE);
676 ret = _request_firmware(firmware_p, name, device, buf, size, 684 ret = _request_firmware(firmware_p, name, device, buf, size,
677 FW_OPT_UEVENT | FW_OPT_NOCACHE); 685 FW_OPT_UEVENT | FW_OPT_NOCACHE);
@@ -769,6 +777,12 @@ request_firmware_nowait(
769 fw_work->opt_flags = FW_OPT_NOWAIT | 777 fw_work->opt_flags = FW_OPT_NOWAIT |
770 (uevent ? FW_OPT_UEVENT : FW_OPT_USERHELPER); 778 (uevent ? FW_OPT_UEVENT : FW_OPT_USERHELPER);
771 779
780 if (!uevent && fw_cache_is_setup(device, name)) {
781 kfree_const(fw_work->name);
782 kfree(fw_work);
783 return -EOPNOTSUPP;
784 }
785
772 if (!try_module_get(module)) { 786 if (!try_module_get(module)) {
773 kfree_const(fw_work->name); 787 kfree_const(fw_work->name);
774 kfree(fw_work); 788 kfree(fw_work);