ia64/xen-unstable

changeset 14698:d05a3220ea05

Some save/restore cleanups.

Signed-off-by: Steven Hand <steven@xensource.com>
author Steven Hand <steven@xensource.com>
date Mon Apr 02 16:46:52 2007 +0100 (2007-04-02)
parents 9695cc13c48c
children e9986e48ebe1
files tools/libxc/xc_core.c tools/libxc/xc_core_x86.c tools/libxc/xc_hvm_restore.c tools/libxc/xc_hvm_save.c tools/libxc/xc_linux_restore.c tools/libxc/xc_linux_save.c tools/libxc/xc_resume.c tools/libxc/xenguest.h tools/libxc/xg_private.h tools/python/xen/xend/XendCheckpoint.py tools/xcutils/xc_restore.c
line diff
     1.1 --- a/tools/libxc/xc_core.c	Mon Apr 02 16:26:23 2007 +0100
     1.2 +++ b/tools/libxc/xc_core.c	Mon Apr 02 16:46:52 2007 +0100
     1.3 @@ -312,7 +312,7 @@ xc_domain_dumpcore_via_callback(int xc_h
     1.4  
     1.5      int auto_translated_physmap;
     1.6      xen_pfn_t *p2m = NULL;
     1.7 -    unsigned long max_pfn = 0;
     1.8 +    unsigned long p2m_size = 0;
     1.9      struct xen_dumpcore_p2m *p2m_array = NULL;
    1.10  
    1.11      uint64_t *pfn_array = NULL;
    1.12 @@ -396,7 +396,7 @@ xc_domain_dumpcore_via_callback(int xc_h
    1.13          }
    1.14  
    1.15          sts = xc_core_arch_map_p2m(xc_handle, &info, live_shinfo,
    1.16 -                                   &p2m, &max_pfn);
    1.17 +                                   &p2m, &p2m_size);
    1.18          if ( sts != 0 )
    1.19              goto out;
    1.20      }
     2.1 --- a/tools/libxc/xc_core_x86.c	Mon Apr 02 16:26:23 2007 +0100
     2.2 +++ b/tools/libxc/xc_core_x86.c	Mon Apr 02 16:46:52 2007 +0100
     2.3 @@ -38,7 +38,7 @@ xc_core_arch_memory_map_get(int xc_handl
     2.4                              xc_core_memory_map_t **mapp,
     2.5                              unsigned int *nr_entries)
     2.6  {
     2.7 -    unsigned long max_pfn = max_gpfn(xc_handle, info->domid);
     2.8 +    unsigned long p2m_size = max_gpfn(xc_handle, info->domid);
     2.9      xc_core_memory_map_t *map;
    2.10  
    2.11      map = malloc(sizeof(*map));
    2.12 @@ -49,7 +49,7 @@ xc_core_arch_memory_map_get(int xc_handl
    2.13      }
    2.14  
    2.15      map->addr = 0;
    2.16 -    map->size = max_pfn << PAGE_SHIFT;
    2.17 +    map->size = p2m_size << PAGE_SHIFT;
    2.18  
    2.19      *mapp = map;
    2.20      *nr_entries = 1;
    2.21 @@ -65,13 +65,13 @@ xc_core_arch_map_p2m(int xc_handle, xc_d
    2.22      xen_pfn_t *live_p2m_frame_list_list = NULL;
    2.23      xen_pfn_t *live_p2m_frame_list = NULL;
    2.24      uint32_t dom = info->domid;
    2.25 -    unsigned long max_pfn = max_gpfn(xc_handle, info->domid);
    2.26 +    unsigned long p2m_size = max_gpfn(xc_handle, info->domid);
    2.27      int ret = -1;
    2.28      int err;
    2.29  
    2.30 -    if ( max_pfn < info->nr_pages  )
    2.31 +    if ( p2m_size < info->nr_pages  )
    2.32      {
    2.33 -        ERROR("max_pfn < nr_pages -1 (%lx < %lx", max_pfn, info->nr_pages - 1);
    2.34 +        ERROR("p2m_size < nr_pages -1 (%lx < %lx", p2m_size, info->nr_pages - 1);
    2.35          goto out;
    2.36      }
    2.37  
    2.38 @@ -106,7 +106,7 @@ xc_core_arch_map_p2m(int xc_handle, xc_d
    2.39          goto out;
    2.40      }
    2.41  
    2.42 -    *pfnp = max_pfn;
    2.43 +    *pfnp = p2m_size;
    2.44  
    2.45      ret = 0;
    2.46  
     3.1 --- a/tools/libxc/xc_hvm_restore.c	Mon Apr 02 16:26:23 2007 +0100
     3.2 +++ b/tools/libxc/xc_hvm_restore.c	Mon Apr 02 16:46:52 2007 +0100
     3.3 @@ -95,7 +95,7 @@ int xc_hvm_restore(int xc_handle, int io
     3.4      unsigned long pfn_array_size = max_pfn + 1;
     3.5  
     3.6      /* Number of pages of memory the guest has.  *Not* the same as max_pfn. */
     3.7 -    unsigned long nr_pages = max_pfn + 1;
     3.8 +    unsigned long nr_pages = max_pfn;
     3.9      /* MMIO hole doesn't contain RAM */
    3.10      if ( nr_pages >= HVM_BELOW_4G_MMIO_START >> PAGE_SHIFT ) 
    3.11          nr_pages -= HVM_BELOW_4G_MMIO_LENGTH >> PAGE_SHIFT; 
    3.12 @@ -270,7 +270,6 @@ int xc_hvm_restore(int xc_handle, int io
    3.13  
    3.14      }/*while 1*/
    3.15      
    3.16 -/*    xc_set_hvm_param(xc_handle, dom, HVM_PARAM_APIC_ENABLED, apic);*/
    3.17      xc_set_hvm_param(xc_handle, dom, HVM_PARAM_PAE_ENABLED, pae);
    3.18      xc_set_hvm_param(xc_handle, dom, HVM_PARAM_STORE_EVTCHN, store_evtchn);
    3.19  
    3.20 @@ -279,13 +278,22 @@ int xc_hvm_restore(int xc_handle, int io
    3.21      else
    3.22          shared_page_nr = (v_end >> PAGE_SHIFT) - 1;
    3.23  
    3.24 +    /* Ensure we clear these pages */
    3.25 +    if ( xc_clear_domain_page(xc_handle, dom, shared_page_nr) ||
    3.26 +         xc_clear_domain_page(xc_handle, dom, shared_page_nr-1) ||
    3.27 +         xc_clear_domain_page(xc_handle, dom, shared_page_nr-2) ) {
    3.28 +        rc = -1;
    3.29 +        goto out;
    3.30 +    }
    3.31 +
    3.32      xc_set_hvm_param(xc_handle, dom, HVM_PARAM_STORE_PFN, shared_page_nr-1);
    3.33      xc_set_hvm_param(xc_handle, dom, HVM_PARAM_BUFIOREQ_PFN, shared_page_nr-2);
    3.34      xc_set_hvm_param(xc_handle, dom, HVM_PARAM_IOREQ_PFN, shared_page_nr);
    3.35  
    3.36      /* caculate the store_mfn , wrong val cause hang when introduceDomain */
    3.37      *store_mfn = (v_end >> PAGE_SHIFT) - 2;
    3.38 -    DPRINTF("hvm restore:calculate new store_mfn=0x%lx,v_end=0x%llx..\n", *store_mfn, v_end);
    3.39 +    DPRINTF("hvm restore: calculate new store_mfn=0x%lx, v_end=0x%llx.\n", 
    3.40 +            *store_mfn, v_end);
    3.41  
    3.42      if (!read_exact(io_fd, &nr_vcpus, sizeof(uint32_t))) {
    3.43          ERROR("error read nr vcpu !\n");
     4.1 --- a/tools/libxc/xc_hvm_save.c	Mon Apr 02 16:26:23 2007 +0100
     4.2 +++ b/tools/libxc/xc_hvm_save.c	Mon Apr 02 16:46:52 2007 +0100
     4.3 @@ -332,10 +332,10 @@ int xc_hvm_save(int xc_handle, int io_fd
     4.4  
     4.5      unsigned long total_sent    = 0;
     4.6  
     4.7 -    DPRINTF("xc_hvm_save:dom=%d, max_iters=%d, max_factor=%d, flags=0x%x, live=%d, debug=%d.\n",
     4.8 -            dom, max_iters, max_factor, flags,
     4.9 +    DPRINTF("xc_hvm_save: dom=%d, max_iters=%d, max_factor=%d, flags=0x%x, "
    4.10 +            "live=%d, debug=%d.\n", dom, max_iters, max_factor, flags,
    4.11              live, debug);
    4.12 -
    4.13 +    
    4.14      /* If no explicit control parameters given, use defaults */
    4.15      if(!max_iters)
    4.16          max_iters = DEF_MAX_ITERS;
    4.17 @@ -382,7 +382,6 @@ int xc_hvm_save(int xc_handle, int io_fd
    4.18          ERROR("HVM: Could not read magic PFN parameters");
    4.19          goto out;
    4.20      }
    4.21 -
    4.22      DPRINTF("saved hvm domain info:max_memkb=0x%lx, max_mfn=0x%lx, "
    4.23              "nr_pages=0x%lx\n", info.max_memkb, max_mfn, info.nr_pages); 
    4.24  
     5.1 --- a/tools/libxc/xc_linux_restore.c	Mon Apr 02 16:26:23 2007 +0100
     5.2 +++ b/tools/libxc/xc_linux_restore.c	Mon Apr 02 16:46:52 2007 +0100
     5.3 @@ -22,8 +22,14 @@ static unsigned long hvirt_start;
     5.4  /* #levels of page tables used by the current guest */
     5.5  static unsigned int pt_levels;
     5.6  
     5.7 -/* total number of pages used by the current guest */
     5.8 -static unsigned long max_pfn;
     5.9 +/* number of pfns this guest has (i.e. number of entries in the P2M) */
    5.10 +static unsigned long p2m_size;
    5.11 +
    5.12 +/* number of 'in use' pfns in the guest (i.e. #P2M entries with a valid mfn) */
    5.13 +static unsigned long nr_pfns;
    5.14 +
    5.15 +/* largest possible value of nr_pfns (i.e. domain's maximum memory size) */
    5.16 +static unsigned long max_nr_pfns;
    5.17  
    5.18  /* Live mapping of the table mapping each PFN to its current MFN. */
    5.19  static xen_pfn_t *live_p2m = NULL;
    5.20 @@ -34,7 +40,6 @@ static xen_pfn_t *p2m = NULL;
    5.21  /* A table of P2M mappings in the current region */
    5.22  static xen_pfn_t *p2m_batch = NULL;
    5.23  
    5.24 -
    5.25  static ssize_t
    5.26  read_exact(int fd, void *buf, size_t count)
    5.27  {
    5.28 @@ -85,11 +90,11 @@ static int uncanonicalize_pagetable(int 
    5.29          
    5.30          pfn = (pte >> PAGE_SHIFT) & MFN_MASK_X86;
    5.31          
    5.32 -        if(pfn >= max_pfn) {
    5.33 +        if(pfn >= p2m_size) {
    5.34              /* This "page table page" is probably not one; bail. */
    5.35              ERROR("Frame number in type %lu page table is out of range: "
    5.36 -                  "i=%d pfn=0x%lx max_pfn=%lu",
    5.37 -                  type >> 28, i, pfn, max_pfn);
    5.38 +                  "i=%d pfn=0x%lx p2m_size=%lu",
    5.39 +                  type >> 28, i, pfn, p2m_size);
    5.40              return 0;
    5.41          }
    5.42          
    5.43 @@ -138,8 +143,9 @@ static int uncanonicalize_pagetable(int 
    5.44      return 1;
    5.45  }
    5.46  
    5.47 -int xc_linux_restore(int xc_handle, int io_fd,
    5.48 -                     uint32_t dom, unsigned long nr_pfns,
    5.49 +
    5.50 +int xc_linux_restore(int xc_handle, int io_fd, uint32_t dom,
    5.51 +                     unsigned long p2msize, unsigned long maxnrpfns,
    5.52                       unsigned int store_evtchn, unsigned long *store_mfn,
    5.53                       unsigned int console_evtchn, unsigned long *console_mfn)
    5.54  {
    5.55 @@ -191,9 +197,13 @@ int xc_linux_restore(int xc_handle, int 
    5.56      unsigned int max_vcpu_id = 0;
    5.57      int new_ctxt_format = 0;
    5.58  
    5.59 -    max_pfn = nr_pfns;
    5.60 +    p2m_size    = p2msize;
    5.61 +    max_nr_pfns = maxnrpfns;
    5.62  
    5.63 -    DPRINTF("xc_linux_restore start: max_pfn = %lx\n", max_pfn);
    5.64 +    /* For info only */
    5.65 +    nr_pfns = 0;
    5.66 +
    5.67 +    DPRINTF("xc_linux_restore start: p2m_size = %lx\n", p2m_size);
    5.68  
    5.69      /*
    5.70       * XXX For now, 32bit dom0's can only save/restore 32bit domUs
    5.71 @@ -294,8 +304,8 @@ int xc_linux_restore(int xc_handle, int 
    5.72      }
    5.73  
    5.74      /* We want zeroed memory so use calloc rather than malloc. */
    5.75 -    p2m        = calloc(max_pfn, sizeof(xen_pfn_t));
    5.76 -    pfn_type   = calloc(max_pfn, sizeof(unsigned long));
    5.77 +    p2m        = calloc(p2m_size, sizeof(xen_pfn_t));
    5.78 +    pfn_type   = calloc(p2m_size, sizeof(unsigned long));
    5.79      region_mfn = calloc(MAX_BATCH_SIZE, sizeof(xen_pfn_t));
    5.80      p2m_batch  = calloc(MAX_BATCH_SIZE, sizeof(xen_pfn_t));
    5.81  
    5.82 @@ -325,13 +335,13 @@ int xc_linux_restore(int xc_handle, int 
    5.83      }
    5.84      shared_info_frame = domctl.u.getdomaininfo.shared_info_frame;
    5.85  
    5.86 -    if (xc_domain_setmaxmem(xc_handle, dom, PFN_TO_KB(max_pfn)) != 0) {
    5.87 +    if (xc_domain_setmaxmem(xc_handle, dom, PFN_TO_KB(max_nr_pfns)) != 0) {
    5.88          errno = ENOMEM;
    5.89          goto out;
    5.90      }
    5.91  
    5.92      /* Mark all PFNs as invalid; we allocate on demand */
    5.93 -    for ( pfn = 0; pfn < max_pfn; pfn++ )
    5.94 +    for ( pfn = 0; pfn < p2m_size; pfn++ )
    5.95          p2m[pfn] = INVALID_P2M_ENTRY;
    5.96  
    5.97      if(!(mmu = xc_init_mmu_updates(xc_handle, dom))) {
    5.98 @@ -352,7 +362,7 @@ int xc_linux_restore(int xc_handle, int 
    5.99  
   5.100          int j, nr_mfns = 0; 
   5.101  
   5.102 -        this_pc = (n * 100) / max_pfn;
   5.103 +        this_pc = (n * 100) / p2m_size;
   5.104          if ( (this_pc - prev_pc) >= 5 )
   5.105          {
   5.106              PPRINTF("\b\b\b\b%3d%%", this_pc);
   5.107 @@ -436,6 +446,7 @@ int xc_linux_restore(int xc_handle, int 
   5.108                  if (p2m[pfn] == INVALID_P2M_ENTRY) {
   5.109                      /* We just allocated a new mfn above; update p2m */
   5.110                      p2m[pfn] = p2m_batch[nr_mfns++]; 
   5.111 +                    nr_pfns++; 
   5.112                  }
   5.113  
   5.114                  /* setup region_mfn[] for batch map */
   5.115 @@ -465,7 +476,7 @@ int xc_linux_restore(int xc_handle, int 
   5.116                  /* a bogus/unmapped page: skip it */
   5.117                  continue;
   5.118  
   5.119 -            if ( pfn > max_pfn )
   5.120 +            if ( pfn > p2m_size )
   5.121              {
   5.122                  ERROR("pfn out of range");
   5.123                  goto out;
   5.124 @@ -518,7 +529,7 @@ int xc_linux_restore(int xc_handle, int 
   5.125              else if ( pagetype != XEN_DOMCTL_PFINFO_NOTAB )
   5.126              {
   5.127                  ERROR("Bogus page type %lx page table is out of range: "
   5.128 -                    "i=%d max_pfn=%lu", pagetype, i, max_pfn);
   5.129 +                    "i=%d p2m_size=%lu", pagetype, i, p2m_size);
   5.130                  goto out;
   5.131  
   5.132              }
   5.133 @@ -598,7 +609,7 @@ int xc_linux_restore(int xc_handle, int 
   5.134          int j, k;
   5.135          
   5.136          /* First pass: find all L3TABs current in > 4G mfns and get new mfns */
   5.137 -        for ( i = 0; i < max_pfn; i++ )
   5.138 +        for ( i = 0; i < p2m_size; i++ )
   5.139          {
   5.140              if ( ((pfn_type[i] & XEN_DOMCTL_PFINFO_LTABTYPE_MASK) ==
   5.141                    XEN_DOMCTL_PFINFO_L3TAB) &&
   5.142 @@ -646,7 +657,7 @@ int xc_linux_restore(int xc_handle, int 
   5.143          /* Second pass: find all L1TABs and uncanonicalize them */
   5.144          j = 0;
   5.145  
   5.146 -        for ( i = 0; i < max_pfn; i++ )
   5.147 +        for ( i = 0; i < p2m_size; i++ )
   5.148          {
   5.149              if ( ((pfn_type[i] & XEN_DOMCTL_PFINFO_LTABTYPE_MASK) ==
   5.150                    XEN_DOMCTL_PFINFO_L1TAB) )
   5.151 @@ -655,7 +666,7 @@ int xc_linux_restore(int xc_handle, int 
   5.152                  j++;
   5.153              }
   5.154  
   5.155 -            if(i == (max_pfn-1) || j == MAX_BATCH_SIZE) {
   5.156 +            if(i == (p2m_size-1) || j == MAX_BATCH_SIZE) {
   5.157  
   5.158                  if (!(region_base = xc_map_foreign_batch(
   5.159                            xc_handle, dom, PROT_READ | PROT_WRITE,
   5.160 @@ -689,7 +700,7 @@ int xc_linux_restore(int xc_handle, int 
   5.161       * will barf when doing the type-checking.
   5.162       */
   5.163      nr_pins = 0;
   5.164 -    for ( i = 0; i < max_pfn; i++ )
   5.165 +    for ( i = 0; i < p2m_size; i++ )
   5.166      {
   5.167          if ( (pfn_type[i] & XEN_DOMCTL_PFINFO_LPINTAB) == 0 )
   5.168              continue;
   5.169 @@ -736,7 +747,7 @@ int xc_linux_restore(int xc_handle, int 
   5.170      }
   5.171  
   5.172      DPRINTF("\b\b\b\b100%%\n");
   5.173 -    DPRINTF("Memory reloaded.\n");
   5.174 +    DPRINTF("Memory reloaded (%ld pages of max %ld)\n", nr_pfns, max_nr_pfns);
   5.175  
   5.176      /* Get the list of PFNs that are not in the psuedo-phys map */
   5.177      {
   5.178 @@ -808,7 +819,7 @@ int xc_linux_restore(int xc_handle, int 
   5.179               * resume record.
   5.180               */
   5.181              pfn = ctxt.user_regs.edx;
   5.182 -            if ((pfn >= max_pfn) ||
   5.183 +            if ((pfn >= p2m_size) ||
   5.184                  (pfn_type[pfn] != XEN_DOMCTL_PFINFO_NOTAB)) {
   5.185                  ERROR("Suspend record frame number is bad");
   5.186                  goto out;
   5.187 @@ -816,7 +827,7 @@ int xc_linux_restore(int xc_handle, int 
   5.188              ctxt.user_regs.edx = mfn = p2m[pfn];
   5.189              start_info = xc_map_foreign_range(
   5.190                  xc_handle, dom, PAGE_SIZE, PROT_READ | PROT_WRITE, mfn);
   5.191 -            start_info->nr_pages = max_pfn;
   5.192 +            start_info->nr_pages = p2m_size;
   5.193              start_info->shared_info = shared_info_frame << PAGE_SHIFT;
   5.194              start_info->flags = 0;
   5.195              *store_mfn = start_info->store_mfn = p2m[start_info->store_mfn];
   5.196 @@ -835,7 +846,7 @@ int xc_linux_restore(int xc_handle, int 
   5.197  
   5.198          for (j = 0; (512*j) < ctxt.gdt_ents; j++) {
   5.199              pfn = ctxt.gdt_frames[j];
   5.200 -            if ((pfn >= max_pfn) ||
   5.201 +            if ((pfn >= p2m_size) ||
   5.202                  (pfn_type[pfn] != XEN_DOMCTL_PFINFO_NOTAB)) {
   5.203                  ERROR("GDT frame number is bad");
   5.204                  goto out;
   5.205 @@ -846,16 +857,16 @@ int xc_linux_restore(int xc_handle, int 
   5.206          /* Uncanonicalise the page table base pointer. */
   5.207          pfn = xen_cr3_to_pfn(ctxt.ctrlreg[3]);
   5.208  
   5.209 -        if (pfn >= max_pfn) {
   5.210 -            ERROR("PT base is bad: pfn=%lu max_pfn=%lu type=%08lx",
   5.211 -                  pfn, max_pfn, pfn_type[pfn]);
   5.212 +        if (pfn >= p2m_size) {
   5.213 +            ERROR("PT base is bad: pfn=%lu p2m_size=%lu type=%08lx",
   5.214 +                  pfn, p2m_size, pfn_type[pfn]);
   5.215              goto out;
   5.216          }
   5.217  
   5.218          if ( (pfn_type[pfn] & XEN_DOMCTL_PFINFO_LTABTYPE_MASK) !=
   5.219               ((unsigned long)pt_levels<<XEN_DOMCTL_PFINFO_LTAB_SHIFT) ) {
   5.220              ERROR("PT base is bad. pfn=%lu nr=%lu type=%08lx %08lx",
   5.221 -                  pfn, max_pfn, pfn_type[pfn],
   5.222 +                  pfn, p2m_size, pfn_type[pfn],
   5.223                    (unsigned long)pt_levels<<XEN_DOMCTL_PFINFO_LTAB_SHIFT);
   5.224              goto out;
   5.225          }
   5.226 @@ -867,16 +878,16 @@ int xc_linux_restore(int xc_handle, int 
   5.227          {
   5.228              pfn = xen_cr3_to_pfn(ctxt.ctrlreg[1]);
   5.229  
   5.230 -            if (pfn >= max_pfn) {
   5.231 -                ERROR("User PT base is bad: pfn=%lu max_pfn=%lu type=%08lx",
   5.232 -                      pfn, max_pfn, pfn_type[pfn]);
   5.233 +            if (pfn >= p2m_size) {
   5.234 +                ERROR("User PT base is bad: pfn=%lu p2m_size=%lu type=%08lx",
   5.235 +                      pfn, p2m_size, pfn_type[pfn]);
   5.236                  goto out;
   5.237              }
   5.238  
   5.239              if ( (pfn_type[pfn] & XEN_DOMCTL_PFINFO_LTABTYPE_MASK) !=
   5.240                   ((unsigned long)pt_levels<<XEN_DOMCTL_PFINFO_LTAB_SHIFT) ) {
   5.241                  ERROR("User PT base is bad. pfn=%lu nr=%lu type=%08lx %08lx",
   5.242 -                      pfn, max_pfn, pfn_type[pfn],
   5.243 +                      pfn, p2m_size, pfn_type[pfn],
   5.244                        (unsigned long)pt_levels<<XEN_DOMCTL_PFINFO_LTAB_SHIFT);
   5.245                  goto out;
   5.246              }
   5.247 @@ -915,7 +926,7 @@ int xc_linux_restore(int xc_handle, int 
   5.248      /* Uncanonicalise the pfn-to-mfn table frame-number list. */
   5.249      for (i = 0; i < P2M_FL_ENTRIES; i++) {
   5.250          pfn = p2m_frame_list[i];
   5.251 -        if ((pfn >= max_pfn) || (pfn_type[pfn] != XEN_DOMCTL_PFINFO_NOTAB)) {
   5.252 +        if ((pfn >= p2m_size) || (pfn_type[pfn] != XEN_DOMCTL_PFINFO_NOTAB)) {
   5.253              ERROR("PFN-to-MFN frame number is bad");
   5.254              goto out;
   5.255          }
   5.256 @@ -930,8 +941,8 @@ int xc_linux_restore(int xc_handle, int 
   5.257          goto out;
   5.258      }
   5.259  
   5.260 -    memcpy(live_p2m, p2m, P2M_SIZE);
   5.261 -    munmap(live_p2m, P2M_SIZE);
   5.262 +    memcpy(live_p2m, p2m, ROUNDUP(p2m_size * sizeof(xen_pfn_t), PAGE_SHIFT));
   5.263 +    munmap(live_p2m, ROUNDUP(p2m_size * sizeof(xen_pfn_t), PAGE_SHIFT));
   5.264  
   5.265      DPRINTF("Domain ready to be built.\n");
   5.266  
     6.1 --- a/tools/libxc/xc_linux_save.c	Mon Apr 02 16:26:23 2007 +0100
     6.2 +++ b/tools/libxc/xc_linux_save.c	Mon Apr 02 16:46:52 2007 +0100
     6.3 @@ -25,7 +25,7 @@
     6.4  **
     6.5  */
     6.6  #define DEF_MAX_ITERS   29   /* limit us to 30 times round loop   */
     6.7 -#define DEF_MAX_FACTOR   3   /* never send more than 3x nr_pfns   */
     6.8 +#define DEF_MAX_FACTOR   3   /* never send more than 3x p2m_size  */
     6.9  
    6.10  
    6.11  /* max mfn of the whole machine */
    6.12 @@ -37,8 +37,8 @@ static unsigned long hvirt_start;
    6.13  /* #levels of page tables used by the current guest */
    6.14  static unsigned int pt_levels;
    6.15  
    6.16 -/* total number of pages used by the current guest */
    6.17 -static unsigned long max_pfn;
    6.18 +/* number of pfns this guest has (i.e. number of entries in the P2M) */
    6.19 +static unsigned long p2m_size;
    6.20  
    6.21  /* Live mapping of the table mapping each PFN to its current MFN. */
    6.22  static xen_pfn_t *live_p2m = NULL;
    6.23 @@ -57,7 +57,7 @@ static unsigned long m2p_mfn0;
    6.24   */
    6.25  #define MFN_IS_IN_PSEUDOPHYS_MAP(_mfn)          \
    6.26  (((_mfn) < (max_mfn)) &&                        \
    6.27 - ((mfn_to_pfn(_mfn) < (max_pfn)) &&               \
    6.28 + ((mfn_to_pfn(_mfn) < (p2m_size)) &&               \
    6.29    (live_p2m[mfn_to_pfn(_mfn)] == (_mfn))))
    6.30  
    6.31  
    6.32 @@ -79,7 +79,7 @@ static unsigned long m2p_mfn0;
    6.33  */
    6.34  
    6.35  #define BITS_PER_LONG (sizeof(unsigned long) * 8)
    6.36 -#define BITMAP_SIZE   ((max_pfn + BITS_PER_LONG - 1) / 8)
    6.37 +#define BITMAP_SIZE   ((p2m_size + BITS_PER_LONG - 1) / 8)
    6.38  
    6.39  #define BITMAP_ENTRY(_nr,_bmap) \
    6.40     ((volatile unsigned long *)(_bmap))[(_nr)/BITS_PER_LONG]
    6.41 @@ -343,7 +343,7 @@ static int print_stats(int xc_handle, ui
    6.42  }
    6.43  
    6.44  
    6.45 -static int analysis_phase(int xc_handle, uint32_t domid, int max_pfn,
    6.46 +static int analysis_phase(int xc_handle, uint32_t domid, int p2m_size,
    6.47                            unsigned long *arr, int runs)
    6.48  {
    6.49      long long start, now;
    6.50 @@ -356,7 +356,7 @@ static int analysis_phase(int xc_handle,
    6.51          int i;
    6.52  
    6.53          xc_shadow_control(xc_handle, domid, XEN_DOMCTL_SHADOW_OP_CLEAN,
    6.54 -                          arr, max_pfn, NULL, 0, NULL);
    6.55 +                          arr, p2m_size, NULL, 0, NULL);
    6.56          DPRINTF("#Flush\n");
    6.57          for ( i = 0; i < 40; i++ ) {
    6.58              usleep(50000);
    6.59 @@ -682,7 +682,7 @@ int xc_linux_save(int xc_handle, int io_
    6.60      /* base of the region in which domain memory is mapped */
    6.61      unsigned char *region_base = NULL;
    6.62  
    6.63 -    /* power of 2 order of max_pfn */
    6.64 +    /* power of 2 order of p2m_size */
    6.65      int order_nr;
    6.66  
    6.67      /* bitmap of pages:
    6.68 @@ -730,7 +730,7 @@ int xc_linux_save(int xc_handle, int io_
    6.69          goto out;
    6.70      }
    6.71  
    6.72 -    max_pfn = live_shinfo->arch.max_pfn;
    6.73 +    p2m_size = live_shinfo->arch.max_pfn;
    6.74  
    6.75      live_p2m_frame_list_list = map_frame_list_list(xc_handle, dom,
    6.76                                                     live_shinfo);
    6.77 @@ -777,7 +777,7 @@ int xc_linux_save(int xc_handle, int io_
    6.78      memcpy(p2m_frame_list, live_p2m_frame_list, P2M_FL_SIZE);
    6.79  
    6.80      /* Canonicalise the pfn-to-mfn table frame-number list. */
    6.81 -    for (i = 0; i < max_pfn; i += fpp) {
    6.82 +    for (i = 0; i < p2m_size; i += fpp) {
    6.83          if (!translate_mfn_to_pfn(&p2m_frame_list[i/fpp])) {
    6.84              ERROR("Frame# in pfn-to-mfn frame list is not in pseudophys");
    6.85              ERROR("entry %d: p2m_frame_list[%ld] is 0x%"PRIx64, i, i/fpp,
    6.86 @@ -813,12 +813,12 @@ int xc_linux_save(int xc_handle, int io_
    6.87      }
    6.88  
    6.89      /* pretend we sent all the pages last iteration */
    6.90 -    sent_last_iter = max_pfn;
    6.91 +    sent_last_iter = p2m_size;
    6.92  
    6.93  
    6.94 -    /* calculate the power of 2 order of max_pfn, e.g.
    6.95 +    /* calculate the power of 2 order of p2m_size, e.g.
    6.96         15->4 16->4 17->5 */
    6.97 -    for (i = max_pfn-1, order_nr = 0; i ; i >>= 1, order_nr++)
    6.98 +    for (i = p2m_size-1, order_nr = 0; i ; i >>= 1, order_nr++)
    6.99          continue;
   6.100  
   6.101      /* Setup to_send / to_fix and to_skip bitmaps */
   6.102 @@ -844,7 +844,7 @@ int xc_linux_save(int xc_handle, int io_
   6.103          return 1;
   6.104      }
   6.105  
   6.106 -    analysis_phase(xc_handle, dom, max_pfn, to_skip, 0);
   6.107 +    analysis_phase(xc_handle, dom, p2m_size, to_skip, 0);
   6.108  
   6.109      /* We want zeroed memory so use calloc rather than malloc. */
   6.110      pfn_type   = calloc(MAX_BATCH_SIZE, sizeof(*pfn_type));
   6.111 @@ -867,7 +867,7 @@ int xc_linux_save(int xc_handle, int io_
   6.112      {
   6.113          int err=0;
   6.114          unsigned long mfn;
   6.115 -        for (i = 0; i < max_pfn; i++) {
   6.116 +        for (i = 0; i < p2m_size; i++) {
   6.117  
   6.118              mfn = live_p2m[i];
   6.119              if((mfn != INVALID_P2M_ENTRY) && (mfn_to_pfn(mfn) != i)) {
   6.120 @@ -882,8 +882,8 @@ int xc_linux_save(int xc_handle, int io_
   6.121  
   6.122      /* Start writing out the saved-domain record. */
   6.123  
   6.124 -    if (!write_exact(io_fd, &max_pfn, sizeof(unsigned long))) {
   6.125 -        ERROR("write: max_pfn");
   6.126 +    if (!write_exact(io_fd, &p2m_size, sizeof(unsigned long))) {
   6.127 +        ERROR("write: p2m_size");
   6.128          goto out;
   6.129      }
   6.130  
   6.131 @@ -929,9 +929,9 @@ int xc_linux_save(int xc_handle, int io_
   6.132  
   6.133          DPRINTF("Saving memory pages: iter %d   0%%", iter);
   6.134  
   6.135 -        while( N < max_pfn ){
   6.136 +        while( N < p2m_size ){
   6.137  
   6.138 -            unsigned int this_pc = (N * 100) / max_pfn;
   6.139 +            unsigned int this_pc = (N * 100) / p2m_size;
   6.140  
   6.141              if ((this_pc - prev_pc) >= 5) {
   6.142                  DPRINTF("\b\b\b\b%3d%%", this_pc);
   6.143 @@ -942,7 +942,7 @@ int xc_linux_save(int xc_handle, int io_
   6.144                 but this is fast enough for the moment. */
   6.145              if (!last_iter && xc_shadow_control(
   6.146                      xc_handle, dom, XEN_DOMCTL_SHADOW_OP_PEEK,
   6.147 -                    to_skip, max_pfn, NULL, 0, NULL) != max_pfn) {
   6.148 +                    to_skip, p2m_size, NULL, 0, NULL) != p2m_size) {
   6.149                  ERROR("Error peeking shadow bitmap");
   6.150                  goto out;
   6.151              }
   6.152 @@ -950,9 +950,9 @@ int xc_linux_save(int xc_handle, int io_
   6.153  
   6.154              /* load pfn_type[] with the mfn of all the pages we're doing in
   6.155                 this batch. */
   6.156 -            for (batch = 0; batch < MAX_BATCH_SIZE && N < max_pfn ; N++) {
   6.157 +            for (batch = 0; batch < MAX_BATCH_SIZE && N < p2m_size ; N++) {
   6.158  
   6.159 -                int n = permute(N, max_pfn, order_nr);
   6.160 +                int n = permute(N, p2m_size, order_nr);
   6.161  
   6.162                  if (debug) {
   6.163                      DPRINTF("%d pfn= %08lx mfn= %08lx %d  [mfn]= %08lx\n",
   6.164 @@ -1123,7 +1123,7 @@ int xc_linux_save(int xc_handle, int io_
   6.165              print_stats( xc_handle, dom, sent_this_iter, &stats, 1);
   6.166  
   6.167              DPRINTF("Total pages sent= %ld (%.2fx)\n",
   6.168 -                    total_sent, ((float)total_sent)/max_pfn );
   6.169 +                    total_sent, ((float)total_sent)/p2m_size );
   6.170              DPRINTF("(of which %ld were fixups)\n", needed_to_fix  );
   6.171          }
   6.172  
   6.173 @@ -1150,7 +1150,7 @@ int xc_linux_save(int xc_handle, int io_
   6.174              if (((sent_this_iter > sent_last_iter) && RATE_IS_MAX()) ||
   6.175                  (iter >= max_iters) ||
   6.176                  (sent_this_iter+skip_this_iter < 50) ||
   6.177 -                (total_sent > max_pfn*max_factor)) {
   6.178 +                (total_sent > p2m_size*max_factor)) {
   6.179                  DPRINTF("Start last iteration\n");
   6.180                  last_iter = 1;
   6.181  
   6.182 @@ -1168,7 +1168,7 @@ int xc_linux_save(int xc_handle, int io_
   6.183  
   6.184              if (xc_shadow_control(xc_handle, dom, 
   6.185                                    XEN_DOMCTL_SHADOW_OP_CLEAN, to_send, 
   6.186 -                                  max_pfn, NULL, 0, &stats) != max_pfn) {
   6.187 +                                  p2m_size, NULL, 0, &stats) != p2m_size) {
   6.188                  ERROR("Error flushing shadow PT");
   6.189                  goto out;
   6.190              }
   6.191 @@ -1220,7 +1220,7 @@ int xc_linux_save(int xc_handle, int io_
   6.192          unsigned int i,j;
   6.193          unsigned long pfntab[1024];
   6.194  
   6.195 -        for (i = 0, j = 0; i < max_pfn; i++) {
   6.196 +        for (i = 0, j = 0; i < p2m_size; i++) {
   6.197              if (!is_mapped(live_p2m[i]))
   6.198                  j++;
   6.199          }
   6.200 @@ -1230,13 +1230,13 @@ int xc_linux_save(int xc_handle, int io_
   6.201              goto out;
   6.202          }
   6.203  
   6.204 -        for (i = 0, j = 0; i < max_pfn; ) {
   6.205 +        for (i = 0, j = 0; i < p2m_size; ) {
   6.206  
   6.207              if (!is_mapped(live_p2m[i]))
   6.208                  pfntab[j++] = i;
   6.209  
   6.210              i++;
   6.211 -            if (j == 1024 || i == max_pfn) {
   6.212 +            if (j == 1024 || i == p2m_size) {
   6.213                  if(!write_exact(io_fd, &pfntab, sizeof(unsigned long)*j)) {
   6.214                      ERROR("Error when writing to state file (6b) (errno %d)",
   6.215                            errno);
   6.216 @@ -1333,7 +1333,7 @@ int xc_linux_save(int xc_handle, int io_
   6.217          munmap(live_p2m_frame_list, P2M_FLL_ENTRIES * PAGE_SIZE);
   6.218  
   6.219      if (live_p2m)
   6.220 -        munmap(live_p2m, P2M_SIZE);
   6.221 +        munmap(live_p2m, ROUNDUP(p2m_size * sizeof(xen_pfn_t), PAGE_SHIFT));
   6.222  
   6.223      if (live_m2p)
   6.224          munmap(live_m2p, M2P_SIZE(max_mfn));
     7.1 --- a/tools/libxc/xc_resume.c	Mon Apr 02 16:26:23 2007 +0100
     7.2 +++ b/tools/libxc/xc_resume.c	Mon Apr 02 16:46:52 2007 +0100
     7.3 @@ -46,7 +46,7 @@ static int xc_domain_resume_any(int xc_h
     7.4      xc_dominfo_t info;
     7.5      int i, rc = -1;
     7.6  #if defined(__i386__) || defined(__x86_64__)
     7.7 -    unsigned long mfn, max_pfn = 0;
     7.8 +    unsigned long mfn, p2m_size = 0;
     7.9      vcpu_guest_context_t ctxt;
    7.10      start_info_t *start_info;
    7.11      shared_info_t *shinfo = NULL;
    7.12 @@ -74,7 +74,7 @@ static int xc_domain_resume_any(int xc_h
    7.13          goto out;
    7.14      }
    7.15  
    7.16 -    max_pfn = shinfo->arch.max_pfn;
    7.17 +    p2m_size = shinfo->arch.max_pfn;
    7.18  
    7.19      p2m_frame_list_list =
    7.20          xc_map_foreign_range(xc_handle, domid, PAGE_SIZE, PROT_READ,
     8.1 --- a/tools/libxc/xenguest.h	Mon Apr 02 16:26:23 2007 +0100
     8.2 +++ b/tools/libxc/xenguest.h	Mon Apr 02 16:46:52 2007 +0100
     8.3 @@ -43,15 +43,16 @@ int xc_hvm_save(int xc_handle, int io_fd
     8.4   * @parm xc_handle a handle to an open hypervisor interface
     8.5   * @parm fd the file descriptor to restore a domain from
     8.6   * @parm dom the id of the domain
     8.7 - * @parm nr_pfns the number of pages
     8.8 + * @parm p2m_size number of pages the guest has (i.e. number entries in P2M)
     8.9 + * @parm max_nr_pfns domains maximum real memory allocation, in pages
    8.10   * @parm store_evtchn the store event channel for this domain to use
    8.11   * @parm store_mfn returned with the mfn of the store page
    8.12   * @return 0 on success, -1 on failure
    8.13   */
    8.14  int xc_linux_restore(int xc_handle, int io_fd, uint32_t dom,
    8.15 -                     unsigned long nr_pfns, unsigned int store_evtchn,
    8.16 -                     unsigned long *store_mfn, unsigned int console_evtchn,
    8.17 -                     unsigned long *console_mfn);
    8.18 +                     unsigned long p2m_size, unsigned long max_nr_pfns,
    8.19 +                     unsigned int store_evtchn, unsigned long *store_mfn,
    8.20 +                     unsigned int console_evtchn, unsigned long *console_mfn);
    8.21  
    8.22  /**
    8.23   * This function will restore a saved hvm domain running unmodified guest.
     9.1 --- a/tools/libxc/xg_private.h	Mon Apr 02 16:26:23 2007 +0100
     9.2 +++ b/tools/libxc/xg_private.h	Mon Apr 02 16:46:52 2007 +0100
     9.3 @@ -148,17 +148,16 @@ typedef l4_pgentry_64_t l4_pgentry_t;
     9.4  
     9.5  #define ROUNDUP(_x,_w) (((unsigned long)(_x)+(1UL<<(_w))-1) & ~((1UL<<(_w))-1))
     9.6  
     9.7 -/* Size in bytes of the P2M (rounded up to the nearest PAGE_SIZE bytes) */
     9.8 -#define P2M_SIZE        ROUNDUP((max_pfn * sizeof(xen_pfn_t)), PAGE_SHIFT)
     9.9 -
    9.10  /* Number of xen_pfn_t in a page */
    9.11  #define fpp             (PAGE_SIZE/sizeof(xen_pfn_t))
    9.12  
    9.13 +/* XXX SMH: following 3 skanky macros rely on variable p2m_size being set */
    9.14 +
    9.15  /* Number of entries in the pfn_to_mfn_frame_list_list */
    9.16 -#define P2M_FLL_ENTRIES (((max_pfn)+(fpp*fpp)-1)/(fpp*fpp))
    9.17 +#define P2M_FLL_ENTRIES (((p2m_size)+(fpp*fpp)-1)/(fpp*fpp))
    9.18  
    9.19  /* Number of entries in the pfn_to_mfn_frame_list */
    9.20 -#define P2M_FL_ENTRIES  (((max_pfn)+fpp-1)/fpp)
    9.21 +#define P2M_FL_ENTRIES  (((p2m_size)+fpp-1)/fpp)
    9.22  
    9.23  /* Size in bytes of the pfn_to_mfn_frame_list     */
    9.24  #define P2M_FL_SIZE     ((P2M_FL_ENTRIES)*sizeof(unsigned long))
    10.1 --- a/tools/python/xen/xend/XendCheckpoint.py	Mon Apr 02 16:26:23 2007 +0100
    10.2 +++ b/tools/python/xen/xend/XendCheckpoint.py	Mon Apr 02 16:46:52 2007 +0100
    10.3 @@ -187,6 +187,7 @@ def restore(xd, fd, dominfo = None, paus
    10.4      assert console_port
    10.5  
    10.6      nr_pfns = (dominfo.getMemoryTarget() + 3) / 4 
    10.7 +    max_nr_pfns = (dominfo.getMemoryMaximum() + 3) / 4 
    10.8  
    10.9      # if hvm, pass mem size to calculate the store_mfn
   10.10      image_cfg = dominfo.info.get('image', {})
   10.11 @@ -203,17 +204,17 @@ def restore(xd, fd, dominfo = None, paus
   10.12      try:
   10.13          l = read_exact(fd, sizeof_unsigned_long,
   10.14                         "not a valid guest state file: pfn count read")
   10.15 -        max_pfn = unpack("L", l)[0]    # native sizeof long
   10.16 +        p2m_size = unpack("L", l)[0]    # native sizeof long
   10.17  
   10.18 -        if max_pfn > 16*1024*1024:     # XXX 
   10.19 +        if p2m_size > 16*1024*1024:     # XXX 
   10.20              raise XendError(
   10.21                  "not a valid guest state file: pfn count out of range")
   10.22  
   10.23          shadow = dominfo.info['shadow_memory']
   10.24          log.debug("restore:shadow=0x%x, _static_max=0x%x, _static_min=0x%x, "
   10.25 -                  "nr_pfns=0x%x.", dominfo.info['shadow_memory'],
   10.26 +                  "p2m_size=0x%x.", dominfo.info['shadow_memory'],
   10.27                    dominfo.info['memory_static_max'],
   10.28 -                  dominfo.info['memory_static_min'], nr_pfns)
   10.29 +                  dominfo.info['memory_static_min'], p2m_size)
   10.30  
   10.31          balloon.free(xc.pages_to_kib(nr_pfns) + shadow * 1024)
   10.32  
   10.33 @@ -221,7 +222,7 @@ def restore(xd, fd, dominfo = None, paus
   10.34          dominfo.info['shadow_memory'] = shadow_cur
   10.35  
   10.36          cmd = map(str, [xen.util.auxbin.pathTo(XC_RESTORE),
   10.37 -                        fd, dominfo.getDomid(), max_pfn,
   10.38 +                        fd, dominfo.getDomid(), p2m_size, max_nr_pfns, 
   10.39                          store_port, console_port, int(is_hvm), pae, apic])
   10.40          log.debug("[xc_restore]: %s", string.join(cmd))
   10.41  
    11.1 --- a/tools/xcutils/xc_restore.c	Mon Apr 02 16:26:23 2007 +0100
    11.2 +++ b/tools/xcutils/xc_restore.c	Mon Apr 02 16:46:52 2007 +0100
    11.3 @@ -18,15 +18,14 @@
    11.4  int
    11.5  main(int argc, char **argv)
    11.6  {
    11.7 -    unsigned int xc_fd, io_fd, domid, max_pfn, store_evtchn, console_evtchn;
    11.8 +    unsigned int xc_fd, io_fd, domid, store_evtchn, console_evtchn;
    11.9      unsigned int hvm, pae, apic;
   11.10      int ret;
   11.11 -    unsigned long store_mfn, console_mfn;
   11.12 +    unsigned long p2m_size, max_nr_pfns, store_mfn, console_mfn;
   11.13  
   11.14 -    if (argc != 9)
   11.15 -	errx(1,
   11.16 -	     "usage: %s iofd domid max_pfn store_evtchn console_evtchn hvm pae apic",
   11.17 -	     argv[0]);
   11.18 +    if (argc != 10)
   11.19 +        errx(1, "usage: %s iofd domid p2m_size max_nr_pfns store_evtchn "
   11.20 +             "console_evtchn hvm pae apic", argv[0]);
   11.21  
   11.22      xc_fd = xc_interface_open();
   11.23      if (xc_fd < 0)
   11.24 @@ -34,19 +33,21 @@ main(int argc, char **argv)
   11.25  
   11.26      io_fd = atoi(argv[1]);
   11.27      domid = atoi(argv[2]);
   11.28 -    max_pfn = atoi(argv[3]);
   11.29 -    store_evtchn = atoi(argv[4]);
   11.30 -    console_evtchn = atoi(argv[5]);
   11.31 -    hvm  = atoi(argv[6]);
   11.32 -    pae  = atoi(argv[7]);
   11.33 -    apic = atoi(argv[8]);
   11.34 +    p2m_size = atoi(argv[3]);
   11.35 +    max_nr_pfns = atoi(argv[4]);
   11.36 +    store_evtchn = atoi(argv[5]);
   11.37 +    console_evtchn = atoi(argv[6]);
   11.38 +    hvm  = atoi(argv[7]);
   11.39 +    pae  = atoi(argv[8]);
   11.40 +    apic = atoi(argv[9]);
   11.41  
   11.42      if (hvm) {
   11.43 -        ret = xc_hvm_restore(xc_fd, io_fd, domid, max_pfn, store_evtchn,
   11.44 +        ret = xc_hvm_restore(xc_fd, io_fd, domid, max_nr_pfns, store_evtchn,
   11.45                  &store_mfn, pae, apic);
   11.46 -    } else 
   11.47 -        ret = xc_linux_restore(xc_fd, io_fd, domid, max_pfn, store_evtchn,
   11.48 -                &store_mfn, console_evtchn, &console_mfn);
   11.49 +    } else
   11.50 +        ret = xc_linux_restore(xc_fd, io_fd, domid, p2m_size,
   11.51 +                               max_nr_pfns, store_evtchn, &store_mfn,
   11.52 +                               console_evtchn, &console_mfn);
   11.53  
   11.54      if (ret == 0) {
   11.55  	printf("store-mfn %li\n", store_mfn);