ia64/xen-unstable

changeset 2130:c61b505b6a52

bitkeeper revision 1.1159.1.17 (411756a8kKZuzEWAvdGV8rtw_viqYA)

Merge labyrinth.cl.cam.ac.uk:/auto/groups/xeno/BK/xeno.bk
into labyrinth.cl.cam.ac.uk:/auto/anfs/scratch/labyrinth/iap10/xeno-clone/xeno.bk
author iap10@labyrinth.cl.cam.ac.uk
date Mon Aug 09 10:49:12 2004 +0000 (2004-08-09)
parents e2ca4e318afa 452bfe2b4c6d
children 2acd7bcbfab4 9f51eece2c65
files linux-2.4.26-xen-sparse/arch/xen/kernel/setup.c linux-2.6.7-xen-sparse/drivers/xen/netfront/netfront.c linux-2.6.7-xen-sparse/drivers/xen/privcmd/privcmd.c linux-2.6.7-xen-sparse/include/asm-xen/proc_cmd.h tools/libxc/xc_linux_save.c tools/libxc/xc_private.c tools/libxc/xc_private.h xen/arch/x86/domain.c xen/include/hypervisor-ifs/arch-x86_32.h xen/include/hypervisor-ifs/hypervisor-if.h
line diff
     1.1 --- a/linux-2.4.26-xen-sparse/arch/xen/kernel/setup.c	Mon Aug 09 10:20:37 2004 +0000
     1.2 +++ b/linux-2.4.26-xen-sparse/arch/xen/kernel/setup.c	Mon Aug 09 10:49:12 2004 +0000
     1.3 @@ -60,7 +60,7 @@ static int errno;
     1.4   */
     1.5  shared_info_t *HYPERVISOR_shared_info = (shared_info_t *)empty_zero_page;
     1.6  
     1.7 -unsigned long *phys_to_machine_mapping;
     1.8 +unsigned long *phys_to_machine_mapping, *pfn_to_mfn_frame_list;
     1.9  
    1.10  multicall_entry_t multicall_list[8];
    1.11  int nr_multicall_ents = 0;
    1.12 @@ -202,6 +202,7 @@ int xen_module_init(struct module *mod)
    1.13  
    1.14  void __init setup_arch(char **cmdline_p)
    1.15  {
    1.16 +    int i,j;
    1.17      unsigned long bootmap_size, start_pfn, lmax_low_pfn;
    1.18      int mem_param;  /* user specified memory size in pages */
    1.19      int boot_pfn;   /* low pages available for bootmem */
    1.20 @@ -370,6 +371,22 @@ void __init setup_arch(char **cmdline_p)
    1.21  
    1.22      paging_init();
    1.23  
    1.24 +    pfn_to_mfn_frame_list = alloc_bootmem_low_pages(PAGE_SIZE);
    1.25 +    for ( i=0, j=0; i < max_pfn; i+=(PAGE_SIZE/sizeof(unsigned long)), j++ )
    1.26 +    {	
    1.27 +        pfn_to_mfn_frame_list[j] = 
    1.28 +            virt_to_machine(&phys_to_machine_mapping[i]) >> PAGE_SHIFT;
    1.29 +    }
    1.30 +//pfn_to_mfn_frame_list[0] = 0xdeadbeff;
    1.31 +printk("Hsi %lx %lx :: %lx\n",    pfn_to_mfn_frame_list,
    1.32 +       virt_to_machine(pfn_to_mfn_frame_list),
    1.33 +HYPERVISOR_shared_info->arch.mfn_to_pfn_start
    1.34 +       );
    1.35 +    HYPERVISOR_shared_info->arch.pfn_to_mfn_frame_list =
    1.36 +	virt_to_machine(pfn_to_mfn_frame_list) >> PAGE_SHIFT;
    1.37 +
    1.38 +
    1.39 +
    1.40      /* If we are a privileged guest OS then we should request IO privileges. */
    1.41      if ( start_info.flags & SIF_PRIVILEGED ) 
    1.42      {
    1.43 @@ -1194,50 +1211,16 @@ static void __do_suspend(void)
    1.44      extern void time_suspend(void);
    1.45      extern void time_resume(void);
    1.46  
    1.47 -    unsigned long *pfn_to_mfn_frame_list = NULL;
    1.48      suspend_record_t *suspend_record     = NULL;
    1.49 -    struct net_device *dev;
    1.50 -    char name[6];
    1.51 -    int i, j;
    1.52  
    1.53 -    if ( (pfn_to_mfn_frame_list = (unsigned long *)__get_free_page(GFP_KERNEL))
    1.54 -         == NULL )
    1.55 -        goto out;
    1.56      if ( (suspend_record = (suspend_record_t *)__get_free_page(GFP_KERNEL))
    1.57           == NULL )
    1.58          goto out;
    1.59  
    1.60 -    suspend_record->pfn_to_mfn_frame_list = 
    1.61 -        virt_to_machine(pfn_to_mfn_frame_list) >> PAGE_SHIFT;
    1.62 -    suspend_record->nr_pfns = max_pfn;
    1.63 +    suspend_record->nr_pfns = max_pfn; /* final number of pfns */
    1.64  
    1.65 -    for ( i=0, j=0; i < max_pfn; i+=(PAGE_SIZE/sizeof(unsigned long)), j++ )
    1.66 -    {	
    1.67 -        pfn_to_mfn_frame_list[j] = 
    1.68 -            virt_to_machine(&phys_to_machine_mapping[i]) >> PAGE_SHIFT;
    1.69 -    }
    1.70 -    /*
    1.71 -     * NB. This is /not/ a full dev_close() as that loses route information!
    1.72 -     * Instead we do essentialy the same as dev_close() but without notifying
    1.73 -     * various registered subsystems about the NETDEV_DOWN event.
    1.74 -     */
    1.75 -    rtnl_lock();
    1.76 -    for ( i = 0; i < 10; i++ )
    1.77 -    {
    1.78 -        sprintf(name, "eth%d", i);
    1.79 -        if ( ((dev = __dev_get_by_name(name)) != NULL) &&
    1.80 -             (dev->flags & IFF_UP) )
    1.81 -        {
    1.82 -            dev_deactivate(dev);
    1.83 -            clear_bit(__LINK_STATE_START, &dev->state);
    1.84 -            if ( dev->stop != NULL )
    1.85 -                dev->stop(dev);
    1.86 -            dev->flags &= ~IFF_UP;
    1.87 -        }
    1.88 -    }
    1.89 -    rtnl_unlock();
    1.90 -
    1.91 -    blkdev_suspend();
    1.92 +    //netdev_suspend();
    1.93 +    //blkdev_suspend();
    1.94  
    1.95      __cli();
    1.96  
    1.97 @@ -1272,36 +1255,10 @@ static void __do_suspend(void)
    1.98  
    1.99      __sti();
   1.100  
   1.101 -    blkdev_resume();
   1.102 -
   1.103 -    /*
   1.104 -     * We now do the opposite of the network suspend code. Basically it's
   1.105 -     * dev_open() but without notifying anyone about NETDEV_UP.
   1.106 -     */
   1.107 -    rtnl_lock();
   1.108 -    for ( i = 0; i < 10; i++ )
   1.109 -    {
   1.110 -        sprintf(name, "eth%d", i);
   1.111 -        if ( ((dev = __dev_get_by_name(name)) != NULL) &&
   1.112 -             !(dev->flags & IFF_UP) )
   1.113 -        {
   1.114 -            set_bit(__LINK_STATE_START, &dev->state);
   1.115 -            if ( (dev->open == NULL) || (dev->open(dev) == 0) )
   1.116 -            {
   1.117 -                dev->flags |= IFF_UP;
   1.118 -                dev_activate(dev);
   1.119 -            }
   1.120 -            else
   1.121 -            {
   1.122 -                clear_bit(__LINK_STATE_START, &dev->state);
   1.123 -            } 
   1.124 -        }
   1.125 -    }
   1.126 -    rtnl_unlock();
   1.127 +    //blkdev_resume();
   1.128 +    //netdev_resume();
   1.129  
   1.130   out:
   1.131 -    if ( pfn_to_mfn_frame_list != NULL )
   1.132 -        free_page((unsigned long)pfn_to_mfn_frame_list);
   1.133      if ( suspend_record != NULL )
   1.134          free_page((unsigned long)suspend_record);
   1.135  }
     2.1 --- a/linux-2.6.7-xen-sparse/drivers/xen/netfront/netfront.c	Mon Aug 09 10:20:37 2004 +0000
     2.2 +++ b/linux-2.6.7-xen-sparse/drivers/xen/netfront/netfront.c	Mon Aug 09 10:49:12 2004 +0000
     2.3 @@ -256,6 +256,10 @@ static void network_alloc_rx_buffers(str
     2.4          
     2.5          rx_pfn_array[nr_pfns] = virt_to_machine(skb->head) >> PAGE_SHIFT;
     2.6  
     2.7 +	/* remove this page from pseudo phys map (migration optimization) */
     2.8 +	phys_to_machine_mapping[virt_to_phys(skb->head) >> PAGE_SHIFT] 
     2.9 +	    = 0x80000001;
    2.10 +
    2.11          rx_mcl[nr_pfns].op = __HYPERVISOR_update_va_mapping;
    2.12          rx_mcl[nr_pfns].args[0] = (unsigned long)skb->head >> PAGE_SHIFT;
    2.13          rx_mcl[nr_pfns].args[1] = 0;
     3.1 --- a/linux-2.6.7-xen-sparse/drivers/xen/privcmd/privcmd.c	Mon Aug 09 10:20:37 2004 +0000
     3.2 +++ b/linux-2.6.7-xen-sparse/drivers/xen/privcmd/privcmd.c	Mon Aug 09 10:49:12 2004 +0000
     3.3 @@ -181,6 +181,18 @@ static int privcmd_ioctl(struct inode *i
     3.4      break;
     3.5  #endif
     3.6  
     3.7 +    case IOCTL_PRIVCMD_GET_MACH2PHYS_START_MFN:
     3.8 +    {
     3.9 +	unsigned long m2p_start_mfn = 
    3.10 +	    HYPERVISOR_shared_info->arch.mfn_to_pfn_start;
    3.11 +
    3.12 +	if( put_user( m2p_start_mfn, (unsigned long *) data ) )
    3.13 +	    ret = -EFAULT;
    3.14 +	else
    3.15 +	    ret = 0;
    3.16 +    }
    3.17 +    break;
    3.18 +
    3.19      default:
    3.20          ret = -EINVAL;
    3.21          break;
     4.1 --- a/linux-2.6.7-xen-sparse/include/asm-xen/proc_cmd.h	Mon Aug 09 10:20:37 2004 +0000
     4.2 +++ b/linux-2.6.7-xen-sparse/include/asm-xen/proc_cmd.h	Mon Aug 09 10:49:12 2004 +0000
     4.3 @@ -58,6 +58,8 @@ typedef struct privcmd_blkmsg
     4.4  #define IOCTL_PRIVCMD_MMAP             \
     4.5      _IOC(_IOC_NONE, 'P', 2, sizeof(privcmd_mmap_t))
     4.6  #define IOCTL_PRIVCMD_MMAPBATCH             \
     4.7 -    _IOC(_IOC_NONE, 'P', 2, sizeof(privcmd_mmapbatch_t))
     4.8 +    _IOC(_IOC_NONE, 'P', 3, sizeof(privcmd_mmapbatch_t))
     4.9 +#define IOCTL_PRIVCMD_GET_MACH2PHYS_START_MFN \
    4.10 +    _IOC(_IOC_READ, 'P', 4, sizeof(unsigned long))
    4.11  
    4.12  #endif /* __PROC_CMD_H__ */
     5.1 --- a/tools/libxc/xc_linux_save.c	Mon Aug 09 10:20:37 2004 +0000
     5.2 +++ b/tools/libxc/xc_linux_save.c	Mon Aug 09 10:49:12 2004 +0000
     5.3 @@ -12,7 +12,7 @@
     5.4  
     5.5  #define BATCH_SIZE 1024   /* 1024 pages (4MB) at a time */
     5.6  
     5.7 -#define DEBUG 0
     5.8 +#define DEBUG 1
     5.9  #define DDEBUG 0
    5.10  
    5.11  #if DEBUG
    5.12 @@ -32,6 +32,8 @@
    5.13   * in the guest's pseudophysical map.
    5.14   * 0x80000000-3 mark the shared_info, and blk/net rings
    5.15   */
    5.16 +
    5.17 +#if 0 
    5.18  #define MFN_IS_IN_PSEUDOPHYS_MAP(_mfn)                                    \
    5.19      (((_mfn) < (1024*1024)) &&                                            \
    5.20       (((live_mfn_to_pfn_table[_mfn] < nr_pfns) &&                         \
    5.21 @@ -39,7 +41,13 @@
    5.22        ((live_mfn_to_pfn_table[_mfn] >= 0x80000000) &&                     \
    5.23         (live_mfn_to_pfn_table[_mfn] <= 0x80000003)) ||                    \
    5.24        (live_pfn_to_mfn_table[live_mfn_to_pfn_table[_mfn]] == 0x80000004)))
    5.25 -     
    5.26 +#endif
    5.27 +#define MFN_IS_IN_PSEUDOPHYS_MAP(_mfn)                                    \
    5.28 +    (((_mfn) < (1024*1024)) &&                                            \
    5.29 +     ((live_mfn_to_pfn_table[_mfn] < nr_pfns) &&                         \
    5.30 +       (live_pfn_to_mfn_table[live_mfn_to_pfn_table[_mfn]] == (_mfn))))
    5.31 +
    5.32 + 
    5.33  /* Returns TRUE if MFN is successfully converted to a PFN. */
    5.34  #define translate_mfn_to_pfn(_pmfn)            \
    5.35  ({                                             \
    5.36 @@ -238,7 +246,7 @@ int xc_linux_save(int xc_handle, XcIOCon
    5.37      int rc = 1, i, j, k, last_iter, iter = 0;
    5.38      unsigned long mfn;
    5.39      u32 domid = ioctxt->domain;
    5.40 -    int live = (ioctxt->flags & XCFLAGS_LIVE);
    5.41 +    int live = 0; // (ioctxt->flags & XCFLAGS_LIVE);
    5.42      int debug = (ioctxt->flags & XCFLAGS_DEBUG);
    5.43      int sent_last_iter, skip_this_iter;
    5.44  
    5.45 @@ -270,9 +278,10 @@ int xc_linux_save(int xc_handle, XcIOCon
    5.46      unsigned long *live_pfn_to_mfn_table = NULL;
    5.47      /* Live mapping of system MFN to PFN table. */
    5.48      unsigned long *live_mfn_to_pfn_table = NULL;
    5.49 +    unsigned long mfn_to_pfn_table_start_mfn;
    5.50      
    5.51      /* Live mapping of shared info structure */
    5.52 -    unsigned long *live_shinfo;
    5.53 +    shared_info_t *live_shinfo;
    5.54  
    5.55      /* base of the region in which domain memory is mapped */
    5.56      unsigned char *region_base = NULL;
    5.57 @@ -302,12 +311,6 @@ int xc_linux_save(int xc_handle, XcIOCon
    5.58          return 1;
    5.59      }
    5.60  
    5.61 -    /* Ensure that the domain exists, and that it is stopped. */
    5.62 -    if ( xc_domain_pause(xc_handle, domid) ){
    5.63 -        xcio_perror(ioctxt, "Could not pause domain");
    5.64 -        goto out;
    5.65 -    }
    5.66 -
    5.67      if ( xc_domain_getfullinfo( xc_handle, domid, &op, &ctxt) )
    5.68      {
    5.69          xcio_error(ioctxt, "Could not get full domain info");
    5.70 @@ -321,18 +324,8 @@ int xc_linux_save(int xc_handle, XcIOCon
    5.71          xcio_error(ioctxt, "Domain is not in a valid Linux guest OS state");
    5.72          goto out;
    5.73      }
    5.74 -
    5.75 -    /* Map the suspend-record MFN to pin it. The page must be owned by 
    5.76 -       domid for this to succeed. */
    5.77 -    p_srec = mfn_mapper_map_single(xc_handle, domid,
    5.78 -                                   sizeof(*p_srec), PROT_READ, 
    5.79 -                                   ctxt.cpu_ctxt.esi);
    5.80 -    if (!p_srec){
    5.81 -        xcio_error(ioctxt, "Couldn't map state record");
    5.82 -        goto out;
    5.83 -    }
    5.84 -
    5.85 -    nr_pfns = p_srec->nr_pfns;
    5.86 +    
    5.87 +    nr_pfns = op.u.getdomaininfo.max_pages; 
    5.88  
    5.89      /* cheesy sanity check */
    5.90      if ( nr_pfns > 1024*1024 ){
    5.91 @@ -340,34 +333,28 @@ int xc_linux_save(int xc_handle, XcIOCon
    5.92          goto out;
    5.93      }
    5.94  
    5.95 +
    5.96 +    /* Map the shared info frame */
    5.97 +    live_shinfo = mfn_mapper_map_single(xc_handle, domid,
    5.98 +                                        PAGE_SIZE, PROT_READ,
    5.99 +                                        shared_info_frame);
   5.100 +
   5.101 +    if (!live_shinfo){
   5.102 +        xcio_error(ioctxt, "Couldn't map live_shinfo");
   5.103 +        goto out;
   5.104 +    }
   5.105 +
   5.106      /* the pfn_to_mfn_frame_list fits in a single page */
   5.107      live_pfn_to_mfn_frame_list = 
   5.108          mfn_mapper_map_single(xc_handle, domid, 
   5.109                                PAGE_SIZE, PROT_READ, 
   5.110 -                              p_srec->pfn_to_mfn_frame_list );
   5.111 +                              live_shinfo->arch.pfn_to_mfn_frame_list );
   5.112  
   5.113      if (!live_pfn_to_mfn_frame_list){
   5.114          xcio_error(ioctxt, "Couldn't map pfn_to_mfn_frame_list");
   5.115          goto out;
   5.116      }
   5.117  
   5.118 -    /* Track the mfn_to_pfn table down from the domains PT */
   5.119 -    {
   5.120 -        unsigned long *pgd;
   5.121 -        unsigned long mfn_to_pfn_table_start_mfn;
   5.122 -
   5.123 -        pgd = mfn_mapper_map_single(xc_handle, domid, 
   5.124 -                                    PAGE_SIZE, PROT_READ, 
   5.125 -                                    ctxt.pt_base>>PAGE_SHIFT);
   5.126 -
   5.127 -        mfn_to_pfn_table_start_mfn = 
   5.128 -            pgd[HYPERVISOR_VIRT_START>>L2_PAGETABLE_SHIFT]>>PAGE_SHIFT;
   5.129 -
   5.130 -        live_mfn_to_pfn_table = 
   5.131 -            mfn_mapper_map_single(xc_handle, 0x7FFFU, 
   5.132 -                                  PAGE_SIZE*1024, PROT_READ, 
   5.133 -                                  mfn_to_pfn_table_start_mfn );
   5.134 -    }
   5.135  
   5.136      /* Map all the frames of the pfn->mfn table. For migrate to succeed, 
   5.137         the guest must not change which frames are used for this purpose. 
   5.138 @@ -383,9 +370,17 @@ int xc_linux_save(int xc_handle, XcIOCon
   5.139          goto out;
   5.140      }
   5.141  
   5.142 +    /* Setup the mfn_to_pfn table mapping */
   5.143 +    mfn_to_pfn_table_start_mfn = xc_get_m2p_start_mfn( xc_handle );
   5.144 +
   5.145 +    live_mfn_to_pfn_table = 
   5.146 +	mfn_mapper_map_single(xc_handle, 0x7FFFFFFF, 
   5.147 +			      PAGE_SIZE*1024, PROT_READ, 
   5.148 +			      mfn_to_pfn_table_start_mfn );
   5.149  
   5.150      /* Canonicalise the pfn-to-mfn table frame-number list. */
   5.151      memcpy( pfn_to_mfn_frame_list, live_pfn_to_mfn_frame_list, PAGE_SIZE );
   5.152 +
   5.153      for ( i = 0; i < nr_pfns; i += 1024 ){
   5.154          if ( !translate_mfn_to_pfn(&pfn_to_mfn_frame_list[i/1024]) ){
   5.155              xcio_error(ioctxt, "Frame # in pfn-to-mfn frame list is not in pseudophys");
   5.156 @@ -393,8 +388,8 @@ int xc_linux_save(int xc_handle, XcIOCon
   5.157          }
   5.158      }
   5.159  
   5.160 -    /* At this point, we can start the domain again if we're doing a
   5.161 -       live suspend */
   5.162 +
   5.163 +    /* Domain is still running at this point */
   5.164  
   5.165      if( live ){ 
   5.166          if ( xc_shadow_control( xc_handle, domid, 
   5.167 @@ -404,15 +399,31 @@ int xc_linux_save(int xc_handle, XcIOCon
   5.168              goto out;
   5.169          }
   5.170  
   5.171 -        if ( xc_domain_unpause(xc_handle, domid) < 0 ){
   5.172 -            xcio_error(ioctxt, "Couldn't unpause domain");
   5.173 -            goto out;
   5.174 -        }
   5.175 -
   5.176          last_iter = 0;
   5.177          sent_last_iter = 1<<20; /* 4GB of pages */
   5.178      } else{
   5.179 +	/* This is a non-live suspend. Issue the call back to get the
   5.180 +	 domain suspended */
   5.181 +
   5.182          last_iter = 1;
   5.183 +
   5.184 +	xcio_suspend_domain(ioctxt);
   5.185 +
   5.186 +	if ( xc_domain_getfullinfo( xc_handle, domid, &op, &ctxt) )
   5.187 +	{
   5.188 +	    xcio_error(ioctxt, "Could not get full domain info");
   5.189 +	    goto out;
   5.190 +	}
   5.191 +
   5.192 +	if ( (op.u.getdomaininfo.flags & 
   5.193 +	     ( DOMFLAGS_SHUTDOWN | (SHUTDOWN_suspend<<DOMFLAGS_SHUTDOWNSHIFT) ))
   5.194 +	     != ( DOMFLAGS_SHUTDOWN | (SHUTDOWN_suspend<<DOMFLAGS_SHUTDOWNSHIFT) ))
   5.195 +	{
   5.196 +	    xcio_error(ioctxt, "Domain appears not to have suspended: %lx",
   5.197 +		       op.u.getdomaininfo.flags);
   5.198 +	    goto out;
   5.199 +	}
   5.200 +
   5.201      }
   5.202  
   5.203      /* calculate the power of 2 order of nr_pfns, e.g.
   5.204 @@ -421,7 +432,11 @@ int xc_linux_save(int xc_handle, XcIOCon
   5.205  
   5.206      /* Setup to_send bitmap */
   5.207      {
   5.208 -        int sz = (nr_pfns/8) + 8; /* includes slop at end of array */
   5.209 +	/* size these for a maximal 4GB domain, to make interaction
   5.210 +	   with balloon driver easier. It's only user space memory,
   5.211 +	   ater all... (3x 128KB) */
   5.212 +
   5.213 +        int sz = ( 1<<20 ) / 8;
   5.214   
   5.215          to_send = malloc( sz );
   5.216          to_fix  = calloc( 1, sz );
   5.217 @@ -469,24 +484,23 @@ int xc_linux_save(int xc_handle, XcIOCon
   5.218       * Quick belt and braces sanity check.
   5.219       */
   5.220  #if DEBUG
   5.221 -    for ( i = 0; i < nr_pfns; i++ ){
   5.222 -        mfn = live_pfn_to_mfn_table[i];
   5.223 -
   5.224 -        if( (live_mfn_to_pfn_table[mfn] != i) && (mfn != 0x80000004) )
   5.225 -            printf("i=0x%x mfn=%x live_mfn_to_pfn_table=%x\n",
   5.226 -                   i,mfn,live_mfn_to_pfn_table[mfn]);
   5.227 +    {
   5.228 +	int err=0;
   5.229 +	for ( i = 0; i < nr_pfns; i++ )
   5.230 +	{
   5.231 +	    mfn = live_pfn_to_mfn_table[i];
   5.232 +	    
   5.233 +	    if( (live_mfn_to_pfn_table[mfn] != i) && (mfn != 0x80000001) )
   5.234 +	    {
   5.235 +		printf("i=0x%x mfn=%lx live_mfn_to_pfn_table=%lx\n",
   5.236 +		       i,mfn,live_mfn_to_pfn_table[mfn]);
   5.237 +		err++;
   5.238 +	    }
   5.239 +	}
   5.240 +	printf("Had %d unexplained entries in p2m table\n",err);
   5.241      }
   5.242  #endif
   5.243  
   5.244 -    /* Map the shared info frame */
   5.245 -    live_shinfo = mfn_mapper_map_single(xc_handle, domid,
   5.246 -                                        PAGE_SIZE, PROT_READ,
   5.247 -                                        shared_info_frame);
   5.248 -
   5.249 -    if (!live_shinfo){
   5.250 -        xcio_error(ioctxt, "Couldn't map live_shinfo");
   5.251 -        goto out;
   5.252 -    }
   5.253  
   5.254      /* Start writing out the saved-domain record. */
   5.255  
   5.256 @@ -529,9 +543,10 @@ int xc_linux_save(int xc_handle, XcIOCon
   5.257                 but this is fast enough for the moment. */
   5.258  
   5.259              if ( !last_iter && 
   5.260 -                 xc_shadow_control(xc_handle, domid, 
   5.261 +		 xc_shadow_control(xc_handle, domid, 
   5.262                                     DOM0_SHADOW_CONTROL_OP_PEEK,
   5.263 -                                   to_skip, nr_pfns, NULL) != nr_pfns ) {
   5.264 +                                   to_skip, nr_pfns, NULL) != nr_pfns )
   5.265 +	    {
   5.266                  xcio_error(ioctxt, "Error peeking shadow bitmap");
   5.267                  goto out;
   5.268              }
   5.269 @@ -591,7 +606,7 @@ int xc_linux_save(int xc_handle, XcIOCon
   5.270                       !test_bit(n, to_send) )
   5.271                  {
   5.272                      needed_to_fix++;
   5.273 -                    DPRINTF("Fix! iter %d, pfn %lx. mfn %lx\n",
   5.274 +                    DPRINTF("Fix! iter %d, pfn %x. mfn %lx\n",
   5.275                              iter,n,pfn_type[batch]);
   5.276                  }
   5.277  
   5.278 @@ -764,7 +779,26 @@ int xc_linux_save(int xc_handle, XcIOCon
   5.279                  DPRINTF("Start last iteration\n");
   5.280                  last_iter = 1;
   5.281  
   5.282 -                xc_domain_pause( xc_handle, domid );
   5.283 +		xcio_suspend_domain(ioctxt);
   5.284 +		
   5.285 +		if ( xc_domain_getfullinfo( xc_handle, domid, &op, &ctxt) )
   5.286 +		{
   5.287 +		    xcio_error(ioctxt, "Could not get full domain info");
   5.288 +		    goto out;
   5.289 +		}
   5.290 +		
   5.291 +		if ( (op.u.getdomaininfo.flags & 
   5.292 +		      ( DOMFLAGS_SHUTDOWN |
   5.293 +			(SHUTDOWN_suspend<<DOMFLAGS_SHUTDOWNSHIFT) ))
   5.294 +		     != ( DOMFLAGS_SHUTDOWN |
   5.295 +			  (SHUTDOWN_suspend<<DOMFLAGS_SHUTDOWNSHIFT) ))
   5.296 +		{
   5.297 +		    xcio_error(ioctxt, 
   5.298 +			       "Domain appears not to have suspended: %lx",
   5.299 +			       op.u.getdomaininfo.flags);
   5.300 +		    goto out;
   5.301 +		}
   5.302 +
   5.303              } 
   5.304  
   5.305              if ( xc_shadow_control( xc_handle, domid, 
   5.306 @@ -796,19 +830,36 @@ int xc_linux_save(int xc_handle, XcIOCon
   5.307          goto out;
   5.308      }
   5.309  
   5.310 -    /* Get the final execution context */
   5.311 -    if ( xc_domain_getfullinfo( xc_handle, domid, &op, &ctxt) )
   5.312 +printf("SUSPPPPPPPP flags %08lx shinfo %08lx eip %08lx esi %08lx\n", 
   5.313 +       op.u.getdomaininfo.flags, op.u.getdomaininfo.shared_info_frame,
   5.314 +       ctxt.cpu_ctxt.eip, ctxt.cpu_ctxt.esi );
   5.315 +
   5.316 +    /* Map the suspend-record MFN to pin it. The page must be owned by 
   5.317 +       domid for this to succeed. */
   5.318 +    p_srec = mfn_mapper_map_single(xc_handle, domid,
   5.319 +                                   sizeof(*p_srec), PROT_READ, 
   5.320 +                                   ctxt.cpu_ctxt.esi);
   5.321 +    if (!p_srec){
   5.322 +        xcio_error(ioctxt, "Couldn't map suspend record");
   5.323 +        goto out;
   5.324 +    }
   5.325 +
   5.326 +
   5.327 +printf("nrpfns according to suspend record is %ld\n", p_srec->nr_pfns );
   5.328 +
   5.329 +    if (nr_pfns != p_srec->nr_pfns )
   5.330      {
   5.331 -        xcio_perror(ioctxt, "Could not get full domain info");
   5.332 +	xcio_error(ioctxt, "Suspend record nr_pfns unexpected (%ld != %ld)",
   5.333 +		   p_srec->nr_pfns, nr_pfns);
   5.334          goto out;
   5.335      }
   5.336  
   5.337      /* Canonicalise the suspend-record frame number. */
   5.338      if ( !translate_mfn_to_pfn(&ctxt.cpu_ctxt.esi) ){
   5.339 -        xcio_error(ioctxt, "State record is not in range of pseudophys map");
   5.340 +        xcio_error(ioctxt, "Suspend record is not in range of pseudophys map");
   5.341          goto out;
   5.342      }
   5.343 -
   5.344 +       
   5.345      /* Canonicalise each GDT frame number. */
   5.346      for ( i = 0; i < ctxt.gdt_ents; i += 512 ) {
   5.347          if ( !translate_mfn_to_pfn(&ctxt.gdt_frames[i]) ) {
   5.348 @@ -831,7 +882,7 @@ int xc_linux_save(int xc_handle, XcIOCon
   5.349          goto out;
   5.350      }
   5.351      munmap(live_shinfo, PAGE_SIZE);
   5.352 -
   5.353 +printf("Everything saved OK!\n");
   5.354   out:
   5.355      if ( pfn_type != NULL ) free(pfn_type);
   5.356      DPRINTF("Save exit rc=%d\n",rc);
     6.1 --- a/tools/libxc/xc_private.c	Mon Aug 09 10:20:37 2004 +0000
     6.2 +++ b/tools/libxc/xc_private.c	Mon Aug 09 10:49:12 2004 +0000
     6.3 @@ -317,3 +317,18 @@ unsigned long csum_page (void * page)
     6.4  
     6.5      return sum ^ (sum>>32);
     6.6  }
     6.7 +
     6.8 +unsigned long xc_get_m2p_start_mfn ( int xc_handle )
     6.9 +{
    6.10 +    unsigned long mfn;
    6.11 +
    6.12 +    if ( ioctl( xc_handle, IOCTL_PRIVCMD_GET_MACH2PHYS_START_MFN, &mfn ) < 0 )
    6.13 +    {
    6.14 +	perror("xc_get_m2p_start_mfn:");
    6.15 +	return 0;
    6.16 +    }
    6.17 +    return mfn;
    6.18 +}
    6.19 +
    6.20 +
    6.21 +
     7.1 --- a/tools/libxc/xc_private.h	Mon Aug 09 10:20:37 2004 +0000
     7.2 +++ b/tools/libxc/xc_private.h	Mon Aug 09 10:49:12 2004 +0000
     7.3 @@ -209,4 +209,7 @@ int xc_domain_getfullinfo(int xc_handle,
     7.4                            u32 domid,
     7.5                            dom0_op_t *op,
     7.6                            full_execution_context_t *ctxt );
     7.7 +
     7.8 +unsigned long xc_get_m2p_start_mfn ( int xc_handle );
     7.9 +
    7.10  #endif /* __XC_PRIVATE_H__ */
     8.1 --- a/xen/arch/x86/domain.c	Mon Aug 09 10:20:37 2004 +0000
     8.2 +++ b/xen/arch/x86/domain.c	Mon Aug 09 10:49:12 2004 +0000
     8.3 @@ -219,6 +219,8 @@ void arch_do_createdomain(struct domain 
     8.4  {
     8.5      d->shared_info = (void *)alloc_xenheap_page();
     8.6      memset(d->shared_info, 0, PAGE_SIZE);
     8.7 +    d->shared_info->arch.mfn_to_pfn_start = 
     8.8 +	virt_to_phys(&machine_to_phys_mapping[0])>>PAGE_SHIFT;
     8.9      SHARE_PFN_WITH_DOMAIN(virt_to_page(d->shared_info), d);
    8.10      machine_to_phys_mapping[virt_to_phys(d->shared_info) >> 
    8.11                             PAGE_SHIFT] = 0x80000000UL;  /* debug */
     9.1 --- a/xen/include/hypervisor-ifs/arch-x86_32.h	Mon Aug 09 10:20:37 2004 +0000
     9.2 +++ b/xen/include/hypervisor-ifs/arch-x86_32.h	Mon Aug 09 10:49:12 2004 +0000
     9.3 @@ -131,6 +131,12 @@ typedef struct {
     9.4      unsigned long failsafe_callback_eip;
     9.5  } PACKED full_execution_context_t;
     9.6  
     9.7 +typedef struct {
     9.8 +    u64 mfn_to_pfn_start;      /* MFN of start of m2p table */
     9.9 +    u64 pfn_to_mfn_frame_list; /* MFN of a table of MFNs that 
    9.10 +				  make up p2m table */
    9.11 +} PACKED arch_shared_info_t;
    9.12 +
    9.13  #define ARCH_HAS_FAST_TRAP
    9.14  
    9.15  #endif
    10.1 --- a/xen/include/hypervisor-ifs/hypervisor-if.h	Mon Aug 09 10:20:37 2004 +0000
    10.2 +++ b/xen/include/hypervisor-ifs/hypervisor-if.h	Mon Aug 09 10:49:12 2004 +0000
    10.3 @@ -330,6 +330,8 @@ typedef struct shared_info_st
    10.4  
    10.5      execution_context_t execution_context; /* 328 */
    10.6  
    10.7 +    arch_shared_info_t arch;
    10.8 +
    10.9  } PACKED shared_info_t;
   10.10  
   10.11  /*