Branch data Line data Source code
1 : : /* SPDX-License-Identifier: GPL-2.0 */
2 : : #ifndef __LINUX_BITMAP_H
3 : : #define __LINUX_BITMAP_H
4 : :
5 : : #ifndef __ASSEMBLY__
6 : :
7 : : #include <linux/types.h>
8 : : #include <linux/bitops.h>
9 : : #include <linux/string.h>
10 : : #include <linux/kernel.h>
11 : :
12 : : /*
13 : : * bitmaps provide bit arrays that consume one or more unsigned
14 : : * longs. The bitmap interface and available operations are listed
15 : : * here, in bitmap.h
16 : : *
17 : : * Function implementations generic to all architectures are in
18 : : * lib/bitmap.c. Functions implementations that are architecture
19 : : * specific are in various include/asm-<arch>/bitops.h headers
20 : : * and other arch/<arch> specific files.
21 : : *
22 : : * See lib/bitmap.c for more details.
23 : : */
24 : :
25 : : /**
26 : : * DOC: bitmap overview
27 : : *
28 : : * The available bitmap operations and their rough meaning in the
29 : : * case that the bitmap is a single unsigned long are thus:
30 : : *
31 : : * The generated code is more efficient when nbits is known at
32 : : * compile-time and at most BITS_PER_LONG.
33 : : *
34 : : * ::
35 : : *
36 : : * bitmap_zero(dst, nbits) *dst = 0UL
37 : : * bitmap_fill(dst, nbits) *dst = ~0UL
38 : : * bitmap_copy(dst, src, nbits) *dst = *src
39 : : * bitmap_and(dst, src1, src2, nbits) *dst = *src1 & *src2
40 : : * bitmap_or(dst, src1, src2, nbits) *dst = *src1 | *src2
41 : : * bitmap_xor(dst, src1, src2, nbits) *dst = *src1 ^ *src2
42 : : * bitmap_andnot(dst, src1, src2, nbits) *dst = *src1 & ~(*src2)
43 : : * bitmap_complement(dst, src, nbits) *dst = ~(*src)
44 : : * bitmap_equal(src1, src2, nbits) Are *src1 and *src2 equal?
45 : : * bitmap_intersects(src1, src2, nbits) Do *src1 and *src2 overlap?
46 : : * bitmap_subset(src1, src2, nbits) Is *src1 a subset of *src2?
47 : : * bitmap_empty(src, nbits) Are all bits zero in *src?
48 : : * bitmap_full(src, nbits) Are all bits set in *src?
49 : : * bitmap_weight(src, nbits) Hamming Weight: number set bits
50 : : * bitmap_set(dst, pos, nbits) Set specified bit area
51 : : * bitmap_clear(dst, pos, nbits) Clear specified bit area
52 : : * bitmap_find_next_zero_area(buf, len, pos, n, mask) Find bit free area
53 : : * bitmap_find_next_zero_area_off(buf, len, pos, n, mask) as above
54 : : * bitmap_shift_right(dst, src, n, nbits) *dst = *src >> n
55 : : * bitmap_shift_left(dst, src, n, nbits) *dst = *src << n
56 : : * bitmap_remap(dst, src, old, new, nbits) *dst = map(old, new)(src)
57 : : * bitmap_bitremap(oldbit, old, new, nbits) newbit = map(old, new)(oldbit)
58 : : * bitmap_onto(dst, orig, relmap, nbits) *dst = orig relative to relmap
59 : : * bitmap_fold(dst, orig, sz, nbits) dst bits = orig bits mod sz
60 : : * bitmap_parse(buf, buflen, dst, nbits) Parse bitmap dst from kernel buf
61 : : * bitmap_parse_user(ubuf, ulen, dst, nbits) Parse bitmap dst from user buf
62 : : * bitmap_parselist(buf, dst, nbits) Parse bitmap dst from kernel buf
63 : : * bitmap_parselist_user(buf, dst, nbits) Parse bitmap dst from user buf
64 : : * bitmap_find_free_region(bitmap, bits, order) Find and allocate bit region
65 : : * bitmap_release_region(bitmap, pos, order) Free specified bit region
66 : : * bitmap_allocate_region(bitmap, pos, order) Allocate specified bit region
67 : : * bitmap_from_arr32(dst, buf, nbits) Copy nbits from u32[] buf to dst
68 : : * bitmap_to_arr32(buf, src, nbits) Copy nbits from buf to u32[] dst
69 : : *
70 : : * Note, bitmap_zero() and bitmap_fill() operate over the region of
71 : : * unsigned longs, that is, bits behind bitmap till the unsigned long
72 : : * boundary will be zeroed or filled as well. Consider to use
73 : : * bitmap_clear() or bitmap_set() to make explicit zeroing or filling
74 : : * respectively.
75 : : */
76 : :
77 : : /**
78 : : * DOC: bitmap bitops
79 : : *
80 : : * Also the following operations in asm/bitops.h apply to bitmaps.::
81 : : *
82 : : * set_bit(bit, addr) *addr |= bit
83 : : * clear_bit(bit, addr) *addr &= ~bit
84 : : * change_bit(bit, addr) *addr ^= bit
85 : : * test_bit(bit, addr) Is bit set in *addr?
86 : : * test_and_set_bit(bit, addr) Set bit and return old value
87 : : * test_and_clear_bit(bit, addr) Clear bit and return old value
88 : : * test_and_change_bit(bit, addr) Change bit and return old value
89 : : * find_first_zero_bit(addr, nbits) Position first zero bit in *addr
90 : : * find_first_bit(addr, nbits) Position first set bit in *addr
91 : : * find_next_zero_bit(addr, nbits, bit)
92 : : * Position next zero bit in *addr >= bit
93 : : * find_next_bit(addr, nbits, bit) Position next set bit in *addr >= bit
94 : : * find_next_and_bit(addr1, addr2, nbits, bit)
95 : : * Same as find_next_bit, but in
96 : : * (*addr1 & *addr2)
97 : : *
98 : : */
99 : :
100 : : /**
101 : : * DOC: declare bitmap
102 : : * The DECLARE_BITMAP(name,bits) macro, in linux/types.h, can be used
103 : : * to declare an array named 'name' of just enough unsigned longs to
104 : : * contain all bit positions from 0 to 'bits' - 1.
105 : : */
106 : :
107 : : /*
108 : : * Allocation and deallocation of bitmap.
109 : : * Provided in lib/bitmap.c to avoid circular dependency.
110 : : */
111 : : extern unsigned long *bitmap_alloc(unsigned int nbits, gfp_t flags);
112 : : extern unsigned long *bitmap_zalloc(unsigned int nbits, gfp_t flags);
113 : : extern void bitmap_free(const unsigned long *bitmap);
114 : :
115 : : /*
116 : : * lib/bitmap.c provides these functions:
117 : : */
118 : :
119 : : extern int __bitmap_empty(const unsigned long *bitmap, unsigned int nbits);
120 : : extern int __bitmap_full(const unsigned long *bitmap, unsigned int nbits);
121 : : extern int __bitmap_equal(const unsigned long *bitmap1,
122 : : const unsigned long *bitmap2, unsigned int nbits);
123 : : extern bool __pure __bitmap_or_equal(const unsigned long *src1,
124 : : const unsigned long *src2,
125 : : const unsigned long *src3,
126 : : unsigned int nbits);
127 : : extern void __bitmap_complement(unsigned long *dst, const unsigned long *src,
128 : : unsigned int nbits);
129 : : extern void __bitmap_shift_right(unsigned long *dst, const unsigned long *src,
130 : : unsigned int shift, unsigned int nbits);
131 : : extern void __bitmap_shift_left(unsigned long *dst, const unsigned long *src,
132 : : unsigned int shift, unsigned int nbits);
133 : : extern int __bitmap_and(unsigned long *dst, const unsigned long *bitmap1,
134 : : const unsigned long *bitmap2, unsigned int nbits);
135 : : extern void __bitmap_or(unsigned long *dst, const unsigned long *bitmap1,
136 : : const unsigned long *bitmap2, unsigned int nbits);
137 : : extern void __bitmap_xor(unsigned long *dst, const unsigned long *bitmap1,
138 : : const unsigned long *bitmap2, unsigned int nbits);
139 : : extern int __bitmap_andnot(unsigned long *dst, const unsigned long *bitmap1,
140 : : const unsigned long *bitmap2, unsigned int nbits);
141 : : extern int __bitmap_intersects(const unsigned long *bitmap1,
142 : : const unsigned long *bitmap2, unsigned int nbits);
143 : : extern int __bitmap_subset(const unsigned long *bitmap1,
144 : : const unsigned long *bitmap2, unsigned int nbits);
145 : : extern int __bitmap_weight(const unsigned long *bitmap, unsigned int nbits);
146 : : extern void __bitmap_set(unsigned long *map, unsigned int start, int len);
147 : : extern void __bitmap_clear(unsigned long *map, unsigned int start, int len);
148 : :
149 : : extern unsigned long bitmap_find_next_zero_area_off(unsigned long *map,
150 : : unsigned long size,
151 : : unsigned long start,
152 : : unsigned int nr,
153 : : unsigned long align_mask,
154 : : unsigned long align_offset);
155 : :
156 : : /**
157 : : * bitmap_find_next_zero_area - find a contiguous aligned zero area
158 : : * @map: The address to base the search on
159 : : * @size: The bitmap size in bits
160 : : * @start: The bitnumber to start searching at
161 : : * @nr: The number of zeroed bits we're looking for
162 : : * @align_mask: Alignment mask for zero area
163 : : *
164 : : * The @align_mask should be one less than a power of 2; the effect is that
165 : : * the bit offset of all zero areas this function finds is multiples of that
166 : : * power of 2. A @align_mask of 0 means no alignment is required.
167 : : */
168 : : static inline unsigned long
169 : : bitmap_find_next_zero_area(unsigned long *map,
170 : : unsigned long size,
171 : : unsigned long start,
172 : : unsigned int nr,
173 : : unsigned long align_mask)
174 : : {
175 : 3 : return bitmap_find_next_zero_area_off(map, size, start, nr,
176 : : align_mask, 0);
177 : : }
178 : :
179 : : extern int __bitmap_parse(const char *buf, unsigned int buflen, int is_user,
180 : : unsigned long *dst, int nbits);
181 : : extern int bitmap_parse_user(const char __user *ubuf, unsigned int ulen,
182 : : unsigned long *dst, int nbits);
183 : : extern int bitmap_parselist(const char *buf, unsigned long *maskp,
184 : : int nmaskbits);
185 : : extern int bitmap_parselist_user(const char __user *ubuf, unsigned int ulen,
186 : : unsigned long *dst, int nbits);
187 : : extern void bitmap_remap(unsigned long *dst, const unsigned long *src,
188 : : const unsigned long *old, const unsigned long *new, unsigned int nbits);
189 : : extern int bitmap_bitremap(int oldbit,
190 : : const unsigned long *old, const unsigned long *new, int bits);
191 : : extern void bitmap_onto(unsigned long *dst, const unsigned long *orig,
192 : : const unsigned long *relmap, unsigned int bits);
193 : : extern void bitmap_fold(unsigned long *dst, const unsigned long *orig,
194 : : unsigned int sz, unsigned int nbits);
195 : : extern int bitmap_find_free_region(unsigned long *bitmap, unsigned int bits, int order);
196 : : extern void bitmap_release_region(unsigned long *bitmap, unsigned int pos, int order);
197 : : extern int bitmap_allocate_region(unsigned long *bitmap, unsigned int pos, int order);
198 : :
199 : : #ifdef __BIG_ENDIAN
200 : : extern void bitmap_copy_le(unsigned long *dst, const unsigned long *src, unsigned int nbits);
201 : : #else
202 : : #define bitmap_copy_le bitmap_copy
203 : : #endif
204 : : extern unsigned int bitmap_ord_to_pos(const unsigned long *bitmap, unsigned int ord, unsigned int nbits);
205 : : extern int bitmap_print_to_pagebuf(bool list, char *buf,
206 : : const unsigned long *maskp, int nmaskbits);
207 : :
208 : : #define BITMAP_FIRST_WORD_MASK(start) (~0UL << ((start) & (BITS_PER_LONG - 1)))
209 : : #define BITMAP_LAST_WORD_MASK(nbits) (~0UL >> (-(nbits) & (BITS_PER_LONG - 1)))
210 : :
211 : : /*
212 : : * The static inlines below do not handle constant nbits==0 correctly,
213 : : * so make such users (should any ever turn up) call the out-of-line
214 : : * versions.
215 : : */
216 : : #define small_const_nbits(nbits) \
217 : : (__builtin_constant_p(nbits) && (nbits) <= BITS_PER_LONG && (nbits) > 0)
218 : :
219 : : static inline void bitmap_zero(unsigned long *dst, unsigned int nbits)
220 : : {
221 : 2 : unsigned int len = BITS_TO_LONGS(nbits) * sizeof(unsigned long);
222 : 3 : memset(dst, 0, len);
223 : : }
224 : :
225 : : static inline void bitmap_fill(unsigned long *dst, unsigned int nbits)
226 : : {
227 : 3 : unsigned int len = BITS_TO_LONGS(nbits) * sizeof(unsigned long);
228 : 3 : memset(dst, 0xff, len);
229 : : }
230 : :
231 : : static inline void bitmap_copy(unsigned long *dst, const unsigned long *src,
232 : : unsigned int nbits)
233 : : {
234 : 3 : unsigned int len = BITS_TO_LONGS(nbits) * sizeof(unsigned long);
235 : 3 : memcpy(dst, src, len);
236 : : }
237 : :
238 : : /*
239 : : * Copy bitmap and clear tail bits in last word.
240 : : */
241 : 0 : static inline void bitmap_copy_clear_tail(unsigned long *dst,
242 : : const unsigned long *src, unsigned int nbits)
243 : : {
244 : : bitmap_copy(dst, src, nbits);
245 : 0 : if (nbits % BITS_PER_LONG)
246 : 0 : dst[nbits / BITS_PER_LONG] &= BITMAP_LAST_WORD_MASK(nbits);
247 : 0 : }
248 : :
249 : : /*
250 : : * On 32-bit systems bitmaps are represented as u32 arrays internally, and
251 : : * therefore conversion is not needed when copying data from/to arrays of u32.
252 : : */
253 : : #if BITS_PER_LONG == 64
254 : : extern void bitmap_from_arr32(unsigned long *bitmap, const u32 *buf,
255 : : unsigned int nbits);
256 : : extern void bitmap_to_arr32(u32 *buf, const unsigned long *bitmap,
257 : : unsigned int nbits);
258 : : #else
259 : : #define bitmap_from_arr32(bitmap, buf, nbits) \
260 : : bitmap_copy_clear_tail((unsigned long *) (bitmap), \
261 : : (const unsigned long *) (buf), (nbits))
262 : : #define bitmap_to_arr32(buf, bitmap, nbits) \
263 : : bitmap_copy_clear_tail((unsigned long *) (buf), \
264 : : (const unsigned long *) (bitmap), (nbits))
265 : : #endif
266 : :
267 : 3 : static inline int bitmap_and(unsigned long *dst, const unsigned long *src1,
268 : : const unsigned long *src2, unsigned int nbits)
269 : : {
270 : 3 : if (small_const_nbits(nbits))
271 : 3 : return (*dst = *src1 & *src2 & BITMAP_LAST_WORD_MASK(nbits)) != 0;
272 : 3 : return __bitmap_and(dst, src1, src2, nbits);
273 : : }
274 : :
275 : 3 : static inline void bitmap_or(unsigned long *dst, const unsigned long *src1,
276 : : const unsigned long *src2, unsigned int nbits)
277 : : {
278 : 3 : if (small_const_nbits(nbits))
279 : 3 : *dst = *src1 | *src2;
280 : : else
281 : 0 : __bitmap_or(dst, src1, src2, nbits);
282 : 3 : }
283 : :
284 : 0 : static inline void bitmap_xor(unsigned long *dst, const unsigned long *src1,
285 : : const unsigned long *src2, unsigned int nbits)
286 : : {
287 : 0 : if (small_const_nbits(nbits))
288 : 0 : *dst = *src1 ^ *src2;
289 : : else
290 : 0 : __bitmap_xor(dst, src1, src2, nbits);
291 : 0 : }
292 : :
293 : 2 : static inline int bitmap_andnot(unsigned long *dst, const unsigned long *src1,
294 : : const unsigned long *src2, unsigned int nbits)
295 : : {
296 : 2 : if (small_const_nbits(nbits))
297 : 0 : return (*dst = *src1 & ~(*src2) & BITMAP_LAST_WORD_MASK(nbits)) != 0;
298 : 2 : return __bitmap_andnot(dst, src1, src2, nbits);
299 : : }
300 : :
301 : 0 : static inline void bitmap_complement(unsigned long *dst, const unsigned long *src,
302 : : unsigned int nbits)
303 : : {
304 : 0 : if (small_const_nbits(nbits))
305 : 0 : *dst = ~(*src);
306 : : else
307 : 0 : __bitmap_complement(dst, src, nbits);
308 : 0 : }
309 : :
310 : : #ifdef __LITTLE_ENDIAN
311 : : #define BITMAP_MEM_ALIGNMENT 8
312 : : #else
313 : : #define BITMAP_MEM_ALIGNMENT (8 * sizeof(unsigned long))
314 : : #endif
315 : : #define BITMAP_MEM_MASK (BITMAP_MEM_ALIGNMENT - 1)
316 : :
317 : 3 : static inline int bitmap_equal(const unsigned long *src1,
318 : : const unsigned long *src2, unsigned int nbits)
319 : : {
320 : 3 : if (small_const_nbits(nbits))
321 : 3 : return !((*src1 ^ *src2) & BITMAP_LAST_WORD_MASK(nbits));
322 : 1 : if (__builtin_constant_p(nbits & BITMAP_MEM_MASK) &&
323 : : IS_ALIGNED(nbits, BITMAP_MEM_ALIGNMENT))
324 : 0 : return !memcmp(src1, src2, nbits / 8);
325 : 1 : return __bitmap_equal(src1, src2, nbits);
326 : : }
327 : :
328 : : /**
329 : : * bitmap_or_equal - Check whether the or of two bitmaps is equal to a third
330 : : * @src1: Pointer to bitmap 1
331 : : * @src2: Pointer to bitmap 2 will be or'ed with bitmap 1
332 : : * @src3: Pointer to bitmap 3. Compare to the result of *@src1 | *@src2
333 : : * @nbits: number of bits in each of these bitmaps
334 : : *
335 : : * Returns: True if (*@src1 | *@src2) == *@src3, false otherwise
336 : : */
337 : : static inline bool bitmap_or_equal(const unsigned long *src1,
338 : : const unsigned long *src2,
339 : : const unsigned long *src3,
340 : : unsigned int nbits)
341 : : {
342 : : if (!small_const_nbits(nbits))
343 : : return __bitmap_or_equal(src1, src2, src3, nbits);
344 : :
345 : : return !(((*src1 | *src2) ^ *src3) & BITMAP_LAST_WORD_MASK(nbits));
346 : : }
347 : :
348 : 3 : static inline int bitmap_intersects(const unsigned long *src1,
349 : : const unsigned long *src2, unsigned int nbits)
350 : : {
351 : 3 : if (small_const_nbits(nbits))
352 : 3 : return ((*src1 & *src2) & BITMAP_LAST_WORD_MASK(nbits)) != 0;
353 : : else
354 : 3 : return __bitmap_intersects(src1, src2, nbits);
355 : : }
356 : :
357 : 3 : static inline int bitmap_subset(const unsigned long *src1,
358 : : const unsigned long *src2, unsigned int nbits)
359 : : {
360 : 3 : if (small_const_nbits(nbits))
361 : 3 : return ! ((*src1 & ~(*src2)) & BITMAP_LAST_WORD_MASK(nbits));
362 : : else
363 : 3 : return __bitmap_subset(src1, src2, nbits);
364 : : }
365 : :
366 : 3 : static inline int bitmap_empty(const unsigned long *src, unsigned nbits)
367 : : {
368 : 3 : if (small_const_nbits(nbits))
369 : 3 : return ! (*src & BITMAP_LAST_WORD_MASK(nbits));
370 : :
371 : 3 : return find_first_bit(src, nbits) == nbits;
372 : : }
373 : :
374 : 3 : static inline int bitmap_full(const unsigned long *src, unsigned int nbits)
375 : : {
376 : 3 : if (small_const_nbits(nbits))
377 : 0 : return ! (~(*src) & BITMAP_LAST_WORD_MASK(nbits));
378 : :
379 : 3 : return find_first_zero_bit(src, nbits) == nbits;
380 : : }
381 : :
382 : : static __always_inline int bitmap_weight(const unsigned long *src, unsigned int nbits)
383 : : {
384 : 0 : if (small_const_nbits(nbits))
385 : 3 : return hweight_long(*src & BITMAP_LAST_WORD_MASK(nbits));
386 : 0 : return __bitmap_weight(src, nbits);
387 : : }
388 : :
389 : : static __always_inline void bitmap_set(unsigned long *map, unsigned int start,
390 : : unsigned int nbits)
391 : : {
392 : 3 : if (__builtin_constant_p(nbits) && nbits == 1)
393 : 0 : __set_bit(start, map);
394 : 3 : else if (__builtin_constant_p(start & BITMAP_MEM_MASK) &&
395 : 3 : IS_ALIGNED(start, BITMAP_MEM_ALIGNMENT) &&
396 : 3 : __builtin_constant_p(nbits & BITMAP_MEM_MASK) &&
397 : : IS_ALIGNED(nbits, BITMAP_MEM_ALIGNMENT))
398 : 3 : memset((char *)map + start / 8, 0xff, nbits / 8);
399 : : else
400 : 3 : __bitmap_set(map, start, nbits);
401 : : }
402 : :
403 : : static __always_inline void bitmap_clear(unsigned long *map, unsigned int start,
404 : : unsigned int nbits)
405 : : {
406 : 3 : if (__builtin_constant_p(nbits) && nbits == 1)
407 : 3 : __clear_bit(start, map);
408 : 3 : else if (__builtin_constant_p(start & BITMAP_MEM_MASK) &&
409 : 0 : IS_ALIGNED(start, BITMAP_MEM_ALIGNMENT) &&
410 : 0 : __builtin_constant_p(nbits & BITMAP_MEM_MASK) &&
411 : : IS_ALIGNED(nbits, BITMAP_MEM_ALIGNMENT))
412 : 3 : memset((char *)map + start / 8, 0, nbits / 8);
413 : : else
414 : 3 : __bitmap_clear(map, start, nbits);
415 : : }
416 : :
417 : : static inline void bitmap_shift_right(unsigned long *dst, const unsigned long *src,
418 : : unsigned int shift, unsigned int nbits)
419 : : {
420 : : if (small_const_nbits(nbits))
421 : : *dst = (*src & BITMAP_LAST_WORD_MASK(nbits)) >> shift;
422 : : else
423 : : __bitmap_shift_right(dst, src, shift, nbits);
424 : : }
425 : :
426 : 0 : static inline void bitmap_shift_left(unsigned long *dst, const unsigned long *src,
427 : : unsigned int shift, unsigned int nbits)
428 : : {
429 : 0 : if (small_const_nbits(nbits))
430 : 0 : *dst = (*src << shift) & BITMAP_LAST_WORD_MASK(nbits);
431 : : else
432 : 0 : __bitmap_shift_left(dst, src, shift, nbits);
433 : 0 : }
434 : :
435 : : static inline int bitmap_parse(const char *buf, unsigned int buflen,
436 : : unsigned long *maskp, int nmaskbits)
437 : : {
438 : 0 : return __bitmap_parse(buf, buflen, 0, maskp, nmaskbits);
439 : : }
440 : :
441 : : /**
442 : : * BITMAP_FROM_U64() - Represent u64 value in the format suitable for bitmap.
443 : : * @n: u64 value
444 : : *
445 : : * Linux bitmaps are internally arrays of unsigned longs, i.e. 32-bit
446 : : * integers in 32-bit environment, and 64-bit integers in 64-bit one.
447 : : *
448 : : * There are four combinations of endianness and length of the word in linux
449 : : * ABIs: LE64, BE64, LE32 and BE32.
450 : : *
451 : : * On 64-bit kernels 64-bit LE and BE numbers are naturally ordered in
452 : : * bitmaps and therefore don't require any special handling.
453 : : *
454 : : * On 32-bit kernels 32-bit LE ABI orders lo word of 64-bit number in memory
455 : : * prior to hi, and 32-bit BE orders hi word prior to lo. The bitmap on the
456 : : * other hand is represented as an array of 32-bit words and the position of
457 : : * bit N may therefore be calculated as: word #(N/32) and bit #(N%32) in that
458 : : * word. For example, bit #42 is located at 10th position of 2nd word.
459 : : * It matches 32-bit LE ABI, and we can simply let the compiler store 64-bit
460 : : * values in memory as it usually does. But for BE we need to swap hi and lo
461 : : * words manually.
462 : : *
463 : : * With all that, the macro BITMAP_FROM_U64() does explicit reordering of hi and
464 : : * lo parts of u64. For LE32 it does nothing, and for BE environment it swaps
465 : : * hi and lo words, as is expected by bitmap.
466 : : */
467 : : #if __BITS_PER_LONG == 64
468 : : #define BITMAP_FROM_U64(n) (n)
469 : : #else
470 : : #define BITMAP_FROM_U64(n) ((unsigned long) ((u64)(n) & ULONG_MAX)), \
471 : : ((unsigned long) ((u64)(n) >> 32))
472 : : #endif
473 : :
474 : : /**
475 : : * bitmap_from_u64 - Check and swap words within u64.
476 : : * @mask: source bitmap
477 : : * @dst: destination bitmap
478 : : *
479 : : * In 32-bit Big Endian kernel, when using ``(u32 *)(&val)[*]``
480 : : * to read u64 mask, we will get the wrong word.
481 : : * That is ``(u32 *)(&val)[0]`` gets the upper 32 bits,
482 : : * but we expect the lower 32-bits of u64.
483 : : */
484 : : static inline void bitmap_from_u64(unsigned long *dst, u64 mask)
485 : : {
486 : 3 : dst[0] = mask & ULONG_MAX;
487 : :
488 : : if (sizeof(mask) > sizeof(unsigned long))
489 : 3 : dst[1] = mask >> 32;
490 : : }
491 : :
492 : : #endif /* __ASSEMBLY__ */
493 : :
494 : : #endif /* __LINUX_BITMAP_H */
|