Commit 20a7b6be authored by Linus Torvalds's avatar Linus Torvalds
Browse files
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
parents 2a1a4bee baaabecf
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -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>
+2 −6
Original line number Diff line number Diff line
@@ -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);
+2 −0
Original line number Diff line number Diff line
@@ -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 */
+11 −6
Original line number Diff line number Diff line
@@ -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
+5 −5
Original line number Diff line number Diff line
@@ -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;
Loading