nvmem: core: fix read buffer in place

Message ID 20190320193242.20159-1-jorge.ramirez-ortiz@linaro.org
State Accepted
Commit 2fe518fecb3a4727393be286db9804cd82ee2d91
Headers show
Series
  • nvmem: core: fix read buffer in place
Related show

Commit Message

Jorge Ramirez March 20, 2019, 7:32 p.m.
When the bit_offset in the cell is zero, the pointer to the msb will
not be properly initialized (ie, will still be pointing to the first
byte in the buffer).

This being the case, if there are bits to clear in the msb, those will
be left untouched while the mask will incorrectly clear bit positions
on the first byte.

This commit also makes sure that any byte unused in the cell is
cleared.

Signed-off-by: Jorge Ramirez-Ortiz <jorge.ramirez-ortiz@linaro.org>

---
 drivers/nvmem/core.c | 15 ++++++++++-----
 1 file changed, 10 insertions(+), 5 deletions(-)

-- 
2.20.1

Comments

Srinivas Kandagatla April 4, 2019, 11:01 a.m. | #1
On 20/03/2019 19:32, Jorge Ramirez-Ortiz wrote:
> When the bit_offset in the cell is zero, the pointer to the msb will

> not be properly initialized (ie, will still be pointing to the first

> byte in the buffer).

> 

> This being the case, if there are bits to clear in the msb, those will

> be left untouched while the mask will incorrectly clear bit positions

> on the first byte.

> 

> This commit also makes sure that any byte unused in the cell is

> cleared.

> 

> Signed-off-by: Jorge Ramirez-Ortiz <jorge.ramirez-ortiz@linaro.org>

Applied Thanks,
Srini

Patch

diff --git a/drivers/nvmem/core.c b/drivers/nvmem/core.c
index f24008b66826..53dc37574b5d 100644
--- a/drivers/nvmem/core.c
+++ b/drivers/nvmem/core.c
@@ -1166,7 +1166,7 @@  EXPORT_SYMBOL_GPL(nvmem_cell_put);
 static void nvmem_shift_read_buffer_in_place(struct nvmem_cell *cell, void *buf)
 {
 	u8 *p, *b;
-	int i, bit_offset = cell->bit_offset;
+	int i, extra, bit_offset = cell->bit_offset;
 
 	p = b = buf;
 	if (bit_offset) {
@@ -1181,11 +1181,16 @@  static void nvmem_shift_read_buffer_in_place(struct nvmem_cell *cell, void *buf)
 			p = b;
 			*b++ >>= bit_offset;
 		}
-
-		/* result fits in less bytes */
-		if (cell->bytes != DIV_ROUND_UP(cell->nbits, BITS_PER_BYTE))
-			*p-- = 0;
+	} else {
+		/* point to the msb */
+		p += cell->bytes - 1;
 	}
+
+	/* result fits in less bytes */
+	extra = cell->bytes - DIV_ROUND_UP(cell->nbits, BITS_PER_BYTE);
+	while (--extra >= 0)
+		*p-- = 0;
+
 	/* clear msb bits if any leftover in the last byte */
 	*p &= GENMASK((cell->nbits%BITS_PER_BYTE) - 1, 0);
 }