Just like the kernel, the fallback implementation of xc_map_foreign_bulk() should clear the error indication array upon success. Also, a few allocations were needlessly using calloc() instead of malloc(). Finally, in xc_domain_save() allocate the error indicator array once (along with the other arrays) instead of using realloc() (without error checking) in the loop body. Signed-off-by: Jan Beulich --- 2010-01-06.orig/tools/libxc/xc_domain_save.c 2010-01-12 10:22:58.000000000 +0100 +++ 2010-01-06/tools/libxc/xc_domain_save.c 2010-01-22 08:33:52.000000000 +0100 @@ -1059,7 +1059,8 @@ int xc_domain_save(int xc_handle, int io pfn_type = xg_memalign(PAGE_SIZE, ROUNDUP( MAX_BATCH_SIZE * sizeof(*pfn_type), PAGE_SHIFT)); pfn_batch = calloc(MAX_BATCH_SIZE, sizeof(*pfn_batch)); - if ( (pfn_type == NULL) || (pfn_batch == NULL) ) + pfn_err = malloc(MAX_BATCH_SIZE * sizeof(*pfn_err)); + if ( (pfn_type == NULL) || (pfn_batch == NULL) || (pfn_err == NULL) ) { ERROR("failed to alloc memory for pfn_type and/or pfn_batch arrays"); errno = ENOMEM; @@ -1273,7 +1274,6 @@ int xc_domain_save(int xc_handle, int io if ( batch == 0 ) goto skip; /* vanishingly unlikely... */ - pfn_err = realloc(pfn_err, sizeof(int) * batch); region_base = xc_map_foreign_bulk( xc_handle, dom, PROT_READ, pfn_type, pfn_err, batch); if ( region_base == NULL ) --- 2010-01-06.orig/tools/libxc/xc_linux.c 2010-01-14 14:05:14.000000000 +0100 +++ 2010-01-06/tools/libxc/xc_linux.c 2010-01-22 08:38:41.000000000 +0100 @@ -186,7 +186,7 @@ void *xc_map_foreign_bulk(int xc_handle, * IOCTL_PRIVCMD_MMAPBATCH_V2 is not supported - fall back to * IOCTL_PRIVCMD_MMAPBATCH. */ - xen_pfn_t *pfn = calloc(num, sizeof(*pfn)); + xen_pfn_t *pfn = malloc(num * sizeof(*pfn)); if ( pfn ) { --- 2010-01-06.orig/tools/libxc/xc_misc.c 2010-01-08 15:38:59.000000000 +0100 +++ 2010-01-06/tools/libxc/xc_misc.c 2010-01-22 08:39:22.000000000 +0100 @@ -360,7 +360,7 @@ void *xc_map_foreign_pages(int xc_handle return NULL; } - err = calloc(num, sizeof(*err)); + err = malloc(num * sizeof(*err)); if (!err) return NULL; @@ -397,7 +397,7 @@ xc_map_foreign_bulk(int xc_handle, uint3 return NULL; } - pfn = calloc(num, sizeof(*pfn)); + pfn = malloc(num * sizeof(*pfn)); if (!pfn) { errno = ENOMEM; return NULL; @@ -416,7 +416,8 @@ xc_map_foreign_bulk(int xc_handle, uint3 err[i] = -EINVAL; break; } - } + } else + memset(err, 0, num * sizeof(*err)); free(pfn);