Driver core fixes for 5.9-rc5
Here are some small driver core and debugfs fixes for 5.9-rc5 Included in here are: - firmware loader memory leak fix - firmware loader testing fixes for non-EFI systems - device link locking fixes found by lockdep - kobject_del() bugfix that has been affecting some callers - debugfs minor fix All of these have been in linux-next for a while with no reported issues. Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> -----BEGIN PGP SIGNATURE----- iG0EABECAC0WIQT0tgzFv3jCIUoxPcsxR9QN2y37KQUCX13Zhw8cZ3JlZ0Brcm9h aC5jb20ACgkQMUfUDdst+ylfNQCfX4Bx9J1aLGr0/MOBwlXXEycChE0AmwQ9rXa7 u5Przdz+fMr1mLyNBaY5 =4kmo -----END PGP SIGNATURE----- Merge tag 'driver-core-5.9-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core Pull driver core fixes from Greg KH: "Here are some small driver core and debugfs fixes for 5.9-rc5 Included in here are: - firmware loader memory leak fix - firmware loader testing fixes for non-EFI systems - device link locking fixes found by lockdep - kobject_del() bugfix that has been affecting some callers - debugfs minor fix All of these have been in linux-next for a while with no reported issues" * tag 'driver-core-5.9-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core: test_firmware: Test platform fw loading on non-EFI systems PM: <linux/device.h>: fix @em_pd kernel-doc warning kobject: Drop unneeded conditional in __kobject_del() driver core: Fix device_pm_lock() locking for device links MAINTAINERS: Add the security document to SECURITY CONTACT driver code: print symbolic error code debugfs: Fix module state check condition kobject: Restore old behaviour of kobject_del(NULL) firmware_loader: fix memory leak for paged buffer
This commit is contained in:
Коммит
20a7b6be05
|
@ -15577,6 +15577,7 @@ F: include/uapi/linux/sed*
|
|||
SECURITY CONTACT
|
||||
M: Security Officers <security@kernel.org>
|
||||
S: Supported
|
||||
F: Documentation/admin-guide/security-bugs.rst
|
||||
|
||||
SECURITY SUBSYSTEM
|
||||
M: James Morris <jmorris@namei.org>
|
||||
|
|
|
@ -807,9 +807,7 @@ static void device_link_put_kref(struct device_link *link)
|
|||
void device_link_del(struct device_link *link)
|
||||
{
|
||||
device_links_write_lock();
|
||||
device_pm_lock();
|
||||
device_link_put_kref(link);
|
||||
device_pm_unlock();
|
||||
device_links_write_unlock();
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(device_link_del);
|
||||
|
@ -830,7 +828,6 @@ void device_link_remove(void *consumer, struct device *supplier)
|
|||
return;
|
||||
|
||||
device_links_write_lock();
|
||||
device_pm_lock();
|
||||
|
||||
list_for_each_entry(link, &supplier->links.consumers, s_node) {
|
||||
if (link->consumer == consumer) {
|
||||
|
@ -839,7 +836,6 @@ void device_link_remove(void *consumer, struct device *supplier)
|
|||
}
|
||||
}
|
||||
|
||||
device_pm_unlock();
|
||||
device_links_write_unlock();
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(device_link_remove);
|
||||
|
@ -4237,10 +4233,10 @@ int dev_err_probe(const struct device *dev, int err, const char *fmt, ...)
|
|||
vaf.va = &args;
|
||||
|
||||
if (err != -EPROBE_DEFER) {
|
||||
dev_err(dev, "error %d: %pV", err, &vaf);
|
||||
dev_err(dev, "error %pe: %pV", ERR_PTR(err), &vaf);
|
||||
} else {
|
||||
device_set_deferred_probe_reason(dev, &vaf);
|
||||
dev_dbg(dev, "error %d: %pV", err, &vaf);
|
||||
dev_dbg(dev, "error %pe: %pV", ERR_PTR(err), &vaf);
|
||||
}
|
||||
|
||||
va_end(args);
|
||||
|
|
|
@ -142,10 +142,12 @@ int assign_fw(struct firmware *fw, struct device *device, u32 opt_flags);
|
|||
void fw_free_paged_buf(struct fw_priv *fw_priv);
|
||||
int fw_grow_paged_buf(struct fw_priv *fw_priv, int pages_needed);
|
||||
int fw_map_paged_buf(struct fw_priv *fw_priv);
|
||||
bool fw_is_paged_buf(struct fw_priv *fw_priv);
|
||||
#else
|
||||
static inline void fw_free_paged_buf(struct fw_priv *fw_priv) {}
|
||||
static inline int fw_grow_paged_buf(struct fw_priv *fw_priv, int pages_needed) { return -ENXIO; }
|
||||
static inline int fw_map_paged_buf(struct fw_priv *fw_priv) { return -ENXIO; }
|
||||
static inline bool fw_is_paged_buf(struct fw_priv *fw_priv) { return false; }
|
||||
#endif
|
||||
|
||||
#endif /* __FIRMWARE_LOADER_H */
|
||||
|
|
|
@ -252,9 +252,11 @@ static void __free_fw_priv(struct kref *ref)
|
|||
list_del(&fw_priv->list);
|
||||
spin_unlock(&fwc->lock);
|
||||
|
||||
fw_free_paged_buf(fw_priv); /* free leftover pages */
|
||||
if (!fw_priv->allocated_size)
|
||||
if (fw_is_paged_buf(fw_priv))
|
||||
fw_free_paged_buf(fw_priv);
|
||||
else if (!fw_priv->allocated_size)
|
||||
vfree(fw_priv->data);
|
||||
|
||||
kfree_const(fw_priv->fw_name);
|
||||
kfree(fw_priv);
|
||||
}
|
||||
|
@ -268,6 +270,11 @@ static void free_fw_priv(struct fw_priv *fw_priv)
|
|||
}
|
||||
|
||||
#ifdef CONFIG_FW_LOADER_PAGED_BUF
|
||||
bool fw_is_paged_buf(struct fw_priv *fw_priv)
|
||||
{
|
||||
return fw_priv->is_paged_buf;
|
||||
}
|
||||
|
||||
void fw_free_paged_buf(struct fw_priv *fw_priv)
|
||||
{
|
||||
int i;
|
||||
|
@ -275,6 +282,8 @@ void fw_free_paged_buf(struct fw_priv *fw_priv)
|
|||
if (!fw_priv->pages)
|
||||
return;
|
||||
|
||||
vunmap(fw_priv->data);
|
||||
|
||||
for (i = 0; i < fw_priv->nr_pages; i++)
|
||||
__free_page(fw_priv->pages[i]);
|
||||
kvfree(fw_priv->pages);
|
||||
|
@ -328,10 +337,6 @@ int fw_map_paged_buf(struct fw_priv *fw_priv)
|
|||
if (!fw_priv->data)
|
||||
return -ENOMEM;
|
||||
|
||||
/* page table is no longer needed after mapping, let's free */
|
||||
kvfree(fw_priv->pages);
|
||||
fw_priv->pages = NULL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -16,9 +16,9 @@
|
|||
|
||||
/* Exported for use by lib/test_firmware.c only */
|
||||
LIST_HEAD(efi_embedded_fw_list);
|
||||
EXPORT_SYMBOL_GPL(efi_embedded_fw_list);
|
||||
|
||||
static bool checked_for_fw;
|
||||
EXPORT_SYMBOL_NS_GPL(efi_embedded_fw_list, TEST_FIRMWARE);
|
||||
bool efi_embedded_fw_checked;
|
||||
EXPORT_SYMBOL_NS_GPL(efi_embedded_fw_checked, TEST_FIRMWARE);
|
||||
|
||||
static const struct dmi_system_id * const embedded_fw_table[] = {
|
||||
#ifdef CONFIG_TOUCHSCREEN_DMI
|
||||
|
@ -116,14 +116,14 @@ void __init efi_check_for_embedded_firmwares(void)
|
|||
}
|
||||
}
|
||||
|
||||
checked_for_fw = true;
|
||||
efi_embedded_fw_checked = true;
|
||||
}
|
||||
|
||||
int efi_get_embedded_fw(const char *name, const u8 **data, size_t *size)
|
||||
{
|
||||
struct efi_embedded_fw *iter, *fw = NULL;
|
||||
|
||||
if (!checked_for_fw) {
|
||||
if (!efi_embedded_fw_checked) {
|
||||
pr_warn("Warning %s called while we did not check for embedded fw\n",
|
||||
__func__);
|
||||
return -ENOENT;
|
||||
|
|
|
@ -177,7 +177,7 @@ static int open_proxy_open(struct inode *inode, struct file *filp)
|
|||
goto out;
|
||||
|
||||
if (!fops_get(real_fops)) {
|
||||
#ifdef MODULE
|
||||
#ifdef CONFIG_MODULES
|
||||
if (real_fops->owner &&
|
||||
real_fops->owner->state == MODULE_STATE_GOING)
|
||||
goto out;
|
||||
|
@ -312,7 +312,7 @@ static int full_proxy_open(struct inode *inode, struct file *filp)
|
|||
goto out;
|
||||
|
||||
if (!fops_get(real_fops)) {
|
||||
#ifdef MODULE
|
||||
#ifdef CONFIG_MODULES
|
||||
if (real_fops->owner &&
|
||||
real_fops->owner->state == MODULE_STATE_GOING)
|
||||
goto out;
|
||||
|
|
|
@ -8,8 +8,8 @@
|
|||
#define EFI_EMBEDDED_FW_PREFIX_LEN 8
|
||||
|
||||
/*
|
||||
* This struct and efi_embedded_fw_list are private to the efi-embedded fw
|
||||
* implementation they are in this header for use by lib/test_firmware.c only!
|
||||
* This struct is private to the efi-embedded fw implementation.
|
||||
* They are in this header for use by lib/test_firmware.c only!
|
||||
*/
|
||||
struct efi_embedded_fw {
|
||||
struct list_head list;
|
||||
|
@ -18,8 +18,6 @@ struct efi_embedded_fw {
|
|||
size_t length;
|
||||
};
|
||||
|
||||
extern struct list_head efi_embedded_fw_list;
|
||||
|
||||
/**
|
||||
* struct efi_embedded_fw_desc - This struct is used by the EFI embedded-fw
|
||||
* code to search for embedded firmwares.
|
||||
|
|
|
@ -604,9 +604,6 @@ static void __kobject_del(struct kobject *kobj)
|
|||
struct kernfs_node *sd;
|
||||
const struct kobj_type *ktype;
|
||||
|
||||
if (!kobj)
|
||||
return;
|
||||
|
||||
sd = kobj->sd;
|
||||
ktype = get_ktype(kobj);
|
||||
|
||||
|
@ -637,8 +634,12 @@ static void __kobject_del(struct kobject *kobj)
|
|||
*/
|
||||
void kobject_del(struct kobject *kobj)
|
||||
{
|
||||
struct kobject *parent = kobj->parent;
|
||||
struct kobject *parent;
|
||||
|
||||
if (!kobj)
|
||||
return;
|
||||
|
||||
parent = kobj->parent;
|
||||
__kobject_del(kobj);
|
||||
kobject_put(parent);
|
||||
}
|
||||
|
|
|
@ -26,6 +26,8 @@
|
|||
#include <linux/vmalloc.h>
|
||||
#include <linux/efi_embedded_fw.h>
|
||||
|
||||
MODULE_IMPORT_NS(TEST_FIRMWARE);
|
||||
|
||||
#define TEST_FIRMWARE_NAME "test-firmware.bin"
|
||||
#define TEST_FIRMWARE_NUM_REQS 4
|
||||
#define TEST_FIRMWARE_BUF_SIZE SZ_1K
|
||||
|
@ -489,6 +491,9 @@ out:
|
|||
static DEVICE_ATTR_WO(trigger_request);
|
||||
|
||||
#ifdef CONFIG_EFI_EMBEDDED_FIRMWARE
|
||||
extern struct list_head efi_embedded_fw_list;
|
||||
extern bool efi_embedded_fw_checked;
|
||||
|
||||
static ssize_t trigger_request_platform_store(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
const char *buf, size_t count)
|
||||
|
@ -501,6 +506,7 @@ static ssize_t trigger_request_platform_store(struct device *dev,
|
|||
};
|
||||
struct efi_embedded_fw efi_embedded_fw;
|
||||
const struct firmware *firmware = NULL;
|
||||
bool saved_efi_embedded_fw_checked;
|
||||
char *name;
|
||||
int rc;
|
||||
|
||||
|
@ -513,6 +519,8 @@ static ssize_t trigger_request_platform_store(struct device *dev,
|
|||
efi_embedded_fw.data = (void *)test_data;
|
||||
efi_embedded_fw.length = sizeof(test_data);
|
||||
list_add(&efi_embedded_fw.list, &efi_embedded_fw_list);
|
||||
saved_efi_embedded_fw_checked = efi_embedded_fw_checked;
|
||||
efi_embedded_fw_checked = true;
|
||||
|
||||
pr_info("loading '%s'\n", name);
|
||||
rc = firmware_request_platform(&firmware, name, dev);
|
||||
|
@ -530,6 +538,7 @@ static ssize_t trigger_request_platform_store(struct device *dev,
|
|||
rc = count;
|
||||
|
||||
out:
|
||||
efi_embedded_fw_checked = saved_efi_embedded_fw_checked;
|
||||
release_firmware(firmware);
|
||||
list_del(&efi_embedded_fw.list);
|
||||
kfree(name);
|
||||
|
|
Загрузка…
Ссылка в новой задаче