Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit be84e964 authored by Rodríguez Barbarin, José Javier's avatar Rodríguez Barbarin, José Javier Committed by Greg Kroah-Hartman
Browse files

mcb-lpc: Reallocate memory region to avoid memory overlapping



[ Upstream commit 2025b2ca8004c04861903d076c67a73a0ec6dfca ]

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.

Co-developed-by: default avatarJorge Sanjuan Garcia <jorge.sanjuangarcia@duagon.com>
Signed-off-by: default avatarJorge Sanjuan Garcia <jorge.sanjuangarcia@duagon.com>
Signed-off-by: default avatarJavier Rodriguez <josejavier.rodriguez@duagon.com>
Signed-off-by: default avatarJohannes Thumshirn <jth@kernel.org>
Link: https://lore.kernel.org/r/20230411083329.4506-4-jth@kernel.org


Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: default avatarSasha Levin <sashal@kernel.org>
parent 3235094d
Loading
Loading
Loading
Loading
+31 −4
Original line number Diff line number Diff line
@@ -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)