[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-devel] [PATCH] fix xenctl_cpumap translation to handle bitops accessed like arrays



On PowerPC (and other big endian and/or RISC architectures) bit
offsets in a bitmap are actually represented by a bit-offset from an
element in an array rather than a bit-offset from the base memory
pointer,  see xen/include/asm-powerpc/bitops.h for a complete
explanation.

This complicates the conversion of cpumask_t from/to xenctl_cpumap.

The following patch allows an architecture to declare that bitops are
"by long" rather than "by bit" and use an alternate scheme for
encoding.

Signed-off-by: Jimi Xenidis <jimix@xxxxxxxxxxxxxx>

---

diff -r b04e24db308f xen/common/domctl.c
--- a/xen/common/domctl.c       Sun Dec 17 12:40:10 2006 -0500
+++ b/xen/common/domctl.c       Fri Dec 15 17:03:47 2006 -0500
@@ -30,14 +30,36 @@ void cpumask_to_xenctl_cpumap(
 void cpumask_to_xenctl_cpumap(
     struct xenctl_cpumap *xenctl_cpumap, cpumask_t *cpumask)
 {
-    unsigned int guest_bytes, copy_bytes, i;
+    unsigned int guest_bytes, copy_bytes, xen_bytes, i;
     uint8_t zero = 0;
+    cpumask_t local;
 
     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);
+
+    xen_bytes = (NR_CPUS + 7) / 8;
+    if (bitmap_by_long) {
+        if (((guest_bytes * 8) % BITS_PER_LONG) != 0) {
+            printk("%s: Unable to translate bitmap\n", __func__);
+            return;
+        }
+
+        /* local copy */
+        memcpy(cpus_addr(local), cpus_addr(*cpumask), sizeof (local));
+
+        /* clear unused bits */
+        for (i = NR_CPUS; i < sizeof(local) * 8; i++) {
+            /* non-atomic version */
+            __clear_bit(i, cpus_addr(local));
+        }
+
+        xen_bytes = sizeof(local);
+        cpumask = &local;
+    }
+
+    copy_bytes  = min_t(unsigned int, guest_bytes, xen_bytes);
 
     copy_to_guest(xenctl_cpumap->bitmap,
                   (uint8_t *)cpus_addr(*cpumask),
@@ -50,10 +72,20 @@ void xenctl_cpumap_to_cpumask(
 void xenctl_cpumap_to_cpumask(
     cpumask_t *cpumask, struct xenctl_cpumap *xenctl_cpumap)
 {
-    unsigned int guest_bytes, copy_bytes;
+    unsigned int guest_bytes, copy_bytes, xen_bytes;
 
     guest_bytes = (xenctl_cpumap->nr_cpus + 7) / 8;
-    copy_bytes  = min_t(unsigned int, guest_bytes, (NR_CPUS + 7) / 8);
+    xen_bytes = (NR_CPUS + 7) / 8;
+
+    if (bitmap_by_long) {
+        if (((guest_bytes * 8) % BITS_PER_LONG) != 0) {
+            printk("%s: Unable to translate bitmap\n", __func__);
+            return;
+        }
+        xen_bytes = sizeof(*cpumask);
+    }
+
+    copy_bytes  = min_t(unsigned int, guest_bytes, xen_bytes);
 
     cpus_clear(*cpumask);
 
diff -r b04e24db308f xen/include/asm-powerpc/bitops.h
--- a/xen/include/asm-powerpc/bitops.h  Sun Dec 17 12:40:10 2006 -0500
+++ b/xen/include/asm-powerpc/bitops.h  Fri Dec 15 16:24:26 2006 -0500
@@ -41,6 +41,9 @@
 #define _PPC64_BITOPS_H
 
 #include <asm/memory.h>
+
+/* The following indicates that bitops are implemented as described above */
+#define bitmap_by_long (1)
 
 /*
  * clear_bit doesn't imply a memory barrier
diff -r b04e24db308f xen/include/xen/bitops.h
--- a/xen/include/xen/bitops.h  Sun Dec 17 12:40:10 2006 -0500
+++ b/xen/include/xen/bitops.h  Fri Dec 15 16:22:32 2006 -0500
@@ -75,6 +75,10 @@ static __inline__ int generic_fls(int x)
  * scope
  */
 #include <asm/bitops.h>
+
+#ifndef bitmap_by_long
+#define bitmap_by_long (0)
+#endif
 
 
 static inline int generic_fls64(__u64 x)

_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.