aboutsummaryrefslogtreecommitdiffstats
path: root/tools/libxc/xc_dom_x86.c
diff options
context:
space:
mode:
authorKeir Fraser <keir.fraser@citrix.com>2009-05-26 09:58:38 +0100
committerKeir Fraser <keir.fraser@citrix.com>2009-05-26 09:58:38 +0100
commit6a9b5290e9d24efbc6271b4d7e80682b440c812e (patch)
treeb5ff5a8e6ab3e0fb38810b8b96434fc35ae18b26 /tools/libxc/xc_dom_x86.c
parent2cda4bd1e1a623b7c99bf2266dcb9ff82aa0f463 (diff)
downloadxen-6a9b5290e9d24efbc6271b4d7e80682b440c812e.tar.gz
xen-6a9b5290e9d24efbc6271b4d7e80682b440c812e.tar.bz2
xen-6a9b5290e9d24efbc6271b4d7e80682b440c812e.zip
Add support for superpages (hugepages) in PV domain
This patch adds the option "superpages" to the domain configuration file. If it is set, the domain is populated using 2M pages. This code does not support fallback to small pages. If the domain can not be created with 2M pages, the create will fail. The patch also includes support for saving and restoring domains with the superpage flag set. However, if a domain has freed small pages within its physical page array and then extended the array, the restore will fill in those freed pages. It will then attempt to allocate more than its memory limit and will fail. This is significant because apparently Linux does this during boot, thus a freshly booted Linux image can not be saved and restored successfully. Signed-off-by: Dave McCracken <dcm@mccr.org>
Diffstat (limited to 'tools/libxc/xc_dom_x86.c')
-rw-r--r--tools/libxc/xc_dom_x86.c55
1 files changed, 44 insertions, 11 deletions
diff --git a/tools/libxc/xc_dom_x86.c b/tools/libxc/xc_dom_x86.c
index 6ae9487656..a89eb4fef7 100644
--- a/tools/libxc/xc_dom_x86.c
+++ b/tools/libxc/xc_dom_x86.c
@@ -26,6 +26,9 @@
/* ------------------------------------------------------------------------ */
+#define SUPERPAGE_PFN_SHIFT 9
+#define SUPERPAGE_NR_PFNS (1UL << SUPERPAGE_PFN_SHIFT)
+
#define bits_to_mask(bits) (((xen_vaddr_t)1 << (bits))-1)
#define round_down(addr, mask) ((addr) & ~(mask))
#define round_up(addr, mask) ((addr) | (mask))
@@ -691,7 +694,7 @@ static int x86_shadow(int xc, domid_t domid)
return rc;
}
-int arch_setup_meminit(struct xc_dom_image *dom)
+int arch_setup_meminit(struct xc_dom_image *dom, int superpages)
{
int rc;
xen_pfn_t pfn, allocsz, i;
@@ -707,19 +710,49 @@ int arch_setup_meminit(struct xc_dom_image *dom)
return rc;
}
- /* setup initial p2m */
dom->p2m_host = xc_dom_malloc(dom, sizeof(xen_pfn_t) * dom->total_pages);
- for ( pfn = 0; pfn < dom->total_pages; pfn++ )
- dom->p2m_host[pfn] = pfn;
+ if (superpages)
+ {
+ int count = dom->total_pages >> SUPERPAGE_PFN_SHIFT;
+ xen_pfn_t extents[count];
+
+ xc_dom_printf("Populating memory with %d superpages\n", count);
+ for (pfn = 0; pfn < count; pfn++)
+ extents[pfn] = pfn << SUPERPAGE_PFN_SHIFT;
+ rc = xc_domain_memory_populate_physmap(dom->guest_xc, dom->guest_domid,
+ count, SUPERPAGE_PFN_SHIFT, 0,
+ extents);
+ if (!rc)
+ {
+ int i, j;
+ xen_pfn_t mfn;
- /* allocate guest memory */
- for ( i = rc = allocsz = 0; (i < dom->total_pages) && !rc; i += allocsz )
+ /* Expand the returned mfn into the p2m array */
+ pfn = 0;
+ for (i = 0; i < count; i++)
+ {
+ mfn = extents[i];
+ for (j = 0; j < SUPERPAGE_NR_PFNS; j++, pfn++)
+ {
+ dom->p2m_host[pfn] = mfn + j;
+ }
+ }
+ }
+ } else
{
- allocsz = dom->total_pages - i;
- if ( allocsz > 1024*1024 )
- allocsz = 1024*1024;
- rc = xc_domain_memory_populate_physmap(
- dom->guest_xc, dom->guest_domid, allocsz, 0, 0, &dom->p2m_host[i]);
+ /* setup initial p2m */
+ for ( pfn = 0; pfn < dom->total_pages; pfn++ )
+ dom->p2m_host[pfn] = pfn;
+
+ /* allocate guest memory */
+ for ( i = rc = allocsz = 0; (i < dom->total_pages) && !rc; i += allocsz )
+ {
+ allocsz = dom->total_pages - i;
+ if ( allocsz > 1024*1024 )
+ allocsz = 1024*1024;
+ rc = xc_domain_memory_populate_physmap(
+ dom->guest_xc, dom->guest_domid, allocsz, 0, 0, &dom->p2m_host[i]);
+ }
}
return rc;