Modify bitmap_set_value() to suppress compiler warning
Subsystems (6)
cover Modify bitmap_set_value() to suppress compiler warning
Hi All,
The purpose of this patchset is to suppress the compiler warning (-Wtype-limits).
In function bitmap_set_value(), add explicit check to see if the value being written into the bitmap does not fall outside the bitmap.
The situation that it is falling outside is never possible in the code because the boundaries are required to be correct before the function is called. The responsibility is on the caller for ensuring the boundaries are correct.
The code change is simply to silence the GCC warning messages because GCC is not aware that the boundaries have already been checked. As such, we're better off using __builtin_unreachable() here because we can avoid the latency of the conditional check entirely.
Michal,
What do you think of [PATCH 4/4]? Is the conditional check needed, and also whether returning -EINVAL looks good?
Syed Nayyar Waris (4):
bitmap: Modify bitmap_set_value() to check bitmap length lib/test_bitmap.c: Modify for_each_set_clump test
gpio: xilinx: Modify bitmap_set_value() calls
gpio: xilinx: Add extra check if sum of widths exceed 64
drivers/gpio/gpio-xilinx.c | 18 ++++++++++++------ include/linux/bitmap.h | 35 +++++++++++++++++++++-------------- lib/test_bitmap.c | 4 ++-- 3 files changed, 35 insertions(+), 22 deletions(-)
base-commit: b640c4e12bbe1f0b6383c3ef788a89e5427c763f
Signature · 1 line
2.29.0
PATCH 1/4 bitmap: Modify bitmap_set_value() to check bitmap length
Add explicit check to see if the value being written into the bitmap does not fall outside the bitmap.
The situation that it is falling outside would never be possible in the code because the boundaries are required to be correct before the function is called. The responsibility is on the caller for ensuring the boundaries are correct.
This is just to suppress the GCC -Wtype-limits warnings.
--- include/linux/bitmap.h | 35 +++++++++++++++++++++-------------- 1 file changed, 21 insertions(+), 14 deletions(-)
include/linux/bitmap.h +21 -14
@@ -78,8 +78,9 @@* bitmap_get_value(map, start, nbits) Get bit value of size * 'nbits' from map at start * bitmap_set_value8(map, value, start) Set 8bit value to map at start -* bitmap_set_value(map, value, start, nbits) Set bit value of size 'nbits' -* of map at start +* bitmap_set_value(map, nbits, value, value_width, start) +* Set bit value of size value_width +* to map at start * * Note, bitmap_zero() and bitmap_fill() operate over the region of * unsigned longs, that is, bits behind bitmap till the unsigned long
@@ -610,30 +611,36 @@ static inline void bitmap_set_value8(unsigned long *map, unsigned long value, }/** -* bitmap_set_value - set n-bit value within a memory region +* bitmap_set_value - set value within a memory region * @map: address to the bitmap memory region -* @value: value of nbits -* @start: bit offset of the n-bit value -* @nbits: size of value in bits (must be between 1 and BITS_PER_LONG inclusive). +* @nbits: size of map in bits +* @value: value of clump +* @value_width: size of value in bits (must be between 1 and BITS_PER_LONG inclusive) +* @start: bit offset of the value */ -static inline void bitmap_set_value (unsigned long *map, -unsigned long value, -unsigned long start,unsigned long nbits) +static inline void bitmap_set_value (unsigned long *map,unsigned long nbits, +unsigned long value,unsigned long value_width, +unsigned long start) { -const size_t index =BIT_WORD (start); +const unsigned long index =BIT_WORD (start); +const unsigned long length =BIT_WORD (nbits);const unsigned long offset = start %BITS_PER_LONG ;const unsigned long ceiling =round_up (start +1 ,BITS_PER_LONG );const unsigned long space = ceiling - start; - value &=GENMASK (nbits -1 ,0 ); + value &=GENMASK (value_width -1 ,0 ); -if (space >= nbits) { - map[index] &= ~(GENMASK (nbits -1 ,0 ) << offset); +if (space >= value_width) { + map[index] &= ~(GENMASK (value_width -1 ,0 ) << offset); map[index] |= value << offset; }else { map[index +0 ] &= ~BITMAP_FIRST_WORD_MASK (start); map[index +0 ] |= value << offset; - map[index +1 ] &= ~BITMAP_LAST_WORD_MASK (start + nbits); + +if (index +1 >= length) +__builtin_unreachable (); + + map[index +1 ] &= ~BITMAP_LAST_WORD_MASK (start + value_width); map[index +1 ] |= value >> space; } }
Signature · 1 line
2.29.0
Re: [PATCH 1/4] bitmap: Modify bitmap_set_value() to check bitmap length
Quoted 7 lines · Syed Nayyar Waris
Add explicit check to see if the value being written into the bitmap does not fall outside the bitmap.
The situation that it is falling outside would never be possible in the code because the boundaries are required to be correct before the function is called. The responsibility is on the caller for ensuring the boundaries are correct.
This is just to suppress the GCC -Wtype-limits warnings.
Hi Syed,
This commit message sounds a bit strange without the context of our earlier discussion thread. Would you be able to reword the commit message to explain the motivation for using __builtin_unreachable()?
Thanks,
William Breathitt Gray
Quoted 76 lines
Cc Arnd Bergmann <[email protected]>Signed-off-by Syed Nayyar Waris <[email protected]>--- include/linux/bitmap.h | 35 +++++++++++++++++++++-------------- 1 file changed, 21 insertions(+), 14 deletions(-)include/linux/bitmap.h +21
-14@@ -78,8 +78,9 @@* bitmap_get_value(map, start, nbits) Get bit value of size * 'nbits' from map at start * bitmap_set_value8(map, value, start) Set 8bit value to map at start -* bitmap_set_value(map, value, start, nbits) Set bit value of size 'nbits' -* of map at start +* bitmap_set_value(map, nbits, value, value_width, start) +* Set bit value of size value_width +* to map at start * * Note, bitmap_zero() and bitmap_fill() operate over the region of * unsigned longs, that is, bits behind bitmap till the unsigned long @@ -610,30 +611,36 @@ static inline void bitmap_set_value8(unsigned long *map, unsigned long value, }/** -* bitmap_set_value - set n-bit value within a memory region +* bitmap_set_value - set value within a memory region * @map: address to the bitmap memory region -* @value: value of nbits -* @start: bit offset of the n-bit value -* @nbits: size of value in bits (must be between 1 and BITS_PER_LONG inclusive). +* @nbits: size of map in bits +* @value: value of clump +* @value_width: size of value in bits (must be between 1 and BITS_PER_LONG inclusive) +* @start: bit offset of the value */ -static inline void bitmap_set_value (unsigned long *map, -unsigned long value, -unsigned long start,unsigned long nbits) +static inline void bitmap_set_value (unsigned long *map,unsigned long nbits, +unsigned long value,unsigned long value_width, +unsigned long start) { -const size_t index =BIT_WORD (start); +const unsigned long index =BIT_WORD (start); +const unsigned long length =BIT_WORD (nbits);const unsigned long offset = start %BITS_PER_LONG ;const unsigned long ceiling =round_up (start +1 ,BITS_PER_LONG );const unsigned long space = ceiling - start; - value &=GENMASK (nbits -1 ,0 ); + value &=GENMASK (value_width -1 ,0 ); -if (space >= nbits) { - map[index] &= ~(GENMASK (nbits -1 ,0 ) << offset); +if (space >= value_width) { + map[index] &= ~(GENMASK (value_width -1 ,0 ) << offset); map[index] |= value << offset; }else { map[index +0 ] &= ~BITMAP_FIRST_WORD_MASK (start); map[index +0 ] |= value << offset; - map[index +1 ] &= ~BITMAP_LAST_WORD_MASK (start + nbits); + +if (index +1 >= length) +__builtin_unreachable (); + + map[index +1 ] &= ~BITMAP_LAST_WORD_MASK (start + value_width); map[index +1 ] |= value >> space; } }Signature · 1 line
2.29.0
Re: [PATCH 1/4] bitmap: Modify bitmap_set_value() to check bitmap length
Quoted 12 lines · William Breathitt Gray
Quoted 7 lines · Syed Nayyar Waris
Add explicit check to see if the value being written into the bitmap does not fall outside the bitmap.
The situation that it is falling outside would never be possible in the code because the boundaries are required to be correct before the function is called. The responsibility is on the caller for ensuring the boundaries are correct.
This is just to suppress the GCC -Wtype-limits warnings.Hi Syed,
Quoted 7 lines
This commit message sounds a bit strange without the context of our earlier discussion thread. Would you be able to reword the commit message to explain the motivation for using
__builtin_unreachable()?Thanks,
William Breathitt Gray
Hi William,
Actually I explained the motivation for using __builtin_unreachable() in the cover letter.
So, left it here in this patch.
I am sending this patch again updating the commit message.
Regards
Syed Nayyar Waris
Quoted 77 lines
Quoted 77 lines
Cc Arnd Bergmann <[email protected]>Signed-off-by Syed Nayyar Waris <[email protected]>--- include/linux/bitmap.h | 35 +++++++++++++++++++++-------------- 1 file changed, 21 insertions(+), 14 deletions(-)include/linux/bitmap.h +21
-15@@ -78,8 +78,9 @@* bitmap_get_value(map, start, nbits) Get bit value of size * 'nbits' from map at start * bitmap_set_value8(map, value, start) Set 8bit value to map at start -* bitmap_set_value(map, value, start, nbits) Set bit value of size 'nbits' -* of map at start +* bitmap_set_value(map, nbits, value, value_width, start) +* Set bit value of size value_width +* to map at start * * Note, bitmap_zero() and bitmap_fill() operate over the region of * unsigned longs, that is, bits behind bitmap till the unsigned long @@ -610,30 +611,36 @@ static inline void bitmap_set_value8(unsigned long *map, unsigned long value, }/** -* bitmap_set_value - set n-bit value within a memory region +* bitmap_set_value - set value within a memory region * @map: address to the bitmap memory region -* @value: value of nbits -* @start: bit offset of the n-bit value -* @nbits: size of value in bits (must be between 1 and BITS_PER_LONG inclusive). +* @nbits: size of map in bits +* @value: value of clump +* @value_width: size of value in bits (must be between 1 and BITS_PER_LONG inclusive) +* @start: bit offset of the value */ -static inline void bitmap_set_value (unsigned long *map, -unsigned long value, -unsigned long start,unsigned long nbits) +static inline void bitmap_set_value (unsigned long *map,unsigned long nbits, +unsigned long value,unsigned long value_width, +unsigned long start) { -const size_t index =BIT_WORD (start); +const unsigned long index =BIT_WORD (start); +const unsigned long length =BIT_WORD (nbits);const unsigned long offset = start %BITS_PER_LONG ;const unsigned long ceiling =round_up (start +1 ,BITS_PER_LONG );const unsigned long space = ceiling - start; - value &=GENMASK (nbits -1 ,0 ); + value &=GENMASK (value_width -1 ,0 ); -if (space >= nbits) { - map[index] &= ~(GENMASK (nbits -1 ,0 ) << offset); +if (space >= value_width) { + map[index] &= ~(GENMASK (value_width -1 ,0 ) << offset); map[index] |= value << offset; }else { map[index +0 ] &= ~BITMAP_FIRST_WORD_MASK (start); map[index +0 ] |= value << offset; - map[index +1 ] &= ~BITMAP_LAST_WORD_MASK (start + nbits); + +if (index +1 >= length) +__builtin_unreachable (); + + map[index +1 ] &= ~BITMAP_LAST_WORD_MASK (start + value_width); map[index +1 ] |= value >> space; } } --2.29.0
PATCH 2/4 lib/test_bitmap.c: Modify for_each_set_clump test
In reply to Syed Nayyar WarisModify the test where bitmap_set_value() is called. bitmap_set_value() now takes an extra bitmap-width as second argument and the width of value is now present as the fourth argument.
--- lib/test_bitmap.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
lib/test_bitmap.c +2 -2
@@ -656,8 +656,8 @@ static void __init prepare_test_data(unsigned int index)unsigned long width =0 ;for (i =0 ; i < clump_test_data[index].count; i++) { -bitmap_set_value (clump_test_data[index].data, - clump_bitmap_data[(clump_test_data[index].offset)++], width,32 ); +bitmap_set_value (clump_test_data[index].data,256 , + clump_bitmap_data[(clump_test_data[index].offset)++],32 , width); width +=32 ; } }
Signature · 1 line
2.29.0
PATCH 3/4 gpio: xilinx: Modify bitmap_set_value() calls
In reply to Syed Nayyar WarisModify the bitmap_set_value() calls. bitmap_set_value() now takes an extra bitmap width as second argument and the width of value is now present as the fourth argument.
--- drivers/gpio/gpio-xilinx.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-)
drivers/gpio/gpio-xilinx.c +6 -6
@@ -151,16 +151,16 @@ static void xgpio_set_multiple(struct gpio_chip *gc, unsigned long *mask,spin_lock_irqsave (&chip->gpio_lock[0 ], flags);spin_lock (&chip->gpio_lock[1 ]); -bitmap_set_value (old, state[0 ],0 , width[0 ]); -bitmap_set_value (old, state[1 ], width[0 ], width[1 ]); +bitmap_set_value (old,64 , state[0 ], width[0 ],0 ); +bitmap_set_value (old,64 , state[1 ], width[1 ], width[0 ]);bitmap_replace (new, old, bits, mask, gc->ngpio); -bitmap_set_value (old, state[0 ],0 ,32 ); -bitmap_set_value (old, state[1 ],32 ,32 ); +bitmap_set_value (old,64 , state[0 ],32 ,0 ); +bitmap_set_value (old,64 , state[1 ],32 ,32 ); state[0 ] =bitmap_get_value (new,0 , width[0 ]); state[1 ] =bitmap_get_value (new, width[0 ], width[1 ]); -bitmap_set_value (new, state[0 ],0 ,32 ); -bitmap_set_value (new, state[1 ],32 ,32 ); +bitmap_set_value (new,64 , state[0 ],32 ,0 ); +bitmap_set_value (new,64 , state[1 ],32 ,32 );bitmap_xor (changed, old, new,64 );if (((u32 *)changed)[0 ])
Signature · 1 line
2.29.0
Re: [RESEND PATCH 3/4] gpio: xilinx: Modify bitmap_set_value() calls
Quoted 39 lines · Syed Nayyar Waris
Modify the
bitmap_set_value()calls.bitmap_set_value()now takes an extra bitmap width as second argument and the width of value is now present as the fourth argument.Cc Michal Simek <[email protected]>Signed-off-by Syed Nayyar Waris <[email protected]>--- drivers/gpio/gpio-xilinx.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-)drivers/gpio/gpio-xilinx.c +6
-7@@ -151,16 +151,16 @@ static void xgpio_set_multiple(struct gpio_chip *gc, unsigned long *mask,spin_lock_irqsave (&chip->gpio_lock[0 ], flags);spin_lock (&chip->gpio_lock[1 ]); -bitmap_set_value (old, state[0 ],0 , width[0 ]); -bitmap_set_value (old, state[1 ], width[0 ], width[1 ]); +bitmap_set_value (old,64 , state[0 ], width[0 ],0 ); +bitmap_set_value (old,64 , state[1 ], width[1 ], width[0 ]);bitmap_replace (new, old, bits, mask, gc->ngpio); -bitmap_set_value (old, state[0 ],0 ,32 ); -bitmap_set_value (old, state[1 ],32 ,32 ); +bitmap_set_value (old,64 , state[0 ],32 ,0 ); +bitmap_set_value (old,64 , state[1 ],32 ,32 ); state[0 ] =bitmap_get_value (new,0 , width[0 ]); state[1 ] =bitmap_get_value (new, width[0 ], width[1 ]); -bitmap_set_value (new, state[0 ],0 ,32 ); -bitmap_set_value (new, state[1 ],32 ,32 ); +bitmap_set_value (new,64 , state[0 ],32 ,0 ); +bitmap_set_value (new,64 , state[1 ],32 ,32 );bitmap_xor (changed, old, new,64 );if (((u32 *)changed)[0 ]) --
Quoted 2 lines
2.29.0
This series is not bisectable because you modify the interface - breaking existing users - and you only fix them later. Please squash those changes into a single commit.
Bartosz
Re: [RESEND PATCH 3/4] gpio: xilinx: Modify bitmap_set_value() calls
Quoted 48 lines · Bartosz Golaszewski
Quoted 39 lines · Syed Nayyar Waris
Modify the
bitmap_set_value()calls.bitmap_set_value()now takes an extra bitmap width as second argument and the width of value is now present as the fourth argument.Cc Michal Simek <[email protected]>Signed-off-by Syed Nayyar Waris <[email protected]>--- drivers/gpio/gpio-xilinx.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-)drivers/gpio/gpio-xilinx.c +6
-7@@ -151,16 +151,16 @@ static void xgpio_set_multiple(struct gpio_chip *gc, unsigned long *mask,spin_lock_irqsave (&chip->gpio_lock[0 ], flags);spin_lock (&chip->gpio_lock[1 ]); -bitmap_set_value (old, state[0 ],0 , width[0 ]); -bitmap_set_value (old, state[1 ], width[0 ], width[1 ]); +bitmap_set_value (old,64 , state[0 ], width[0 ],0 ); +bitmap_set_value (old,64 , state[1 ], width[1 ], width[0 ]);bitmap_replace (new, old, bits, mask, gc->ngpio); -bitmap_set_value (old, state[0 ],0 ,32 ); -bitmap_set_value (old, state[1 ],32 ,32 ); +bitmap_set_value (old,64 , state[0 ],32 ,0 ); +bitmap_set_value (old,64 , state[1 ],32 ,32 ); state[0 ] =bitmap_get_value (new,0 , width[0 ]); state[1 ] =bitmap_get_value (new, width[0 ], width[1 ]); -bitmap_set_value (new, state[0 ],0 ,32 ); -bitmap_set_value (new, state[1 ],32 ,32 ); +bitmap_set_value (new,64 , state[0 ],32 ,0 ); +bitmap_set_value (new,64 , state[1 ],32 ,32 );bitmap_xor (changed, old, new,64 );if (((u32 *)changed)[0 ]) --Quoted 2 lines
2.29.0
This series is not bisectable because you modify the interface - breaking existing users - and you only fix them later. Please squash those changes into a single commit.
Quoted 1 line
Bartosz
Hi Bartosz,
I have squashed the changes and have sent a new patchset v2.
Regards
Syed Nayyar Waris
_______________________________________________
linux-arm-kernel mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
PATCH 4/4 gpio: xilinx: Add extra check to see if sum of widths exceed 64
In reply to Syed Nayyar WarisAdd extra check to see if sum of widths does not exceed 64. If it exceeds then return -EINVAL alongwith appropriate error message.
--- drivers/gpio/gpio-xilinx.c | 6 ++++++ 1 file changed, 6 insertions(+)
drivers/gpio/gpio-xilinx.c +6 -0
@@ -340,6 +340,12 @@ static int xgpio_probe(struct platform_device *pdev) chip->gc.base =-1 ; chip->gc.ngpio = chip->gpio_width[0 ] + chip->gpio_width[1 ]; + +if (chip->gc.ngpio >64 ) { +dev_err (&pdev->dev,"invalid configuration: number of GPIO is greater than 64" ); +return -EINVAL ; + } + chip->gc.parent = &pdev->dev; chip->gc.direction_input = xgpio_dir_in; chip->gc.direction_output = xgpio_dir_out;
Signature · 1 line
2.29.0