All of lore.kernel.org
 help / color / mirror / Atom feed
From: Syed Nayyar Waris <syednwaris@gmail.com>
To: linus.walleij@linaro.org, akpm@linux-foundation.org
Cc: andriy.shevchenko@linux.intel.com, vilhelm.gray@gmail.com,
	michal.simek@xilinx.com, arnd@arndb.de, rrichter@marvell.com,
	linus.walleij@linaro.org, bgolaszewski@baylibre.com,
	yamada.masahiro@socionext.com, rui.zhang@intel.com,
	daniel.lezcano@linaro.org, amit.kucheria@verdurent.com,
	linux-arch@vger.kernel.org, linux-gpio@vger.kernel.org,
	linux-kernel@vger.kernel.org,
	linux-arm-kernel@lists.infradead.org, linux-pm@vger.kernel.org
Subject: [PATCH v2 1/2] bitmap: Modify bitmap_set_value() to check bitmap length
Date: Sat, 12 Dec 2020 15:04:05 +0530	[thread overview]
Message-ID: <20268bfeb500ad8819e3a11aa1bea27eade4fd39.1607765147.git.syednwaris@gmail.com> (raw)
In-Reply-To: <cover.1607765147.git.syednwaris@gmail.com>

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.
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.

Cc: Arnd Bergmann <arnd@arndb.de>
Signed-off-by: Syed Nayyar Waris <syednwaris@gmail.com>
Acked-by: William Breathitt Gray <vilhelm.gray@gmail.com>

lib/test_bitmap.c: Modify for_each_set_clump test

Modify 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.

Signed-off-by: Syed Nayyar Waris <syednwaris@gmail.com>

gpio: xilinx: Modify bitmap_set_value() calls

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 <michal.simek@xilinx.com>
Signed-off-by: Syed Nayyar Waris <syednwaris@gmail.com>
---
 drivers/gpio/gpio-xilinx.c | 12 ++++++------
 include/linux/bitmap.h     | 35 +++++++++++++++++++++--------------
 lib/test_bitmap.c          |  4 ++--
 3 files changed, 29 insertions(+), 22 deletions(-)

diff --git a/drivers/gpio/gpio-xilinx.c b/drivers/gpio/gpio-xilinx.c
index ad4ee4145db4..05dae086c4d0 100644
--- a/drivers/gpio/gpio-xilinx.c
+++ b/drivers/gpio/gpio-xilinx.c
@@ -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])
diff --git a/include/linux/bitmap.h b/include/linux/bitmap.h
index 386d08777342..efb6199ea1e7 100644
--- a/include/linux/bitmap.h
+++ b/include/linux/bitmap.h
@@ -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;
 	}
 }
diff --git a/lib/test_bitmap.c b/lib/test_bitmap.c
index 1c5791ff02cb..7fafe6a0bc08 100644
--- a/lib/test_bitmap.c
+++ b/lib/test_bitmap.c
@@ -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;
 	}
 }
-- 
2.29.0


WARNING: multiple messages have this Message-ID (diff)
From: Syed Nayyar Waris <syednwaris@gmail.com>
To: linus.walleij@linaro.org, akpm@linux-foundation.org
Cc: linux-arch@vger.kernel.org, amit.kucheria@verdurent.com,
	arnd@arndb.de, yamada.masahiro@socionext.com,
	linux-kernel@vger.kernel.org, linus.walleij@linaro.org,
	daniel.lezcano@linaro.org, vilhelm.gray@gmail.com,
	michal.simek@xilinx.com, bgolaszewski@baylibre.com,
	rrichter@marvell.com, linux-gpio@vger.kernel.org,
	linux-pm@vger.kernel.org, rui.zhang@intel.com,
	andriy.shevchenko@linux.intel.com,
	linux-arm-kernel@lists.infradead.org
Subject: [PATCH v2 1/2] bitmap: Modify bitmap_set_value() to check bitmap length
Date: Sat, 12 Dec 2020 15:04:05 +0530	[thread overview]
Message-ID: <20268bfeb500ad8819e3a11aa1bea27eade4fd39.1607765147.git.syednwaris@gmail.com> (raw)
In-Reply-To: <cover.1607765147.git.syednwaris@gmail.com>

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.
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.

Cc: Arnd Bergmann <arnd@arndb.de>
Signed-off-by: Syed Nayyar Waris <syednwaris@gmail.com>
Acked-by: William Breathitt Gray <vilhelm.gray@gmail.com>

lib/test_bitmap.c: Modify for_each_set_clump test

Modify 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.

Signed-off-by: Syed Nayyar Waris <syednwaris@gmail.com>

gpio: xilinx: Modify bitmap_set_value() calls

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 <michal.simek@xilinx.com>
Signed-off-by: Syed Nayyar Waris <syednwaris@gmail.com>
---
 drivers/gpio/gpio-xilinx.c | 12 ++++++------
 include/linux/bitmap.h     | 35 +++++++++++++++++++++--------------
 lib/test_bitmap.c          |  4 ++--
 3 files changed, 29 insertions(+), 22 deletions(-)

diff --git a/drivers/gpio/gpio-xilinx.c b/drivers/gpio/gpio-xilinx.c
index ad4ee4145db4..05dae086c4d0 100644
--- a/drivers/gpio/gpio-xilinx.c
+++ b/drivers/gpio/gpio-xilinx.c
@@ -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])
diff --git a/include/linux/bitmap.h b/include/linux/bitmap.h
index 386d08777342..efb6199ea1e7 100644
--- a/include/linux/bitmap.h
+++ b/include/linux/bitmap.h
@@ -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;
 	}
 }
diff --git a/lib/test_bitmap.c b/lib/test_bitmap.c
index 1c5791ff02cb..7fafe6a0bc08 100644
--- a/lib/test_bitmap.c
+++ b/lib/test_bitmap.c
@@ -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;
 	}
 }
-- 
2.29.0


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

  reply	other threads:[~2020-12-12 10:13 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-12-12  9:33 [PATCH v2 0/2] Modify bitmap_set_value() to suppress compiler warning Syed Nayyar Waris
2020-12-12  9:33 ` Syed Nayyar Waris
2020-12-12  9:34 ` Syed Nayyar Waris [this message]
2020-12-12  9:34   ` [PATCH v2 1/2] bitmap: Modify bitmap_set_value() to check bitmap length Syed Nayyar Waris
2020-12-12 15:56   ` kernel test robot
2020-12-12 17:05   ` kernel test robot
2020-12-13 14:55   ` Andy Shevchenko
2020-12-13 14:55     ` Andy Shevchenko
2020-12-12  9:34 ` [PATCH v2 2/2] gpio: xilinx: Add extra check if sum of widths exceed 64 Syed Nayyar Waris
2020-12-12  9:34   ` Syed Nayyar Waris

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20268bfeb500ad8819e3a11aa1bea27eade4fd39.1607765147.git.syednwaris@gmail.com \
    --to=syednwaris@gmail.com \
    --cc=akpm@linux-foundation.org \
    --cc=amit.kucheria@verdurent.com \
    --cc=andriy.shevchenko@linux.intel.com \
    --cc=arnd@arndb.de \
    --cc=bgolaszewski@baylibre.com \
    --cc=daniel.lezcano@linaro.org \
    --cc=linus.walleij@linaro.org \
    --cc=linux-arch@vger.kernel.org \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-gpio@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-pm@vger.kernel.org \
    --cc=michal.simek@xilinx.com \
    --cc=rrichter@marvell.com \
    --cc=rui.zhang@intel.com \
    --cc=vilhelm.gray@gmail.com \
    --cc=yamada.masahiro@socionext.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.