# HG changeset patch
# User kfraser@xxxxxxxxxxxxxxxxxxxxx
# Date 1169216668 0
# Node ID fa5bc90a3cb7ef206e29cb28c0c4d1d762eb9362
# Parent 3157835b1d45f7175aba2b4a98cac93f527d6b10
[XEN] Convert between long-based and byte-based bitmap arrays.
Use this for conversion of the domctl_cpumap type on big-endian
systems.
Original patch from Jimi Xenidis <jimix@xxxxxxxxxxxxxx>
Signed-off-by: Keir Fraser <keir@xxxxxxxxxxxxx>
---
xen/common/bitmap.c | 51 +++++++++++++++++++++++++++++++++++++++++++++++
xen/common/domctl.c | 21 +++++++++++--------
xen/include/xen/bitmap.h | 3 ++
3 files changed, 66 insertions(+), 9 deletions(-)
diff -r 3157835b1d45 -r fa5bc90a3cb7 xen/common/bitmap.c
--- a/xen/common/bitmap.c Fri Jan 19 13:43:17 2007 +0000
+++ b/xen/common/bitmap.c Fri Jan 19 14:24:28 2007 +0000
@@ -10,6 +10,7 @@
#include <xen/errno.h>
#include <xen/bitmap.h>
#include <xen/bitops.h>
+#include <asm/byteorder.h>
/*
* bitmaps provide an array of bits, implemented using an an
@@ -467,3 +468,53 @@ int bitmap_allocate_region(unsigned long
return 0;
}
EXPORT_SYMBOL(bitmap_allocate_region);
+
+#ifdef __BIG_ENDIAN
+
+void bitmap_long_to_byte(uint8_t *bp, const unsigned long *lp, int nbits)
+{
+ unsigned long l;
+ int i, j, b;
+
+ for (i = 0, b = 0; nbits > 0; i++, b += sizeof(l)) {
+ l = lp[i];
+ for (j = 0; (j < sizeof(l)) && (nbits > 0); j++) {
+ bp[b+j] = l;
+ l >>= 8;
+ nbits -= 8;
+ }
+ }
+}
+
+void bitmap_byte_to_long(unsigned long *lp, const uint8_t *bp, int nbits)
+{
+ unsigned long l;
+ int i, j, b;
+
+ for (i = 0, b = 0; nbits > 0; i++, b += sizeof(l)) {
+ l = 0;
+ for (j = 0; (j < sizeof(l)) && (nbits > 0); j++) {
+ l <<= 8;
+ l |= bp[b+j];
+ nbits -= 8;
+ }
+ lp[i] = l;
+ }
+}
+
+#elif defined(__LITTLE_ENDIAN)
+
+void bitmap_long_to_byte(uint8_t *bp, const unsigned long *lp, int nbits)
+{
+ memcpy(bp, lp, (nbits+7)/8);
+}
+
+void bitmap_byte_to_long(unsigned long *lp, const uint8_t *bp, int nbits)
+{
+ /* We may need to pad the final longword with zeroes. */
+ if (nbits & (BITS_PER_LONG-1))
+ lp[BITS_TO_LONGS(nbits)-1] = 0;
+ memcpy(lp, bp, (nbits+7)/8);
+}
+
+#endif
diff -r 3157835b1d45 -r fa5bc90a3cb7 xen/common/domctl.c
--- a/xen/common/domctl.c Fri Jan 19 13:43:17 2007 +0000
+++ b/xen/common/domctl.c Fri Jan 19 14:24:28 2007 +0000
@@ -18,6 +18,7 @@
#include <xen/console.h>
#include <xen/iocap.h>
#include <xen/guest_access.h>
+#include <xen/bitmap.h>
#ifdef CONFIG_COMPAT
#include <xen/compat.h>
#endif
@@ -40,16 +41,17 @@ void cpumask_to_xenctl_cpumap(
{
unsigned int guest_bytes, copy_bytes, i;
uint8_t zero = 0;
+ uint8_t bytemap[(NR_CPUS + 7) / 8];
if ( guest_handle_is_null(xenctl_cpumap->bitmap) )
return;
guest_bytes = (xenctl_cpumap->nr_cpus + 7) / 8;
- copy_bytes = min_t(unsigned int, guest_bytes, (NR_CPUS + 7) / 8);
-
- copy_to_guest(xenctl_cpumap->bitmap,
- (uint8_t *)cpus_addr(*cpumask),
- copy_bytes);
+ copy_bytes = min_t(unsigned int, guest_bytes, sizeof(bytemap));
+
+ bitmap_long_to_byte(bytemap, cpus_addr(*cpumask), NR_CPUS);
+
+ copy_to_guest(xenctl_cpumap->bitmap, &bytemap[0], copy_bytes);
for ( i = copy_bytes; i < guest_bytes; i++ )
copy_to_guest_offset(xenctl_cpumap->bitmap, i, &zero, 1);
@@ -59,18 +61,19 @@ void xenctl_cpumap_to_cpumask(
cpumask_t *cpumask, struct xenctl_cpumap *xenctl_cpumap)
{
unsigned int guest_bytes, copy_bytes;
+ uint8_t bytemap[(NR_CPUS + 7) / 8];
guest_bytes = (xenctl_cpumap->nr_cpus + 7) / 8;
- copy_bytes = min_t(unsigned int, guest_bytes, (NR_CPUS + 7) / 8);
+ copy_bytes = min_t(unsigned int, guest_bytes, sizeof(bytemap));
cpus_clear(*cpumask);
if ( guest_handle_is_null(xenctl_cpumap->bitmap) )
return;
- copy_from_guest((uint8_t *)cpus_addr(*cpumask),
- xenctl_cpumap->bitmap,
- copy_bytes);
+ copy_from_guest(&bytemap[0], xenctl_cpumap->bitmap, copy_bytes);
+
+ bitmap_byte_to_long(cpus_addr(*cpumask), bytemap, NR_CPUS);
}
#endif /* COMPAT */
diff -r 3157835b1d45 -r fa5bc90a3cb7 xen/include/xen/bitmap.h
--- a/xen/include/xen/bitmap.h Fri Jan 19 13:43:17 2007 +0000
+++ b/xen/include/xen/bitmap.h Fri Jan 19 14:24:28 2007 +0000
@@ -251,6 +251,9 @@ static inline void bitmap_shift_left(uns
__bitmap_shift_left(dst, src, n, nbits);
}
+void bitmap_long_to_byte(uint8_t *bp, const unsigned long *lp, int nbits);
+void bitmap_byte_to_long(unsigned long *lp, const uint8_t *bp, int nbits);
+
#endif /* __ASSEMBLY__ */
#endif /* __XEN_BITMAP_H */
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|