summaryrefslogtreecommitdiff
path: root/drivers/mcb/mcb-lpc.c
diff options
context:
space:
mode:
authorRodríguez Barbarin, José Javier <JoseJavier.Rodriguez@duagon.com>2023-04-11 10:33:29 +0200
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2023-04-20 14:24:01 +0200
commit2025b2ca8004c04861903d076c67a73a0ec6dfca (patch)
tree8f12535e45269fbacb2b15878eade781054a6176 /drivers/mcb/mcb-lpc.c
parent9be24faadd085c284890c3afcec7a0184642315a (diff)
downloadlwn-2025b2ca8004c04861903d076c67a73a0ec6dfca.tar.gz
lwn-2025b2ca8004c04861903d076c67a73a0ec6dfca.zip
mcb-lpc: Reallocate memory region to avoid memory overlapping
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>
Diffstat (limited to 'drivers/mcb/mcb-lpc.c')
-rw-r--r--drivers/mcb/mcb-lpc.c35
1 files changed, 31 insertions, 4 deletions
diff --git a/drivers/mcb/mcb-lpc.c b/drivers/mcb/mcb-lpc.c
index 53decd89876e..a851e0236464 100644
--- a/drivers/mcb/mcb-lpc.c
+++ b/drivers/mcb/mcb-lpc.c
@@ -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)