On 02/11/2013 10:24 AM, Eric Blake wrote: > On 01/30/2013 11:51 AM, John Ferlan wrote: >> Turns out the issue regarding ptr_arith and sign_exension weren't false >> positives. When shifting an 'unsigned char' as a target, it gets promoted >> to an 'int'; however, that 'int' cannot be shifted 32 bits which was how >> the algorithm was written. For the ptr_arith rather than index into the >> cpumap, change the to address as necessary and assign directly. >> --- >> src/xen/xen_hypervisor.c | 10 +++++----- > >> for (j = 0; j < maplen; j++) { >> - /* coverity[ptr_arith] */ >> - /* coverity[sign_extension] */ >> - *(pm + (j / 8)) |= cpumap[j] << (8 * (j & 7)); >> + if ((j & 7) == 0) >> + pm = (uint64_t *)((uint64_t)&xen_cpumap + (j & ~0x7UL)); > > I'm not happy with how this turned out. We are turning an address into > a pointer but not via intptr_t (probably warnings on mingw); then doing > math on that pointer, then turning the result back into a uint64_t > pointer. It looks like we are risking alignment errors. > >> + *pm |= (uint64_t)cpumap[j] << (8 * (j & 7)); More research - I think this is highly over-engineered, which explains why we got it so wrong. I checked a full range of xen-devel, from RHEL 5 (3.0.3, about as old as we support out-of-the-box with libvirt.git) to Fedora 18 (4.2.1); ALL of those versions had: /usr/include/xen/dom0_ops.h: typedef uint64_t cpumap_t; which means this type has (more or less) _always_ been exactly 64 bits; the code that tries to allow for iterating through 16 bytes instead of 8 is over-engineered. Really, _ALL_ we are doing is reading a little-endian 64-bit number in from the user (possibly in unaligned memory), and turning it into a host-endian cpumap_t to hand to xen. I should have a patch soon. -- Eric Blake eblake redhat com +1-919-301-3266 Libvirt virtualization library http://libvirt.org
Attachment:
signature.asc
Description: OpenPGP digital signature
-- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list