Commit 8b55992f added some Coverity comments to silence what was a real bug in the code. Since then, we've had a miserable run of trying to fix the underlying problem (commits c059cde and ba5193c), and still have a problem on 32-bit machines. This fixes the problem for once and for all, by realizing that on older xen, cpumap_t is identical to uint64_t, and using the new virendian.h to do the transformation from the API (documented to be little-endian) to the host structure. * src/xen/xen_hypervisor.c (virXen_setvcpumap): Do the conversion correctly. Finally. --- src/xen/xen_hypervisor.c | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/src/xen/xen_hypervisor.c b/src/xen/xen_hypervisor.c index 9b7dd2e..d803972 100644 --- a/src/xen/xen_hypervisor.c +++ b/src/xen/xen_hypervisor.c @@ -80,6 +80,7 @@ #include "virfile.h" #include "virnodesuspend.h" #include "virtypedparam.h" +#include "virendian.h" #define VIR_FROM_THIS VIR_FROM_XEN @@ -1773,18 +1774,13 @@ virXen_setvcpumap(int handle, ret = -1; } else { cpumap_t xen_cpumap; /* limited to 64 CPUs in old hypervisors */ - uint64_t *pm = &xen_cpumap; - int j; + char buf[8] = ""; - if ((maplen > (int)sizeof(cpumap_t)) || (sizeof(cpumap_t) & 7)) + if (maplen > sizeof(cpumap_t) || sizeof(cpumap_t) != sizeof(uint64_t)) return -1; - - memset(&xen_cpumap, 0, sizeof(cpumap_t)); - for (j = 0; j < maplen; j++) { - if ((j & 7) == 0) - pm = (uint64_t *)((uint64_t)&xen_cpumap + (j & ~0x7UL)); - *pm |= (uint64_t)cpumap[j] << (8 * (j & 7)); - } + /* Supply trailing 0s if user's input array was short */ + memcpy(buf, cpumap, maplen); + xen_cpumap = virReadBufInt64LE(buf); if (hv_versions.hypervisor == 1) { xen_op_v1 op; -- 1.8.1.2 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list