firmware: Store opt_flags in fw_priv
Instead of passing opt_flags around so much, store it in the private structure so it can be examined by internals without needing to add more arguments to functions. Co-developed-by: Scott Branden <scott.branden@broadcom.com> Signed-off-by: Scott Branden <scott.branden@broadcom.com> Signed-off-by: Kees Cook <keescook@chromium.org> Link: https://lore.kernel.org/r/20201002173828.2099543-15-keescook@chromium.org Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
0fa8e08464
commit
89287c169f
@ -490,13 +490,11 @@ exit:
|
|||||||
/**
|
/**
|
||||||
* fw_load_sysfs_fallback() - load a firmware via the sysfs fallback mechanism
|
* fw_load_sysfs_fallback() - load a firmware via the sysfs fallback mechanism
|
||||||
* @fw_sysfs: firmware sysfs information for the firmware to load
|
* @fw_sysfs: firmware sysfs information for the firmware to load
|
||||||
* @opt_flags: flags of options, FW_OPT_*
|
|
||||||
* @timeout: timeout to wait for the load
|
* @timeout: timeout to wait for the load
|
||||||
*
|
*
|
||||||
* In charge of constructing a sysfs fallback interface for firmware loading.
|
* In charge of constructing a sysfs fallback interface for firmware loading.
|
||||||
**/
|
**/
|
||||||
static int fw_load_sysfs_fallback(struct fw_sysfs *fw_sysfs,
|
static int fw_load_sysfs_fallback(struct fw_sysfs *fw_sysfs, long timeout)
|
||||||
u32 opt_flags, long timeout)
|
|
||||||
{
|
{
|
||||||
int retval = 0;
|
int retval = 0;
|
||||||
struct device *f_dev = &fw_sysfs->dev;
|
struct device *f_dev = &fw_sysfs->dev;
|
||||||
@ -518,7 +516,7 @@ static int fw_load_sysfs_fallback(struct fw_sysfs *fw_sysfs,
|
|||||||
list_add(&fw_priv->pending_list, &pending_fw_head);
|
list_add(&fw_priv->pending_list, &pending_fw_head);
|
||||||
mutex_unlock(&fw_lock);
|
mutex_unlock(&fw_lock);
|
||||||
|
|
||||||
if (opt_flags & FW_OPT_UEVENT) {
|
if (fw_priv->opt_flags & FW_OPT_UEVENT) {
|
||||||
fw_priv->need_uevent = true;
|
fw_priv->need_uevent = true;
|
||||||
dev_set_uevent_suppress(f_dev, false);
|
dev_set_uevent_suppress(f_dev, false);
|
||||||
dev_dbg(f_dev, "firmware: requesting %s\n", fw_priv->fw_name);
|
dev_dbg(f_dev, "firmware: requesting %s\n", fw_priv->fw_name);
|
||||||
@ -580,10 +578,10 @@ static int fw_load_from_user_helper(struct firmware *firmware,
|
|||||||
}
|
}
|
||||||
|
|
||||||
fw_sysfs->fw_priv = firmware->priv;
|
fw_sysfs->fw_priv = firmware->priv;
|
||||||
ret = fw_load_sysfs_fallback(fw_sysfs, opt_flags, timeout);
|
ret = fw_load_sysfs_fallback(fw_sysfs, timeout);
|
||||||
|
|
||||||
if (!ret)
|
if (!ret)
|
||||||
ret = assign_fw(firmware, device, opt_flags);
|
ret = assign_fw(firmware, device);
|
||||||
|
|
||||||
out_unlock:
|
out_unlock:
|
||||||
usermodehelper_read_unlock();
|
usermodehelper_read_unlock();
|
||||||
@ -625,7 +623,6 @@ static bool fw_run_sysfs_fallback(u32 opt_flags)
|
|||||||
* @fw: pointer to firmware image
|
* @fw: pointer to firmware image
|
||||||
* @name: name of firmware file to look for
|
* @name: name of firmware file to look for
|
||||||
* @device: device for which firmware is being loaded
|
* @device: device for which firmware is being loaded
|
||||||
* @opt_flags: options to control firmware loading behaviour
|
|
||||||
* @ret: return value from direct lookup which triggered the fallback mechanism
|
* @ret: return value from direct lookup which triggered the fallback mechanism
|
||||||
*
|
*
|
||||||
* This function is called if direct lookup for the firmware failed, it enables
|
* This function is called if direct lookup for the firmware failed, it enables
|
||||||
|
@ -67,10 +67,9 @@ static inline void unregister_sysfs_loader(void)
|
|||||||
#endif /* CONFIG_FW_LOADER_USER_HELPER */
|
#endif /* CONFIG_FW_LOADER_USER_HELPER */
|
||||||
|
|
||||||
#ifdef CONFIG_EFI_EMBEDDED_FIRMWARE
|
#ifdef CONFIG_EFI_EMBEDDED_FIRMWARE
|
||||||
int firmware_fallback_platform(struct fw_priv *fw_priv, u32 opt_flags);
|
int firmware_fallback_platform(struct fw_priv *fw_priv);
|
||||||
#else
|
#else
|
||||||
static inline int firmware_fallback_platform(struct fw_priv *fw_priv,
|
static inline int firmware_fallback_platform(struct fw_priv *fw_priv)
|
||||||
u32 opt_flags)
|
|
||||||
{
|
{
|
||||||
return -ENOENT;
|
return -ENOENT;
|
||||||
}
|
}
|
||||||
|
@ -8,13 +8,13 @@
|
|||||||
#include "fallback.h"
|
#include "fallback.h"
|
||||||
#include "firmware.h"
|
#include "firmware.h"
|
||||||
|
|
||||||
int firmware_fallback_platform(struct fw_priv *fw_priv, u32 opt_flags)
|
int firmware_fallback_platform(struct fw_priv *fw_priv)
|
||||||
{
|
{
|
||||||
const u8 *data;
|
const u8 *data;
|
||||||
size_t size;
|
size_t size;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
if (!(opt_flags & FW_OPT_FALLBACK_PLATFORM))
|
if (!(fw_priv->opt_flags & FW_OPT_FALLBACK_PLATFORM))
|
||||||
return -ENOENT;
|
return -ENOENT;
|
||||||
|
|
||||||
rc = security_kernel_load_data(LOADING_FIRMWARE, true);
|
rc = security_kernel_load_data(LOADING_FIRMWARE, true);
|
||||||
|
@ -68,6 +68,7 @@ struct fw_priv {
|
|||||||
void *data;
|
void *data;
|
||||||
size_t size;
|
size_t size;
|
||||||
size_t allocated_size;
|
size_t allocated_size;
|
||||||
|
u32 opt_flags;
|
||||||
#ifdef CONFIG_FW_LOADER_PAGED_BUF
|
#ifdef CONFIG_FW_LOADER_PAGED_BUF
|
||||||
bool is_paged_buf;
|
bool is_paged_buf;
|
||||||
struct page **pages;
|
struct page **pages;
|
||||||
@ -136,7 +137,7 @@ static inline void fw_state_done(struct fw_priv *fw_priv)
|
|||||||
__fw_state_set(fw_priv, FW_STATUS_DONE);
|
__fw_state_set(fw_priv, FW_STATUS_DONE);
|
||||||
}
|
}
|
||||||
|
|
||||||
int assign_fw(struct firmware *fw, struct device *device, u32 opt_flags);
|
int assign_fw(struct firmware *fw, struct device *device);
|
||||||
|
|
||||||
#ifdef CONFIG_FW_LOADER_PAGED_BUF
|
#ifdef CONFIG_FW_LOADER_PAGED_BUF
|
||||||
void fw_free_paged_buf(struct fw_priv *fw_priv);
|
void fw_free_paged_buf(struct fw_priv *fw_priv);
|
||||||
|
@ -168,7 +168,9 @@ static int fw_cache_piggyback_on_request(const char *name);
|
|||||||
|
|
||||||
static struct fw_priv *__allocate_fw_priv(const char *fw_name,
|
static struct fw_priv *__allocate_fw_priv(const char *fw_name,
|
||||||
struct firmware_cache *fwc,
|
struct firmware_cache *fwc,
|
||||||
void *dbuf, size_t size)
|
void *dbuf,
|
||||||
|
size_t size,
|
||||||
|
u32 opt_flags)
|
||||||
{
|
{
|
||||||
struct fw_priv *fw_priv;
|
struct fw_priv *fw_priv;
|
||||||
|
|
||||||
@ -186,6 +188,7 @@ static struct fw_priv *__allocate_fw_priv(const char *fw_name,
|
|||||||
fw_priv->fwc = fwc;
|
fw_priv->fwc = fwc;
|
||||||
fw_priv->data = dbuf;
|
fw_priv->data = dbuf;
|
||||||
fw_priv->allocated_size = size;
|
fw_priv->allocated_size = size;
|
||||||
|
fw_priv->opt_flags = opt_flags;
|
||||||
fw_state_init(fw_priv);
|
fw_state_init(fw_priv);
|
||||||
#ifdef CONFIG_FW_LOADER_USER_HELPER
|
#ifdef CONFIG_FW_LOADER_USER_HELPER
|
||||||
INIT_LIST_HEAD(&fw_priv->pending_list);
|
INIT_LIST_HEAD(&fw_priv->pending_list);
|
||||||
@ -210,8 +213,10 @@ static struct fw_priv *__lookup_fw_priv(const char *fw_name)
|
|||||||
/* Returns 1 for batching firmware requests with the same name */
|
/* Returns 1 for batching firmware requests with the same name */
|
||||||
static int alloc_lookup_fw_priv(const char *fw_name,
|
static int alloc_lookup_fw_priv(const char *fw_name,
|
||||||
struct firmware_cache *fwc,
|
struct firmware_cache *fwc,
|
||||||
struct fw_priv **fw_priv, void *dbuf,
|
struct fw_priv **fw_priv,
|
||||||
size_t size, u32 opt_flags)
|
void *dbuf,
|
||||||
|
size_t size,
|
||||||
|
u32 opt_flags)
|
||||||
{
|
{
|
||||||
struct fw_priv *tmp;
|
struct fw_priv *tmp;
|
||||||
|
|
||||||
@ -227,7 +232,7 @@ static int alloc_lookup_fw_priv(const char *fw_name,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
tmp = __allocate_fw_priv(fw_name, fwc, dbuf, size);
|
tmp = __allocate_fw_priv(fw_name, fwc, dbuf, size, opt_flags);
|
||||||
if (tmp) {
|
if (tmp) {
|
||||||
INIT_LIST_HEAD(&tmp->list);
|
INIT_LIST_HEAD(&tmp->list);
|
||||||
if (!(opt_flags & FW_OPT_NOCACHE))
|
if (!(opt_flags & FW_OPT_NOCACHE))
|
||||||
@ -640,7 +645,7 @@ static int fw_add_devm_name(struct device *dev, const char *name)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int assign_fw(struct firmware *fw, struct device *device, u32 opt_flags)
|
int assign_fw(struct firmware *fw, struct device *device)
|
||||||
{
|
{
|
||||||
struct fw_priv *fw_priv = fw->priv;
|
struct fw_priv *fw_priv = fw->priv;
|
||||||
int ret;
|
int ret;
|
||||||
@ -659,8 +664,8 @@ int assign_fw(struct firmware *fw, struct device *device, u32 opt_flags)
|
|||||||
* should be fixed in devres or driver core.
|
* should be fixed in devres or driver core.
|
||||||
*/
|
*/
|
||||||
/* don't cache firmware handled without uevent */
|
/* don't cache firmware handled without uevent */
|
||||||
if (device && (opt_flags & FW_OPT_UEVENT) &&
|
if (device && (fw_priv->opt_flags & FW_OPT_UEVENT) &&
|
||||||
!(opt_flags & FW_OPT_NOCACHE)) {
|
!(fw_priv->opt_flags & FW_OPT_NOCACHE)) {
|
||||||
ret = fw_add_devm_name(device, fw_priv->fw_name);
|
ret = fw_add_devm_name(device, fw_priv->fw_name);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
mutex_unlock(&fw_lock);
|
mutex_unlock(&fw_lock);
|
||||||
@ -672,7 +677,7 @@ int assign_fw(struct firmware *fw, struct device *device, u32 opt_flags)
|
|||||||
* After caching firmware image is started, let it piggyback
|
* After caching firmware image is started, let it piggyback
|
||||||
* on request firmware.
|
* on request firmware.
|
||||||
*/
|
*/
|
||||||
if (!(opt_flags & FW_OPT_NOCACHE) &&
|
if (!(fw_priv->opt_flags & FW_OPT_NOCACHE) &&
|
||||||
fw_priv->fwc->state == FW_LOADER_START_CACHE) {
|
fw_priv->fwc->state == FW_LOADER_START_CACHE) {
|
||||||
if (fw_cache_piggyback_on_request(fw_priv->fw_name))
|
if (fw_cache_piggyback_on_request(fw_priv->fw_name))
|
||||||
kref_get(&fw_priv->ref);
|
kref_get(&fw_priv->ref);
|
||||||
@ -783,7 +788,7 @@ _request_firmware(const struct firmware **firmware_p, const char *name,
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (ret == -ENOENT)
|
if (ret == -ENOENT)
|
||||||
ret = firmware_fallback_platform(fw->priv, opt_flags);
|
ret = firmware_fallback_platform(fw->priv);
|
||||||
|
|
||||||
if (ret) {
|
if (ret) {
|
||||||
if (!(opt_flags & FW_OPT_NO_WARN))
|
if (!(opt_flags & FW_OPT_NO_WARN))
|
||||||
@ -792,7 +797,7 @@ _request_firmware(const struct firmware **firmware_p, const char *name,
|
|||||||
name, ret);
|
name, ret);
|
||||||
ret = firmware_fallback_sysfs(fw, name, device, opt_flags, ret);
|
ret = firmware_fallback_sysfs(fw, name, device, opt_flags, ret);
|
||||||
} else
|
} else
|
||||||
ret = assign_fw(fw, device, opt_flags);
|
ret = assign_fw(fw, device);
|
||||||
|
|
||||||
out:
|
out:
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user