git: edeb8cfad053 - stable/14 - LinuxKPI: Add bitmap_intersects(), bitmap_from_arr32()
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Sat, 17 Feb 2024 21:33:07 UTC
The branch stable/14 has been updated by wulf: URL: https://cgit.FreeBSD.org/src/commit/?id=edeb8cfad053bba99fcf35ff66dbe34ea7ee17bc commit edeb8cfad053bba99fcf35ff66dbe34ea7ee17bc Author: Vladimir Kondratyev <wulf@FreeBSD.org> AuthorDate: 2023-12-24 08:19:59 +0000 Commit: Vladimir Kondratyev <wulf@FreeBSD.org> CommitDate: 2024-02-17 20:58:38 +0000 LinuxKPI: Add bitmap_intersects(), bitmap_from_arr32() and bitmap_shift_right() functions to linux/bitmap.h They perform calculation of two bitmaps intersection, copying the contents of u32 array of bits to bitmap and logical right shifting of the bits in a bitmap. Sponsored by: Serenity Cyber Security, LLC Reviewed by: manu MFC after: 1 week Differential Revision: https://reviews.freebsd.org/D42812 (cherry picked from commit 5ae2e6f913fa1df5f3262255558b76af05409a09) --- sys/compat/linuxkpi/common/include/linux/bitmap.h | 78 +++++++++++++++++++++++ 1 file changed, 78 insertions(+) diff --git a/sys/compat/linuxkpi/common/include/linux/bitmap.h b/sys/compat/linuxkpi/common/include/linux/bitmap.h index 85cef18ec14a..84e0ba9c88ca 100644 --- a/sys/compat/linuxkpi/common/include/linux/bitmap.h +++ b/sys/compat/linuxkpi/common/include/linux/bitmap.h @@ -264,6 +264,27 @@ bitmap_subset(const unsigned long *pa, return (1); } +static inline bool +bitmap_intersects(const unsigned long *pa, const unsigned long *pb, + unsigned size) +{ + const unsigned end = BIT_WORD(size); + const unsigned tail = size & (BITS_PER_LONG - 1); + unsigned i; + + for (i = 0; i != end; i++) + if (pa[i] & pb[i]) + return (true); + + if (tail) { + const unsigned long mask = BITMAP_LAST_WORD_MASK(tail); + + if (pa[end] & pb[end] & mask) + return (true); + } + return (false); +} + static inline void bitmap_complement(unsigned long *dst, const unsigned long *src, const unsigned int size) @@ -306,6 +327,29 @@ bitmap_to_arr32(uint32_t *dst, const unsigned long *src, unsigned int size) dst[end - 1] &= (uint32_t)(UINT_MAX >> (32 - (size % 32))); } +static inline void +bitmap_from_arr32(unsigned long *dst, const uint32_t *src, + unsigned int size) +{ + const unsigned int end = BIT_WORD(size); + const unsigned int tail = size & (BITS_PER_LONG - 1); + +#ifdef __LP64__ + const unsigned int end32 = howmany(size, 32); + unsigned int i = 0; + + while (i < end32) { + dst[i++/2] = (unsigned long) *(src++); + if (i < end32) + dst[i++/2] |= ((unsigned long) *(src++)) << 32; + } +#else + bitmap_copy(dst, (unsigned long *)src, size); +#endif + if ((size % BITS_PER_LONG) != 0) + dst[end] &= BITMAP_LAST_WORD_MASK(tail); +} + static inline void bitmap_or(unsigned long *dst, const unsigned long *src1, const unsigned long *src2, const unsigned int size) @@ -350,6 +394,40 @@ bitmap_xor(unsigned long *dst, const unsigned long *src1, dst[i] = src1[i] ^ src2[i]; } +static inline void +bitmap_shift_right(unsigned long *dst, const unsigned long *src, + unsigned int shift, unsigned int size) +{ + const unsigned int end = BITS_TO_LONGS(size); + const unsigned int tail = size & (BITS_PER_LONG - 1); + const unsigned long mask = BITMAP_LAST_WORD_MASK(tail); + const unsigned int off = BIT_WORD(shift); + const unsigned int rem = shift & (BITS_PER_LONG - 1); + unsigned long left, right; + unsigned int i, srcpos; + + for (i = 0, srcpos = off; srcpos < end; i++, srcpos++) { + right = src[srcpos]; + left = 0; + + if (srcpos == end - 1) + right &= mask; + + if (rem != 0) { + right >>= rem; + if (srcpos + 1 < end) { + left = src[srcpos + 1]; + if (srcpos + 1 == end - 1) + left &= mask; + left <<= (BITS_PER_LONG - rem); + } + } + dst[i] = left | right; + } + if (off != 0) + memset(dst + end - off, 0, off * sizeof(unsigned long)); +} + static inline unsigned long * bitmap_alloc(unsigned int size, gfp_t flags) {