]> xenbits.xensource.com Git - people/sstabellini/xen-unstable.git/.git/commitdiff
libxl: allow copying between bitmaps of different sizes
authorWei Liu <wei.liu2@citrix.com>
Tue, 25 Nov 2014 10:59:47 +0000 (10:59 +0000)
committerIan Campbell <ian.campbell@citrix.com>
Fri, 28 Nov 2014 11:01:00 +0000 (11:01 +0000)
When parsing bitmap objects JSON parser will create libxl_bitmap map of the
smallest size needed.

This can cause problems when saved image file specifies CPU affinity.  For
example, if 'vcpu_hard_affinity' in the saved image has only the first CPU
specified, just a single byte will be allocated and libxl_bitmap->size will be
set to 1.

This will result in assertion in libxl_set_vcpuaffinity()->libxl_bitmap_copy()
since the destination bitmap is created for maximum number of CPUs.

We could allocate that bitmap of the same size as the source, however, it is
later passed to xc_vcpu_setaffinity() which expects it to be sized to the max
number of CPUs

To fix this issue, introduce an internal function to allowing copying between
bitmaps of different sizes. Note that this function is only used in
libxl_set_vcpuaffinity at the moment. Though NUMA placement logic invoke
libxl_bitmap_copy as well there's no need to replace those invocations.  NUMA
placement logic comes into effect when no vcpu / node pinning is provided, so
it always operates on bitmap of the same sizes (that is, size of maximum
number of cpus /nodes).

Reported-by: Boris Ostrovsky <boris.ostrovsky@oracle.com>
Signed-off-by: Wei Liu <wei.liu2@citrix.com>
Cc: Ian Campbell <ian.campbell@citrix.com>
Cc: Ian Jackson <ian.jackson@eu.citrix.com>
Cc: Dario Faggioli <dario.faggioli@citrix.com>
Reviewed-by: Dario Faggioli <dario.faggioli@citrix.com>
Tested-by: Boris Ostrovsky <boris.ostrovsky@oracle.com>
Acked-by: Ian Campbell <ian.campbell@citrix.com>
tools/libxl/libxl.c
tools/libxl/libxl_internal.h
tools/libxl/libxl_utils.c

index de23fec44a438431529f84bb744c26735517d075..1e9da1002be461d288621183b6666435464ccf0b 100644 (file)
@@ -5320,7 +5320,7 @@ int libxl_set_vcpuaffinity(libxl_ctx *ctx, uint32_t domid, uint32_t vcpuid,
         if (rc)
             goto out;
 
-        libxl_bitmap_copy(ctx, &hard, cpumap_hard);
+        libxl__bitmap_copy_best_effort(gc, &hard, cpumap_hard);
         flags = XEN_VCPUAFFINITY_HARD;
     }
     if (cpumap_soft) {
@@ -5328,7 +5328,7 @@ int libxl_set_vcpuaffinity(libxl_ctx *ctx, uint32_t domid, uint32_t vcpuid,
         if (rc)
             goto out;
 
-        libxl_bitmap_copy(ctx, &soft, cpumap_soft);
+        libxl__bitmap_copy_best_effort(gc, &soft, cpumap_soft);
         flags |= XEN_VCPUAFFINITY_SOFT;
     }
 
index 436142142101f4e2c07c52d8d836f578367a816b..a38f695751891d6e9e9aae1cf922dbce50285eaf 100644 (file)
@@ -3617,6 +3617,17 @@ static inline void libxl__update_config_vtpm(libxl__gc *gc,
         libxl_device_##type##_copy(CTX, DA_p, (dev));           \
     })
 
+/* This function copies X bytes from source to destination bitmap,
+ * where X is the smaller of the two sizes.
+ *
+ * If destination's size is larger than source, the extra bytes are
+ * untouched.
+ *
+ * XXX This is introduced to fix a regression for 4.5. It shall
+ * be revisited in 4.6 time frame.
+ */
+void libxl__bitmap_copy_best_effort(libxl__gc *gc, libxl_bitmap *dptr,
+                                    const libxl_bitmap *sptr);
 #endif
 
 /*
index 58df4f3b7e51d207b12c11af3b91654f7251f65d..3e1ba170bd15e84840c0b108ef23538b6ee727ef 100644 (file)
@@ -614,6 +614,21 @@ void libxl_bitmap_copy(libxl_ctx *ctx, libxl_bitmap *dptr,
     memcpy(dptr->map, sptr->map, sz * sizeof(*dptr->map));
 }
 
+/* This function copies X bytes from source to destination bitmap,
+ * where X is the smaller of the two sizes.
+ *
+ * If destination's size is larger than source, the extra bytes are
+ * untouched.
+ */
+void libxl__bitmap_copy_best_effort(libxl__gc *gc, libxl_bitmap *dptr,
+                                    const libxl_bitmap *sptr)
+{
+    int sz;
+
+    sz = dptr->size < sptr->size ? dptr->size : sptr->size;
+    memcpy(dptr->map, sptr->map, sz * sizeof(*dptr->map));
+}
+
 void libxl_bitmap_copy_alloc(libxl_ctx *ctx,
                              libxl_bitmap *dptr,
                              const libxl_bitmap *sptr)