Skip to content

Commit be94215

Browse files
Xiang Chenambarus
authored andcommitted
mtd: spi-nor: core: Fix an issue of releasing resources during read/write
If rmmod the driver during read or write, the driver will release the resources which are used during read or write, so it is possible to refer to NULL pointer. Use the testcase "mtd_debug read /dev/mtd0 0xc00000 0x400000 dest_file & sleep 0.5;rmmod spi_hisi_sfc_v3xx.ko", the issue can be reproduced in hisi_sfc_v3xx driver. To avoid the issue, fill the interface _get_device and _put_device of mtd_info to grab the reference to the spi controller driver module, so the request of rmmod the driver is rejected before read/write is finished. Fixes: b199489 ("mtd: spi-nor: add the framework for SPI NOR") Signed-off-by: Xiang Chen <chenxiang66@hisilicon.com> Signed-off-by: Yicong Yang <yangyicong@hisilicon.com> Signed-off-by: Tudor Ambarus <tudor.ambarus@microchip.com> Tested-by: Michael Walle <michael@walle.cc> Tested-by: Tudor Ambarus <tudor.ambarus@microchip.com> Reviewed-by: Michael Walle <michael@walle.cc> Cc: stable@vger.kernel.org Link: https://lore.kernel.org/r/1617262486-4223-1-git-send-email-yangyicong@hisilicon.com
1 parent b206b82 commit be94215

1 file changed

Lines changed: 33 additions & 0 deletions

File tree

drivers/mtd/spi-nor/core.c

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2905,6 +2905,37 @@ static void spi_nor_resume(struct mtd_info *mtd)
29052905
dev_err(dev, "resume() failed\n");
29062906
}
29072907

2908+
static int spi_nor_get_device(struct mtd_info *mtd)
2909+
{
2910+
struct mtd_info *master = mtd_get_master(mtd);
2911+
struct spi_nor *nor = mtd_to_spi_nor(master);
2912+
struct device *dev;
2913+
2914+
if (nor->spimem)
2915+
dev = nor->spimem->spi->controller->dev.parent;
2916+
else
2917+
dev = nor->dev;
2918+
2919+
if (!try_module_get(dev->driver->owner))
2920+
return -ENODEV;
2921+
2922+
return 0;
2923+
}
2924+
2925+
static void spi_nor_put_device(struct mtd_info *mtd)
2926+
{
2927+
struct mtd_info *master = mtd_get_master(mtd);
2928+
struct spi_nor *nor = mtd_to_spi_nor(master);
2929+
struct device *dev;
2930+
2931+
if (nor->spimem)
2932+
dev = nor->spimem->spi->controller->dev.parent;
2933+
else
2934+
dev = nor->dev;
2935+
2936+
module_put(dev->driver->owner);
2937+
}
2938+
29082939
void spi_nor_restore(struct spi_nor *nor)
29092940
{
29102941
/* restore the addressing mode */
@@ -3099,6 +3130,8 @@ int spi_nor_scan(struct spi_nor *nor, const char *name,
30993130
mtd->_read = spi_nor_read;
31003131
mtd->_suspend = spi_nor_suspend;
31013132
mtd->_resume = spi_nor_resume;
3133+
mtd->_get_device = spi_nor_get_device;
3134+
mtd->_put_device = spi_nor_put_device;
31023135

31033136
if (info->flags & USE_FSR)
31043137
nor->flags |= SNOR_F_USE_FSR;

0 commit comments

Comments
 (0)