lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [day] [month] [year] [list]
Date:   Wed, 18 Nov 2020 16:47:26 +0000
From:   Srinivas Kandagatla <srinivas.kandagatla@...aro.org>
To:     lee.jones@...aro.org
Cc:     linux-kernel@...r.kernel.org,
        Srinivas Kandagatla <srinivas.kandagatla@...aro.org>
Subject: [PATCH] mfd: core: update mfd_of_node_list list on mfd_remove_devices

Call to mfd_add_devices() after mfd_remove_devices() will always
fail in device tree use-case, because new device will find a matching node
in the global mfd_of_node_list resulting in mfd_match_of_node_to_dev()
to return -EAGAIN.

This is one of the use-case with WCD934x where mfd devices can disappear and
reappear when ADSP either restarts or its services restarts.

Fix this issue by removing the state entry in global mfd_of_node_list
during mfd_remove_devices.

Fixes: 466a62d7642f ("mfd: core: Make a best effort attempt to match devices with the correct of_nodes")
Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@...aro.org>
---
 drivers/mfd/mfd-core.c | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/drivers/mfd/mfd-core.c b/drivers/mfd/mfd-core.c
index fc00aaccb5f7..3e845be895ac 100644
--- a/drivers/mfd/mfd-core.c
+++ b/drivers/mfd/mfd-core.c
@@ -359,6 +359,7 @@ static int mfd_remove_devices_fn(struct device *dev, void *data)
 	struct platform_device *pdev;
 	const struct mfd_cell *cell;
 	int *level = data;
+	struct mfd_of_node_entry *of_entry, *tmp;
 
 	if (dev->type != &mfd_dev_type)
 		return 0;
@@ -372,6 +373,12 @@ static int mfd_remove_devices_fn(struct device *dev, void *data)
 	regulator_bulk_unregister_supply_alias(dev, cell->parent_supplies,
 					       cell->num_parent_supplies);
 
+	list_for_each_entry_safe(of_entry, tmp, &mfd_of_node_list, list)
+		if (of_entry->dev == &pdev->dev) {
+			list_del(&of_entry->list);
+			kfree(of_entry);
+		}
+
 	platform_device_unregister(pdev);
 	return 0;
 }
-- 
2.21.0

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ