From: Yang Weijiang <weijiang.y...@intel.com> BITMAP_LAST_WORD_MASK(nbits) returns 0xffffffff when "nbits=0", this leads to error returns in some functions. This patch also checks bits input in some slow bitmap op functions, if bits = 0, do early return to keep the dst data unchanged.
this patch is a follow-up patch of : https://lists.gnu.org/archive/html/qemu-devel/2018-12/msg03510.html Signed-off-by: Yang Weijiang <weijiang.y...@intel.com> --- include/qemu/bitmap.h | 24 ++++++++++++++++++++++++ util/bitmap.c | 24 ++++++++++++++++++++++++ 2 files changed, 48 insertions(+) diff --git a/include/qemu/bitmap.h b/include/qemu/bitmap.h index 509eeddece..b6ce0ed551 100644 --- a/include/qemu/bitmap.h +++ b/include/qemu/bitmap.h @@ -113,6 +113,10 @@ static inline void bitmap_zero(unsigned long *dst, long nbits) static inline void bitmap_fill(unsigned long *dst, long nbits) { + if (unlikely(!nbits)) { + return; + } + size_t nlongs = BITS_TO_LONGS(nbits); if (!small_nbits(nbits)) { long len = (nlongs - 1) * sizeof(unsigned long); @@ -174,6 +178,10 @@ static inline void bitmap_complement(unsigned long *dst, const unsigned long *src, long nbits) { + if (unlikely(!nbits)) { + return; + } + if (small_nbits(nbits)) { *dst = ~(*src) & BITMAP_LAST_WORD_MASK(nbits); } else { @@ -184,6 +192,10 @@ static inline void bitmap_complement(unsigned long *dst, static inline int bitmap_equal(const unsigned long *src1, const unsigned long *src2, long nbits) { + if (unlikely(!nbits)) { + return 0; + } + if (small_nbits(nbits)) { return ! ((*src1 ^ *src2) & BITMAP_LAST_WORD_MASK(nbits)); } else { @@ -193,6 +205,10 @@ static inline int bitmap_equal(const unsigned long *src1, static inline int bitmap_empty(const unsigned long *src, long nbits) { + if (unlikely(!nbits)) { + return 0; + } + if (small_nbits(nbits)) { return ! (*src & BITMAP_LAST_WORD_MASK(nbits)); } else { @@ -202,6 +218,10 @@ static inline int bitmap_empty(const unsigned long *src, long nbits) static inline int bitmap_full(const unsigned long *src, long nbits) { + if (unlikely(!nbits)) { + return 0; + } + if (small_nbits(nbits)) { return ! (~(*src) & BITMAP_LAST_WORD_MASK(nbits)); } else { @@ -212,6 +232,10 @@ static inline int bitmap_full(const unsigned long *src, long nbits) static inline int bitmap_intersects(const unsigned long *src1, const unsigned long *src2, long nbits) { + if (unlikely(!nbits)) { + return 0; + } + if (small_nbits(nbits)) { return ((*src1 & *src2) & BITMAP_LAST_WORD_MASK(nbits)) != 0; } else { diff --git a/util/bitmap.c b/util/bitmap.c index cb618c65a5..64bb16a46a 100644 --- a/util/bitmap.c +++ b/util/bitmap.c @@ -42,6 +42,10 @@ int slow_bitmap_empty(const unsigned long *bitmap, long bits) { long k, lim = bits/BITS_PER_LONG; + if (unlikely(!bits)) { + return 0; + } + for (k = 0; k < lim; ++k) { if (bitmap[k]) { return 0; @@ -60,6 +64,10 @@ int slow_bitmap_full(const unsigned long *bitmap, long bits) { long k, lim = bits/BITS_PER_LONG; + if (unlikely(!bits)) { + return 0; + } + for (k = 0; k < lim; ++k) { if (~bitmap[k]) { return 0; @@ -80,6 +88,10 @@ int slow_bitmap_equal(const unsigned long *bitmap1, { long k, lim = bits/BITS_PER_LONG; + if (unlikely(!bits)) { + return 0; + } + for (k = 0; k < lim; ++k) { if (bitmap1[k] != bitmap2[k]) { return 0; @@ -116,6 +128,10 @@ int slow_bitmap_and(unsigned long *dst, const unsigned long *bitmap1, long nr = BITS_TO_LONGS(bits); unsigned long result = 0; + if (unlikely(!bits)) { + return 0; + } + for (k = 0; k < nr; k++) { result |= (dst[k] = bitmap1[k] & bitmap2[k]); } @@ -342,6 +358,10 @@ int slow_bitmap_intersects(const unsigned long *bitmap1, { long k, lim = bits/BITS_PER_LONG; + if (unlikely(!bits)) { + return 0; + } + for (k = 0; k < lim; ++k) { if (bitmap1[k] & bitmap2[k]) { return 1; @@ -360,6 +380,10 @@ long slow_bitmap_count_one(const unsigned long *bitmap, long nbits) { long k, lim = nbits / BITS_PER_LONG, result = 0; + if (unlikely(!nbits)) { + return 0; + } + for (k = 0; k < lim; k++) { result += ctpopl(bitmap[k]); } -- 2.17.1