Commit Graph

109 Commits

Author SHA1 Message Date
Takashi Iwai
fe304143b0 firmware: Avoid deadlock of usermodehelper lock at shutdown
When a system goes to reboot/shutdown, it tries to disable the
usermode helper via usermodehelper_disable().  This might be blocked
when a driver tries to load a firmware beforehand and it's stuck by
some reason.  For example, dell_rbu driver loads the firmware in
non-hotplug mode and waits for user-space clearing the loading sysfs
flag.  If user-space doesn't clear the flag, it waits forever, thus
blocks the reboot, too.

As a workaround, in this patch, the firmware class driver registers a
reboot notifier so that it can abort all pending f/w bufs before
issuing usermodehelper_disable().

Signed-off-by: Takashi Iwai <tiwai@suse.de>
Acked-by: Ming Lei <ming.lei@canonical.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2013-06-03 13:57:29 -07:00
Linus Torvalds
d895cb1af1 Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
Pull vfs pile (part one) from Al Viro:
 "Assorted stuff - cleaning namei.c up a bit, fixing ->d_name/->d_parent
  locking violations, etc.

  The most visible changes here are death of FS_REVAL_DOT (replaced with
  "has ->d_weak_revalidate()") and a new helper getting from struct file
  to inode.  Some bits of preparation to xattr method interface changes.

  Misc patches by various people sent this cycle *and* ocfs2 fixes from
  several cycles ago that should've been upstream right then.

  PS: the next vfs pile will be xattr stuff."

* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs: (46 commits)
  saner proc_get_inode() calling conventions
  proc: avoid extra pde_put() in proc_fill_super()
  fs: change return values from -EACCES to -EPERM
  fs/exec.c: make bprm_mm_init() static
  ocfs2/dlm: use GFP_ATOMIC inside a spin_lock
  ocfs2: fix possible use-after-free with AIO
  ocfs2: Fix oops in ocfs2_fast_symlink_readpage() code path
  get_empty_filp()/alloc_file() leave both ->f_pos and ->f_version zero
  target: writev() on single-element vector is pointless
  export kernel_write(), convert open-coded instances
  fs: encode_fh: return FILEID_INVALID if invalid fid_type
  kill f_vfsmnt
  vfs: kill FS_REVAL_DOT by adding a d_weak_revalidate dentry op
  nfsd: handle vfs_getattr errors in acl protocol
  switch vfs_getattr() to struct path
  default SET_PERSONALITY() in linux/elf.h
  ceph: prepopulate inodes only when request is aborted
  d_hash_and_lookup(): export, switch open-coded instances
  9p: switch v9fs_set_create_acl() to inode+fid, do it before d_instantiate()
  9p: split dropping the acls from v9fs_set_create_acl()
  ...
2013-02-26 20:16:07 -08:00
Al Viro
3dadecce20 switch vfs_getattr() to struct path
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
2013-02-26 02:46:08 -05:00
Takashi Iwai
807be03cae firmware: Ignore abort check when no user-helper is used
FW_STATUS_ABORT can be set only during the user-helper invocation,
thus we can ignore the check when CONFIG_HW_LOADER_USER_HELPER is
disabled.

Acked-by: Ming Lei <ming.lei@canonical.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2013-02-03 17:57:40 -08:00
Takashi Iwai
cd7239fab7 firmware: Reduce ifdef CONFIG_FW_LOADER_USER_HELPER
By shuffling the code, reduce a few ifdefs in firmware_class.c.
Also, firmware_buf fmt field is changed to is_pages_buf boolean for
simplification.

Acked-by: Ming Lei <ming.lei@canonical.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2013-02-03 17:57:40 -08:00
Takashi Iwai
7b1269f778 firmware: Make user-mode helper optional
This patch adds a new kconfig, CONFIG_FW_LOADER_USER_HELPER, and
guards the user-helper codes in firmware_class.c with ifdefs.

Yeah, yeah, there are lots of ifdefs in this patch.  The further
clean-up with code shuffling follows in the next.

Acked-by: Ming Lei <ming.lei@canonical.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2013-02-03 17:57:40 -08:00
Takashi Iwai
4e0c92d015 firmware: Refactoring for splitting user-mode helper code
Since 3.7 kernel, the firmware loader can read the firmware files
directly, and the traditional user-mode helper is invoked only as a
fallback.  This seems working pretty well, and the next step would be
to reduce the redundant user-mode helper stuff in future.

This patch is a preparation for that: refactor the code for splitting
user-mode helper stuff more easily.  No functional change.

Acked-by: Ming Lei <ming.lei@canonical.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2013-02-03 17:57:40 -08:00
Luciano Coelho
4adf07fba3 firmware: make sure the fw file size is not 0
If the requested firmware file size is 0 bytes in the filesytem, we
will try to vmalloc(0), which causes a warning:

  vmalloc: allocation failure: 0 bytes
  kworker/1:1: page allocation failure: order:0, mode:0xd2
    __vmalloc_node_range+0x164/0x208
    __vmalloc_node+0x4c/0x58
    vmalloc+0x38/0x44
    _request_firmware_load+0x220/0x6b0
    request_firmware+0x64/0xc8
    wl18xx_setup+0xb4/0x570 [wl18xx]
    wlcore_nvs_cb+0x64/0x9f8 [wlcore]
    request_firmware_work_func+0x94/0x100
    process_one_work+0x1d0/0x750
    worker_thread+0x184/0x4ac
    kthread+0xb4/0xc0

To fix this, check whether the file size is less than or equal to zero
in fw_read_file_contents().

Cc: stable <stable@vger.kernel.org> [3.7]
Signed-off-by: Luciano Coelho <coelho@ti.com>
Acked-by: Ming Lei <ming.lei@canonical.com>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2013-01-16 09:09:53 -08:00
Ming Lei
6a927857d8 firmware loader: document firmware cache mechanism
This patch documents the firmware cache mechanism so that
users of request_firmware() know that it can be called
safely inside device's suspend and resume callback, and
the device's firmware needn't be cached any more by individual
driver itself to deal with firmware loss during system resume.

Signed-off-by: Ming Lei <ming.lei@canonical.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2012-11-14 15:07:18 -08:00
Ming Lei
2760284206 firmware loader: introduce module parameter to customize(v4) fw search path
This patch introduces one module parameter of 'path' in firmware_class
to support customizing firmware image search path, so that people can
use its own firmware path if the default built-in paths can't meet their
demand[1], and the typical usage is passing the below from kernel command
parameter when 'firmware_class' is built in kernel:

	firmware_class.path=$CUSTOMIZED_PATH

[1], https://lkml.org/lkml/2012/10/11/337

Cc: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Ming Lei <ming.lei@canonical.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2012-11-14 15:07:18 -08:00
Cesar Eduardo Barros
60dac5e284 firmware: use noinline_for_stack
The comment above fw_file_size() suggests it is noinline for stack size
reasons. Use noinline_for_stack to make this more clear.

Signed-off-by: Cesar Eduardo Barros <cesarb@cesarb.net>
Acked-by: Ming Lei <ming.lei@canonical.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2012-11-14 15:05:05 -08:00
Chuansheng Liu
bd9eb7fbe6 firmware loader: Fix the concurrent request_firmware() race for kref_get/put
There is one race that both request_firmware() with the same
firmware name.

The race scenerio is as below:
CPU1                                                  CPU2
request_firmware() -->
_request_firmware_load() return err                   another request_firmware() is coming -->
_request_firmware_cleanup is called -->               _request_firmware_prepare -->
release_firmware --->                                 fw_lookup_and_allocate_buf -->
                                                      spin_lock(&fwc->lock)
...                                                   __fw_lookup_buf() return true
fw_free_buf() will be called -->                      ...
kref_put -->
decrease the refcount to 0
                                                      kref_get(&tmp->ref) ==> it will trigger warning
                                                                              due to refcount == 0
__fw_free_buf() -->
...                                                   spin_unlock(&fwc->lock)
spin_lock(&fwc->lock)
list_del(&buf->list)
spin_unlock(&fwc->lock)
kfree(buf)
                                                      After that, the freed buf will be used.

The key race is decreasing refcount to 0 and list_del is not protected together by
fwc->lock, and it is possible another thread try to get it between refcount==0
and list_del.

Fix it here to protect it together.

Acked-by: Ming Lei <ming.lei@canonical.com>
Signed-off-by: liu chuansheng <chuansheng.liu@intel.com>
Cc: stable <stable@vger.kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2012-11-14 15:04:23 -08:00
Chuansheng Liu
ce2fcbd99c firmware loader: Fix the race FW_STATUS_DONE is followed by class_timeout
There is a race as below when calling request_firmware():
CPU1                                   CPU2
write 0 > loading
mutex_lock(&fw_lock)
...
set_bit FW_STATUS_DONE                 class_timeout is coming
                                       set_bit FW_STATUS_ABORT
complete_all &completion
...
mutex_unlock(&fw_lock)

In this time, the bit FW_STATUS_DONE and FW_STATUS_ABORT are set,
and request_firmware() will return failure due to condition in
_request_firmware_load():
	if (!buf->size || test_bit(FW_STATUS_ABORT, &buf->status))
		retval = -ENOENT;

But from the above scenerio, it should be a successful requesting.
So we need judge if the bit FW_STATUS_DONE is already set before
calling fw_load_abort() in timeout function.

As Ming's proposal, we need change the timer into sched_work to
benefit from using &fw_lock mutex also.

Signed-off-by: liu chuansheng <chuansheng.liu@intel.com>
Acked-by: Ming Lei <ming.lei@canonical.com>
Cc: stable <stable@vger.kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2012-11-14 15:04:23 -08:00
Ming Lei
d28d3882bd firmware loader: sync firmware cache by async_synchronize_full_domain
async.c has provided synchronization mechanism on async_schedule_*,
so use async_synchronize_full_domain to sync caching firmware instead
of reinventing the wheel.

Signed-off-by: Ming Lei <ming.lei@canonical.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2012-10-22 08:37:18 -07:00
Ming Lei
746058f430 firmware loader: let direct loading back on 'firmware_buf'
Firstly 'firmware_buf' is introduced to make all loading requests
to share one firmware kernel buffer, so firmware_buf should
be used in direct loading for saving memory and speedup firmware
loading.

Secondly, the commit below

	abb139e75c2cdbb955e840d6331cb5863e409d0e(firmware:teach
	the kernel to load firmware files directly from the filesystem)

introduces direct loading for fixing udev regression, but it
bypasses the firmware cache meachnism, so this patch enables
caching firmware for direct loading case since it is still needed
to solve drivers' dependency during system resume.

Cc: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Ming Lei <ming.lei@canonical.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2012-10-22 08:37:17 -07:00
Ming Lei
253c9240ee firmware loader: fix one reqeust_firmware race
Several loading requests may be pending on one same
firmware buf, and this patch moves fw_map_pages_buf()
before complete_all(&fw_buf->completion) and let all
requests see the mapped 'buf->data' once the loading
is completed.

Signed-off-by: Ming Lei <ming.lei@canonical.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2012-10-22 08:37:17 -07:00
Ming Lei
373304fe10 firmware loader: cancel uncache work before caching firmware
Under 'Opportunistic sleep' situation, system sleep might be
triggered very frequently, so the uncahce work may not be completed
before caching firmware during next suspend.

This patch cancels the uncache work before caching firmware to
fix the problem above.

Also this patch optimizes the cacheing firmware mechanism a bit by
only storing one firmware cache entry for one firmware image.

So if the firmware is still cached during suspend, it doesn't need
to be loaded from user space any more.

Signed-off-by: Ming Lei <ming.lei@canonical.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2012-10-22 08:37:16 -07:00
Linus Torvalds
ce57e981f2 firmware: use 'kernel_read()' to read firmware into kernel buffer
Fengguang correctly points out that the firmware reading should not use
vfs_read(), since the buffer is in kernel space.

The vfs_read() just happened to work for kernel threads, but sparse
warns about the incorrect address spaces, and it's definitely incorrect
and could fail for other users of the firmware loading.

Reported-by: Fengguang Wu <fengguang.wu@intel.com>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2012-10-04 09:19:02 -07:00
Linus Torvalds
abb139e75c firmware: teach the kernel to load firmware files directly from the filesystem
This is a first step in allowing people to by-pass udev for loading
device firmware.  Current versions of udev will deadlock (causing us to
block for the 30 second timeout) under some circumstances if the
firmware is loaded as part of the module initialization path, and this
is causing problems for media drivers in particular.

The current patch hardcodes the firmware path that udev uses by default,
and will fall back to the legacy udev mode if the firmware cannot be
found there.  We'd like to add support for both configuring the paths
and the fallback behaviour, but in the meantime this hopefully fixes the
immediate problem, while also giving us a way forward.

[ v2: Some VFS layer interface cleanups suggested by Al Viro ]
[ v3: use the default udev paths suggested by Kay Sievers ]

Suggested-by: Ivan Kalvachev <ikalvachev@gmail.com>
Acked-by: Greg KH <gregkh@linuxfoundation.org>
Acked-by: Al Viro <viro@zeniv.linux.org.uk>
Cc: Mauro Carvalho Chehab <mchehab@redhat.com>
Cc: Kay Sievers <kay@redhat.com>
Cc: Ming Lei <ming.lei@canonical.com>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2012-10-03 15:58:32 -07:00
Ming Lei
cfe016b14e firmware loader: fix compile warning when CONFIG_PM=n
This patch replaces the previous macro of CONFIG_PM with
CONFIG_PM_SLEEP becasue firmware cache is only used in
system sleep situations.

Also this patch fixes the below compile warning when
CONFIG_PM=n:

	drivers/base/firmware_class.c:1147: warning: 'device_cache_fw_images'
	defined but not used
	drivers/base/firmware_class.c:1212: warning:
	'device_uncache_fw_images_delay' defined but not used

Reported-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Ming Lei <ming.lei@canonical.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2012-09-10 16:40:30 -07:00
Ming Lei
ac39b3ea73 firmware loader: let caching firmware piggyback on loading firmware
After starting caching firmware, there is still some time left
before devices are suspended, during the period, request_firmware
or its nowait version may still be triggered by the below situations
to load firmware images which can't be cached during suspend/resume
cycle.

	- new devices added
	- driver bind
	- or device open kind of things

This patch utilizes the piggyback trick to cache firmware for
this kind of situation: just increase the firmware buf's reference
count and add the fw name entry into cache entry list after starting
caching firmware and before syscore_suspend() is called.

Signed-off-by: Ming Lei <ming.lei@canonical.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2012-09-06 14:46:16 -07:00
Ming Lei
ef40bb1bd0 firmware loader: fix firmware -ENOENT situations
If the requested firmware image doesn't exist, firmware->priv
should be set for the later concurrent requests, otherwise
warning and oops will be triggered inside firmware_free_data().

Signed-off-by: Ming Lei <ming.lei@canonical.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2012-09-06 14:46:16 -07:00
Ming Lei
ab6dd8e5ec firmware loader: fix build failure if FW_LOADER is m
device_cache_fw_images need to iterate devices in system,
so this patch applies the introduced dpm_for_each_dev to
avoid link failure if CONFIG_FW_LOADER is m.

Reported-by: Fengguang Wu <fengguang.wu@intel.com>
Signed-off-by: Ming Lei <ming.lei@canonical.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2012-08-17 07:37:35 -07:00
Ming Lei
c08f67730a firmware loader: fix compile failure if !PM
'return 0' should be added to fw_pm_notify if !PM because
return value of the funcion is defined as 'int'.

Reported-by: Fengguang Wu <fengguang.wu@intel.com>
Signed-off-by: Ming Lei <ming.lei@canonical.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2012-08-17 07:36:11 -07:00
Ming Lei
07646d9c09 firmware loader: cache devices firmware during suspend/resume cycle
This patch implements caching devices' firmware automatically
during system syspend/resume cycle, so any device drivers can
call request_firmware or request_firmware_nowait inside resume
path to get the cached firmware if they have loaded firmwares
successfully at least once before entering suspend.

Signed-off-by: Ming Lei <ming.lei@canonical.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2012-08-16 13:44:44 -07:00
Ming Lei
ffe53f6f38 firmware loader: use small timeout for cache device firmware
Because device_cache_fw_images only cache the firmware which has been
loaded sucessfully at leat once, using a small loading timeout should
be reasonable.

Signed-off-by: Ming Lei <ming.lei@canonical.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2012-08-16 13:44:44 -07:00
Ming Lei
37276a51f8 firmware: introduce device_cache/uncache_fw_images
This patch introduces the three helpers below:

	void device_cache_fw_images(void)
	void device_uncache_fw_images(void)
	void device_uncache_fw_images_delay(unsigned long)

so we can use device_cache_fw_images() to cache firmware for
all devices which need firmware to work, and the device driver
can get the firmware easily from kernel memory when system isn't
ready for completing requests of loading firmware.

After system is ready for completing firmware loading, driver core
will call device_uncache_fw_images() or its delay version to free
the cached firmware.

The above helpers will be used to cache device firmware during
system suspend/resume cycle in the following patches.

Signed-off-by: Ming Lei <ming.lei@canonical.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2012-08-16 13:44:44 -07:00
Ming Lei
f531f05ae9 firmware loader: store firmware name into devres list
This patch will store firmware name into devres list of the device
which is requesting firmware loading, so that we can implement
auto cache and uncache firmware for devices in need.

Signed-off-by: Ming Lei <ming.lei@canonical.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2012-08-16 13:28:50 -07:00
Ming Lei
6f21a62a58 firmware loader: fix comments on request_firmware_nowait
request_firmware_nowait is allowed to be called in atomic
context now if @gfp is GFP_ATOMIC, so fix the obsolete
comments and states which situations are suitable for using
it.

Signed-off-by: Ming Lei <ming.lei@canonical.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2012-08-16 13:28:50 -07:00
Ming Lei
0cfc1e1e7b firmware loader: fix device lifetime
Callers of request_firmware* must hold the reference count of
@device, otherwise it is easy to trigger oops since the firmware
loader device is the child of @device.

This patch adds comments about the usage. In fact, most of drivers
call request_firmware* in its probe() or open(), so the constraint
should be reasonable and can be satisfied.

Also this patch holds the reference count of @device before
schedule_work() in request_firmware_nowait() to avoid that
the @device is released after request_firmware_nowait returns
and before the worker function is scheduled.

Signed-off-by: Ming Lei <ming.lei@canonical.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2012-08-16 13:28:50 -07:00
Ming Lei
2887b3959c firmware loader: introduce cache_firmware and uncache_firmware
This patches introduce two kernel APIs of cache_firmware and
uncache_firmware, both of which take the firmware file name
as the only parameter.

So any drivers can call cache_firmware to cache the specified
firmware file into kernel memory, and can use the cached firmware
in situations which can't request firmware from user space.

Signed-off-by: Ming Lei <ming.lei@canonical.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2012-08-16 13:24:21 -07:00
Ming Lei
1f2b79599e firmware loader: always let firmware_buf own the pages buffer
This patch always let firmware_buf own the pages buffer allocated
inside firmware_data_write, and add all instances of firmware_buf
into the firmware cache global list. Also introduce one private field
in 'struct firmware', so release_firmware will see the instance of
firmware_buf associated with the current firmware instance, then just
'free' the instance of firmware_buf.

The firmware_buf instance represents one pages buffer for one
firmware image, so lots of firmware loading requests can share
the same firmware_buf instance if they request the same firmware
image file.

This patch will make implementation of the following cache_firmware/
uncache_firmware very easy and simple.

In fact, the patch improves request_formware/release_firmware:

        - only request userspace to write firmware image once if
	several devices share one same firmware image and its drivers
	call request_firmware concurrently.

Signed-off-by: Ming Lei <ming.lei@canonical.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2012-08-16 13:22:45 -07:00
Ming Lei
1244691c73 firmware loader: introduce firmware_buf
This patch introduces struct firmware_buf to describe the buffer
which holds the firmware data, which will make the following
cache_firmware/uncache_firmware implemented easily.

Signed-off-by: Ming Lei <ming.lei@canonical.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2012-08-16 13:15:08 -07:00
Ming Lei
99c2aa7230 firmware loader: fix creation failure of fw loader device
If one device driver calls request_firmware_nowait() to request
several different firmwares' loading, device_add() will return
failure since all firmware loader device use same name of the
device who is requesting firmware.

This patch always use the name of firmware image as the firmware
loader device name to fix the problem since the following patches
for caching firmware will make sure only one loading for same
firmware is alllowd at the same time.

Signed-off-by: Ming Lei <ming.lei@canonical.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2012-08-16 13:13:19 -07:00
Ming Lei
0c25a850f7 firmware loader: remove unnecessary wmb()
The wmb() inside fw_load_abort is not necessary, since
complete() and wait_on_completion() has implied one pair
of memory barrier.

Also wmb() isn't a correct usage, so just remove it.

Signed-off-by: Ming Lei <ming.lei@canonical.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2012-08-16 13:13:18 -07:00
Ming Lei
28eefa750b firmware loader: fix races during loading firmware
This patch fixes two races in loading firmware:

1, FW_STATUS_DONE should be set before waking up the task waitting
on _request_firmware_load, otherwise FW_STATUS_ABORT may be
thought as DONE mistakenly.

2, Inside _request_firmware_load(), there is a small window between
wait_for_completion() and mutex_lock(&fw_lock), and 'echo 1 > loading'
still may happen during the period, so this patch checks FW_STATUS_DONE
to prevent pages' buffer completed from being freed in firmware_loading_store.

Signed-off-by: Ming Lei <ming.lei@canonical.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2012-08-16 13:13:18 -07:00
Ming Lei
65710cb6ea firmware loader: simplify pages ownership transfer
This patch doesn't transfer ownership of pages' buffer to the
instance of firmware until the firmware loading is completed,
which will simplify firmware_loading_store a lot, so help
to introduce the following cache_firmware and uncache_firmware
mechanism during system suspend-resume cycle.

In fact, this patch fixes one bug: if writing data into
firmware loader device is bypassed between writting 1 and 0 to
'loading', OOPS will be triggered without the patch.

Also handle the vmap failure case, and add some comments to make
code more readable.

Signed-off-by: Ming Lei <ming.lei@canonical.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2012-08-16 13:13:18 -07:00
Lars-Peter Clausen
b0d1f807f3 driver-core: Use kobj_to_dev instead of re-implementing it
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2012-07-16 18:05:45 -07:00
Stephen Boyd
a36cf844c5 firmware_class: Move request_firmware_nowait() to workqueues
Oddly enough a work_struct was already part of the firmware_work
structure but nobody was using it. Instead of creating a new
kthread for each request_firmware_nowait() call just schedule the
work on the system workqueue. This should avoid some overhead
in forking new threads when they're not strictly necessary.

Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
Acked-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
2012-03-28 23:31:00 +02:00
Stephen Boyd
dddb5549da firmware_class: Reorganize fw_create_instance()
Recent patches to split up the three phases of request_firmware()
lead to a casting away of const in fw_create_instance(). We can
avoid this cast by splitting up fw_create_instance() a bit.

Make _request_firmware_setup() return a struct fw_priv and use
that struct instead of passing struct firmware to
_request_firmware(). Move the uevent and device file creation
bits to the loading phase and rename the function to
_request_firmware_load() to better reflect its purpose.

Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
Acked-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
2012-03-28 23:30:43 +02:00
Rafael J. Wysocki
9b78c1da60 firmware_class: Do not warn that system is not ready from async loads
If firmware is requested asynchronously, by calling
request_firmware_nowait(), there is no reason to fail the request
(and warn the user) when the system is (presumably temporarily)
unready to handle it (because user space is not available yet or
frozen).  For this reason, introduce an alternative routine for
read-locking umhelper_sem, usermodehelper_read_lock_wait(), that
will wait for usermodehelper_disabled to be unset (possibly with
a timeout) and make request_firmware_work_func() use it instead of
usermodehelper_read_trylock().

Accordingly, modify request_firmware() so that it uses
usermodehelper_read_trylock() to acquire umhelper_sem and remove
the code related to that lock from _request_firmware().

Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
Acked-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: stable@vger.kernel.org
2012-03-28 23:30:02 +02:00
Rafael J. Wysocki
811fa40044 firmware_class: Split _request_firmware() into three functions, v2
Split _request_firmware() into three functions,
_request_firmware_prepare() doing preparatory work that need not be
done under umhelper_sem, _request_firmware_cleanup() doing the
post-error cleanup and _request_firmware() carrying out the remaining
operations.

This change is requisite for moving the acquisition of umhelper_sem
from _request_firmware() to the callers, which is going to be done
subsequently.

Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
Acked-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Reviewed-by: Stephen Boyd <sboyd@codeaurora.org>
Cc: stable@vger.kernel.org
2012-03-28 23:29:55 +02:00
Rafael J. Wysocki
fe2e39d878 firmware_class: Rework usermodehelper check
Instead of two functions, read_lock_usermodehelper() and
usermodehelper_is_disabled(), used in combination, introduce
usermodehelper_read_trylock() that will only return with umhelper_sem
held if usermodehelper_disabled is unset (and will return -EAGAIN
otherwise) and make _request_firmware() use it.

Rename read_unlock_usermodehelper() to
usermodehelper_read_unlock() to follow the naming convention of the
new function.

Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
Acked-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: stable@vger.kernel.org
2012-03-28 23:29:45 +02:00
Tetsuo Handa
e4c89a508f PM / Sleep: Fix read_unlock_usermodehelper() call.
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 <penguin-kernel@I-love.SAKURA.ne.jp>
Acked-by: Srivatsa S. Bhat <srivatsa.bhat@linux.vnet.ibm.com>
Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
2012-01-23 21:59:08 +01:00
Linus Torvalds
eb59c505f8 Merge branch 'pm-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm
* 'pm-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm: (76 commits)
  PM / Hibernate: Implement compat_ioctl for /dev/snapshot
  PM / Freezer: fix return value of freezable_schedule_timeout_killable()
  PM / shmobile: Allow the A4R domain to be turned off at run time
  PM / input / touchscreen: Make st1232 use device PM QoS constraints
  PM / QoS: Introduce dev_pm_qos_add_ancestor_request()
  PM / shmobile: Remove the stay_on flag from SH7372's PM domains
  PM / shmobile: Don't include SH7372's INTCS in syscore suspend/resume
  PM / shmobile: Add support for the sh7372 A4S power domain / sleep mode
  PM: Drop generic_subsys_pm_ops
  PM / Sleep: Remove forward-only callbacks from AMBA bus type
  PM / Sleep: Remove forward-only callbacks from platform bus type
  PM: Run the driver callback directly if the subsystem one is not there
  PM / Sleep: Make pm_op() and pm_noirq_op() return callback pointers
  PM/Devfreq: Add Exynos4-bus device DVFS driver for Exynos4210/4212/4412.
  PM / Sleep: Merge internal functions in generic_ops.c
  PM / Sleep: Simplify generic system suspend callbacks
  PM / Hibernate: Remove deprecated hibernation snapshot ioctls
  PM / Sleep: Fix freezer failures due to racy usermodehelper_is_disabled()
  ARM: S3C64XX: Implement basic power domain support
  PM / shmobile: Use common always on power domain governor
  ...

Fix up trivial conflict in fs/xfs/xfs_buf.c due to removal of unused
XBT_FORCE_SLEEP bit
2012-01-08 13:10:57 -08:00
Neil Horman
eea915bb0d firmware: Fix an oops on reading fw_priv->fw in sysfs loading file
This oops was reported recently:
firmware_loading_store+0xf9/0x17b
dev_attr_store+0x20/0x22
sysfs_write_file+0x101/0x134
vfs_write+0xac/0xf3
sys_write+0x4a/0x6e
system_call_fastpath+0x16/0x1b

The complete backtrace was unfortunately not captured, but details can be found
here:
https://bugzilla.redhat.com/show_bug.cgi?id=769920

The cause is fairly clear.

Its caused by the fact that firmware_loading_store has a case 0 in its
switch statement that reads and writes the fw_priv->fw poniter without the
protection of the fw_lock mutex.  since there is a window between the time that
_request_firmware sets fw_priv->fw to NULL and the time the corresponding sysfs
file is unregistered, its possible for a user space application to race in, and
write a zero to the loading file, causing a NULL dereference in
firmware_loading_store.  Fix it by extending the protection of the fw_lock mutex
to cover all of the firware_loading_store function.

Signed-off-by: Neil Horman <nhorman@tuxdriver.com>
Cc: stable <stable@vger.kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
2012-01-04 16:31:29 -08:00
Srivatsa S. Bhat
b298d289c7 PM / Sleep: Fix freezer failures due to racy usermodehelper_is_disabled()
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 <srivatsa.bhat@linux.vnet.ibm.com>
Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
2011-12-09 23:36:36 +01:00
Linus Torvalds
caca9510ff firmware loader: allow builtin firmware load even if usermodehelper is disabled
In commit a144c6a6c9 ("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 288d5abec8:
"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 <cloos@hjcloos.com>
Bisected-by: Elimar Riesebieter <riesebie@lxtec.de>
Cc: Michel Dänzer <michel@daenzer.net>
Cc: Rafael Wysocki <rjw@sisk.pl>
Cc: Greg Kroah-Hartman <gregkh@suse.de>
Cc: Valdis Kletnieks <valdis.kletnieks@vt.edu>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2011-08-24 15:55:30 -07:00
Rafael J. Wysocki
a144c6a6c9 PM: Print a warning if firmware is requested when tasks are frozen
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 <rjw@sisk.pl>
Acked-by: Greg Kroah-Hartman <gregkh@suse.de>
Reviewed-by: Valdis Kletnieks <valdis.kletnieks@vt.edu>
2011-05-17 23:19:17 +02:00
Bob Liu
072fc8f0a8 firmware_classs: change val uevent's type to bool
Some place in firmware_class.c using "int uevent" define, but others use "bool
uevent".
This patch replace all int uevent define to bool.

Signed-off-by: Bob Liu <lliubbo@gmail.com>
Acked-by: Dmitry Torokhov <dtor@mail.ru>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
2011-02-03 15:39:17 -08:00