forked from mirrors/linux
		
	lib: add bitmap_{from,to}_arr64
Manipulating 64-bit arrays with bitmap functions is potentially dangerous
because on 32-bit BE machines the order of halfwords doesn't match.
Another issue is that compiler may throw a warning about out-of-boundary
access.
This patch adds bitmap_{from,to}_arr64 functions in addition to existing
bitmap_{from,to}_arr32.
CC: Alexander Gordeev <agordeev@linux.ibm.com>
CC: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
CC: Christian Borntraeger <borntraeger@linux.ibm.com>
CC: Claudio Imbrenda <imbrenda@linux.ibm.com>
CC: David Hildenbrand <david@redhat.com>
CC: Heiko Carstens <hca@linux.ibm.com>
CC: Janosch Frank <frankja@linux.ibm.com>
CC: Rasmus Villemoes <linux@rasmusvillemoes.dk>
CC: Sven Schnelle <svens@linux.ibm.com>
CC: Vasily Gorbik <gor@linux.ibm.com>
Signed-off-by: Yury Norov <yury.norov@gmail.com>
			
			
This commit is contained in:
		
							parent
							
								
									e041e0ac53
								
							
						
					
					
						commit
						0a97953fd2
					
				
					 2 changed files with 74 additions and 5 deletions
				
			
		| 
						 | 
				
			
			@ -72,6 +72,8 @@ struct device;
 | 
			
		|||
 *  bitmap_allocate_region(bitmap, pos, order)  Allocate specified bit region
 | 
			
		||||
 *  bitmap_from_arr32(dst, buf, nbits)          Copy nbits from u32[] buf to dst
 | 
			
		||||
 *  bitmap_to_arr32(buf, src, nbits)            Copy nbits from buf to u32[] dst
 | 
			
		||||
 *  bitmap_to_arr64(buf, src, nbits)            Copy nbits from buf to u64[] dst
 | 
			
		||||
 *  bitmap_to_arr64(buf, src, nbits)            Copy nbits from buf to u64[] dst
 | 
			
		||||
 *  bitmap_get_value8(map, start)               Get 8bit value from map at start
 | 
			
		||||
 *  bitmap_set_value8(map, value, start)        Set 8bit value to map at start
 | 
			
		||||
 *
 | 
			
		||||
| 
						 | 
				
			
			@ -285,6 +287,22 @@ void bitmap_to_arr32(u32 *buf, const unsigned long *bitmap,
 | 
			
		|||
			(const unsigned long *) (bitmap), (nbits))
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * On 64-bit systems bitmaps are represented as u64 arrays internally. On LE32
 | 
			
		||||
 * machines the order of hi and lo parts of numbers match the bitmap structure.
 | 
			
		||||
 * In both cases conversion is not needed when copying data from/to arrays of
 | 
			
		||||
 * u64.
 | 
			
		||||
 */
 | 
			
		||||
#if (BITS_PER_LONG == 32) && defined(__BIG_ENDIAN)
 | 
			
		||||
void bitmap_from_arr64(unsigned long *bitmap, const u64 *buf, unsigned int nbits);
 | 
			
		||||
void bitmap_to_arr64(u64 *buf, const unsigned long *bitmap, unsigned int nbits);
 | 
			
		||||
#else
 | 
			
		||||
#define bitmap_from_arr64(bitmap, buf, nbits)			\
 | 
			
		||||
	bitmap_copy_clear_tail((unsigned long *)(bitmap), (const unsigned long *)(buf), (nbits))
 | 
			
		||||
#define bitmap_to_arr64(buf, bitmap, nbits)			\
 | 
			
		||||
	bitmap_copy_clear_tail((unsigned long *)(buf), (const unsigned long *)(bitmap), (nbits))
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
static inline int bitmap_and(unsigned long *dst, const unsigned long *src1,
 | 
			
		||||
			const unsigned long *src2, unsigned int nbits)
 | 
			
		||||
{
 | 
			
		||||
| 
						 | 
				
			
			@ -518,10 +536,7 @@ static inline void bitmap_next_set_region(unsigned long *bitmap,
 | 
			
		|||
 */
 | 
			
		||||
static inline void bitmap_from_u64(unsigned long *dst, u64 mask)
 | 
			
		||||
{
 | 
			
		||||
	dst[0] = mask & ULONG_MAX;
 | 
			
		||||
 | 
			
		||||
	if (sizeof(mask) > sizeof(unsigned long))
 | 
			
		||||
		dst[1] = mask >> 32;
 | 
			
		||||
	bitmap_from_arr64(dst, &mask, 64);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										56
									
								
								lib/bitmap.c
									
									
									
									
									
								
							
							
						
						
									
										56
									
								
								lib/bitmap.c
									
									
									
									
									
								
							| 
						 | 
				
			
			@ -1512,5 +1512,59 @@ void bitmap_to_arr32(u32 *buf, const unsigned long *bitmap, unsigned int nbits)
 | 
			
		|||
		buf[halfwords - 1] &= (u32) (UINT_MAX >> ((-nbits) & 31));
 | 
			
		||||
}
 | 
			
		||||
EXPORT_SYMBOL(bitmap_to_arr32);
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if (BITS_PER_LONG == 32) && defined(__BIG_ENDIAN)
 | 
			
		||||
/**
 | 
			
		||||
 * bitmap_from_arr64 - copy the contents of u64 array of bits to bitmap
 | 
			
		||||
 *	@bitmap: array of unsigned longs, the destination bitmap
 | 
			
		||||
 *	@buf: array of u64 (in host byte order), the source bitmap
 | 
			
		||||
 *	@nbits: number of bits in @bitmap
 | 
			
		||||
 */
 | 
			
		||||
void bitmap_from_arr64(unsigned long *bitmap, const u64 *buf, unsigned int nbits)
 | 
			
		||||
{
 | 
			
		||||
	int n;
 | 
			
		||||
 | 
			
		||||
	for (n = nbits; n > 0; n -= 64) {
 | 
			
		||||
		u64 val = *buf++;
 | 
			
		||||
 | 
			
		||||
		*bitmap++ = val;
 | 
			
		||||
		if (n > 32)
 | 
			
		||||
			*bitmap++ = val >> 32;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/*
 | 
			
		||||
	 * Clear tail bits in the last word beyond nbits.
 | 
			
		||||
	 *
 | 
			
		||||
	 * Negative index is OK because here we point to the word next
 | 
			
		||||
	 * to the last word of the bitmap, except for nbits == 0, which
 | 
			
		||||
	 * is tested implicitly.
 | 
			
		||||
	 */
 | 
			
		||||
	if (nbits % BITS_PER_LONG)
 | 
			
		||||
		bitmap[-1] &= BITMAP_LAST_WORD_MASK(nbits);
 | 
			
		||||
}
 | 
			
		||||
EXPORT_SYMBOL(bitmap_from_arr64);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * bitmap_to_arr64 - copy the contents of bitmap to a u64 array of bits
 | 
			
		||||
 *	@buf: array of u64 (in host byte order), the dest bitmap
 | 
			
		||||
 *	@bitmap: array of unsigned longs, the source bitmap
 | 
			
		||||
 *	@nbits: number of bits in @bitmap
 | 
			
		||||
 */
 | 
			
		||||
void bitmap_to_arr64(u64 *buf, const unsigned long *bitmap, unsigned int nbits)
 | 
			
		||||
{
 | 
			
		||||
	const unsigned long *end = bitmap + BITS_TO_LONGS(nbits);
 | 
			
		||||
 | 
			
		||||
	while (bitmap < end) {
 | 
			
		||||
		*buf = *bitmap++;
 | 
			
		||||
		if (bitmap < end)
 | 
			
		||||
			*buf |= (u64)(*bitmap++) << 32;
 | 
			
		||||
		buf++;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Clear tail bits in the last element of array beyond nbits. */
 | 
			
		||||
	if (nbits % 64)
 | 
			
		||||
		buf[-1] &= GENMASK_ULL(nbits % 64, 0);
 | 
			
		||||
}
 | 
			
		||||
EXPORT_SYMBOL(bitmap_to_arr64);
 | 
			
		||||
#endif
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in a new issue