return err;
}
+static int xc_domain_memory_pod_target(int xc_handle,
+ int op,
+ uint32_t domid,
+ uint64_t target_pages,
+ uint64_t *tot_pages,
+ uint64_t *pod_cache_pages,
+ uint64_t *pod_entries)
+{
+ int err;
+
+ struct xen_pod_target pod_target = {
+ .domid = domid,
+ .target_pages = target_pages
+ };
+
+ err = xc_memory_op(xc_handle, op, &pod_target);
+
+ if ( err < 0 )
+ {
+ DPRINTF("Failed %s_memory_target dom %d\n",
+ (op==XENMEM_set_pod_target)?"set":"get",
+ domid);
+ errno = -err;
+ err = -1;
+ }
+ else
+ err = 0;
+
+ if ( tot_pages )
+ *tot_pages = pod_target.tot_pages;
+ if ( pod_cache_pages )
+ *pod_cache_pages = pod_target.pod_cache_pages;
+ if ( pod_entries )
+ *pod_entries = pod_target.pod_entries;
+
+ return err;
+}
+
+
+int xc_domain_memory_set_pod_target(int xc_handle,
+ uint32_t domid,
+ uint64_t target_pages,
+ uint64_t *tot_pages,
+ uint64_t *pod_cache_pages,
+ uint64_t *pod_entries)
+{
+ return xc_domain_memory_pod_target(xc_handle,
+ XENMEM_set_pod_target,
+ domid,
+ target_pages,
+ tot_pages,
+ pod_cache_pages,
+ pod_entries);
+}
+
+int xc_domain_memory_get_pod_target(int xc_handle,
+ uint32_t domid,
+ uint64_t *tot_pages,
+ uint64_t *pod_cache_pages,
+ uint64_t *pod_entries)
+{
+ return xc_domain_memory_pod_target(xc_handle,
+ XENMEM_get_pod_target,
+ domid,
+ -1,
+ tot_pages,
+ pod_cache_pages,
+ pod_entries);
+}
+
int xc_domain_max_vcpus(int xc_handle, uint32_t domid, unsigned int max)
{
DECLARE_DOMCTL;
}
static int setup_guest(int xc_handle,
- uint32_t dom, int memsize,
+ uint32_t dom, int memsize, int target,
char *image, unsigned long image_size)
{
xen_pfn_t *page_array = NULL;
unsigned long i, nr_pages = (unsigned long)memsize << (20 - PAGE_SHIFT);
+ unsigned long target_pages = (unsigned long)target << (20 - PAGE_SHIFT);
+ unsigned long pod_pages = 0;
unsigned long special_page_nr, entry_eip, cur_pages;
struct xen_add_to_physmap xatp;
struct shared_info *shared_info;
uint64_t v_start, v_end;
int rc;
xen_capabilities_info_t caps;
+ int pod_mode = 0;
+
/* An HVM guest must be initialised with at least 2MB memory. */
- if ( memsize < 2 )
+ if ( memsize < 2 || target < 2 )
goto error_out;
+ if ( memsize > target )
+ pod_mode = 1;
+
if ( elf_init(&elf, image, image_size) != 0 )
goto error_out;
elf_parse_binary(&elf);
.extent_order = SUPERPAGE_PFN_SHIFT,
.domid = dom
};
+
+ if ( pod_mode )
+ sp_req.mem_flags = XENMEMF_populate_on_demand;
+
set_xen_guest_handle(sp_req.extent_start, sp_extents);
for ( i = 0; i < sp_req.nr_extents; i++ )
sp_extents[i] = page_array[cur_pages+(i<<SUPERPAGE_PFN_SHIFT)];
if ( done > 0 )
{
done <<= SUPERPAGE_PFN_SHIFT;
+ if ( pod_mode && target_pages > cur_pages )
+ {
+ int d = target_pages - cur_pages;
+ pod_pages += ( done < d ) ? done : d;
+ }
cur_pages += done;
count -= done;
}
rc = xc_domain_memory_populate_physmap(
xc_handle, dom, count, 0, 0, &page_array[cur_pages]);
cur_pages += count;
+ if ( pod_mode )
+ pod_pages -= count;
}
}
+ if ( pod_mode )
+ rc = xc_domain_memory_set_pod_target(xc_handle,
+ dom,
+ pod_pages,
+ NULL, NULL, NULL);
+
if ( rc != 0 )
{
PERROR("Could not allocate memory for HVM guest.\n");
static int xc_hvm_build_internal(int xc_handle,
uint32_t domid,
int memsize,
+ int target,
char *image,
unsigned long image_size)
{
return -1;
}
- return setup_guest(xc_handle, domid, memsize, image, image_size);
+ return setup_guest(xc_handle, domid, memsize, target, image, image_size);
}
static inline int is_loadable_phdr(Elf32_Phdr *phdr)
((image = xc_read_image(image_name, &image_size)) == NULL) )
return -1;
- sts = xc_hvm_build_internal(xc_handle, domid, memsize, image, image_size);
+ sts = xc_hvm_build_internal(xc_handle, domid, memsize, memsize, image, image_size);
+
+ free(image);
+
+ return sts;
+}
+
+/* xc_hvm_build_target_mem:
+ * Create a domain for a pre-ballooned virtualized Linux, using
+ * files/filenames. If target < memsize, domain is created with
+ * memsize pages marked populate-on-demand, and with a PoD cache size
+ * of target. If target == memsize, pages are populated normally.
+ */
+int xc_hvm_build_target_mem(int xc_handle,
+ uint32_t domid,
+ int memsize,
+ int target,
+ const char *image_name)
+{
+ char *image;
+ int sts;
+ unsigned long image_size;
+
+ if ( (image_name == NULL) ||
+ ((image = xc_read_image(image_name, &image_size)) == NULL) )
+ return -1;
+
+ sts = xc_hvm_build_internal(xc_handle, domid, memsize, target, image, image_size);
free(image);
return -1;
}
- sts = xc_hvm_build_internal(xc_handle, domid, memsize,
+ sts = xc_hvm_build_internal(xc_handle, domid, memsize, memsize,
img, img_len);
/* xc_inflate_buffer may return the original buffer pointer (for