[XEN] Convert between long-based and byte-based bitmap arrays.
authorkfraser@localhost.localdomain <kfraser@localhost.localdomain>
Fri, 19 Jan 2007 14:24:28 +0000 (14:24 +0000)
committerkfraser@localhost.localdomain <kfraser@localhost.localdomain>
Fri, 19 Jan 2007 14:24:28 +0000 (14:24 +0000)
Use this for conversion of the domctl_cpumap type on big-endian
systems.
Original patch from Jimi Xenidis <jimix@watson.ibm.com>
Signed-off-by: Keir Fraser <keir@xensource.com>
xen/common/bitmap.c
xen/common/domctl.c
xen/include/xen/bitmap.h

index 9bdc3157d1345e3f3ce3a6bb533f2db3b3c24195..76f55d29e8b4d16c9b9a81f243841fd0089065a8 100644 (file)
@@ -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 *bitmap, int pos, int order)
        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
index 4494c84494a66e6e71c54f2a3f8f6333304a9a7e..230d2049121b0f85f73a0f5e1ee0506249d9ae32 100644 (file)
@@ -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_bytes  = min_t(unsigned int, guest_bytes, sizeof(bytemap));
 
-    copy_to_guest(xenctl_cpumap->bitmap,
-                  (uint8_t *)cpus_addr(*cpumask),
-                  copy_bytes);
+    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 */
index 91622645c51e2a802c04a39331e8fa067d05305d..a8cd593d23ae796fd39609d9396171adfc34a026 100644 (file)
@@ -251,6 +251,9 @@ static inline void bitmap_shift_left(unsigned long *dst,
                __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 */