Skip to contentSkip to conversation

mcb patches for 6.4

PATCH New Johannes Thumshirn 1 participant 4 messages Apr 11, 2023 Men chameleon bus (mcb)

lore
Share & tools
lore
#0 lore raw

cover mcb patches for 6.4

Hi Greg,

Here's this round's pile of patches for mcb I've collected.

It's fixing/quirking a issue with mcb FPGAs where the identification table is smaller than expected and thus the subordinate drivers can't claim the memory reagions they want.

Byte,
Johannes

Rodríguez Barbarin, José Javier (3):
mcb: Return actual parsed size when reading chameleon table
mcb-pci: Reallocate memory region to avoid memory overlapping
mcb-lpc: Reallocate memory region to avoid memory overlapping

 drivers/mcb/mcb-lpc.c   | 35 +++++++++++++++++++++++++++++++----
 drivers/mcb/mcb-parse.c | 15 ++++++++++-----
 drivers/mcb/mcb-pci.c   | 27 +++++++++++++++++++++++++--
 3 files changed, 66 insertions(+), 11 deletions(-)
Signature · 1 line
2.39.2
#1 lore raw

PATCH 1/3 mcb: Return actual parsed size when reading chameleon table

From: Rodríguez Barbarin, José Javier <[email protected]>

The function chameleon_parse_cells() returns the number of cells parsed which has an undetermined size. This return value is only used for error checking but the number of cells is never used.

Change return value to be number of bytes parsed to allow for memory management improvements.

---
 drivers/mcb/mcb-parse.c | 15 ++++++++++-----
 1 file changed, 10 insertions(+), 5 deletions(-)
drivers/mcb/mcb-parse.c +10 -5
index aa6938da0db8..2aef990f379f 100644
@@ -130,7 +130,7 @@ static void chameleon_parse_bar(void __iomem *base,
 	}
 }
 
-static int chameleon_get_bar(char __iomem **base, phys_addr_t mapbase,
+static int chameleon_get_bar(void __iomem **base, phys_addr_t mapbase,
 			     struct chameleon_bar **cb)
 {
 	struct chameleon_bar *c;
@@ -179,12 +179,13 @@ int chameleon_parse_cells(struct mcb_bus *bus, phys_addr_t mapbase,
 {
 	struct chameleon_fpga_header *header;
 	struct chameleon_bar *cb;
-	char __iomem *p = base;
+	void __iomem *p = base;
 	int num_cells = 0;
 	uint32_t dtype;
 	int bar_count;
 	int ret;
 	u32 hsize;
+	u32 table_size;
 
 	hsize = sizeof(struct chameleon_fpga_header);
 
@@ -239,12 +240,16 @@ int chameleon_parse_cells(struct mcb_bus *bus, phys_addr_t mapbase,
 		num_cells++;
 	}
 
-	if (num_cells == 0)
-		num_cells = -EINVAL;
+	if (num_cells == 0) {
+		ret = -EINVAL;
+		goto free_bar;
+	}
 
+	table_size = p - base;
+	pr_debug("%d cell(s) found. Chameleon table size: 0x%04x bytes\n", num_cells, table_size);
 	kfree(cb);
 	kfree(header);
-	return num_cells;
+	return table_size;
 
 free_bar:
 	kfree(cb);
Signature · 1 line
2.39.2
#2 lore raw

PATCH 2/3 mcb-pci: Reallocate memory region to avoid memory overlapping

In reply to Johannes Thumshirn

From: Rodríguez Barbarin, José Javier <[email protected]>

mcb-pci requests a fixed-size memory region to parse the chameleon table, however, if the chameleon table is smaller that the allocated region, it could overlap with the IP Cores' memory regions.

After parsing the chameleon table, drop/reallocate the memory region with the actual chameleon table size.

---
 drivers/mcb/mcb-pci.c | 27 +++++++++++++++++++++++++--
 1 file changed, 25 insertions(+), 2 deletions(-)
drivers/mcb/mcb-pci.c +25 -2
index dc88232d9af8..53d9202ff9a7 100644
@@ -31,7 +31,7 @@ static int mcb_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
 {
 	struct resource *res;
 	struct priv *priv;
-	int ret;
+	int ret, table_size;
 	unsigned long flags;
 
 	priv = devm_kzalloc(&pdev->dev, sizeof(struct priv), GFP_KERNEL);
@@ -90,7 +90,30 @@ static int mcb_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
 	if (ret < 0)
 		goto out_mcb_bus;
 
-	dev_dbg(&pdev->dev, "Found %d cells\n", ret);
+	table_size = ret;
+
+	if (table_size < CHAM_HEADER_SIZE) {
+		/* Release the previous resources */
+		devm_iounmap(&pdev->dev, priv->base);
+		devm_release_mem_region(&pdev->dev, priv->mapbase, CHAM_HEADER_SIZE);
+
+		/* Then, allocate it again with the actual chameleon table size */
+		res = devm_request_mem_region(&pdev->dev, priv->mapbase,
+						table_size,
+						KBUILD_MODNAME);
+		if (!res) {
+			dev_err(&pdev->dev, "Failed to request PCI memory\n");
+			ret = -EBUSY;
+			goto out_mcb_bus;
+		}
+
+		priv->base = devm_ioremap(&pdev->dev, priv->mapbase, table_size);
+		if (!priv->base) {
+			dev_err(&pdev->dev, "Cannot ioremap\n");
+			ret = -ENOMEM;
+			goto out_mcb_bus;
+		}
+	}
 
 	mcb_bus_add_devices(priv->bus);
 
Signature · 1 line
2.39.2
#3 lore raw

PATCH 3/3 mcb-lpc: Reallocate memory region to avoid memory overlapping

In reply to Johannes Thumshirn

From: Rodríguez Barbarin, José Javier <[email protected]>

mcb-lpc requests a fixed-size memory region to parse the chameleon table, however, if the chameleon table is smaller that the allocated region, it could overlap with the IP Cores' memory regions.

After parsing the chameleon table, drop/reallocate the memory region with the actual chameleon table size.

---
 drivers/mcb/mcb-lpc.c | 35 +++++++++++++++++++++++++++++++----
 1 file changed, 31 insertions(+), 4 deletions(-)
drivers/mcb/mcb-lpc.c +31 -4
index 53decd89876e..a851e0236464 100644
@@ -23,7 +23,7 @@ static int mcb_lpc_probe(struct platform_device *pdev)
 {
 	struct resource *res;
 	struct priv *priv;
-	int ret = 0;
+	int ret = 0, table_size;
 
 	priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
 	if (!priv)
@@ -58,16 +58,43 @@ static int mcb_lpc_probe(struct platform_device *pdev)
 
 	ret = chameleon_parse_cells(priv->bus, priv->mem->start, priv->base);
 	if (ret < 0) {
-		mcb_release_bus(priv->bus);
-		return ret;
+		goto out_mcb_bus;
 	}
 
-	dev_dbg(&pdev->dev, "Found %d cells\n", ret);
+	table_size = ret;
+
+	if (table_size < CHAM_HEADER_SIZE) {
+		/* Release the previous resources */
+		devm_iounmap(&pdev->dev, priv->base);
+		devm_release_mem_region(&pdev->dev, priv->mem->start, resource_size(priv->mem));
+
+		/* Then, allocate it again with the actual chameleon table size */
+		res = devm_request_mem_region(&pdev->dev, priv->mem->start,
+					      table_size,
+					      KBUILD_MODNAME);
+		if (!res) {
+			dev_err(&pdev->dev, "Failed to request PCI memory\n");
+			ret = -EBUSY;
+			goto out_mcb_bus;
+		}
+
+		priv->base = devm_ioremap(&pdev->dev, priv->mem->start, table_size);
+		if (!priv->base) {
+			dev_err(&pdev->dev, "Cannot ioremap\n");
+			ret = -ENOMEM;
+			goto out_mcb_bus;
+		}
+
+		platform_set_drvdata(pdev, priv);
+	}
 
 	mcb_bus_add_devices(priv->bus);
 
 	return 0;
 
+out_mcb_bus:
+	mcb_release_bus(priv->bus);
+	return ret;
 }
 
 static int mcb_lpc_remove(struct platform_device *pdev)
Signature · 1 line
2.39.2