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)
{