[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
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |