[PATCH] mtd: spi-nor: Fix divide by zero for spi-nor-generic flashes
Tudor Ambarus
tudor.ambarus at linaro.org
Mon May 22 02:22:05 PDT 2023
On 5/22/23 09:29, Miquel Raynal wrote:
> Hi Tudor,
Hi, Miquel,
>
> tudor.ambarus at linaro.org wrote on Thu, 18 May 2023 08:54:40 +0000:
>
>> We failed to initialize n_banks for spi-nor-generic flashes, which
>> caused a devide by zero when computing the bank_size.
>>
>> By default we consider that all chips have a single bank. Initialize
>> the default number of banks for spi-nor-generic flashes. Even if the
>> bug is fixed with this simple initialization, check the n_banks value
>> before dividing so that we make sure this kind of bug won't occur again
>> if some other struct instance is created uninitialized.
>>
>> Suggested-by: Todd Brandt <todd.e.brandt at linux.intel.com>
>> Reported-by: Todd Brandt <todd.e.brandt at linux.intel.com>
>> Closes: https://bugzilla.kernel.org/show_bug.cgi?id=217448
>> Fixes: 9d6c5d64f028 ("mtd: spi-nor: Introduce the concept of bank")
>> Link: https://lore.kernel.org/all/20230516225108.29194-1-todd.e.brandt@intel.com/
>> Signed-off-by: Tudor Ambarus <tudor.ambarus at linaro.org>
>> ---
>> drivers/mtd/spi-nor/core.c | 5 ++++-
>> 1 file changed, 4 insertions(+), 1 deletion(-)
>>
>> diff --git a/drivers/mtd/spi-nor/core.c b/drivers/mtd/spi-nor/core.c
>> index 0bb0ad14a2fc..5f29fac8669a 100644
>> --- a/drivers/mtd/spi-nor/core.c
>> +++ b/drivers/mtd/spi-nor/core.c
>> @@ -2018,6 +2018,7 @@ static const struct spi_nor_manufacturer *manufacturers[] = {
>>
>> static const struct flash_info spi_nor_generic_flash = {
>> .name = "spi-nor-generic",
>> + .n_banks = 1,
>
> I definitely missed that structure.
>
>> /*
>> * JESD216 rev A doesn't specify the page size, therefore we need a
>> * sane default.
>> @@ -2921,7 +2922,8 @@ static void spi_nor_late_init_params(struct spi_nor *nor)
>> if (nor->flags & SNOR_F_HAS_LOCK && !nor->params->locking_ops)
>> spi_nor_init_default_locking_ops(nor);
>>
>> - nor->params->bank_size = div64_u64(nor->params->size, nor->info->n_banks);
>> + if (nor->info->n_banks > 1)
>> + params->bank_size = div64_u64(params->size, nor->info->n_banks);
>
> I'm fine with the check as it is written because it also look like an
> optimization, but bank_size should never be 0 otherwise it's a real bug
bank_size was introduced just for chips featuring several banks, but we
made this field mandatory for all flashes, regardless of their type. I
find this restriction unnecessary, because we can differentiate the RWW
flashes by checking the SNOR_F_RWW flag. So the alternative to this
patch is to remove the n_banks restriction and set it just for the RWW
flashes. I think I prefer this, but keep in mind that I never read a RWW
flash's datasheet, not publicly available, so the decision is in your
court. Happy to make a patch.
> that must be catch and fixed. We do not want uninitialized bank_size's.>
>> }
>>
>> /**
>> @@ -2987,6 +2989,7 @@ static void spi_nor_init_default_params(struct spi_nor *nor)
>> /* Set SPI NOR sizes. */
>> params->writesize = 1;
>> params->size = (u64)info->sector_size * info->n_sectors;
>> + params->bank_size = params->size;
>> params->page_size = info->page_size;
>
> We actually discarded that line in a previous discussion:
> https://lore.kernel.org/linux-mtd/20230331194620.839899-1-miquel.raynal@bootlin.com/T/#mcb4f90f7ca48ffe3d9838b2ac6f74e44460c51bd
>
> I'm fine to re-add it though, it does not hurt.
we would get rid of this init as well with my suggestion.
Keep in mind that the bug was introduced in 6.4, so we'll have to fix
this fast, let's come to an agreement.
Cheers,
ta
>
>>
>> if (!(info->flags & SPI_NOR_NO_FR)) {
>
> Reviewed-by: Miquel Raynal <miquel.raynal at bootlin.com>
>
> Thanks,
> Miquèl
More information about the linux-mtd
mailing list