mirror of
https://source.denx.de/u-boot/u-boot.git
synced 2025-12-19 08:21:27 +01:00
spi: spi-mem: fix coverity report CID 537478
Coverity finds a potential integer overflow in the following code: ncycles += ((op->data.nbytes * 8) / op->data.buswidth) / (op->data.dtr ? 2 : 1); A quick analysis shows that the only caller of the suspicious code is the spinand_select_op_variant() function from the drivers/mtd/nand/spi/core.c file. According to the code the value of op->data.nbytes is equal to nanddev_per_page_oobsize(nand) + nanddev_page_size(nand) Therefore it's maximum value a bit larger than 4Kb (I never seen flashes with page size large than 4Kb). So op->data.nbytes always fits within 13 bits. As result an overflow will never happen. Anyway it's better fix an issue to eliminate the error message. Signed-off-by: Mikhail Kshevetskiy <mikhail.kshevetskiy@iopsys.eu>
This commit is contained in:
parent
c675162bcb
commit
c3c758c20d
@ -499,6 +499,31 @@ int spi_mem_adjust_op_size(struct spi_slave *slave, struct spi_mem_op *op)
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(spi_mem_adjust_op_size);
|
||||
|
||||
static inline u64 spi_mem_bytes_to_ncycles(u32 nbytes, u8 buswidth, u8 dtr)
|
||||
{
|
||||
u64 ncycles;
|
||||
u32 divider = buswidth * (dtr ? 2 : 1);
|
||||
|
||||
/*
|
||||
* Theoretically
|
||||
*
|
||||
* ncycles = (nbytes * 8) / (buswidth * (dtr ? 2 : 1));
|
||||
*
|
||||
* may lead to an integer overflow, if nbytes will be larger than
|
||||
* 0x1fffffff. Lets split this operation on:
|
||||
*
|
||||
* 1) Operation with bits 0..28 (overflow will not happen),
|
||||
*
|
||||
* 2) Operation with bits 29..31. Here we'll take into account
|
||||
* that buswidth is a small power of 2 (so whole divider is
|
||||
* small power of 2). Hense we may divide first, then multiply.
|
||||
*/
|
||||
ncycles = ((nbytes & 0x1fffffff) * 8) / divider;
|
||||
ncycles += ((u64) ((nbytes & ~0x1fffffff) / divider)) * 8;
|
||||
|
||||
return ncycles;
|
||||
}
|
||||
|
||||
/**
|
||||
* spi_mem_calc_op_duration() - Derives the theoretical length (in cpu cycles)
|
||||
* of an operation. This helps finding the best
|
||||
@ -518,14 +543,22 @@ u64 spi_mem_calc_op_duration(struct spi_mem_op *op)
|
||||
{
|
||||
u64 ncycles = 0;
|
||||
|
||||
ncycles += ((op->cmd.nbytes * 8) / op->cmd.buswidth) / (op->cmd.dtr ? 2 : 1);
|
||||
ncycles += ((op->addr.nbytes * 8) / op->addr.buswidth) / (op->addr.dtr ? 2 : 1);
|
||||
ncycles += spi_mem_bytes_to_ncycles(op->cmd.nbytes,
|
||||
op->cmd.buswidth,
|
||||
op->cmd.dtr);
|
||||
ncycles += spi_mem_bytes_to_ncycles(op->addr.nbytes,
|
||||
op->addr.buswidth,
|
||||
op->addr.dtr);
|
||||
|
||||
/* Dummy bytes are optional for some SPI flash memory operations */
|
||||
if (op->dummy.nbytes)
|
||||
ncycles += ((op->dummy.nbytes * 8) / op->dummy.buswidth) / (op->dummy.dtr ? 2 : 1);
|
||||
ncycles += spi_mem_bytes_to_ncycles(op->dummy.nbytes,
|
||||
op->dummy.buswidth,
|
||||
op->dummy.dtr);
|
||||
|
||||
ncycles += ((op->data.nbytes * 8) / op->data.buswidth) / (op->data.dtr ? 2 : 1);
|
||||
ncycles += spi_mem_bytes_to_ncycles(op->data.nbytes,
|
||||
op->data.buswidth,
|
||||
op->data.dtr);
|
||||
|
||||
return ncycles;
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user