]>
Commit | Line | Data |
---|---|---|
cd033818 SL |
1 | From 38ef89cf92c2b1cf2aacb011fcf155a04e5e37eb Mon Sep 17 00:00:00 2001 |
2 | From: Jorge Ramirez-Ortiz <jorge.ramirez-ortiz@linaro.org> | |
3 | Date: Sat, 13 Apr 2019 11:32:58 +0100 | |
4 | Subject: nvmem: core: fix read buffer in place | |
5 | ||
6 | [ Upstream commit 2fe518fecb3a4727393be286db9804cd82ee2d91 ] | |
7 | ||
8 | When the bit_offset in the cell is zero, the pointer to the msb will | |
9 | not be properly initialized (ie, will still be pointing to the first | |
10 | byte in the buffer). | |
11 | ||
12 | This being the case, if there are bits to clear in the msb, those will | |
13 | be left untouched while the mask will incorrectly clear bit positions | |
14 | on the first byte. | |
15 | ||
16 | This commit also makes sure that any byte unused in the cell is | |
17 | cleared. | |
18 | ||
19 | Signed-off-by: Jorge Ramirez-Ortiz <jorge.ramirez-ortiz@linaro.org> | |
20 | Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org> | |
21 | Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> | |
22 | Signed-off-by: Sasha Levin <sashal@kernel.org> | |
23 | --- | |
24 | drivers/nvmem/core.c | 15 ++++++++++----- | |
25 | 1 file changed, 10 insertions(+), 5 deletions(-) | |
26 | ||
27 | diff --git a/drivers/nvmem/core.c b/drivers/nvmem/core.c | |
28 | index 6fd4e5a5ef4a..931cc33e46f0 100644 | |
29 | --- a/drivers/nvmem/core.c | |
30 | +++ b/drivers/nvmem/core.c | |
31 | @@ -789,7 +789,7 @@ static inline void nvmem_shift_read_buffer_in_place(struct nvmem_cell *cell, | |
32 | void *buf) | |
33 | { | |
34 | u8 *p, *b; | |
35 | - int i, bit_offset = cell->bit_offset; | |
36 | + int i, extra, bit_offset = cell->bit_offset; | |
37 | ||
38 | p = b = buf; | |
39 | if (bit_offset) { | |
40 | @@ -804,11 +804,16 @@ static inline void nvmem_shift_read_buffer_in_place(struct nvmem_cell *cell, | |
41 | p = b; | |
42 | *b++ >>= bit_offset; | |
43 | } | |
44 | - | |
45 | - /* result fits in less bytes */ | |
46 | - if (cell->bytes != DIV_ROUND_UP(cell->nbits, BITS_PER_BYTE)) | |
47 | - *p-- = 0; | |
48 | + } else { | |
49 | + /* point to the msb */ | |
50 | + p += cell->bytes - 1; | |
51 | } | |
52 | + | |
53 | + /* result fits in less bytes */ | |
54 | + extra = cell->bytes - DIV_ROUND_UP(cell->nbits, BITS_PER_BYTE); | |
55 | + while (--extra >= 0) | |
56 | + *p-- = 0; | |
57 | + | |
58 | /* clear msb bits if any leftover in the last byte */ | |
59 | *p &= GENMASK((cell->nbits%BITS_PER_BYTE) - 1, 0); | |
60 | } | |
61 | -- | |
62 | 2.20.1 | |
63 |