git: 5ae2e6f913fa - main - LinuxKPI: Add bitmap_intersects(), bitmap_from_arr32()
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Sun, 24 Dec 2023 08:23:13 UTC
The branch main has been updated by wulf: URL: https://cgit.FreeBSD.org/src/commit/?id=5ae2e6f913fa1df5f3262255558b76af05409a09 commit 5ae2e6f913fa1df5f3262255558b76af05409a09 Author: Vladimir Kondratyev <wulf@FreeBSD.org> AuthorDate: 2023-12-24 08:19:59 +0000 Commit: Vladimir Kondratyev <wulf@FreeBSD.org> CommitDate: 2023-12-24 08:19:59 +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 --- 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) {