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 for Android: free password hash cracker in your pocket
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date:	Fri, 5 Feb 2010 23:50:43 +0300
From:	Anton Vorontsov <avorontsov@...mvista.com>
To:	Grant Likely <grant.likely@...retlab.ca>,
	David Brownell <dbrownell@...rs.sourceforge.net>
Cc:	Benjamin Herrenschmidt <benh@...nel.crashing.org>,
	David Miller <davem@...emloft.net>,
	Michal Simek <monstr@...str.eu>, linuxppc-dev@...abs.org,
	linux-kernel@...r.kernel.org, devicetree-discuss@...ts.ozlabs.org,
	microblaze-uclinux@...e.uq.edu.au
Subject: [PATCH 2/3] of: Introduce safe accessors for node->data

Platform code use node->data to store some private information
associated with a node.

Previously there was no need for any locks and accessors since we were
initializing the data mostly at boot time and never modified it later.

Though, nowadays OF GPIO infrastructure supports GPIO chips detaching,
so to handle this correctly we have to introduce locking for the
node->data field.

Signed-off-by: Anton Vorontsov <avorontsov@...mvista.com>
---
 drivers/of/base.c  |   45 +++++++++++++++++++++++++++++++++++++++++++++
 include/linux/of.h |    5 +++++
 2 files changed, 50 insertions(+), 0 deletions(-)

diff --git a/drivers/of/base.c b/drivers/of/base.c
index 716d439..41ed6ba 100644
--- a/drivers/of/base.c
+++ b/drivers/of/base.c
@@ -36,8 +36,53 @@ void of_node_init(struct device_node *np)
 {
 	memset(np, 0, sizeof(*np));
 	kref_init(&np->kref);
+	spin_lock_init(&np->data_lock);
 }
 
+/**
+ *	of_node_set_data - Try to set node->data
+ *	@node:	Node
+ *	@data:	Data
+ *
+ *	This function tries to safely set node->data. Returns 0 on success,
+ *	-EBUSY if node->data was already set.
+ */
+int of_node_set_data(struct device_node *np, void *data)
+{
+	int ret = 0;
+	unsigned long flags;
+
+	spin_lock_irqsave(&np->data_lock, flags);
+	if (np->data)
+		ret = -EBUSY;
+	else
+		np->data = data;
+	spin_unlock_irqrestore(&np->data_lock, flags);
+
+	if (!ret)
+		of_node_get(np);
+
+	return ret;
+}
+EXPORT_SYMBOL(of_node_set_data);
+
+/**
+ *	of_node_release_data_unlocked - Release node->data
+ *	@node:	Node
+ *
+ *	This function releases node->data, so that others could set it.
+ *
+ *	This function doesn't grab any locks, so that a caller can grab the
+ *	lock itself, atomically read the data and decide if it wants to
+ *	release it.
+ */
+void of_node_release_data_unlocked(struct device_node *np)
+{
+	np->data = NULL;
+	of_node_put(np);
+}
+EXPORT_SYMBOL(of_node_release_data_unlocked);
+
 int of_n_addr_cells(struct device_node *np)
 {
 	const int *ip;
diff --git a/include/linux/of.h b/include/linux/of.h
index 717d690..c573ee2 100644
--- a/include/linux/of.h
+++ b/include/linux/of.h
@@ -18,6 +18,7 @@
 #include <linux/types.h>
 #include <linux/bitops.h>
 #include <linux/kref.h>
+#include <linux/spinlock.h>
 #include <linux/mod_devicetable.h>
 
 typedef u32 phandle;
@@ -56,6 +57,7 @@ struct device_node {
 	struct	kref kref;
 	unsigned long _flags;
 	void	*data;
+	spinlock_t data_lock;
 #if defined(CONFIG_SPARC)
 	char	*path_component_name;
 	unsigned int unique_id;
@@ -65,6 +67,9 @@ struct device_node {
 
 extern void of_node_init(struct device_node *np);
 
+extern int of_node_set_data(struct device_node *np, void *data);
+extern void of_node_release_data_unlocked(struct device_node *np);
+
 static inline int of_node_check_flag(struct device_node *n, unsigned long flag)
 {
 	return test_bit(flag, &n->_flags);
-- 
1.6.5.7

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ