Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

mcb-pci: Reallocate memory region to avoid memory overlapping

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.

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-3-jth@kernel.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

authored by

Rodríguez Barbarin, José Javier and committed by
Greg Kroah-Hartman
9be24faa a889c276

+25 -2
+25 -2
drivers/mcb/mcb-pci.c
··· 31 31 { 32 32 struct resource *res; 33 33 struct priv *priv; 34 - int ret; 34 + int ret, table_size; 35 35 unsigned long flags; 36 36 37 37 priv = devm_kzalloc(&pdev->dev, sizeof(struct priv), GFP_KERNEL); ··· 90 90 if (ret < 0) 91 91 goto out_mcb_bus; 92 92 93 - dev_dbg(&pdev->dev, "Found %d cells\n", ret); 93 + table_size = ret; 94 + 95 + if (table_size < CHAM_HEADER_SIZE) { 96 + /* Release the previous resources */ 97 + devm_iounmap(&pdev->dev, priv->base); 98 + devm_release_mem_region(&pdev->dev, priv->mapbase, CHAM_HEADER_SIZE); 99 + 100 + /* Then, allocate it again with the actual chameleon table size */ 101 + res = devm_request_mem_region(&pdev->dev, priv->mapbase, 102 + table_size, 103 + KBUILD_MODNAME); 104 + if (!res) { 105 + dev_err(&pdev->dev, "Failed to request PCI memory\n"); 106 + ret = -EBUSY; 107 + goto out_mcb_bus; 108 + } 109 + 110 + priv->base = devm_ioremap(&pdev->dev, priv->mapbase, table_size); 111 + if (!priv->base) { 112 + dev_err(&pdev->dev, "Cannot ioremap\n"); 113 + ret = -ENOMEM; 114 + goto out_mcb_bus; 115 + } 116 + } 94 117 95 118 mcb_bus_add_devices(priv->bus); 96 119