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>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20230809180814.151984-2-eajames@linux.ibm.com>
Date:   Wed,  9 Aug 2023 13:08:13 -0500
From:   Eddie James <eajames@...ux.ibm.com>
To:     linux-fsi@...ts.ozlabs.org
Cc:     joel@....id.au, linux-kernel@...r.kernel.org,
        alistair@...ple.id.au, k@...abs.org,
        Eddie James <eajames@...ux.ibm.com>
Subject: [PATCH 1/2] fsi: Improve master indexing

Master indexing is problematic if a hub is rescanned while the
root master is being rescanned. Always allocate an index for the
FSI master, and set the device name if it hasn't already been set.
Move the call to ida_free to the bottom of master unregistration
and set the number of links to 0 in case another call to scan
comes in before the device is removed.

Signed-off-by: Eddie James <eajames@...ux.ibm.com>
---
 drivers/fsi/fsi-core.c        | 24 +++++++++++++++---------
 drivers/fsi/fsi-master-i2cr.c |  4 +---
 drivers/fsi/fsi-master-i2cr.h |  9 +++++++++
 drivers/fsi/fsi-master.h      |  1 -
 drivers/fsi/i2cr-scom.c       |  2 +-
 5 files changed, 26 insertions(+), 14 deletions(-)

diff --git a/drivers/fsi/fsi-core.c b/drivers/fsi/fsi-core.c
index 86b3108ea753..c7a002076292 100644
--- a/drivers/fsi/fsi-core.c
+++ b/drivers/fsi/fsi-core.c
@@ -1310,13 +1310,19 @@ int fsi_master_register(struct fsi_master *master)
 
 	mutex_init(&master->scan_lock);
 
-	if (!master->idx) {
+	/* Alloc the requested index if it's non-zero */
+	if (master->idx) {
+		master->idx = ida_alloc_range(&master_ida, master->idx,
+					      master->idx, GFP_KERNEL);
+	} else {
 		master->idx = ida_alloc(&master_ida, GFP_KERNEL);
-		if (master->idx < 0)
-			return master->idx;
+	}
+
+	if (master->idx < 0)
+		return master->idx;
 
+	if (!dev_name(&master->dev))
 		dev_set_name(&master->dev, "fsi%d", master->idx);
-	}
 
 	master->dev.class = &fsi_master_class;
 
@@ -1339,17 +1345,17 @@ EXPORT_SYMBOL_GPL(fsi_master_register);
 
 void fsi_master_unregister(struct fsi_master *master)
 {
-	trace_fsi_master_unregister(master);
+	int idx = master->idx;
 
-	if (master->idx >= 0) {
-		ida_free(&master_ida, master->idx);
-		master->idx = -1;
-	}
+	trace_fsi_master_unregister(master);
 
 	mutex_lock(&master->scan_lock);
 	fsi_master_unscan(master);
+	master->n_links = 0;
 	mutex_unlock(&master->scan_lock);
+
 	device_unregister(&master->dev);
+	ida_free(&master_ida, idx);
 }
 EXPORT_SYMBOL_GPL(fsi_master_unregister);
 
diff --git a/drivers/fsi/fsi-master-i2cr.c b/drivers/fsi/fsi-master-i2cr.c
index e4e8a5931ca3..61659c27a973 100644
--- a/drivers/fsi/fsi-master-i2cr.c
+++ b/drivers/fsi/fsi-master-i2cr.c
@@ -267,13 +267,12 @@ static int i2cr_probe(struct i2c_client *client)
 
 	/* Only one I2CR on any given I2C bus (fixed I2C device address) */
 	i2cr->master.idx = client->adapter->nr;
-	dev_set_name(&i2cr->master.dev, "i2cr%d",i2cr->master.idx);
+	dev_set_name(&i2cr->master.dev, "i2cr%d", i2cr->master.idx);
 	i2cr->master.dev.parent = &client->dev;
 	i2cr->master.dev.of_node = of_node_get(dev_of_node(&client->dev));
 	i2cr->master.dev.release = i2cr_release;
 
 	i2cr->master.n_links = 1;
-	i2cr->master.flags = FSI_MASTER_FLAG_I2CR;
 	i2cr->master.read = i2cr_read;
 	i2cr->master.write = i2cr_write;
 
@@ -292,7 +291,6 @@ static void i2cr_remove(struct i2c_client *client)
 {
 	struct fsi_master_i2cr *i2cr = i2c_get_clientdata(client);
 
-	i2cr->master.idx = -1;
 	fsi_master_unregister(&i2cr->master);
 }
 
diff --git a/drivers/fsi/fsi-master-i2cr.h b/drivers/fsi/fsi-master-i2cr.h
index 929d63995c7b..96636bf28cac 100644
--- a/drivers/fsi/fsi-master-i2cr.h
+++ b/drivers/fsi/fsi-master-i2cr.h
@@ -4,6 +4,7 @@
 #ifndef DRIVERS_FSI_MASTER_I2CR_H
 #define DRIVERS_FSI_MASTER_I2CR_H
 
+#include <linux/i2c.h>
 #include <linux/mutex.h>
 
 #include "fsi-master.h"
@@ -21,4 +22,12 @@ struct fsi_master_i2cr {
 int fsi_master_i2cr_read(struct fsi_master_i2cr *i2cr, u32 addr, u64 *data);
 int fsi_master_i2cr_write(struct fsi_master_i2cr *i2cr, u32 addr, u64 data);
 
+static inline bool is_fsi_master_i2cr(struct fsi_master *master)
+{
+	if (master->dev.parent && master->dev.parent->type == &i2c_client_type)
+		return true;
+
+	return false;
+}
+
 #endif /* DRIVERS_FSI_MASTER_I2CR_H */
diff --git a/drivers/fsi/fsi-master.h b/drivers/fsi/fsi-master.h
index a1fa315849d2..967622c1cabf 100644
--- a/drivers/fsi/fsi-master.h
+++ b/drivers/fsi/fsi-master.h
@@ -111,7 +111,6 @@
 
 /* fsi-master definition and flags */
 #define FSI_MASTER_FLAG_SWCLOCK		0x1
-#define FSI_MASTER_FLAG_I2CR		0x2
 
 /*
  * Structures and function prototypes
diff --git a/drivers/fsi/i2cr-scom.c b/drivers/fsi/i2cr-scom.c
index 63b548bdef3e..cb7e02213032 100644
--- a/drivers/fsi/i2cr-scom.c
+++ b/drivers/fsi/i2cr-scom.c
@@ -88,7 +88,7 @@ static int i2cr_scom_probe(struct device *dev)
 	int didx;
 	int ret;
 
-	if (!(fsi_dev->slave->master->flags & FSI_MASTER_FLAG_I2CR))
+	if (!is_fsi_master_i2cr(fsi_dev->slave->master))
 		return -ENODEV;
 
 	scom = devm_kzalloc(dev, sizeof(*scom), GFP_KERNEL);
-- 
2.39.3

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ