ia64/xen-unstable

changeset 19639:205b1badbcfd

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>
author Keir Fraser <keir.fraser@citrix.com>
date Tue May 26 09:58:38 2009 +0100 (2009-05-26)
parents 9535ef2be909
children cc682927d123
files tools/libxc/xc_dom.h tools/libxc/xc_dom_boot.c tools/libxc/xc_dom_compat_linux.c tools/libxc/xc_dom_ia64.c tools/libxc/xc_dom_x86.c tools/libxc/xc_domain_restore.c tools/libxc/xenguest.h tools/python/xen/lowlevel/xc/xc.c tools/python/xen/xend/XendCheckpoint.py tools/python/xen/xend/XendConfig.py tools/python/xen/xend/image.py tools/python/xen/xm/create.dtd tools/python/xen/xm/create.py tools/python/xen/xm/xenapi_create.py tools/xcutils/xc_restore.c
line diff
     1.1 --- a/tools/libxc/xc_dom.h	Tue May 26 09:54:53 2009 +0100
     1.2 +++ b/tools/libxc/xc_dom.h	Tue May 26 09:58:38 2009 +0100
     1.3 @@ -174,7 +174,7 @@ int xc_dom_build_image(struct xc_dom_ima
     1.4  int xc_dom_update_guest_p2m(struct xc_dom_image *dom);
     1.5  
     1.6  int xc_dom_boot_xen_init(struct xc_dom_image *dom, int xc, domid_t domid);
     1.7 -int xc_dom_boot_mem_init(struct xc_dom_image *dom);
     1.8 +int xc_dom_boot_mem_init(struct xc_dom_image *dom, int superpages);
     1.9  void *xc_dom_boot_domU_map(struct xc_dom_image *dom, xen_pfn_t pfn,
    1.10                             xen_pfn_t count);
    1.11  int xc_dom_boot_image(struct xc_dom_image *dom);
    1.12 @@ -260,7 +260,7 @@ static inline xen_pfn_t xc_dom_p2m_guest
    1.13  
    1.14  /* --- arch bits --------------------------------------------------- */
    1.15  
    1.16 -int arch_setup_meminit(struct xc_dom_image *dom);
    1.17 +int arch_setup_meminit(struct xc_dom_image *dom, int superpages);
    1.18  int arch_setup_bootearly(struct xc_dom_image *dom);
    1.19  int arch_setup_bootlate(struct xc_dom_image *dom);
    1.20  
     2.1 --- a/tools/libxc/xc_dom_boot.c	Tue May 26 09:54:53 2009 +0100
     2.2 +++ b/tools/libxc/xc_dom_boot.c	Tue May 26 09:58:38 2009 +0100
     2.3 @@ -129,13 +129,13 @@ int xc_dom_boot_xen_init(struct xc_dom_i
     2.4      return 0;
     2.5  }
     2.6  
     2.7 -int xc_dom_boot_mem_init(struct xc_dom_image *dom)
     2.8 +int xc_dom_boot_mem_init(struct xc_dom_image *dom, int superpages)
     2.9  {
    2.10      long rc;
    2.11  
    2.12      xc_dom_printf("%s: called\n", __FUNCTION__);
    2.13  
    2.14 -    rc = arch_setup_meminit(dom);
    2.15 +    rc = arch_setup_meminit(dom, superpages);
    2.16      if ( rc != 0 )
    2.17      {
    2.18          xc_dom_panic(XC_OUT_OF_MEMORY,
     3.1 --- a/tools/libxc/xc_dom_compat_linux.c	Tue May 26 09:54:53 2009 +0100
     3.2 +++ b/tools/libxc/xc_dom_compat_linux.c	Tue May 26 09:58:38 2009 +0100
     3.3 @@ -28,7 +28,8 @@ static int xc_linux_build_internal(struc
     3.4                                     unsigned int store_evtchn,
     3.5                                     unsigned long *store_mfn,
     3.6                                     unsigned int console_evtchn,
     3.7 -                                   unsigned long *console_mfn)
     3.8 +                                   unsigned long *console_mfn,
     3.9 +    							   int superpages)
    3.10  {
    3.11      int rc;
    3.12  
    3.13 @@ -42,7 +43,7 @@ static int xc_linux_build_internal(struc
    3.14          goto out;
    3.15      if ( (rc = xc_dom_mem_init(dom, mem_mb)) != 0 )
    3.16          goto out;
    3.17 -    if ( (rc = xc_dom_boot_mem_init(dom)) != 0 )
    3.18 +    if ( (rc = xc_dom_boot_mem_init(dom, superpages)) != 0 )
    3.19          goto out;
    3.20      if ( (rc = xc_dom_build_image(dom)) != 0 )
    3.21          goto out;
    3.22 @@ -67,7 +68,8 @@ int xc_linux_build_mem(int xc_handle, ui
    3.23                         unsigned long flags,
    3.24                         unsigned int store_evtchn,
    3.25                         unsigned long *store_mfn,
    3.26 -                       unsigned int console_evtchn, unsigned long *console_mfn)
    3.27 +                       unsigned int console_evtchn, unsigned long *console_mfn,
    3.28 +                       int superpages)
    3.29  {
    3.30      struct xc_dom_image *dom;
    3.31      int rc;
    3.32 @@ -82,7 +84,7 @@ int xc_linux_build_mem(int xc_handle, ui
    3.33      rc = xc_linux_build_internal(dom, xc_handle, domid,
    3.34                                   mem_mb, flags,
    3.35                                   store_evtchn, store_mfn,
    3.36 -                                 console_evtchn, console_mfn);
    3.37 +                                 console_evtchn, console_mfn, superpages);
    3.38  
    3.39   out:
    3.40      xc_dom_release(dom);
    3.41 @@ -98,7 +100,8 @@ int xc_linux_build(int xc_handle, uint32
    3.42                     unsigned long flags,
    3.43                     unsigned int store_evtchn,
    3.44                     unsigned long *store_mfn,
    3.45 -                   unsigned int console_evtchn, unsigned long *console_mfn)
    3.46 +                   unsigned int console_evtchn, unsigned long *console_mfn,
    3.47 +                   int superpages)
    3.48  {
    3.49      struct xc_dom_image *dom;
    3.50      int rc;
    3.51 @@ -114,7 +117,7 @@ int xc_linux_build(int xc_handle, uint32
    3.52      rc = xc_linux_build_internal(dom, xc_handle, domid,
    3.53                                   mem_mb, flags,
    3.54                                   store_evtchn, store_mfn,
    3.55 -                                 console_evtchn, console_mfn);
    3.56 +                                 console_evtchn, console_mfn, superpages);
    3.57  
    3.58   out:
    3.59      xc_dom_release(dom);
    3.60 @@ -130,7 +133,8 @@ int xc_dom_linux_build(int xc_handle,
    3.61                         unsigned long flags,
    3.62                         unsigned int store_evtchn,
    3.63                         unsigned long *store_mfn,
    3.64 -                       unsigned int console_evtchn, unsigned long *console_mfn)
    3.65 +                       unsigned int console_evtchn, unsigned long *console_mfn,
    3.66 +                       int superpages)
    3.67  {
    3.68      int rc;
    3.69  
    3.70 @@ -143,7 +147,7 @@ int xc_dom_linux_build(int xc_handle,
    3.71      return xc_linux_build_internal(dom, xc_handle, domid,
    3.72                                     mem_mb, flags,
    3.73                                     store_evtchn, store_mfn,
    3.74 -                                   console_evtchn, console_mfn);
    3.75 +                                   console_evtchn, console_mfn, superpages);
    3.76  }
    3.77  
    3.78  /*
     4.1 --- a/tools/libxc/xc_dom_ia64.c	Tue May 26 09:54:53 2009 +0100
     4.2 +++ b/tools/libxc/xc_dom_ia64.c	Tue May 26 09:58:38 2009 +0100
     4.3 @@ -149,7 +149,7 @@ static void __init register_arch_hooks(v
     4.4  
     4.5  #include "xc_efi.h"
     4.6  
     4.7 -int arch_setup_meminit(struct xc_dom_image *dom)
     4.8 +int arch_setup_meminit(struct xc_dom_image *dom, int superpages)
     4.9  {
    4.10      xen_pfn_t pfn;
    4.11      int rc;
     5.1 --- a/tools/libxc/xc_dom_x86.c	Tue May 26 09:54:53 2009 +0100
     5.2 +++ b/tools/libxc/xc_dom_x86.c	Tue May 26 09:58:38 2009 +0100
     5.3 @@ -26,6 +26,9 @@
     5.4  
     5.5  /* ------------------------------------------------------------------------ */
     5.6  
     5.7 +#define SUPERPAGE_PFN_SHIFT  9
     5.8 +#define SUPERPAGE_NR_PFNS    (1UL << SUPERPAGE_PFN_SHIFT)
     5.9 +
    5.10  #define bits_to_mask(bits)       (((xen_vaddr_t)1 << (bits))-1)
    5.11  #define round_down(addr, mask)   ((addr) & ~(mask))
    5.12  #define round_up(addr, mask)     ((addr) | (mask))
    5.13 @@ -691,7 +694,7 @@ static int x86_shadow(int xc, domid_t do
    5.14      return rc;
    5.15  }
    5.16  
    5.17 -int arch_setup_meminit(struct xc_dom_image *dom)
    5.18 +int arch_setup_meminit(struct xc_dom_image *dom, int superpages)
    5.19  {
    5.20      int rc;
    5.21      xen_pfn_t pfn, allocsz, i;
    5.22 @@ -707,19 +710,49 @@ int arch_setup_meminit(struct xc_dom_ima
    5.23              return rc;
    5.24      }
    5.25  
    5.26 -    /* setup initial p2m */
    5.27      dom->p2m_host = xc_dom_malloc(dom, sizeof(xen_pfn_t) * dom->total_pages);
    5.28 -    for ( pfn = 0; pfn < dom->total_pages; pfn++ )
    5.29 -        dom->p2m_host[pfn] = pfn;
    5.30 +    if (superpages)
    5.31 +    {
    5.32 +        int count = dom->total_pages >> SUPERPAGE_PFN_SHIFT;
    5.33 +        xen_pfn_t extents[count];
    5.34  
    5.35 -    /* allocate guest memory */
    5.36 -    for ( i = rc = allocsz = 0; (i < dom->total_pages) && !rc; i += allocsz )
    5.37 +        xc_dom_printf("Populating memory with %d superpages\n", count);
    5.38 +        for (pfn = 0; pfn < count; pfn++)
    5.39 +            extents[pfn] = pfn << SUPERPAGE_PFN_SHIFT;
    5.40 +        rc = xc_domain_memory_populate_physmap(dom->guest_xc, dom->guest_domid,
    5.41 +                                               count, SUPERPAGE_PFN_SHIFT, 0,
    5.42 +                                               extents);
    5.43 +        if (!rc)
    5.44 +        {
    5.45 +            int i, j;
    5.46 +            xen_pfn_t mfn;
    5.47 +
    5.48 +            /* Expand the returned mfn into the p2m array */
    5.49 +            pfn = 0;
    5.50 +            for (i = 0; i < count; i++)
    5.51 +            {
    5.52 +                mfn = extents[i];
    5.53 +                for (j = 0; j < SUPERPAGE_NR_PFNS; j++, pfn++)
    5.54 +                {
    5.55 +                    dom->p2m_host[pfn] = mfn + j;
    5.56 +                }
    5.57 +            }
    5.58 +        }
    5.59 +    } else
    5.60      {
    5.61 -        allocsz = dom->total_pages - i;
    5.62 -        if ( allocsz > 1024*1024 )
    5.63 -            allocsz = 1024*1024;
    5.64 -        rc = xc_domain_memory_populate_physmap(
    5.65 -            dom->guest_xc, dom->guest_domid, allocsz, 0, 0, &dom->p2m_host[i]);
    5.66 +        /* setup initial p2m */
    5.67 +        for ( pfn = 0; pfn < dom->total_pages; pfn++ )
    5.68 +            dom->p2m_host[pfn] = pfn;
    5.69 +        
    5.70 +        /* allocate guest memory */
    5.71 +        for ( i = rc = allocsz = 0; (i < dom->total_pages) && !rc; i += allocsz )
    5.72 +        {
    5.73 +            allocsz = dom->total_pages - i;
    5.74 +            if ( allocsz > 1024*1024 )
    5.75 +                allocsz = 1024*1024;
    5.76 +            rc = xc_domain_memory_populate_physmap(
    5.77 +                dom->guest_xc, dom->guest_domid, allocsz, 0, 0, &dom->p2m_host[i]);
    5.78 +        }
    5.79      }
    5.80  
    5.81      return rc;
     6.1 --- a/tools/libxc/xc_domain_restore.c	Tue May 26 09:54:53 2009 +0100
     6.2 +++ b/tools/libxc/xc_domain_restore.c	Tue May 26 09:58:38 2009 +0100
     6.3 @@ -53,13 +53,94 @@ static xen_pfn_t *live_p2m = NULL;
     6.4  /* A table mapping each PFN to its new MFN. */
     6.5  static xen_pfn_t *p2m = NULL;
     6.6  
     6.7 -/* A table of P2M mappings in the current region */
     6.8 -static xen_pfn_t *p2m_batch = NULL;
     6.9 -
    6.10  /* Address size of the guest, in bytes */
    6.11  unsigned int guest_width;
    6.12  
    6.13  /*
    6.14 +**
    6.15 +**
    6.16 +*/
    6.17 +#define SUPERPAGE_PFN_SHIFT  9
    6.18 +#define SUPERPAGE_NR_PFNS    (1UL << SUPERPAGE_PFN_SHIFT)
    6.19 +
    6.20 +static int allocate_mfn(int xc_handle, uint32_t dom, unsigned long pfn, int superpages)
    6.21 +{
    6.22 +    unsigned long mfn;
    6.23 +
    6.24 +    if (superpages)
    6.25 +    {
    6.26 +        unsigned long base_pfn;
    6.27 +
    6.28 +        base_pfn = pfn & ~(SUPERPAGE_NR_PFNS-1);
    6.29 +        mfn = base_pfn;
    6.30 +
    6.31 +        if (xc_domain_memory_populate_physmap(xc_handle, dom, 1,
    6.32 +                                              SUPERPAGE_PFN_SHIFT, 0, &mfn) != 0)
    6.33 +        {
    6.34 +            ERROR("Failed to allocate physical memory at pfn 0x%x, base 0x%x.\n", pfn, base_pfn); 
    6.35 +            errno = ENOMEM;
    6.36 +            return 1;
    6.37 +        }
    6.38 +        for (pfn = base_pfn; pfn < base_pfn + SUPERPAGE_NR_PFNS; pfn++, mfn++)
    6.39 +        {
    6.40 +            p2m[pfn] = mfn;
    6.41 +        }
    6.42 +    }
    6.43 +    else
    6.44 +    {
    6.45 +        mfn = pfn;
    6.46 +        if (xc_domain_memory_populate_physmap(xc_handle, dom, 1, 0,
    6.47 +                                              0, &mfn) != 0)
    6.48 +        {
    6.49 +            ERROR("Failed to allocate physical memory.!\n"); 
    6.50 +            errno = ENOMEM;
    6.51 +            return 1;
    6.52 +        }
    6.53 +        p2m[pfn] = mfn;
    6.54 +    }
    6.55 +    return 0;
    6.56 +}
    6.57 +
    6.58 +static int allocate_physmem(int xc_handle, uint32_t dom,
    6.59 +                            unsigned long *region_pfn_type, int region_size,
    6.60 +                            unsigned int hvm, xen_pfn_t *region_mfn, int superpages)
    6.61 +{
    6.62 +	int i;
    6.63 +    unsigned long pfn;
    6.64 +    unsigned long pagetype;
    6.65 +
    6.66 +    for (i = 0; i < region_size; i++)
    6.67 +    {
    6.68 +        pfn      = region_pfn_type[i] & ~XEN_DOMCTL_PFINFO_LTAB_MASK;
    6.69 +        pagetype = region_pfn_type[i] &  XEN_DOMCTL_PFINFO_LTAB_MASK;
    6.70 +
    6.71 +        if ( pfn > p2m_size )
    6.72 +        {
    6.73 +            ERROR("pfn out of range");
    6.74 +            return 1;
    6.75 +        }
    6.76 +        if (pagetype == XEN_DOMCTL_PFINFO_XTAB)
    6.77 +        {
    6.78 +            region_mfn[i] = ~0UL;
    6.79 +        }
    6.80 +        else 
    6.81 +        {
    6.82 +            if (p2m[pfn] == INVALID_P2M_ENTRY)
    6.83 +            {
    6.84 +                if (allocate_mfn(xc_handle, dom, pfn, superpages) != 0)
    6.85 +                    return 1;
    6.86 +            }
    6.87 +
    6.88 +            /* setup region_mfn[] for batch map.
    6.89 +             * For HVM guests, this interface takes PFNs, not MFNs */
    6.90 +            region_mfn[i] = hvm ? pfn : p2m[pfn]; 
    6.91 +        }
    6.92 +    }
    6.93 +    return 0;
    6.94 +}
    6.95 +
    6.96 +
    6.97 +/*
    6.98  ** In the state file (or during transfer), all page-table pages are
    6.99  ** converted into a 'canonical' form where references to actual mfns
   6.100  ** are replaced with references to the corresponding pfns.
   6.101 @@ -67,58 +148,14 @@ unsigned int guest_width;
   6.102  ** the (now known) appropriate mfn values.
   6.103  */
   6.104  static int uncanonicalize_pagetable(int xc_handle, uint32_t dom, 
   6.105 -                                    unsigned long type, void *page)
   6.106 +                                    unsigned long type, void *page, int superpages)
   6.107  {
   6.108      int i, pte_last;
   6.109      unsigned long pfn;
   6.110      uint64_t pte;
   6.111 -    int nr_mfns = 0; 
   6.112  
   6.113      pte_last = PAGE_SIZE / ((pt_levels == 2)? 4 : 8);
   6.114  
   6.115 -    /* First pass: work out how many (if any) MFNs we need to alloc */
   6.116 -    for ( i = 0; i < pte_last; i++ )
   6.117 -    {
   6.118 -        if ( pt_levels == 2 )
   6.119 -            pte = ((uint32_t *)page)[i];
   6.120 -        else
   6.121 -            pte = ((uint64_t *)page)[i];
   6.122 -
   6.123 -        /* XXX SMH: below needs fixing for PROT_NONE etc */
   6.124 -        if ( !(pte & _PAGE_PRESENT) )
   6.125 -            continue;
   6.126 -        
   6.127 -        pfn = (pte >> PAGE_SHIFT) & MFN_MASK_X86;
   6.128 -        
   6.129 -        if ( pfn >= p2m_size )
   6.130 -        {
   6.131 -            /* This "page table page" is probably not one; bail. */
   6.132 -            ERROR("Frame number in type %lu page table is out of range: "
   6.133 -                  "i=%d pfn=0x%lx p2m_size=%lu",
   6.134 -                  type >> 28, i, pfn, p2m_size);
   6.135 -            return 0;
   6.136 -        }
   6.137 -        
   6.138 -        if ( p2m[pfn] == INVALID_P2M_ENTRY )
   6.139 -        {
   6.140 -            /* Have a 'valid' PFN without a matching MFN - need to alloc */
   6.141 -            p2m_batch[nr_mfns++] = pfn; 
   6.142 -            p2m[pfn]--;
   6.143 -        }
   6.144 -    }
   6.145 -
   6.146 -    /* Allocate the requisite number of mfns. */
   6.147 -    if ( nr_mfns &&
   6.148 -         (xc_domain_memory_populate_physmap(xc_handle, dom, nr_mfns, 0, 0,
   6.149 -                                            p2m_batch) != 0) )
   6.150 -    { 
   6.151 -        ERROR("Failed to allocate memory for batch.!\n"); 
   6.152 -        errno = ENOMEM;
   6.153 -        return 0; 
   6.154 -    }
   6.155 -    
   6.156 -    /* Second pass: uncanonicalize each present PTE */
   6.157 -    nr_mfns = 0;
   6.158      for ( i = 0; i < pte_last; i++ )
   6.159      {
   6.160          if ( pt_levels == 2 )
   6.161 @@ -132,9 +169,12 @@ static int uncanonicalize_pagetable(int 
   6.162          
   6.163          pfn = (pte >> PAGE_SHIFT) & MFN_MASK_X86;
   6.164  
   6.165 -        if ( p2m[pfn] == (INVALID_P2M_ENTRY-1) )
   6.166 -            p2m[pfn] = p2m_batch[nr_mfns++];
   6.167 -
   6.168 +        /* Allocate mfn if necessary */
   6.169 +        if ( p2m[pfn] == INVALID_P2M_ENTRY )
   6.170 +        {
   6.171 +            if (allocate_mfn(xc_handle, dom, pfn, superpages) != 0)
   6.172 +                return 0;
   6.173 +        }
   6.174          pte &= ~MADDR_MASK_X86;
   6.175          pte |= (uint64_t)p2m[pfn] << PAGE_SHIFT;
   6.176  
   6.177 @@ -272,7 +312,7 @@ static xen_pfn_t *load_p2m_frame_list(
   6.178  int xc_domain_restore(int xc_handle, int io_fd, uint32_t dom,
   6.179                        unsigned int store_evtchn, unsigned long *store_mfn,
   6.180                        unsigned int console_evtchn, unsigned long *console_mfn,
   6.181 -                      unsigned int hvm, unsigned int pae)
   6.182 +                      unsigned int hvm, unsigned int pae, int superpages)
   6.183  {
   6.184      DECLARE_DOMCTL;
   6.185      int rc = 1, frc, i, j, n, m, pae_extended_cr3 = 0, ext_vcpucontext = 0;
   6.186 @@ -377,11 +417,9 @@ int xc_domain_restore(int xc_handle, int
   6.187  
   6.188      region_mfn = xg_memalign(PAGE_SIZE, ROUNDUP(
   6.189                                MAX_BATCH_SIZE * sizeof(xen_pfn_t), PAGE_SHIFT));
   6.190 -    p2m_batch  = xg_memalign(PAGE_SIZE, ROUNDUP(
   6.191 -                              MAX_BATCH_SIZE * sizeof(xen_pfn_t), PAGE_SHIFT));
   6.192  
   6.193      if ( (p2m == NULL) || (pfn_type == NULL) ||
   6.194 -         (region_mfn == NULL) || (p2m_batch == NULL) )
   6.195 +         (region_mfn == NULL) )
   6.196      {
   6.197          ERROR("memory alloc failed");
   6.198          errno = ENOMEM;
   6.199 @@ -390,8 +428,6 @@ int xc_domain_restore(int xc_handle, int
   6.200  
   6.201      memset(region_mfn, 0,
   6.202             ROUNDUP(MAX_BATCH_SIZE * sizeof(xen_pfn_t), PAGE_SHIFT)); 
   6.203 -    memset(p2m_batch, 0,
   6.204 -           ROUNDUP(MAX_BATCH_SIZE * sizeof(xen_pfn_t), PAGE_SHIFT)); 
   6.205  
   6.206      if ( lock_pages(region_mfn, sizeof(xen_pfn_t) * MAX_BATCH_SIZE) )
   6.207      {
   6.208 @@ -399,12 +435,6 @@ int xc_domain_restore(int xc_handle, int
   6.209          goto out;
   6.210      }
   6.211  
   6.212 -    if ( lock_pages(p2m_batch, sizeof(xen_pfn_t) * MAX_BATCH_SIZE) )
   6.213 -    {
   6.214 -        ERROR("Could not lock p2m_batch");
   6.215 -        goto out;
   6.216 -    }
   6.217 -
   6.218      /* Get the domain's shared-info frame. */
   6.219      domctl.cmd = XEN_DOMCTL_getdomaininfo;
   6.220      domctl.domain = (domid_t)dom;
   6.221 @@ -437,7 +467,7 @@ int xc_domain_restore(int xc_handle, int
   6.222      n = m = 0;
   6.223      for ( ; ; )
   6.224      {
   6.225 -        int j, nr_mfns = 0; 
   6.226 +        int j; 
   6.227  
   6.228          this_pc = (n * 100) / p2m_size;
   6.229          if ( (this_pc - prev_pc) >= 5 )
   6.230 @@ -521,57 +551,9 @@ int xc_domain_restore(int xc_handle, int
   6.231              goto out;
   6.232          }
   6.233  
   6.234 -        /* First pass for this batch: work out how much memory to alloc */
   6.235 -        nr_mfns = 0; 
   6.236 -        for ( i = 0; i < j; i++ )
   6.237 -        {
   6.238 -            unsigned long pfn, pagetype;
   6.239 -            pfn      = region_pfn_type[i] & ~XEN_DOMCTL_PFINFO_LTAB_MASK;
   6.240 -            pagetype = region_pfn_type[i] &  XEN_DOMCTL_PFINFO_LTAB_MASK;
   6.241 -
   6.242 -            if ( (pagetype != XEN_DOMCTL_PFINFO_XTAB) && 
   6.243 -                 (p2m[pfn] == INVALID_P2M_ENTRY) )
   6.244 -            {
   6.245 -                /* Have a live PFN which hasn't had an MFN allocated */
   6.246 -                p2m_batch[nr_mfns++] = pfn; 
   6.247 -                p2m[pfn]--;
   6.248 -            }
   6.249 -        } 
   6.250 -
   6.251 -        /* Now allocate a bunch of mfns for this batch */
   6.252 -        if ( nr_mfns &&
   6.253 -             (xc_domain_memory_populate_physmap(xc_handle, dom, nr_mfns, 0,
   6.254 -                                                0, p2m_batch) != 0) )
   6.255 -        { 
   6.256 -            ERROR("Failed to allocate memory for batch.!\n"); 
   6.257 -            errno = ENOMEM;
   6.258 +        if (allocate_physmem(xc_handle, dom, region_pfn_type,
   6.259 +                             j, hvm, region_mfn, superpages) != 0)
   6.260              goto out;
   6.261 -        }
   6.262 -
   6.263 -        /* Second pass for this batch: update p2m[] and region_mfn[] */
   6.264 -        nr_mfns = 0; 
   6.265 -        for ( i = 0; i < j; i++ )
   6.266 -        {
   6.267 -            unsigned long pfn, pagetype;
   6.268 -            pfn      = region_pfn_type[i] & ~XEN_DOMCTL_PFINFO_LTAB_MASK;
   6.269 -            pagetype = region_pfn_type[i] &  XEN_DOMCTL_PFINFO_LTAB_MASK;
   6.270 -
   6.271 -            if ( pagetype == XEN_DOMCTL_PFINFO_XTAB )
   6.272 -                region_mfn[i] = ~0UL; /* map will fail but we don't care */
   6.273 -            else 
   6.274 -            {
   6.275 -                if ( p2m[pfn] == (INVALID_P2M_ENTRY-1) )
   6.276 -                {
   6.277 -                    /* We just allocated a new mfn above; update p2m */
   6.278 -                    p2m[pfn] = p2m_batch[nr_mfns++]; 
   6.279 -                    nr_pfns++; 
   6.280 -                }
   6.281 -
   6.282 -                /* setup region_mfn[] for batch map.
   6.283 -                 * For HVM guests, this interface takes PFNs, not MFNs */
   6.284 -                region_mfn[i] = hvm ? pfn : p2m[pfn]; 
   6.285 -            }
   6.286 -        } 
   6.287  
   6.288          /* Map relevant mfns */
   6.289          region_base = xc_map_foreign_batch(
   6.290 @@ -633,7 +615,7 @@ int xc_domain_restore(int xc_handle, int
   6.291                      (pagetype != XEN_DOMCTL_PFINFO_L1TAB)) {
   6.292  
   6.293                      if (!uncanonicalize_pagetable(xc_handle, dom, 
   6.294 -                                                  pagetype, page)) {
   6.295 +                                                  pagetype, page, superpages)) {
   6.296                          /*
   6.297                          ** Failing to uncanonicalize a page table can be ok
   6.298                          ** under live migration since the pages type may have
   6.299 @@ -875,7 +857,7 @@ int xc_domain_restore(int xc_handle, int
   6.300                  {
   6.301                      if ( !uncanonicalize_pagetable(
   6.302                          xc_handle, dom, XEN_DOMCTL_PFINFO_L1TAB,
   6.303 -                        region_base + k*PAGE_SIZE) )
   6.304 +                        region_base + k*PAGE_SIZE, superpages) )
   6.305                      {
   6.306                          ERROR("failed uncanonicalize pt!");
   6.307                          goto out;
   6.308 @@ -1223,3 +1205,12 @@ int xc_domain_restore(int xc_handle, int
   6.309      
   6.310      return rc;
   6.311  }
   6.312 +/*
   6.313 + * Local variables:
   6.314 + * mode: C
   6.315 + * c-set-style: "BSD"
   6.316 + * c-basic-offset: 4
   6.317 + * tab-width: 4
   6.318 + * indent-tabs-mode: nil
   6.319 + * End:
   6.320 + */
     7.1 --- a/tools/libxc/xenguest.h	Tue May 26 09:54:53 2009 +0100
     7.2 +++ b/tools/libxc/xenguest.h	Tue May 26 09:58:38 2009 +0100
     7.3 @@ -40,12 +40,13 @@ int xc_domain_save(int xc_handle, int io
     7.4   * @parm store_mfn returned with the mfn of the store page
     7.5   * @parm hvm non-zero if this is a HVM restore
     7.6   * @parm pae non-zero if this HVM domain has PAE support enabled
     7.7 + * @parm superpages non-zero to allocate guest memory with superpages
     7.8   * @return 0 on success, -1 on failure
     7.9   */
    7.10  int xc_domain_restore(int xc_handle, int io_fd, uint32_t dom,
    7.11                        unsigned int store_evtchn, unsigned long *store_mfn,
    7.12                        unsigned int console_evtchn, unsigned long *console_mfn,
    7.13 -                      unsigned int hvm, unsigned int pae);
    7.14 +                      unsigned int hvm, unsigned int pae, int superpages);
    7.15  
    7.16  /**
    7.17   * This function will create a domain for a paravirtualized Linux
    7.18 @@ -62,6 +63,7 @@ int xc_domain_restore(int xc_handle, int
    7.19   * @parm store_mfn returned with the mfn of the store page
    7.20   * @parm console_evtchn the console event channel for this domain to use
    7.21   * @parm conole_mfn returned with the mfn of the console page
    7.22 + * @parm superpages populate memory in guest with superpages
    7.23   * @return 0 on success, -1 on failure
    7.24   */
    7.25  int xc_linux_build(int xc_handle,
    7.26 @@ -75,7 +77,8 @@ int xc_linux_build(int xc_handle,
    7.27                     unsigned int store_evtchn,
    7.28                     unsigned long *store_mfn,
    7.29                     unsigned int console_evtchn,
    7.30 -                   unsigned long *console_mfn);
    7.31 +                   unsigned long *console_mfn,
    7.32 +	           int superpages);
    7.33  
    7.34  /** The same interface, but the dom structure is managed by the caller */
    7.35  struct xc_dom_image;
    7.36 @@ -89,7 +92,8 @@ int xc_dom_linux_build(int xc_handle,
    7.37  		       unsigned int store_evtchn,
    7.38  		       unsigned long *store_mfn,
    7.39  		       unsigned int console_evtchn,
    7.40 -		       unsigned long *console_mfn);
    7.41 +		       unsigned long *console_mfn,
    7.42 +                       int superpages);
    7.43  
    7.44  /**
    7.45   * This function will create a domain for a paravirtualized Linux
    7.46 @@ -108,6 +112,7 @@ int xc_dom_linux_build(int xc_handle,
    7.47   * @parm store_mfn returned with the mfn of the store page
    7.48   * @parm console_evtchn the console event channel for this domain to use
    7.49   * @parm conole_mfn returned with the mfn of the console page
    7.50 + * @parm superpages populate memory in guest with superpages
    7.51   * @return 0 on success, -1 on failure
    7.52   */
    7.53  int xc_linux_build_mem(int xc_handle,
    7.54 @@ -123,7 +128,8 @@ int xc_linux_build_mem(int xc_handle,
    7.55                         unsigned int store_evtchn,
    7.56                         unsigned long *store_mfn,
    7.57                         unsigned int console_evtchn,
    7.58 -                       unsigned long *console_mfn);
    7.59 +                       unsigned long *console_mfn,
    7.60 +                       int superpages);
    7.61  
    7.62  int xc_hvm_build(int xc_handle,
    7.63                   uint32_t domid,
     8.1 --- a/tools/python/xen/lowlevel/xc/xc.c	Tue May 26 09:54:53 2009 +0100
     8.2 +++ b/tools/python/xen/lowlevel/xc/xc.c	Tue May 26 09:58:38 2009 +0100
     8.3 @@ -405,6 +405,7 @@ static PyObject *pyxc_linux_build(XcObje
     8.4      int flags = 0;
     8.5      int store_evtchn, console_evtchn;
     8.6      int vhpt = 0;
     8.7 +    int superpages = 0;
     8.8      unsigned int mem_mb;
     8.9      unsigned long store_mfn = 0;
    8.10      unsigned long console_mfn = 0;
    8.11 @@ -417,14 +418,14 @@ static PyObject *pyxc_linux_build(XcObje
    8.12                                  "console_evtchn", "image",
    8.13                                  /* optional */
    8.14                                  "ramdisk", "cmdline", "flags",
    8.15 -                                "features", "vhpt", NULL };
    8.16 +                                "features", "vhpt", "superpages", NULL };
    8.17  
    8.18 -    if ( !PyArg_ParseTupleAndKeywords(args, kwds, "iiiis|ssisi", kwd_list,
    8.19 +    if ( !PyArg_ParseTupleAndKeywords(args, kwds, "iiiis|ssisii", kwd_list,
    8.20                                        &domid, &store_evtchn, &mem_mb,
    8.21                                        &console_evtchn, &image,
    8.22                                        /* optional */
    8.23                                        &ramdisk, &cmdline, &flags,
    8.24 -                                      &features, &vhpt) )
    8.25 +                                      &features, &vhpt, &superpages) )
    8.26          return NULL;
    8.27  
    8.28      xc_dom_loginit();
    8.29 @@ -436,7 +437,7 @@ static PyObject *pyxc_linux_build(XcObje
    8.30  
    8.31      if ( xc_dom_linux_build(self->xc_handle, dom, domid, mem_mb, image,
    8.32                              ramdisk, flags, store_evtchn, &store_mfn,
    8.33 -                            console_evtchn, &console_mfn) != 0 ) {
    8.34 +                            console_evtchn, &console_mfn, superpages) != 0 ) {
    8.35          goto out;
    8.36      }
    8.37  
     9.1 --- a/tools/python/xen/xend/XendCheckpoint.py	Tue May 26 09:54:53 2009 +0100
     9.2 +++ b/tools/python/xen/xend/XendCheckpoint.py	Tue May 26 09:58:38 2009 +0100
     9.3 @@ -272,9 +272,11 @@ def restore(xd, fd, dominfo = None, paus
     9.4          shadow_cur = xc.shadow_mem_control(dominfo.getDomid(), shadow / 1024)
     9.5          dominfo.info['shadow_memory'] = shadow_cur
     9.6  
     9.7 +        superpages = restore_image.superpages
     9.8 +
     9.9          cmd = map(str, [xen.util.auxbin.pathTo(XC_RESTORE),
    9.10                          fd, dominfo.getDomid(),
    9.11 -                        store_port, console_port, int(is_hvm), pae, apic])
    9.12 +                        store_port, console_port, int(is_hvm), pae, apic, superpages])
    9.13          log.debug("[xc_restore]: %s", string.join(cmd))
    9.14  
    9.15          handler = RestoreInputHandler()
    10.1 --- a/tools/python/xen/xend/XendConfig.py	Tue May 26 09:54:53 2009 +0100
    10.2 +++ b/tools/python/xen/xend/XendConfig.py	Tue May 26 09:58:38 2009 +0100
    10.3 @@ -220,6 +220,7 @@ XENAPI_CFG_TYPES = {
    10.4      'machine_address_size': int,
    10.5      'suppress_spurious_page_faults': bool0,
    10.6      's3_integrity' : int,
    10.7 +    'superpages' : int,
    10.8  }
    10.9  
   10.10  # List of legacy configuration keys that have no equivalent in the
   10.11 @@ -392,6 +393,7 @@ class XendConfig(dict):
   10.12              'other_config': {},
   10.13              'platform': {},
   10.14              'target': 0,
   10.15 +            'superpages': 0,
   10.16          }
   10.17          
   10.18          return defaults
   10.19 @@ -2014,6 +2016,8 @@ class XendConfig(dict):
   10.20              image.append(['ramdisk', self['PV_ramdisk']])
   10.21          if self.has_key('PV_args') and self['PV_args']:
   10.22              image.append(['args', self['PV_args']])
   10.23 +        if self.has_key('superpages'):
   10.24 +            image.append(['superpages', self['superpages']])
   10.25  
   10.26          for key in XENAPI_PLATFORM_CFG_TYPES.keys():
   10.27              if key in self['platform']:
   10.28 @@ -2051,6 +2055,8 @@ class XendConfig(dict):
   10.29              self['PV_ramdisk'] = sxp.child_value(image_sxp, 'ramdisk','')
   10.30              self['PV_args'] = kernel_args
   10.31  
   10.32 +        self['superpages'] = sxp.child_value(image_sxp, 'superpages',0)
   10.33 +
   10.34          for key in XENAPI_PLATFORM_CFG_TYPES.keys():
   10.35              val = sxp.child_value(image_sxp, key, None)
   10.36              if val is not None and val != '':
    11.1 --- a/tools/python/xen/xend/image.py	Tue May 26 09:54:53 2009 +0100
    11.2 +++ b/tools/python/xen/xend/image.py	Tue May 26 09:58:38 2009 +0100
    11.3 @@ -651,6 +651,7 @@ class LinuxImageHandler(ImageHandler):
    11.4          ImageHandler.configure(self, vmConfig)
    11.5          self.vramsize = int(vmConfig['platform'].get('videoram',4)) * 1024
    11.6          self.is_stubdom = (self.kernel.find('stubdom') >= 0)
    11.7 +        self.superpages = vmConfig['superpages']
    11.8  
    11.9      def buildDomain(self):
   11.10          store_evtchn = self.vm.getStorePort()
   11.11 @@ -668,6 +669,7 @@ class LinuxImageHandler(ImageHandler):
   11.12          log.debug("vcpus          = %d", self.vm.getVCpuCount())
   11.13          log.debug("features       = %s", self.vm.getFeatures())
   11.14          log.debug("flags          = %d", self.flags)
   11.15 +        log.debug("superpages     = %d", self.superpages)
   11.16          if arch.type == "ia64":
   11.17              log.debug("vhpt          = %d", self.vhpt)
   11.18  
   11.19 @@ -680,7 +682,8 @@ class LinuxImageHandler(ImageHandler):
   11.20                                ramdisk        = self.ramdisk,
   11.21                                features       = self.vm.getFeatures(),
   11.22                                flags          = self.flags,
   11.23 -                              vhpt           = self.vhpt)
   11.24 +                              vhpt           = self.vhpt,
   11.25 +                              superpages     = self.superpages)
   11.26  
   11.27      def getRequiredAvailableMemory(self, mem_kb):
   11.28          if self.is_stubdom :
    12.1 --- a/tools/python/xen/xm/create.dtd	Tue May 26 09:54:53 2009 +0100
    12.2 +++ b/tools/python/xen/xm/create.dtd	Tue May 26 09:58:38 2009 +0100
    12.3 @@ -54,6 +54,7 @@
    12.4                   actions_after_reboot   %NORMAL_EXIT; #REQUIRED
    12.5                   actions_after_crash    %CRASH_BEHAVIOUR; #REQUIRED
    12.6                   PCI_bus                CDATA #REQUIRED
    12.7 +                 superpages             CDATA #REQUIRED
    12.8                   security_label         CDATA #IMPLIED>
    12.9  
   12.10  <!ELEMENT memory EMPTY> 
    13.1 --- a/tools/python/xen/xm/create.py	Tue May 26 09:54:53 2009 +0100
    13.2 +++ b/tools/python/xen/xm/create.py	Tue May 26 09:58:38 2009 +0100
    13.3 @@ -660,6 +660,8 @@ def configure_image(vals):
    13.4          config_image.append(['videoram', vals.videoram])
    13.5      if vals.extra:
    13.6          config_image.append(['args', vals.extra])
    13.7 +    if vals.superpages:
    13.8 +        config_image.append(['superpages', vals.superpages])
    13.9  
   13.10      if vals.builder == 'hvm':
   13.11          configure_hvm(config_image, vals) 
    14.1 --- a/tools/python/xen/xm/xenapi_create.py	Tue May 26 09:54:53 2009 +0100
    14.2 +++ b/tools/python/xen/xm/xenapi_create.py	Tue May 26 09:58:38 2009 +0100
    14.3 @@ -271,6 +271,8 @@ class xenapi_create:
    14.4                  vm.attributes["auto_power_on"].value == 'true',
    14.5              "s3_integrity":
    14.6                  vm.attributes["s3_integrity"].value,
    14.7 +            "superpages":
    14.8 +                vm.attributes["superpages"].value,
    14.9              "memory_static_max":
   14.10                  get_child_node_attribute(vm, "memory", "static_max"),
   14.11              "memory_static_min":
   14.12 @@ -654,6 +656,8 @@ class sxp2xml:
   14.13              = str(get_child_by_name(config, "vcpus", 1))
   14.14          vm.attributes["s3_integrity"] \
   14.15              = str(get_child_by_name(config, "s3_integrity", 0))
   14.16 +        vm.attributes["superpages"] \
   14.17 +            = str(get_child_by_name(config, "superpages", 0))
   14.18  
   14.19          sec_data = get_child_by_name(config, "security")
   14.20          if sec_data:
    15.1 --- a/tools/xcutils/xc_restore.c	Tue May 26 09:54:53 2009 +0100
    15.2 +++ b/tools/xcutils/xc_restore.c	Tue May 26 09:58:38 2009 +0100
    15.3 @@ -21,11 +21,12 @@ main(int argc, char **argv)
    15.4      unsigned int domid, store_evtchn, console_evtchn;
    15.5      unsigned int hvm, pae, apic;
    15.6      int xc_fd, io_fd, ret;
    15.7 +    int superpages;
    15.8      unsigned long store_mfn, console_mfn;
    15.9  
   15.10 -    if ( argc != 8 )
   15.11 +    if ( (argc != 8) && (argc != 9) )
   15.12          errx(1, "usage: %s iofd domid store_evtchn "
   15.13 -             "console_evtchn hvm pae apic", argv[0]);
   15.14 +             "console_evtchn hvm pae apic [superpages]", argv[0]);
   15.15  
   15.16      xc_fd = xc_interface_open();
   15.17      if ( xc_fd < 0 )
   15.18 @@ -38,9 +39,13 @@ main(int argc, char **argv)
   15.19      hvm  = atoi(argv[5]);
   15.20      pae  = atoi(argv[6]);
   15.21      apic = atoi(argv[7]);
   15.22 +    if ( argc == 9 )
   15.23 +	    superpages = atoi(argv[8]);
   15.24 +    else
   15.25 +	    superpages = 0;
   15.26  
   15.27      ret = xc_domain_restore(xc_fd, io_fd, domid, store_evtchn, &store_mfn,
   15.28 -                            console_evtchn, &console_mfn, hvm, pae);
   15.29 +                            console_evtchn, &console_mfn, hvm, pae, superpages);
   15.30  
   15.31      if ( ret == 0 )
   15.32      {