1 /*
2 * lib/bitmap.c
3 * Helper functions for bitmap.h.
4 *
5 * This source code is licensed under the GNU General Public License,
6 * Version 2. See the file COPYING for more details.
7 */
8 #include <xen/types.h>
9 #include <xen/errno.h>
10 #include <xen/bitmap.h>
11 #include <xen/bitops.h>
12 #include <asm/byteorder.h>
13
14 /*
15 * bitmaps provide an array of bits, implemented using an an
16 * array of unsigned longs. The number of valid bits in a
17 * given bitmap does _not_ need to be an exact multiple of
18 * BITS_PER_LONG.
19 *
20 * The possible unused bits in the last, partially used word
21 * of a bitmap are 'don't care'. The implementation makes
22 * no particular effort to keep them zero. It ensures that
23 * their value will not affect the results of any operation.
24 * The bitmap operations that return Boolean (bitmap_empty,
25 * for example) or scalar (bitmap_weight, for example) results
26 * carefully filter out these unused bits from impacting their
27 * results.
28 *
29 * These operations actually hold to a slightly stronger rule:
30 * if you don't input any bitmaps to these ops that have some
31 * unused bits set, then they won't output any set unused bits
32 * in output bitmaps.
33 *
34 * The byte ordering of bitmaps is more natural on little
35 * endian architectures. See the big-endian headers
36 * include/asm-ppc64/bitops.h and include/asm-s390/bitops.h
37 * for the best explanations of this ordering.
38 */
39
40 /*
41 * If a bitmap has a number of bits which is not a multiple of 8 then
42 * the last few bits of the last byte of the bitmap can be
43 * unexpectedly set which can confuse consumers (e.g. in the tools)
44 * who also round up their loops to 8 bits. Ensure we clear those left
45 * over bits so as to prevent surprises.
46 */
clamp_last_byte(uint8_t * bp,unsigned int nbits)47 static void clamp_last_byte(uint8_t *bp, unsigned int nbits)
48 {
49 unsigned int remainder = nbits % 8;
50
51 if (remainder)
52 bp[nbits/8] &= (1U << remainder) - 1;
53 }
54
__bitmap_empty(const unsigned long * bitmap,int bits)55 int __bitmap_empty(const unsigned long *bitmap, int bits)
56 {
57 int k, lim = bits/BITS_PER_LONG;
58 for (k = 0; k < lim; ++k)
59 if (bitmap[k])
60 return 0;
61
62 if (bits % BITS_PER_LONG)
63 if (bitmap[k] & BITMAP_LAST_WORD_MASK(bits))
64 return 0;
65
66 return 1;
67 }
68 EXPORT_SYMBOL(__bitmap_empty);
69
__bitmap_full(const unsigned long * bitmap,int bits)70 int __bitmap_full(const unsigned long *bitmap, int bits)
71 {
72 int k, lim = bits/BITS_PER_LONG;
73 for (k = 0; k < lim; ++k)
74 if (~bitmap[k])
75 return 0;
76
77 if (bits % BITS_PER_LONG)
78 if (~bitmap[k] & BITMAP_LAST_WORD_MASK(bits))
79 return 0;
80
81 return 1;
82 }
83 EXPORT_SYMBOL(__bitmap_full);
84
__bitmap_equal(const unsigned long * bitmap1,const unsigned long * bitmap2,int bits)85 int __bitmap_equal(const unsigned long *bitmap1,
86 const unsigned long *bitmap2, int bits)
87 {
88 int k, lim = bits/BITS_PER_LONG;
89 for (k = 0; k < lim; ++k)
90 if (bitmap1[k] != bitmap2[k])
91 return 0;
92
93 if (bits % BITS_PER_LONG)
94 if ((bitmap1[k] ^ bitmap2[k]) & BITMAP_LAST_WORD_MASK(bits))
95 return 0;
96
97 return 1;
98 }
99 EXPORT_SYMBOL(__bitmap_equal);
100
__bitmap_complement(unsigned long * dst,const unsigned long * src,int bits)101 void __bitmap_complement(unsigned long *dst, const unsigned long *src, int bits)
102 {
103 int k, lim = bits/BITS_PER_LONG;
104 for (k = 0; k < lim; ++k)
105 dst[k] = ~src[k];
106
107 if (bits % BITS_PER_LONG)
108 dst[k] = ~src[k] & BITMAP_LAST_WORD_MASK(bits);
109 }
110 EXPORT_SYMBOL(__bitmap_complement);
111
__bitmap_and(unsigned long * dst,const unsigned long * bitmap1,const unsigned long * bitmap2,int bits)112 void __bitmap_and(unsigned long *dst, const unsigned long *bitmap1,
113 const unsigned long *bitmap2, int bits)
114 {
115 int k;
116 int nr = BITS_TO_LONGS(bits);
117
118 for (k = 0; k < nr; k++)
119 dst[k] = bitmap1[k] & bitmap2[k];
120 }
121 EXPORT_SYMBOL(__bitmap_and);
122
__bitmap_or(unsigned long * dst,const unsigned long * bitmap1,const unsigned long * bitmap2,int bits)123 void __bitmap_or(unsigned long *dst, const unsigned long *bitmap1,
124 const unsigned long *bitmap2, int bits)
125 {
126 int k;
127 int nr = BITS_TO_LONGS(bits);
128
129 for (k = 0; k < nr; k++)
130 dst[k] = bitmap1[k] | bitmap2[k];
131 }
132 EXPORT_SYMBOL(__bitmap_or);
133
__bitmap_xor(unsigned long * dst,const unsigned long * bitmap1,const unsigned long * bitmap2,int bits)134 void __bitmap_xor(unsigned long *dst, const unsigned long *bitmap1,
135 const unsigned long *bitmap2, int bits)
136 {
137 int k;
138 int nr = BITS_TO_LONGS(bits);
139
140 for (k = 0; k < nr; k++)
141 dst[k] = bitmap1[k] ^ bitmap2[k];
142 }
143 EXPORT_SYMBOL(__bitmap_xor);
144
__bitmap_andnot(unsigned long * dst,const unsigned long * bitmap1,const unsigned long * bitmap2,int bits)145 void __bitmap_andnot(unsigned long *dst, const unsigned long *bitmap1,
146 const unsigned long *bitmap2, int bits)
147 {
148 int k;
149 int nr = BITS_TO_LONGS(bits);
150
151 for (k = 0; k < nr; k++)
152 dst[k] = bitmap1[k] & ~bitmap2[k];
153 }
154 EXPORT_SYMBOL(__bitmap_andnot);
155
__bitmap_intersects(const unsigned long * bitmap1,const unsigned long * bitmap2,int bits)156 int __bitmap_intersects(const unsigned long *bitmap1,
157 const unsigned long *bitmap2, int bits)
158 {
159 int k, lim = bits/BITS_PER_LONG;
160 for (k = 0; k < lim; ++k)
161 if (bitmap1[k] & bitmap2[k])
162 return 1;
163
164 if (bits % BITS_PER_LONG)
165 if ((bitmap1[k] & bitmap2[k]) & BITMAP_LAST_WORD_MASK(bits))
166 return 1;
167 return 0;
168 }
169 EXPORT_SYMBOL(__bitmap_intersects);
170
__bitmap_subset(const unsigned long * bitmap1,const unsigned long * bitmap2,int bits)171 int __bitmap_subset(const unsigned long *bitmap1,
172 const unsigned long *bitmap2, int bits)
173 {
174 int k, lim = bits/BITS_PER_LONG;
175 for (k = 0; k < lim; ++k)
176 if (bitmap1[k] & ~bitmap2[k])
177 return 0;
178
179 if (bits % BITS_PER_LONG)
180 if ((bitmap1[k] & ~bitmap2[k]) & BITMAP_LAST_WORD_MASK(bits))
181 return 0;
182 return 1;
183 }
184 EXPORT_SYMBOL(__bitmap_subset);
185
186 #if BITS_PER_LONG == 32
__bitmap_weight(const unsigned long * bitmap,int bits)187 int __bitmap_weight(const unsigned long *bitmap, int bits)
188 {
189 int k, w = 0, lim = bits/BITS_PER_LONG;
190
191 for (k = 0; k < lim; k++)
192 w += hweight32(bitmap[k]);
193
194 if (bits % BITS_PER_LONG)
195 w += hweight32(bitmap[k] & BITMAP_LAST_WORD_MASK(bits));
196
197 return w;
198 }
199 #else
__bitmap_weight(const unsigned long * bitmap,int bits)200 int __bitmap_weight(const unsigned long *bitmap, int bits)
201 {
202 int k, w = 0, lim = bits/BITS_PER_LONG;
203
204 for (k = 0; k < lim; k++)
205 w += hweight64(bitmap[k]);
206
207 if (bits % BITS_PER_LONG)
208 w += hweight64(bitmap[k] & BITMAP_LAST_WORD_MASK(bits));
209
210 return w;
211 }
212 #endif
213 EXPORT_SYMBOL(__bitmap_weight);
214
__bitmap_set(unsigned long * map,unsigned int start,int len)215 void __bitmap_set(unsigned long *map, unsigned int start, int len)
216 {
217 unsigned long *p = map + BIT_WORD(start);
218 const unsigned int size = start + len;
219 int bits_to_set = BITS_PER_LONG - (start % BITS_PER_LONG);
220 unsigned long mask_to_set = BITMAP_FIRST_WORD_MASK(start);
221
222 while (len - bits_to_set >= 0) {
223 *p |= mask_to_set;
224 len -= bits_to_set;
225 bits_to_set = BITS_PER_LONG;
226 mask_to_set = ~0UL;
227 p++;
228 }
229 if (len) {
230 mask_to_set &= BITMAP_LAST_WORD_MASK(size);
231 *p |= mask_to_set;
232 }
233 }
234
__bitmap_clear(unsigned long * map,unsigned int start,int len)235 void __bitmap_clear(unsigned long *map, unsigned int start, int len)
236 {
237 unsigned long *p = map + BIT_WORD(start);
238 const unsigned int size = start + len;
239 int bits_to_clear = BITS_PER_LONG - (start % BITS_PER_LONG);
240 unsigned long mask_to_clear = BITMAP_FIRST_WORD_MASK(start);
241
242 while (len - bits_to_clear >= 0) {
243 *p &= ~mask_to_clear;
244 len -= bits_to_clear;
245 bits_to_clear = BITS_PER_LONG;
246 mask_to_clear = ~0UL;
247 p++;
248 }
249 if (len) {
250 mask_to_clear &= BITMAP_LAST_WORD_MASK(size);
251 *p &= ~mask_to_clear;
252 }
253 }
254
255 /**
256 * bitmap_find_free_region - find a contiguous aligned mem region
257 * @bitmap: an array of unsigned longs corresponding to the bitmap
258 * @bits: number of bits in the bitmap
259 * @order: region size to find (size is actually 1<<order)
260 *
261 * This is used to allocate a memory region from a bitmap. The idea is
262 * that the region has to be 1<<order sized and 1<<order aligned (this
263 * makes the search algorithm much faster).
264 *
265 * The region is marked as set bits in the bitmap if a free one is
266 * found.
267 *
268 * Returns either beginning of region or negative error
269 */
bitmap_find_free_region(unsigned long * bitmap,int bits,int order)270 int bitmap_find_free_region(unsigned long *bitmap, int bits, int order)
271 {
272 unsigned long mask;
273 int pages = 1 << order;
274 int i;
275
276 if(pages > BITS_PER_LONG)
277 return -EINVAL;
278
279 /* make a mask of the order */
280 mask = (1ul << (pages - 1));
281 mask += mask - 1;
282
283 /* run up the bitmap pages bits at a time */
284 for (i = 0; i < bits; i += pages) {
285 int index = i/BITS_PER_LONG;
286 int offset = i - (index * BITS_PER_LONG);
287 if((bitmap[index] & (mask << offset)) == 0) {
288 /* set region in bimap */
289 bitmap[index] |= (mask << offset);
290 return i;
291 }
292 }
293 return -ENOMEM;
294 }
295 EXPORT_SYMBOL(bitmap_find_free_region);
296
297 /**
298 * bitmap_release_region - release allocated bitmap region
299 * @bitmap: a pointer to the bitmap
300 * @pos: the beginning of the region
301 * @order: the order of the bits to release (number is 1<<order)
302 *
303 * This is the complement to __bitmap_find_free_region and releases
304 * the found region (by clearing it in the bitmap).
305 */
bitmap_release_region(unsigned long * bitmap,int pos,int order)306 void bitmap_release_region(unsigned long *bitmap, int pos, int order)
307 {
308 int pages = 1 << order;
309 unsigned long mask = (1ul << (pages - 1));
310 int index = pos/BITS_PER_LONG;
311 int offset = pos - (index * BITS_PER_LONG);
312 mask += mask - 1;
313 bitmap[index] &= ~(mask << offset);
314 }
315 EXPORT_SYMBOL(bitmap_release_region);
316
bitmap_allocate_region(unsigned long * bitmap,int pos,int order)317 int bitmap_allocate_region(unsigned long *bitmap, int pos, int order)
318 {
319 int pages = 1 << order;
320 unsigned long mask = (1ul << (pages - 1));
321 int index = pos/BITS_PER_LONG;
322 int offset = pos - (index * BITS_PER_LONG);
323
324 /* We don't do regions of pages > BITS_PER_LONG. The
325 * algorithm would be a simple look for multiple zeros in the
326 * array, but there's no driver today that needs this. If you
327 * trip this BUG(), you get to code it... */
328 BUG_ON(pages > BITS_PER_LONG);
329 mask += mask - 1;
330 if (bitmap[index] & (mask << offset))
331 return -EBUSY;
332 bitmap[index] |= (mask << offset);
333 return 0;
334 }
335 EXPORT_SYMBOL(bitmap_allocate_region);
336
337 #ifdef __BIG_ENDIAN
338
bitmap_long_to_byte(uint8_t * bp,const unsigned long * lp,int nbits)339 void bitmap_long_to_byte(uint8_t *bp, const unsigned long *lp, int nbits)
340 {
341 unsigned long l;
342 int i, j, b;
343
344 for (i = 0, b = 0; nbits > 0; i++, b += sizeof(l)) {
345 l = lp[i];
346 for (j = 0; (j < sizeof(l)) && (nbits > 0); j++) {
347 bp[b+j] = l;
348 l >>= 8;
349 nbits -= 8;
350 }
351 }
352 clamp_last_byte(bp, nbits);
353 }
354
bitmap_byte_to_long(unsigned long * lp,const uint8_t * bp,int nbits)355 void bitmap_byte_to_long(unsigned long *lp, const uint8_t *bp, int nbits)
356 {
357 unsigned long l;
358 int i, j, b;
359
360 for (i = 0, b = 0; nbits > 0; i++, b += sizeof(l)) {
361 l = 0;
362 for (j = 0; (j < sizeof(l)) && (nbits > 0); j++) {
363 l |= (unsigned long)bp[b+j] << (j*8);
364 nbits -= 8;
365 }
366 lp[i] = l;
367 }
368 }
369
370 #elif defined(__LITTLE_ENDIAN)
371
bitmap_long_to_byte(uint8_t * bp,const unsigned long * lp,int nbits)372 void bitmap_long_to_byte(uint8_t *bp, const unsigned long *lp, int nbits)
373 {
374 memcpy(bp, lp, (nbits+7)/8);
375 clamp_last_byte(bp, nbits);
376 }
377
bitmap_byte_to_long(unsigned long * lp,const uint8_t * bp,int nbits)378 void bitmap_byte_to_long(unsigned long *lp, const uint8_t *bp, int nbits)
379 {
380 /* We may need to pad the final longword with zeroes. */
381 if (nbits & (BITS_PER_LONG-1))
382 lp[BITS_TO_LONGS(nbits)-1] = 0;
383 memcpy(lp, bp, (nbits+7)/8);
384 }
385
386 #endif
387