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