Skip to content

Commit

Permalink
mcb-lpc: Reallocate memory region to avoid memory overlapping
Browse files Browse the repository at this point in the history
[ Upstream commit 2025b2c ]

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: Jorge Sanjuan Garcia <jorge.sanjuangarcia@duagon.com>
Signed-off-by: Jorge Sanjuan Garcia <jorge.sanjuangarcia@duagon.com>
Signed-off-by: Javier Rodriguez <josejavier.rodriguez@duagon.com>
Signed-off-by: Johannes Thumshirn <jth@kernel.org>
Link: https://lore.kernel.org/r/20230411083329.4506-4-jth@kernel.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
  • Loading branch information
mad-jrodriguez authored and gregkh committed Nov 2, 2023
1 parent c9efc3e commit bede8b4
Showing 1 changed file with 31 additions and 4 deletions.
35 changes: 31 additions & 4 deletions drivers/mcb/mcb-lpc.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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)
Expand Down

0 comments on commit bede8b4

Please sign in to comment.